sodcalculator

10 Tech How-To

Selenium WebDriver JavaScript Waits: How to Use

Guide 10-19869 · Updated · Step by step

When automating web tests with Selenium WebDriver, elements often appear or become interactive after a delay due to network latency, animations, or dynamic content. JavaScript waits—specifically explicit and implicit waits—let your test pause until a condition is met, reducing flaky failures. This guide shows you how to implement reliable waits in your Selenium JavaScript tests (using Node.js and the official selenium-webdriver package).

What You’ll Need

  • Node.js installed (v12 or later)
  • A Selenium WebDriver project set up with the selenium-webdriver npm package
  • A browser driver (e.g., ChromeDriver) matching your browser version
  • Basic familiarity with async/await in JavaScript

Step-by-Step

  1. Install the Selenium WebDriver package (if not already done):
    npm install selenium-webdriver
  2. Import the required modules in your test script:
    const { Builder, By, until } = require('selenium-webdriver');
  3. Create a driver instance (e.g., for Chrome):
    let driver = await new Builder().forBrowser('chrome').build();
  4. Set an implicit wait (optional but recommended) to apply a default timeout for all element searches:
    await driver.manage().setTimeouts({ implicit: 5000 }); // 5 seconds
  5. Use explicit waits for specific conditions with driver.wait(). For example, wait for an element to be located:
    let element = await driver.wait(until.elementLocated(By.id('submit')), 10000);
  6. Wait for an element to be visible (not just present in the DOM):
    await driver.wait(until.elementIsVisible(element), 10000);
  7. Wait for an element to be clickable (visible and enabled):
    await driver.wait(until.elementIsEnabled(element), 10000);
  8. Wait for a specific text to appear in an element:
    await driver.wait(until.elementTextIs(element, 'Success'), 10000);
  9. Use a custom condition function for complex scenarios, e.g., wait until a button’s class changes:
    await driver.wait(async function() {
      let classes = await element.getAttribute('class');
      return classes.includes('active');
    }, 10000, 'Button did not become active');
  10. Always clean up by quitting the driver after tests:
    await driver.quit();

Common Mistakes

  • Mixing implicit and explicit waits carelessly – implicit waits apply globally; explicit waits override them for specific calls, but combining them can cause unpredictable wait times.
  • Using too short a timeout – if the element takes longer than your timeout, the test fails. Choose a timeout based on the slowest expected response.
  • Waiting for the element to be present but not visible – many elements exist in the DOM but are hidden; always wait for visibility if you need to interact with it.
  • Not using await on wait calls – forgetting await leads to unhandled promises and flaky behavior.
  • Hard-coding sleeps (e.g., setTimeout) – these are brittle and slow; prefer conditional waits.

Tips

  • Prefer explicit waits over implicit waits because they are more precise and reduce the chance of over-waiting.
  • Use a base timeout constant (e.g., const TIMEOUT = 10000;) to keep tests consistent.
  • For single-page apps, wait for network requests to complete by checking for a specific element or state change.
  • Use until.elementLocated() for elements that are dynamically added after an action.
  • When waiting for multiple elements, use until.elementsLocated() to get an array.
  • Always provide a custom error message in driver.wait() to help debug failures.

Troubleshooting

Wait times out even though the element appears quickly: Check if the element is inside an iframe. If so, switch to the iframe first using driver.switchTo().frame().

Element is found but not clickable: The element might be covered by another element. Use driver.wait(until.elementIsEnabled(element)) and also ensure it’s visible. If it’s still not clickable, try scrolling it into view with driver.executeScript("arguments[0].scrollIntoView();", element).

Implicit wait seems ignored: Implicit waits only apply to findElement and findElements calls, not to driver.wait(). For explicit waits, you must specify the timeout explicitly.

Tests are slow because of long waits: Reduce the timeout to the minimum that reliably works, and use explicit waits only where needed. Also consider using until.elementIsVisible() instead of a fixed sleep.

Wait condition never becomes true: Verify the condition logic. For custom functions, ensure they return a boolean or a truthy value. Log the current state inside the function to debug.

Browser driver crashes: Ensure your browser driver version matches your browser version. Update both to the latest stable releases.

Frequently Asked Questions

What is the difference between implicit and explicit waits?

Implicit wait sets a default timeout for every findElement call, while explicit wait applies a specific timeout to a particular condition. Explicit waits are more flexible and recommended.

Can I use both implicit and explicit waits together?

Yes, but it’s generally not recommended because they can interfere. If you do, remember that explicit waits override implicit waits for the duration of the explicit wait.

How do I wait for an element to disappear?

Use until.stalenessOf(element) or a custom condition that checks element.isDisplayed() returns false.

What is the default timeout for driver.wait()?

There is no default; you must provide a timeout in milliseconds. If you omit it, the wait will use the implicit wait timeout (if set), otherwise it may wait indefinitely.

Why is my wait not working with async/await?

Make sure you are using await before driver.wait() and that your test function is declared async. Also, ensure your custom condition function is async if it uses async operations.

Can I wait for a JavaScript variable to change?

Yes, use driver.wait() with a custom function that executes JavaScript via driver.executeScript() and returns the desired value.

Related

General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.

More in this bed

The whole Tech How-To bed →