18

I'm testing a page with an iFrame whose contents are generated by JavaScript dynamically. I have to wait for the iFrame loaded completely to make sure that all the elements are present. I tried the following code, it didn't work.

WebDriver frame = wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("frmMain"));

I also tried to wait for some element in the iFrame to be present. It didn't work, neither.

Any help would be greatly appreciated, thanks!

Ripon Al Wasim
  • 36,924
  • 42
  • 155
  • 176
user2432405
  • 1,406
  • 2
  • 14
  • 29

3 Answers3

18

Select any element on IFrame which takes maximum time to load e.g. any button or image and the wait using the following code.

WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.visibilityOfElementLocated((By
                .name("element"))));

Or rather you can wait for for iFrame to appear and then switch to it and then use the above statement !

Ripon Al Wasim
  • 36,924
  • 42
  • 155
  • 176
Abhishek Singh
  • 10,243
  • 22
  • 74
  • 108
  • I tested the page with the following code: public void SelectSomething(WebDriver driver, String s) { driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); WebDriverWait wait = new WebDriverWait(driver, 20); WebDriver frame = wait.until( ExpectedConditions.frameToBeAvailableAndSwitchToIt("frmMain")); wait = new WebDriverWait(frame, 30); System.out.println("#######################" + (new Date())); System.out.println(frame.getPageSource()); System.out.println("#######################" + (new Date())); //////To be continued... – user2432405 Aug 29 '13 at 03:12
  • try { wait.until(ExpectedConditions.presenceOfElementLocated(By.tagName("img"))); } catch (TimeoutException e) { System.out.println(frame.getPageSource()); } System.out.println("#######################" + (new Date())); System.out.println(frame.getPageSource()); System.out.println("#######################" + (new Date())); } //////To be continued... – user2432405 Aug 29 '13 at 03:14
  • And get the following results sometimes: #######################Thu Aug 29 10:30:36 CST 2013 #######################Thu Aug 29 10:30:37 CST 2013 PageSource Section#2 #######################Thu Aug 29 10:31:09 CST 2013 PageSource Section#3 #######################Thu Aug 29 10:31:09 CST 2013 //////To be continued... – user2432405 Aug 29 '13 at 03:15
  • Here are two problems I couldn't work out: 1. frame.getPageSource() got the source of the whole page, other than that of the iframe. 2. I had waited long enough for elements in the iframe to be present, but the source got with method frame.getPageSource() didn't include anyone. Sorry for the ugly formatting. – user2432405 Aug 29 '13 at 03:15
  • Have you tried switching to the Iframe first and then waiting for an element in it to loading? This is what I do in my code. In C# this is done with `driver.SwitchTo().Frame(driver.FindElement(By.CssSelector(IFrameCss)));` – craastad Aug 29 '13 at 07:11
4

The most robust way to verify a page reload is to verify that an element went stale and then to verify that a new element has loaded.

Choose an element, elementToBeStale, which exists on the "old" page. This is the element you expect to go stale when the page reloads.

Now choose an element you expect to appear on the page once it has reloaded, xPathOfElementToLoad. Note that this can be the same element you expected to go stale.

Note that xPathOfElementToLoad can't be a WebElement because the it doesn't yet exist on the page so it can't be represented by one.

WebDriverWait wait = new WebDriverWait(driver, WAIT_TIME, POLL_INTERVAL);

ExpectedCondition<Boolean> cond1 = ExpectedConditions.stalenessOf(elementToBeStale);
ExpectedCondition<WebElement> cond2 = ExpectedConditions.presenceOfElementLocated(By.xpath(xPathOfElementToLoad));
ExpectedCondition<Boolean> cond = ExpectedConditions.and(cond1, cond2);

wait.until(cond);

This is useful for page reloads because on a page reload waiting for a WebElement to go stale guarantees the element no longer exists and then waiting for a new element to exist guarantees the new page has loaded

Archmede
  • 1,592
  • 2
  • 20
  • 37
  • Thanks! This helped me a lot. Just needed to change second condition (cond2) to more general one without putting locator there: `ExpectedCondition stalenessOfOldElement = ExpectedConditions.stalenessOf(elementOld); ExpectedCondition visibilityOfNewElement = ExpectedConditions.visibilityOf(elementNew); ExpectedCondition readyToSwitch = ExpectedConditions.and(stalenessOfOldElement, visibilityOfNewElement); wait.until(readyToSwitch);` – Grzech May 12 '22 at 07:23
  • @Grzech the reason I use an xpath for the new element is because how would you have found the element you're looking for if the page hasn't loaded yet? – Archmede May 12 '22 at 13:35
0

I don't know if you already solved this, but here it goes.

Your code is missing the type of search for the element, and I think is "By.ID", so your code should be:

WebDriver frame = wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt((By.ID, "frmMain")))
Nitin
  • 2,701
  • 2
  • 30
  • 60