Tuesday, October 23, 2018

Selenium Firefox - Test dynamic webelement with waits

Problem

The problem I am having today is that my test that was working is now having issues related to browser performance. I am testing for an element to display in two tabs. The first tab opens and the element is captured. Next, the second tab opens to the same exact page, but Selenium can't find the element to capture before closing the browser.

I thought my implicit wait on the driver would suffice. It seemed to yesterday anyhow. So, now I am researching "waits".
https://www.seleniumhq.org/docs/04_webdriver_advanced.jsp

I didn't seen enough information on the main website for Java. So, I googled online for more information. Perhaps someone else has a cleaner solution? During my search, I noticed that there are two explicit waits: WebDriverWait and FluentWait. But, what is the difference?

FluentWait vs WebDriverWait

https://www.softwaretestingmaterial.com/webdriverwait-selenium-webdriver
https://www.softwaretestingmaterial.com/selenium-fluentwait/
https://stackoverflow.com/questions/40753321/fluent-wait-vs-webdriver-wait
Essentially, the difference is FluentWait offers more handling of exceptions in case the Wait doesn't find the element, etc. This is my understanding so far. Thus, I'll continue with WebDriverWait which auto ignores exceptions (like NoSuchElementException).

This is all good to know, but useless without knowing the impact of the class ExpectedConditions. This class "ExpectedConditions" has some key methods that we need to know when looking for a specific element or element attribute or element value.
https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html
Well, there are a lot. Unfortunately, there aren't examples for each of these methods giving a descent explanation between the methods that appear similar.

Moving forward, this is an interesting, old article (posted in 2014). The author is first looking for the element and then looking for the text inside the element. Is this really necessary instead of simply looking for the text inside the element? Isn't there a wait on the element being completely rendered with text already? I don't know, but this would be to discover and understand.
http://www.software-testing-tutorials-automation.com/2014/01/webdriver-wait-for-text-to-be-present.html

Solution

Before digging into the details to understand, I discovered that this works. Here's my code which resolved my issue. Notice, this is a common method used by multiple tests.

public static Boolean isAgreementDisplayed(Webdriver driver, Integer waitSeconds) {

    WebDriverWait wait = new WebDriverWait(drive, waitSeconds);
    wait.until(ExpectedConditions.presenceOfElementLocated(By.className("modal-title")));

    boolean modalTitleExists = wait.until(
            ExpectedConditions.textToBePresentInElementLocated(By.className("modal-title"), "User Agreement"));

    return modalTitleExists;
}

Now, if I remove the first "wait" call, will my code still work? Surprisingly, or maybe not surprisingly, it does work. So, now my code looks like this (although I know I can shorten it more) and my test waits for my dynamic webelement to display and check its text before completing assertion.

public static Boolean isAgreementDisplayed(Webdriver driver, Integer waitSeconds) {

    WebDriverWait wait = new WebDriverWait(drive, waitSeconds);
    boolean modalTitleExists = wait.until(
            ExpectedConditions.textToBePresentInElementLocated(By.className("modal-title"), "User Agreement"));

    return modalTitleExists;
}

Cheers!



No comments:

Post a Comment