Search code examples
javafor-loopiframeselenium-chromedriveriterator

Loop through list of iframes, check for element in iframe and do action with it


Here is the situation: On https://www.globalsqa.com/samplepagetest/ I am trying to access the page "Alertbox" through page dropdown menu Tester's Hub/Demo Testing Site/Alertbox. Before the actual Alertbox page opens, an ad is shown which I want to close off course. An ad is located inside an iframe which in nested inside another iframe.

Now here it becomes interesting...

When page loads, there are several different iframes (7 max from what I could tell) and nested iframe with an ad appears randomly under one of these 7 iframes every time page is loaded.

My idea was to create a list of iframes and for loop, go through all iframes and check whether nested iframe is located under it. When correct iframe is identifed, switch to nested iframe and close down the ad. I also added try/catch method to ignore intercept and staleElement exceptions.

There is something wrong in the for loop code, as loop executes on the first element only. Please see edit below

Edit: I decided to use .println() method and go step by step to see where is the mistake in code. I printed size and iframe id's from the list and they all check out. When I run the test, only first element gets printed out which means it checks only first element for if condition and when it passes, it doesn't loop over the rest of the list. How do I make the loop switch to next element after if condition?

My code:

@Test
    public void globalSQAHoverMenuTest() {
        driver.get("https://www.globalsqa.com/samplepagetest/");
        wdwait.until(ExpectedConditions.presenceOfElementLocated(By.id("menu-item-2822")));
        multiactions.moveToElement(driver.findElement(By.id("menu-item-2822"))).perform();
        wdwait.until(ExpectedConditions.presenceOfElementLocated(By.linkText("Demo Testing Site")));
        multiactions.moveToElement(driver.findElement(By.linkText("Demo Testing Site"))).perform();
        wdwait.until(ExpectedConditions.presenceOfElementLocated(By.linkText("AlertBox")));
        multiactions.moveToElement(driver.findElement(By.linkText("AlertBox"))).click().perform();

        List<WebElement> iframeList = driver.findElements(By.xpath("//iframe[@allowtransparency=\"true\"]"));
        try {
            for (WebElement webElement : iframeList) {
                System.out.println(webElement);
                driver.switchTo().frame(webElement);
                if (!driver.findElements(By.id("ad_iframe")).isEmpty()) {
                    driver.switchTo().frame(driver.findElement(By.id("ad_iframe")));
                    wdwait.until(ExpectedConditions.presenceOfElementLocated(By.id("dismiss-button")));
                    driver.findElement(By.id("dismiss-button")).click();
                }
            }
        }

        catch (ElementClickInterceptedException e) {

        }

        catch (StaleElementReferenceException e) {

        }
    }

Solution

  • I found the solution. Basically after the if statement, I was trapped inside one of iframes, so couldn't iterate through the rest of them as they were located "outside" of it. When I add the following code after if statement, ad closes consistently each time:

    if statement() {
    }
    driver.switchTo().defaultContent();