1

I made a loop for an iframe locator with java code but its not working. Can anyone see the problem?

invoking the class with:

driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
            WebElement searchButton = IFrameLocator.switchToIFrameWithElement(driver,driver.findElement(By.cssSelector("[href*='Search.mvc'][class*='magnify']")));

and use this after:

searchButton.click();


public class IFrameLocator {

    public static WebElement switchToIFrameWithElement(WebDriver driver, WebElement element) {
        try {
            driver.switchTo().defaultContent();
            element.isDisplayed();
        } catch (Exception continueFlow) {

            WebDriverWait wait = new WebDriverWait(driver, 20);
            List<WebElement> frames = driver.findElements(By.cssSelector("iframe"));
            for (WebElement frame : frames) {
                driver.switchTo().defaultContent();
                try {
                    wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(frame));
                    if (element.isDisplayed()) {
                        break;
                    }
                } catch (NoSuchElementException | StaleElementReferenceException | ElementNotInteractableException ignored) {
                }
            }
        }   return element;
    }
}
Moshe Slavin
  • 5,127
  • 5
  • 23
  • 38
  • "frameToBeAvailableAndSwitchToIt" takes a locator. https://seleniumhq.github.io/selenium/docs/api/dotnet/html/M_OpenQA_Selenium_Support_UI_ExpectedConditions_FrameToBeAvailableAndSwitchToIt.htm Maybe check if it's present instead... and then run a switchto on it:driver.switchTo().frame([name or id]); – pcalkins Jun 18 '19 at 17:27
  • switchTo().frame() might also work by just using the element object. – pcalkins Jun 18 '19 at 17:34
  • i added System.out.println("Iframelocator has been invoked"); but its not even going in to the method as it seems. – Yalcin Batur Jun 18 '19 at 17:34
  • Driver not loaded... no such element: Unable to locate element: {"method":"css selector","selector":"[href*='Search.mvc'][class*='magnify']"} – Yalcin Batur Jun 18 '19 at 17:37
  • the method is in a catch... what are you catching here? – pcalkins Jun 18 '19 at 17:43
  • StaleElementReferenceException available element. Assume there is an element that is found on a web page referenced as a WebElement in WebDriver. If the DOM changes then the WebElement goes stale. If we try to interact with an element which is staled then the StaleElementReferenceException is thrown. ElementNotInteractableException ElementNotInteractableException is the W3C exception which is thrown to indicate that although an element is present on the HTML DOM, it is not in a state that can be interacted with – Yalcin Batur Jun 18 '19 at 17:46
  • you may or may not get the stale reference depending on how fast the site returns all these search buttons. (or one button?... you should probably post the markup here) You need to have a method you call, and if you get the stale element exception you re-call that method. – pcalkins Jun 18 '19 at 17:48
  • Did you checked [this](https://stackoverflow.com/questions/55536851/is-there-a-way-to-search-webelement-on-a-main-window-first-if-not-found-then-s/55537186#55537186) – supputuri Jun 18 '19 at 17:51
  • ahh I see what you're trying to do. So you're trying to find out if the search button is inside an iframe. Stale element only fires if you first find the element, and then it changes before you do something with it. You are finding the element with your "driver.findElement(By.cssSelector("[href*='Search.mvc'][class*='magnify']")" call, which means it's not in an iframe. (actually unsure of this.. .maybe it can find it in an iframe.) – pcalkins Jun 18 '19 at 17:53
  • to be clear " element.isDisplayed();" is throwing the stale element error. This does not mean it's not there. It means something changed it between finding the element and calling any method on it. You'll need a method that detects the true/false state and re-call that if you catch a stale element exception. (since other exceptions can be called be sure to check for this specific exception) What's probably happening is the iframes are still loading their pages. – pcalkins Jun 18 '19 at 17:58
  • yes it is in a frame. It works if i write it like this: wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("ifrUserTools")); WebElement searchButton = wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("[href*='Search.mvc'][class*='magnify']"))); searchButton.click(); – Yalcin Batur Jun 18 '19 at 18:04
  • But i just want the loop to be working in order to save time for searching for frames when the element is in one. – Yalcin Batur Jun 18 '19 at 18:05
  • Did you checked this – supputuri what is the .size for it cant resolve the method. – Yalcin Batur Jun 18 '19 at 18:06
  • the second wait would be the problem then. Maybe just try removing the wait from the searchButton click. It's already waiting for the iframe to load so unless you do another action there you should be safe without it. Just test for existence. – pcalkins Jun 18 '19 at 18:17
  • 1
    ...and then get rid of the implicitwait. – pcalkins Jun 18 '19 at 18:20
  • solved thanks, see my answer – Yalcin Batur Jun 20 '19 at 11:08

1 Answers1

0

Because i was passing the whole Webelement By cssSelector it was not even going in the loop. So i pass the element like this:

WebElement searchButton = IFrameLocator.switchToIFrameWithElement(driver, By.cssSelector("[href*='Search.mvc'][class*='magnify']"));

So i changed the code and removed the By.cssSelector in 2 spots and all working fine now:

public class IFrameLocator {

public static WebElement switchToIFrameWithElement(WebDriver driver, By element) {
    driver.switchTo().defaultContent();

    try {
        if (driver.findElement(element).isDisplayed()) ;
        {
            System.out.println("Element is displayed on main page");
        }
    } catch (Exception continueFlow) {
        List<WebElement> frames = driver.findElements(By.cssSelector("iframe"));
        for (WebElement frame : frames) {
            driver.switchTo().defaultContent();
            System.out.println("going back to main page");
            try {
                driver.switchTo().frame(frame);
                System.out.println("switched to next frame: " + frame);
                if (driver.findElement(element).isDisplayed()) {
                    System.out.println("element is found in frame: " + frame);
                    break;
                }
            } catch (NoSuchElementException | StaleElementReferenceException | ElementNotInteractableException ignored) {
            }
        }
    }  System.out.println("returned element succesfully");
    return driver.findElement(element);
}

}