Search code examples
javaseleniumxpathperformance-testing

What is the most efficient way to wait for a page element (xpath) to show up in Selenium Webdriver?


I am using Java and Selenium Webdriver in order to test the functionalities of a single page web application.

For this reason, clearly, elements are injected and removed from the DOM dynamically.

I know I can wait for an element to be present in the DOM using similar code that is using WebDriverWait (very neat template I wrote slightly changing GitHub):

public void waitForElement() throws Exception {
    /*
    Inject the following snippet in any web page to test the method
    <button class="i-am-your-class" onclick="alert('Wow, you pressed the button!');">Press me</button>
     */
    System.setProperty("webdriver.gecko.driver", "C:\\Program Files (x86)\\Mozilla Firefox\\geckodriver.exe");
    WebDriver driver = getDriver();
    WebDriverWait wait = new WebDriverWait(driver, 10); // 10 can be reduced as per Test Specifications
    driver.get("http://www.google.com");
    WebElement response = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@class='i-am-your-class']")));
    response.click();
    System.out.println("*****************************************************************************");
    System.out.println(response);
    System.out.println(response.getText());

    driver.close();
}

What I would like to know is if this is also the more efficient way to obtain such result using an xpath.

I have been researching on Stackoverflow and several answers point in a similar direction but no answer is focused on efficiency / performances:

Thanks for your time and help.


Solution

  • There are a couple of facts which you need to consider as follows :

    • WebDriverWait() for 100 shouldn't be a real-time waiter. Consider reducing it as per the Test Specifications. As an example, set it as 10 seconds :

      WebDriverWait wait = new WebDriverWait(driver, 10);
      
    • Moving forward as you are invoking click() method so instead of ExpectedConditions as visibilityOfElementLocated() method use elementToBeClickable() method as follows :

      WebElement response = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//*[@class='i-am-your-class']")));
      
    • Optimize your xpath including the tagName as in By.xpath("//tagName[@class='i-am-your-class']"). As an example :

      By.xpath("//a[@class='i-am-your-class']")
      
    • Optimize your code to invoke click() as soon as the element is returned through WebDriverWait as follows :

      new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//a[@class='i-am-your-class']"))).click();