How exactly implicitWait is handled dynamically in selenium? - selenium

I have a doubt related to the implicit wait of selenium? As we know that Implicit Wait is dynamic wait that means if we mention that wait for 10 seconds for any element to be loaded but if the element is loaded within 4 seconds then driver comes out of the wait.
So, the question is that how driver came to know that element is loaded in 4 seconds and lets come out from the wait? We have not mentioned any condition in Implicit Wait like look for the visibility of any element and then come out then how exactly implicit wait takes a call to to come out of the wait?

The implicit wait is happening at the driver level, Explicit wait is happening at the programming level. Most people are not aware of this.
Implicit wait only checks whether it exists or not, so you don't have to specify any condition as you do for an explicit wait. But I have raised a ticket to include the implicit wait for visibility as well in Chrome(See here https://bugs.chromium.org/p/chromedriver/issues/detail?id=2016) and Firefox, Chrome has incorporated that change but firefox still hasn't. I asked them to include it because Firefox Legacy driver waits for element existence and visibility so I want the same to be here.

Implicit Wait can't be handled dynamically using Selenium. In his epic comment Jim Evans [Maintainer - DotNet client / IEDriverServer] mentioned that, implicitlyWaits are often (always may not be) implemented on the remote side of the WebDriver system. That means ImplicitWait are baked in to the WebDriver variants i.e. GeckoDriver, IEDriverServer, ChromeDriver, the WebDriver Firefox extension that gets installed into the anonymous Firefox profile (Selenium RC), and the Java remote WebDriver server (selenium-server-standalone.jar).
Once you set the implicitly_wait, the WebDriver instance would be able to carry this configuration till its lifetime. To set the timespan of the waiting time, you can:
Python:
driver.implicitly_wait(5)
Java:
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
DotNet:
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
If at any point of time you want to remove the ImplicitWait you can achieve it as follows:
Python:
driver.implicitly_wait(0)
Java:
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
DotNet:
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(0);

Related

What is the difference between implicit wait and AjaxElementLocatorFactory?

Per definition,
An implicit wait is to tell Web Driver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available.
See Implicit wait
Timeout for a WebElement will be assigned to the Object page class with the help of AjaxElementLocatorFactory
See AjaxElementLocatorFactory
From above, it's not clear what exactly the difference between implicit wait and AjaxElementLocatorFactory. Please explain.
Implicit Wait
An implicit wait is the approach to configure the WebDriver to poll the DOM for a certain amount of time when trying to find element/s if they are not immediately available within the HTML DOM. The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object instance.
You can find a couple of relevant discussions in:
Using implicit wait in selenium
selenium implicitly wait doesn't work
Python & Selenium: Difference between driver.implicitly_wait() and time.sleep()
AjaxElementLocatorFactory
AjaxElementLocatorFactory is one of the key advantage in implementing a waiter when using page-factory using the AjaxElementLocatorFactory Class.
AjaxElementLocatorFactory is basically the lazy-loading concept implemented with in Page Factory pattern to identify WebElements only when they are used in any operation i.e. a timeOut for a WebElement which can be assigned to the Object page class with the help of AjaxElementLocatorFactory.
An example:
AjaxElementLocatorFactory myFactory = new AjaxElementLocatorFactory(driver, 20);
PageFactory.initElements(myFactory, this)
Explaination:
In the above code block, when an operation is performed on an element the wait for its visibility starts from that moment only. If the element is not found in the given time interval, Test Case execution will throw NoSuchElementException exception.
You can find a relevant discussion in How to implement AjaxElementLocatorFactory through Selenium and Page Factory?
Implicit wait is something that is relevant to the entire driver object (and applicable to all lookups performed in the context of the driver). AjaxElementLocatorFactory is used when you initiate elements of your Page class. So that the waits are only be relevant to the elements which you describe within your Page class.
Since AjaxElementLocatorFactory utilizes the basic lookups but just wraps it with some more flexible logic, implicit wait that is applicable to all the lookups performed within your driver context might be added to the timeouts you have set up for your AjaxElementLocator (depending on the circumstances). Hence it is not recommended to mix them and in general it is recommended to avoid using implicit waits (it is set to 0 by default).

Protractor on top of my Selenium Code

I have my code written in Selenium for automating my application[Loading time of it varies] and it works fine when we use Thread.sleep for its loading time.I need to move out of thread.sleep as it is not ideal way of writing code,so i have tried to use all waits[implicit,explicit and fluent] given by Selenium.
In spite of that the script is not consistent and it is failing very often[mostly on element not found and stale element exception],so need to know since i have my all frameworks and code in Selenium is that any provision that i can import protractor jar file in it and use some lines of code in order to make my application to get synchronize with my script.
Your implicit wait is not gonna help , if your code works fine with Thread.sleep().
Thread.sleep(time) is an extreme case of Explicit wait.
An explicit wait is code you define to wait for a certain condition to occur before proceeding further in the code.
In Java selenium binding we can defined and use Explicit wait like this :
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
.until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));
This waits up to 10 seconds before throwing a TimeoutException or if it finds the element will return it in 0 - 10 seconds. WebDriverWait by default calls the ExpectedCondition every 500 milliseconds until it returns successfully.
Note that : Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times.
Question : mostly on element not found and stale element exception occurs?
Just verify your locators. Locators should be static not dynamic. Just for example you should never use dynamic ID of any web element which is generated by JS or any other programming language.
Using protractor, you can't just sync your script. All you can do now is to make changes to your locator and waiting time.
Hope this will help you.
It is not possible to use protractor into Selenium, but you can rewrite all tests into protractor and you will inherit all from selenium. Protractor is wrapper for Webdriverjs so you get each and every faeture of webdriverjs in protractor + protractor's own feature of locators and asynchronous waits.

How to use built-in ExpectedConditions with FluentWait?

In Selenium (Java), I want to use ExpectedConditions with FluentWait. I am trying out following code which is not working. It is not waiting for the element to appear in the DOM.
Could someone please help here ?
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(10, TimeUnit.SECONDS)
.pollingEvery(1, TimeUnit.SECONDS);
wait.until(ExpectedConditions.presenceOfElementLocated(By.id("mybutton")));
Note: I have tried this with WebDriverWait and it is working file. I am trying with FluentWait since I want to control polling timeout.
A bit of background :
Fluent Wait
Fluent Wait is the implementation of the Wait interface which an user can configure its timeout and polling interval on the fly. A FluentWait instance defines the maximum amount of time to wait for a condition along with the frequency with which to check the condition. The user can also configure the wait to ignore specific types of exceptions while waiting, such as NoSuchElementExceptions when searching for an element on the page.
WebDriverWait
WebDriverWait is the tailor-made version of FluentWait that uses WebDriver instances.
You can find a detailed discussion on WebDriverWait and FluentWait in both of these QA Implicit vs Explicit vs Fluent Wait and Differences between impilicit, explicit and fluentwait.
ExpectedConditions
ExpectedConditions are the tailor made canned conditions which are generally useful within webdriver tests.
As per your question, as you are trying with FluentWait since you want to control polling timeout you can still achieve the same through WebDriverWait as follows :
WebDriverWait have 3 Constructors and one of them is :
WebDriverWait(WebDriver driver, long timeOutInSeconds, long sleepInMillis)
Details :
public WebDriverWait(WebDriver driver, long timeOutInSeconds, long sleepInMillis)
This wait will ignore instances of NotFoundException that are encountered by default in the `until` condition, and immediately propagate all others. You can also add more to the ignore list by calling ignoring(exceptions to add).
Parameters:
driver - The WebDriver instance to pass to the expected conditions
timeOutInSeconds - The timeout in seconds when an expectation is called
sleepInMillis - The duration in milliseconds to sleep between polls (polling interval).
Solution :
You can use the above mentioned Constructor of WebDriverWait and still can control the polling interval.
Note : To keep your program logic simple and understandable use WebDriverWait instead of Fluent Wait untill and unless absolute necessary.
Trivia :
For further understanding of Fluent Wait you can follow the discussion Selenium Webdriver 3.0.1-[Eclipse-Java-Chrome]: Selenium showing error for FluentWait Class
Yes what NarendraR said is correct. When you have created object for FluentWait used the same object for write ExpectedConditions.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(10, TimeUnit.SECONDS).pollingEvery(1, TimeUnit.SECONDS);
wait.unitl(ExpectedConditions.presenceOfElementLocated(By.id("mybutton")));

Implicit vs Explicit vs Fluent Wait

What is difference in between Implicit, Explicit, Fluent Wait ?
If we set 10 seconds in Implicit wait and before 10 seconds, within 3 seconds only element get located.
That time what will happen ? It will wait for 10 seconds or proceed further.
ImplicitWait
ImplicitWait is an implementation to configure the WebDriver instance i.e. the driver to poll the HTML DOM for a certain amount of time (interms of NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS, MINUTES, HOURS or DAYS) when trying to find an element or elements if they are not immediately available. The default setting is 0 which means the driver when finds an instruction to find an element or elements, the search starts and results are available on immediate basis.
In this case, after a fresh loading of a Webpage an element or elements may be / may not be found on an immediate search. So your Automation Framework may be facing any of these exceptions:
NoSuchElementException
TimeoutException
ElementNotVisibleException
ElementNotSelectableException
Hence you need to induce ImplicitWait. By introducing ImplicitWait the driver will poll the DOM Tree for the configured amount of time looking out for the element or elements. By that time the element or elements for which you had been looking for may be available in the DOM. As in your code you have already set ImplicitWait to a value of 10 seconds, the driver will poll the DOM for 10 seconds.
Python:
driver.implicitly_wait(10)
Java:
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Finally, once you set the ImplicitWait, the WebDriver instance i.e. the driver is able to carry this configuration till its lifetime. But if you need to change the coarse of time for the WebDriver instance i.e. the driver to wait then you can reconfigure it as follows:
Python:
driver.implicitly_wait(5)
Java:
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
If at any point of time you want to nullify the ImplicitWait you can reconfigure it as follows:
Python:
driver.implicitly_wait(0)
Java:
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
Fluent Wait
Fluent Wait is the implementation of the Wait interface through which we can configure the timeout and polling interval on the fly. An instance of FluentWait can be defined to configure the maximum amount of time to wait for a condition as well as the frequency at which the condition must be checked. User can also configure the wait to ignore specific types of exceptions while waiting for an element, such as NoSuchElementException on the page.
Usage:
// Waiting 30 seconds for an element to be present on the page, checking
// for its presence once every 5 seconds.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, SECONDS)
.pollingEvery(5, SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.id("foo"));
}
});
ExplicitWait
ExplicitWait commonly known as WebDriverWait is a specialized implementation of FluentWait through which user can define, configure and implement for the WebDriver instance to wait for a certain condition to be met before proceeding for the next line of code. There are some methods that helps us to implement ExplicitWait that will wait only as long as required. WebDriverWait inconjunction with ExpectedConditions is one of the way ExplicitWait can be achieved.
An Example:
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
.
.
.
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("element_xpath")));
element.click();
Explanation:
This implementation of ExplicitWait waits up to 10 seconds before throwing a TimeoutException or if it finds the element then it will return within 0 to 10 seconds. WebDriverWait by default calls the ExpectedCondition every 500 milliseconds until it returns successfully. A successful return value for the ExpectedCondition function type is a Boolean value of true or a not-null object.
Expected Conditions:
There are some frequently encountered conditions when automating Web Browsers for Testing Web/Mobile Applications. The Java, C# and Python bindings include those convenient methods so we don’t have to write-up an ExpectedCondition class ourselves or create our own utility package for them. Some of the Expected Conditions are:
alertIsPresent()
elementToBeClickable(locator)
elementToBeSelected(WebElement)
frameToBeAvailableAndSwitchToIt(locator)
invisibilityOf(element)
You can find about the all the methods supported by Expected Conditions here.
This particular query :
When searching for a single element, the driver will poll the OM until the element has been found or the configured timeout expires before throwing a NoSuchElementException.
When searching for multiple elements, the driver will poll the DOM until at least one element has been found or the configured timeout has expired.
So as per the first case, driver will wait for 3 seconds only.
If we set 10 seconds in Implicit wait and before 10 seconds, within 3 seconds only element get located.
That time it will proceed further and not wait for set time..
The implicit wait will tell to the web driver to wait for certain amount of time before it throws a "NoSuchElementException". The default setting is 0. Once we set the time, web driver will wait for that time before throwing an exception. If you have given 10 sec as wait time, but element is identified at 3 sec, then it will go to next step after 3 secs.
An explicit wait is code you define to wait for a certain condition to occur before proceeding further in the code. The explicit wait will tell the web driver to wait for certain conditions like visibilityOfElementLocated and maximum amount of time before throwing NoSuchElementException exception. You can refer this - https://qaautomation.expert/2019/07/18/implicit-explicit-fluent-wait-in-selenium-webdriver/

The default value of timeouts on selenium webdriver

I am interested in the default value of timeouts on selenium webdriver.
ImplicitlyWait, SetPageLoadTimeout and SetScriptTimeout.
Because I want to know, Do I need to set a values for those timeouts? or the default value is good for selenium webdriver working.
But I cannot find a correct answer, someone say the default value is 0, and other one say it is 30 sec.
These three timeouts are managed by the server-side of the Selenium equation. Your script, be it in Java, Python, Ruby, C#, or whatever, is a client that sends commands to a server that lives in the browser. (There may be an intermediary that relays commands to the browser, like Selenium grid. Unfortunately, it is also sometimes called a "server".)
The WebDriver specification, which was derived from Selenium has settled on the following values:
For implicit waits: 0 seconds. This means that if a selenium command does not find an element immediately, it reports immediately, rather than wait until an element is found.
For page loads: 300 seconds.
For script timeouts: 30 seconds.
(The specification gives the values in milliseconds. I've converted them to seconds for ease of reading.)
Selenium now follows the WebDriver specification.
In the past Selenium has used other values for these, however. For instance, the Firefox driver used to define its timeouts like this:
The implicit wait timeout is set to 0 by default. This means that if a command that finds elements does not find anything, it won't wait.
The page load timeout is set to -1 by default. This means that Selenium will wait indefinitely for the page to load.
What Saifur found is not the same as the page load timeout. That's a timeout between the Selenium client and the Selenium server, which is not particularly well explained on the page Saifur found.
The script timeout is set to 0 by default. A comment in the source code explains:
The amount of time, in milliseconds, this session should wait for asynchronous scripts to finish executing. If set to 0, then the timeout will not fire until the next event loop after the script is executed. This will give scripts that employ a 0-based setTimeout to finish.
So even if it set to zero, an asynchronous script can still execute but it has to complete before Selenium's timeout gets a chance to run again.
This is from the code that Selenium uses for Firefox. The other browsers use different code bases but they are supposed to behave consistently, at least with regards to things that are proper to Selenium itself, like these timeouts. So the values and their interpretations should be the same for other browsers too.
For implicit wait always default wait it ZERO. , you can check it here :
Selenium Webdriver diff. waits
And if you set custom time then web driver will wait to get element till that time and if element does not found till that time then only web driver will throw exception.
The Selenium documentation is very much unclear on these timeouts.
According to
this
the default timeout of the implicit-wait is 0
According to
this
any page that does not load in 60s will return http communication
timeout unless you explicitly overwrite the timeout.
Unfortunately, I did not find any reference to provide on
ScriptTimeout. But, it's defaults to 0 according to my knowledge
and experience. Will update you with any reference later