How do I use a fluent wait command effectively

Answered

I have a scenario where I want to click on a hyperlink for a contract number on a page to open another window. The issue I originally had is that this contract number takes a few seconds before it becomes visible on the page. Therefore, I thought I’d make use of a fluent wait to poll a search on the element every few seconds until it became visible (I wanted to avoid using Thread.Sleep). However, I’m having issues getting this to work. I’ve detailed below what I’ve done

1) See below for a screenshot of the contract I am trying to click on (254052). This is the contract which takes a few seconds before it appears on the page
How do I use a fluent wait command effectively

The associated HTML for this is below:


<div id="tabular-breakdown" class="tablesorter" style="display: block;">

<table class="tablesorterReport" data-currentpage="0" data-totalcount="696" data-totalpages="35">

<thead>

<tbody>

<tr>

<td>

<a class="" target="_blank" href="/DibsAndrew/CreditControl/AgreementDetail.aspx?contractno=254052">254052</a>

2) So, what I am trying to achieve is to wait for a contract number to be displayed on the list, after which I will click on it. I’ve written the code for a fluentWait, as below:


public static void fluentWaitOnContractSelect(InternetExplorerDriver driver)

{

FluentWait<InternetExplorerDriver> wait = new FluentWait<InternetExplorerDriver>(driver);

wait.withTimeout(8000, TimeUnit.MILLISECONDS);

wait.pollingEvery(10, TimeUnit.MILLISECONDS);

wait.ignoring(NoSuchElementException.class);

wait.ignoring(StaleElementReferenceException.class);
WebElement contractSelect = wait.until(new Function<InternetExplorerDriver,     WebElement>(){
public WebElement apply(InternetExplorerDriver driver) {

WebElement contract = driver.findElement(By.xpath(".//*[@id='tabular-     breakdown']/table/tbody/tr[1]/td[1]/a"));

String value = contract.getAttribute("innerHTML");

if(value.contains("_blank"))

{

contract.click();

return contract;

}

else

{

System.out.println("Value is " + value);

return null;

}

}

});

System.out.println("Webelement value is " + contractSelect.getTagName());

}

3) However, when I run the test I get an error in the console, as follows:
“exception in thread “main” org.openqa.selenium.TimeoutException: Timed out after 8 seconds waiting for genericControls.waitCommands$1@1b68b9a4
Build info: version: ‘2.43.1’, revision: ‘5163bce’, time: ‘2014-09-10 16:27:58′
System info: host: ‘MBD0150′, ip: ‘192.168.55.49’, os.name: ‘Windows 8.1′, os.arch: ‘amd64′, os.version: ‘6.3’, java.version: ‘1.8.0_25′
Driver info: driver.version: unknown
at org.openqa.selenium.support.ui.FluentWait.timeoutException(FluentWait.java:259)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:228)
at genericControls.waitCommands.fluentWaitOnContractSelect(waitCommands.java:24)
at genericControls.contractFunctions.openCloseContractForReportWithBarChart(contractFunctions.java:41)
at Reports.collections.breachReportCompletedSelectContract(collections.java:55)
at Reports.programMain.main(programMain.java:117)
Caused by: org.openqa.selenium.StaleElementReferenceException: Element is no longer valid (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 57 milliseconds
For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html
Build info: version: ‘2.43.1’, revision: ‘5163bce’, time: ‘2014-09-10 16:27:58′
System info: host: ‘MBD0150′, ip: ‘192.168.55.49’, os.name: ‘Windows 8.1′, os.arch: ‘amd64′, os.version: ‘6.3’, java.version: ‘1.8.0_25′
Driver info: org.openqa.selenium.ie.InternetExplorerDriver
Capabilities [{browserAttachTimeout=0, enablePersistentHover=true, ie.forceCreateProcessApi=false, ie.usePerProcessProxy=false, ignoreZoomSetting=false, handlesAlerts=true, version=11, platform=WINDOWS, nativeEvents=true, ie.ensureCleanSession=false, elementScrollBehavior=0, ie.browserCommandLineSwitches=, requireWindowFocus=false, browserName=internet explorer, initialBrowserUrl=http://localhost:30876/, takesScreenshot=true, javascriptEnabled=true, ignoreProtectedModeSettings=false, enableElementCacheCleanup=true, cssSelectorsEnabled=true, unexpectedAlertBehaviour=dismiss}]
Session ID: e9003b03-0004-4846-a0b9-6991cadac9b0
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:204)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:156)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:599)
at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:268)
at org.openqa.selenium.remote.RemoteWebElement.getAttribute(RemoteWebElement.java:123)
at genericControls.waitCommands$1.apply(waitCommands.java:28)
at genericControls.waitCommands$1.apply(waitCommands.java:1)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:208)”

Dos anyone have any ideas on where I might be going wrong?

Many thanks

tilston1001 Train Asked on December 10, 2014 in Selenium WebDriver.
Add Comment
1 Answer(s)
Best answer

Hi Andy,

I should start charging you for all these question :)

We should use Fluent WAit only in cases when the object is present on the page but we are waiting for some property to be changed. When we are waiting for the object,  Implicit wait or Explicit wait can easily work.

package testCases;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
public class Test {
    public static void main(String[] args) {
        WebDriver driver = new FirefoxDriver();
        
        WebDriverWait Wait = new WebDriverWait(driver, 20);
        Wait.until(ExpectedConditions.elementToBeClickable(By.xpath(".//*[@id='tabular-breakdown']/table/tbody/tr[1]/td[1]/a")));
    }
}

Anyways you were getting the timeout error, which means that you element is not present in 8 secs, may be it would work if you increase the time.

Regards,
Lakshay Shrama

xLov3rDns Professor Answered on December 12, 2014.
Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.