8.4. Working with Asynchronous Pages

Asynchronous pages are those whose fields or data is not all displayed when the page is loaded. Sometimes, you need to wait for certain elements to appear, or to disappear, before being able to proceed with your tests. Thucydides provides some handy methods in the PageObject base class to help with these scenarios. They are primarily designed to be used as part of your business methods in your page objects, though in the examples we will show them used as external calls on a PageObject instance for clarity.

8.4.1. Checking whether an element is visible

In WebDriver terms, there is a distinction between when an element is present on the screen (i.e. in the HTML source code), and when it is rendered (i.e. visible to the user). You may also need to check whether an element is visible on the screen. You can do this in two ways. Your first option is to use the isElementVisible method, which returns a boolean value based on whether the element is rendered (visible to the user) or not:

assertThat(indexPage.isElementVisible(By.xpath("//h2[.='A visible title']")), is(true));

or

assertThat(indexPage.isElementVisible(By.xpath("//h2[.='An invisible title']")), is(false));

Your second option is to actively assert that the element should be visible:

indexPage.shouldBeVisible(By.xpath("//h2[.='An invisible title']");

If the element does not appear immediately, you can wait for it to appear:

indexPage.waitForRenderedElements(By.xpath("//h2[.='A title that is not immediately visible']"));

An alternative to the above syntax is to use the more fluid waitFor method which takes a css or xpath selector as argument:

indexPage.waitFor("#popup"); //css selector

indexPage.waitFor("//h2[.='A title that is not immediately visible']"); //xpath selector

If you just want to check if the element is present though not necessarily visible, you can use waitForRenderedElementsToBePresent :

indexPage.waitForRenderedElementsToBePresent(By.xpath("//h2[.='A title that is not immediately visible']"));

or its more expressive flavour, waitForPresenceOf which takes a css or xpath selector as argument.

indexPage.waitForPresenceOf("#popup"); //css

indexPage.waitForPresenceOf("//h2[.='A title that is not immediately visible']"); //xpath

You can also wait for an element to disappear by using waitForRenderedElementsToDisappear or waitForAbsenceOf :

indexPage.waitForRenderedElementsToDisappear(By.xpath("//h2[.='A title that will soon disappear']"));

indexPage.waitForAbsenceOf("#popup");

indexPage.waitForAbsenceOf("//h2[.='A title that will soon disappear']");

For simplicity, you can also use the waitForTextToAppear and waitForTextToDisappear methods:

indexPage.waitForTextToDisappear("A visible bit of text");

If several possible texts may appear, you can use waitForAnyTextToAppear or waitForAllTextToAppear:

indexPage.waitForAnyTextToAppear("this might appear","or this", "or even this");

If you need to wait for one of several possible elements to appear, you can also use the waitForAnyRenderedElementOf method:

indexPage.waitForAnyRenderedElementOf(By.id("color"), By.id("taste"), By.id("sound"));