How to handle Page and Element load times


#1

Wait for page/element to load

When trying to access an element on a website, some of the most common issues that you can face are elements not being immediately available, the page still loading or an element hiding other elements. This is the situation where the WebDriver wait comes in place.

Thread.sleep() and browser.sleep() are useful but…
We tend to use thread / browser.sleep() when the frontend waits for the backend to complete some action. During this time, the frontend traditionally shows a spinner. Automation needs to wait until the spinner goes off, but that doesn’t mean the target element is ready right after the spinner disappears. Thread/browser.sleep() will introduce a fixed period of inactivity no matter what happens which will slow down your test, and if you are using CI generally result in much longer test run times if used all over the place.

The implicit wait will tell to the web driver to wait for a certain amount of time before it throws a “No Such Element Exception”. The default setting is zero. Once we set the time, WebDriver will wait for that time before throwing an exception. The implicit wait can be declared in the setup method of the test script, and the syntax is the following:

Java Projects:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
TypeScript Projects:
browser.manage().timeouts().implicitlyWait(_milliseconds_)

Being easy and simple to apply, implicit wait introduces a few drawbacks as well. It gives the same amount of the test script execution time for each action before resuming the execution. The implicit wait is not considered a good practice because different browsers have different loading times and the implicit wait will cause different results in different browsers.
Thus WebDriver introduces Explicit waits where we can explicitly apply waits whenever the situation arises instead of forcefully waiting while executing each of the test steps.

Explicit wait statement would look like this:

Java Projects:
driver.wait.until(ExpectedConditions.visibilityOfElementLocated(driver.findElement(By(by.css)
TypeScript Projects:
await browser.wait(ExpectedConditions.visibilityOf(element(by.css('cssSelector'))))

The ExpectedConditions package contains various predefined conditions to use with WebDriver wait. You can take a look at the package content here for Java and here for TypeScript (Protractor).

Writing this wait conditions can be annoying and time-consuming, but luckily wait conditions are automatically added on every element you create with Ranorex Webtestit. The wait.untill(until(ExpectedConditions.visibilityOfElementLocated)(…))_ makes sure to wait a certain amount of time until the element is visible, and then proceeds with the next steps. Writing a test without this condition would result in immediate test failure with an org.openqa.selenium.NoSuchElementException in cases where an element is present, but not loaded after some time period.

In this example, we will write a Java test based on this website to check the text of an element which takes a certain time to load after the “Start” button is clicked. The steps are the following:

  • Locate the button that triggers the element load, generate the selector and use .click() method on it.
this.wait.until(ExpectedConditions.visibilityOfElementLocated(this.Start)).click();

Note that the wait.until(ExpectedContitions.visivilityOfElementLocated) method is added automatically on both elements in Ranorex Webtestit.

  • Locate the text element that is shown after the dynamic load and use the .getText() method.

  • In your Test file, assert “Hello World!” text.

     @Test
     public void CheckHelloWorldText() {
         WebDriver driver = getDriver();
     
         // Instantiate the PO file
         ItemsOverviewPo loadTest = new ItemsOverviewPo(driver);
         loadTest.open("https://the-internet.herokuapp.com/dynamic_loading/2");
    
         // Click the Start button
         loadTest.clickStartButton();
    
         // Assert the text
         Assert.assertEquals(loadTest.getTheText(), "Hello World!");
         
         
     }
    

Now, if you would perform the same test, but without the wait statement in our getTheText() method :

    public String getTheText() {
       String Hello_World_Text = driver.findElement(Hello_World_).getText();

       return Hello_World_Text;
    }

Your test would fail with the following error: