Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing Selenium implicit wait inside test process

I know that, according to some opinions, in the perfect case I should not be using implicit wait. But I have a slow UI; it would be a rather big endeavour to add explicit waits to all the numerous places where rendering can happen. A standard implicit wait of 20 seconds, set at driver initialization time, covers 80% of waiting perfectly.

But then I need to handle the remaining 20%. Sometimes I need to wait for an element to DISappear - and the implicit wait means an extra 20 seconds in this case. And sometimes I need to check for the presence of an element but not wait for it for all of 20 seconds (because the element is often not there in the normal execution flow).

So, I naturally want to disable the implicit wait temporarily:

driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
new WebDriverWait(driver, MY_TIMEOUT)).until(ExpectedConditions.WHATEVER_I_NEED);
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);

But will this be stable? Or is changing implicit wait (in this case, from 20 to zero and back to 20) somehow dangerous?

like image 393
Mikhail Ramendik Avatar asked Oct 18 '22 08:10

Mikhail Ramendik


1 Answers

Perfectly valid to do this. More importantly correct way to avoid mixing up implicit and explicit waits. That mixture of waits leads to some hard to debug issues with long wait times. Problem is you could forget to turn off and on the implicit wait. Better to write a utility function to wrap this logic by passing the explicit wait criterion and use it across your code base.

I took a stab at creating a generic method to use. Though generic ain't my strong point.

protected static <T> T waitECTimeoutWrapped(WebDriver driver, ExpectedCondition<T> ec, int timeout) {
    driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
    WebDriverWait wait = new WebDriverWait(driver, timeout);
    T data = waitDriver.until(ec);
    driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
    return data;
}

You can ignore the return data for many cases but this way you can retrieve elements that you may be looking for in one call.

like image 200
Grasshopper Avatar answered Oct 21 '22 03:10

Grasshopper