6

What's the best way to wait for a page to fully load using selenium-webdriver for javascript? I noticed this question is quite similar but I need an implementation in javascript.

var webdriver = require('selenium-webdriver'),
    By = webdriver.By,
    until = webdriver.until;

var driver = new webdriver.Builder()
    .forBrowser('firefox')
    .build();

driver.get('http://www.google.com');

// Wait for the page to fully load here...
// Something like this...
// driver.wait(...);

// Then do other stuff here

driver.quit();
Josh Aguilar
  • 2,111
  • 1
  • 10
  • 17

3 Answers3

19

I found that this works for what I needed.

driver.get('http://www.google.com');

driver.wait(function() {
  return driver.executeScript('return document.readyState').then(function(readyState) {
    return readyState === 'complete';
  });
});

// Do stuff after page load here
Josh Aguilar
  • 2,111
  • 1
  • 10
  • 17
0
This is a solution for both the case where a click brings the user to a page in the same tab and a solution where the click opens the new page in a new browser tab


  /* waitForPageLoad
   * Get the Page ID before the click and after the click. Until the Page id from the first page
   * is no longer equal to the page id of the second page, then we know after a click of a link
   * that the new page is not yet loaded. The timeout will try this until id A is not equal to id B, or timeout.
   * @param {int} timeout
   * @param {string} link
   * @param {string} expectedTitle
   * @return {bool}
   */
  async waitForPageLoad(timeout, link, expectedTitle) {
    let oldHTMLId;
    let newHTMLId;
    let titleWaitingFor;
    const oldHtmlElement = await this.driver.wait(until.elementLocated(By.tagName('html')));
    await link.click();
    await this.driver.wait(async () => {
      const actualTitle = await this.driver.getTitle();
      titleWaitingFor = actualTitle;
      const newHtmlElement = await this.driver.wait(until.elementLocated(By.tagName('html')));
      const newHtmlElementId = await newHtmlElement.getId();
      const oldHtmlElementId = await oldHtmlElement.getId();
      oldHTMLId = oldHtmlElementId;
      newHTMLId = newHtmlElementId;
      return newHtmlElementId !== oldHtmlElementId
      && actualTitle.includes(expectedTitle);
    }, timeout);
    return oldHTMLId !== newHTMLId && titleWaitingFor.includes(expectedTitle);
  }


//This is what I use if the click opens the Page into another browser tab

  /* getWindowHandlesAndExpetedTitle
   * This function waits for the new window handle after a click instead of using a sleep.
   * Once the expected title of the new window is confirmed, the expected title and url are returned.
   * @param expeted title
   * @return string Page Title and url { title: returnTitle, url: currentUrl }.
   */
  async getWindowHandlesAndExpectedPageInfo(expectedTitle, waitTimeout = 6000) {
    try {
      await this.waitForWindowHandleCount(2);
      let returnHandles;
      let returnTitle;
      await this.driver.wait(async () => {
        const handles = await this.driver.getAllWindowHandles();
        returnHandles = handles;
        await this.driver.switchTo().window(handles[1]);
        const actualTitle = await this.driver.getTitle();
        returnTitle = actualTitle;
        return actualTitle.includes(expectedTitle);
      }, waitTimeout);
      const currentUrl = await this.driver.getCurrentUrl();
      await this.driver.close();
      await this.driver.switchTo().window(returnHandles[0]);
      return { title: returnTitle, url: currentUrl };
    } catch (err) {
      console.log(`Function: getWindowHandlesAndExpectedPageInfo failed ${err}`);
      const handles = await this.driver.getAllWindowHandles();
      await this.driver.close();
      await this.driver.switchTo().window(handles[0]);
      return null;
    }
  }

  /* waitForWindowHandleCount
   * This function is a wait for the epected number of window handles to be present.
   * @param int
   */
  async waitForWindowHandleCount(count, waitTimeout = 6000) {
    try {
      await this.driver.wait(async () => {
        const handles = await this.driver.getAllWindowHandles();
        return handles.length === count;
      }, waitTimeout);
    } catch (err) {
      console.log(`Function: waitForWindowHandleCount failed ${err} `);
    }
  }


-2

ock-level HTML elements have a few restrictions:

They must be separated from surrounding text by blank lines. The begin and end tags of the outermost block element must not be indented. Markdown can't be used within HTML blocks.

ochs.tobi
  • 3,214
  • 7
  • 31
  • 52
etre
  • 1