WebDriverWait throws Timeout instead of NoSuch ElementException - selenium

I am using WebDriverWait to find an Element which will be visible after few seconds.
I have declared time for 10sec max to wait for that particular element
WeDriverWait wait = new WebDriverWait(driver, 10)
.until(ExpectedConditions.visibilityOfElement("path"));
now my expection is to , if element is not visible withing 10 seconds then i should get NoSuchElementException after 11th second, but it takes more than 30secs(approx) and throws TimeOut Exception.
Thanks in advance for Suggestion and clarification ...!!!

You saw it right. As per the documentation of WebDriverWait() the constructors are:
WebDriverWait(WebDriver driver, java.time.Clock clock, Sleeper sleeper, long timeOutInSeconds, long sleepTimeOut)
WebDriverWait(WebDriver driver, long timeOutInSeconds)
WebDriverWait(WebDriver driver, long timeOutInSeconds, long sleepInMillis)
For a successful WebDriverWait the desired element/elements is/are returned, whereas incase of a failure timeout exception is thrown.
However there is a small issue in your code block:
WeDriverWait wait = new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElement("path"));
Instead of an instance of WeDriverWait, the desired element is returned. So you need to change the line as:
WebElement element = new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElement("path"));
In a stepwise manner:
WeDriverWait wait = new WebDriverWait(driver, 10)
WebElement element = wait.until(ExpectedConditions.visibilityOfElement("path"));
It is not clear from your question why it takes more than 30 secs(approx) to throw the TimeOutException but the most possible cause is, though you have set the duration of WebDriverWait as 10 seconds, you have also have induced ImplicitlyWait as well and as per the documentation WARNING: Do not mix implicit and explicit waits! Doing so can cause unpredictable wait times. For example, setting an implicit wait of 10 seconds and an explicit wait of 15 seconds could cause a timeout to occur after 20 seconds.

As per WebDriverWait class source:
Wait will ignore instances of NotFoundException that are encountered (thrown) by default in
the 'until' condition, and immediately propagate all others. You can add more to the ignore
list by calling ignoring(exceptions to add)
And NotFoundException is a super class for the following Exceptions:
NoAlertPresentException
NoSuchContextException
NoSuchCookieException
NoSuchElementException
NoSuchFrameException
NoSuchWindowException
Therefore you will not see NoSuchElement exception when using WebDriverWait.
It might also be the case your element is actually present in the DOM but it's not visible due to having i.e. display:none CSS property so you could consider using presenceOfElementLocated condition instead.
More information: How to use Selenium to test web applications using AJAX technology

Related

How to reduce tag waiting time in selenium

I'm trying to click a specific link in the web page with specific text.
However, if the link is not present, it takes 1 minute before it prints out element is not found. How do I reduce this time for faster execution?
try{
if (!driver.findElements(By.xpath("//a[text()='specifictext']/#href")).isEmpty())
{
By loadMoreComment=By.linkText("specifictext");
driver.findElement(loadMoreComment).click();
}
}
catch (NoSuchElementException e)
{
logger.warn("Specific text not found");
}
That would only happen because of implicit waits. Look at below definition
Implicit Waits
An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object instance.
So you should lower that implicit wait if you want an early failure
driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
The above call before your code, will ensure the failure happens within 2 seconds
Use Implicit wait to reduce tag waiting time.
Implicit waits are used to provide a waiting time (say 30 seconds)
between each consecutive test steps across the entire test script or
program. Next step only executed when the 30 Seconds (or whatever time
is given is elapsed) after execution of previous step.
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);

Will the Implicit wait will move on if findElement action is complete?

Implicit Wait : If wait is set, it will wait for specified amount of time for each findElement/findElements call. It will throw an exception if action is not complete.
Assume we set implicit wait to 10 secs. My question is will selenium move on to next step if findElement action is complete before 10 secs?
Yes. Setting implicit wait causes the driver object to wait for the set time if the element it is looking for is not found immediately. The driver object keeps polling the DOM every 500 milliseconds until it finds the element or the time-out expires.
This is the explanation from official Selenium documentation page:
An implicit wait is to tell WebDriver to poll the DOM for a certain
amount of time when trying to find an element or elements if they are
not immediately available. The default setting is 0. Once set, the
implicit wait is set for the life of the WebDriver object instance.
So, to answer your question in short, yes it continues with executing next steps as soon as it finds the element(s) it is looking for. You may also understand that to be the case from a simple experiment like #sircapsalot has shown in his answer.
Answer:
Yes. It will continue with the next step if it finds the element before the implicit timeout is hit.
Proof of concept:
#Test
public void test29800926() {
driver.get("http://ddavison.io/tests/getting-started-with-selenium.htm");
driver.manage().timeouts().implicitlyWait(30000, TimeUnit.MILLISECONDS);
System.out.println(driver.findElement(By.id("click")).getText());
}
Instead of waiting the total of 30 seconds that I set the implicit wait to (30000ms / 1000 = 30sec), it found it immediately and continued to print the text of the element.

Fluent Wait and WebDriver Wait - Differences

I have seen both FluentWait and WebDriverWait in code using Selenium. FluentWait uses a Polling Technique i.e. it will be poll every fixed interval for a particular WebElement. I want to know what Does WebDriverWait do with ExpectedConditions?
Consider following Java example:
WebDriverWait wait = new WebDriverWait(driver, 18);
wait.until(ExpectedConditions.elementToBeClickable(By.linkText("Account")));
WebElement element = driver.findElement(By.linkText("Account"));
element.sendKeys(Keys.CONTROL);
element.click();
Does ExpectedConditions.elementToBeClickable(By.linkText("Account")) monitor for linkText("Account") to be clickable or does it wait 18 seconds before clicking?
In your example wait.until(ExpectedConditions...) will keep looking (every 0.5s) for linkText 'Account' for 18 seconds before timing out.
WebDriverWait is a subclass of FluentWait<WebDriver>.
In FluentWait you have more options to configure, along with maximum wait time, like polling interval, exceptions to ignore etc. Also, in your code, you don't need to wait and then findElement in the next step, you could do:
WebElement element = wait.until(
ExpectedConditions.elementToBeClickable(By.linkText("Account")));

WebDriverWait timer resets between tests?

I have the following code:
// setting timeout to a FULL MINUTE
WebDriverWait wait = new WebDriverWait(driver, 60);
Actions action = new Actions(driver);
// First, click the usermenu
WebElement userMenu = wait.until(ExpectedConditions.elementToBeClickable(By.id("UserMenu")));
userMenu.click();
WebElement adminPortal = driver.findElement(By.id("AdminPortals"));
action.moveToElement(adminPortal);
action.perform();
// Wait for secondary menu to become available
WebElement portal = wait.until(ExpectedConditions.elementToBeClickable(By.id(portalId)));
portal.click();
Basically, "UserMenu" is a drop-down, and there's a hover-over expansion menu "AdminPortals". The above code simulates (in Selenium, the action of clicking on an item in the expanded menu.
The question I have is in relation to the timeout period. When does it start counting down? I assume it is when I use wait.until(). And I assume it stops counting once True is returned by ExpectedConditions? And, the real question is: If I use the same "wait" twice, as I have here, does the 60 seconds reset as the limit between each use, or does it restart counting where it stopped before?
So, if the first wait took 2 seconds, and the second wait took 3 seconds, will the timeout for the third call to wait.until() be 55 seconds, or reset to 60?
Yes, it starts counting down when you call the until method. When you instantiate a new WebDriverWait object and specify a timeout it sets up a clock, so each time you call the util method on that object it will continue to count down the same timer. It doesn't reset the timer each time it returns. If you want the timer to reset you will need to create new WebDriverWait objects.
This is really unclear in the documentation. I had to look at the code to figure out what was going on. The logic is actually inherited from the FluentWait class. Here's the source code link I looked at:
https://code.google.com/p/selenium/source/browse/java/client/src/org/openqa/selenium/support/ui/FluentWait.java
So, if the first wait took 2 seconds, and the second wait took 3 seconds, the timeout for the third call to wait.until() will be 55 seconds.

Wait is not working in selenium webdriver

I need help on wait function in Selenium webdriver.
I have the following code to wait for "Progressing Pop up" to disappear.
It seems it waits only for some seconds and terminates the script. Please let me know what are the other option?
public static void ProcessingData() throws Exception {
WebDriverWait wait1 = new WebDriverWait( driver , 180 );
wait1.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[#class='dijitDialogPaneContent']/div/p/b[contains(text()='Processing ...']")));
}
You placed your timeout on 180, which is 180 milliseconds. You probably mean 180 seconds? So use 180000.
I'd take a closer look at your xpath selector... you are providing
...b[contains(text()='Processing ...']
If you know that the text is equal to processing, then you should use
...b[text()='Processing ...'].
If you know that the text CONTAINS Processing ... then you should use,
...b[contains(text(), 'Processing ...']