Skip to main content
blog title image

3 minute read - Selenium WebDriver FAQs Test Automation

SlowLoadableComponent Must Throw Error in isLoaded

Jul 1, 2020

When using SlowLoadableComponent we have to remember that in the Java Throwable hierarchy the Error and the Exception are siblings. This means that you have to catch exceptions in SlowLoadableComponents and convert them to Errors to cause synchronisation to take place.

The most common mistake when using SlowLoadableComponent is for the isLoaded method to throw exceptions.

This Will Not Sync

A SlowLoadableComponent with the following isLoaded method would never wait because it never throws an Error.

@Override
protected void isLoaded() throws Error {
    // button must exist
    final WebElement button =
            driver.findElement(By.id("button00"));
    if(!button.isDisplayed() && !button.isEnabled()){
        throw new RuntimeException("Button not Ready");
    }
}

isLoaded throws an error to signify the page is not ready.

Explanation

The Java Throwable inheritance hierarchy, just so we remember that Error and Exceptions are siblings:

  • Throwable
    • Error
    • Exception
      • RuntimeException

A Brief intro into SlowLoadableComponent, you can skip the next two paragraphs if you already know what it is:

The SlowLoadableComponent is a support class in WebDriver which provides a simple and consistent way of writing PageObjects which model pages and components that take additional time from being present in the DOM to being ready to use.

A SlowLoadableComponent has a public ‘get’ method that it inherits from SlowLoadableComponent, and 2 additional methods a ’load’ and an ‘isLoaded’ method. When the ‘get’ method is called, the ‘isLoaded’ method is used to check if the component is loaded, if not then the ’load’ method is called, and then the SlowLoadableComponent polls the ‘isLoaded’ method until the component is loaded or a timeout time is exceeded.

The SlowLoadableComponent in the Java support classes for WebDriver uses Error as the escape mechanism in its get() processing:

public T get() {
   try {
      isLoaded();
      return (T) this;
   } catch (Error e) {
      load();
   }
   ...

In Java For Testers I wrote the following paragraph when describing the difference between Error and Exception.

Error is reserved for serious Java platform errors. The general guidance provided to Java programmers is “never catch a Java Error”, which also means we should never catch a Throwable.

As a result I tend to get a little uneasy when throwing Errors, as I prefer to throw Exceptions.

When I use SlowLoadableComponent, I bite the bullet and write throw new Error in my abstraction layers because I need to.

But, the WebDriver code throws exceptions.

WebDriver is particularly fond of NoSuchElementException, especially when your page hasn’t loaded, so if you do something like the following in your isLoaded:

WebElement elem = driver.findElement(By.id("button00"));

…and if the driver cannot find the element, and this is the first time your isLoaded is called then an Exception will be thrown rather than an Error, and your load method will not be called.

Wrap your code in a try catch block and convert any Exception into Error so that you comply with the contract for SlowLoadableComponent.

    try {
        final WebElement button =
                driver.findElement(By.id("button00"));
        if(!button.isDisplayed() && !button.isEnabled()){
            throw new RuntimeException("Button not Ready");
        }
    }catch(Exception e){
        throw new Error(e);
    }

Assuming of course that you do want the load method to fire.

Note: that very often you don’t experience this because the load method is often left empty - particularly when it is a component in a page, or navigated to organically e.g. by clicking a link, rather than an explicit ‘get’.

So, just a cautionary word, based on experience… Handle the exceptions in your isLoaded methods and convert them to Error because that is what the SlowLoadableComponent needs.

Full Source

The full source for this is in my Webdriver Java FAQs project:

Specifically:

If you want to learn how to use Selenium WebDriver with Java then check out our online courses. And we have a full course on Page Objects and the SlowLoadableComponent is covered in depth in our Support classes course.