WebDriver Exploration Part-3(WebDriver Waits)
You may come across scenario's where you see elements on pages are loaded after some delay or after some specific event.
In such a case, our scripts can fail and complain it cannot find the element.
To tackle such scenario's we can have our script developed in such a way that it will wait for some predefined time before interacting with such type of elements
We will stick to our earlier example of clicking Gmail link on google home page, here we assume Gmail link appears after some delay on the home page, below are the ways we can tackle this
Sleeping till things appear on the page 😴
Yes. Sleeping till things get to normal.
Assuming that Gmail link appears within 10 seconds after the page is loaded, we can sleep for 10 seconds before interacting with it, check below
Now some BAD news
In such a case, our scripts can fail and complain it cannot find the element.
To tackle such scenario's we can have our script developed in such a way that it will wait for some predefined time before interacting with such type of elements
We will stick to our earlier example of clicking Gmail link on google home page, here we assume Gmail link appears after some delay on the home page, below are the ways we can tackle this
Sleeping till things appear on the page 😴
Yes. Sleeping till things get to normal.
Assuming that Gmail link appears within 10 seconds after the page is loaded, we can sleep for 10 seconds before interacting with it, check below
[TestMethod] public void Verify_Wait_Sleep() { InternetExplorerOptions options = new InternetExplorerOptions(); options.IntroduceInstabilityByIgnoringProtectedModeSettings = true; options.RequireWindowFocus = true; IWebDriver driver = new InternetExplorerDriver(options); driver.Url = "https://www.google.com/"; //Sleep till things get back to noraml :) System.Threading.Thread.Sleep(10000); //Locate Element By partial link text IWebElement gmailLink = driver.FindElement( By.PartialLinkText("mail")); //Click gmail link gmailLink.Click(); //Driver close first instance driver.Quit(); }
Now some BAD news
- This is the worst way to tackle waits in your scripts as we end up waiting for 10 seconds every time in our script where there is step to click on Gmail link
- If Gmail link appears after 2 seconds then also our script will wait for 10 seconds, so this is not smart enough
Implicit Waits
We can use an implicit wait of 10 seconds that is applicable to the life of WebDriver object instance.
So if the Gmail link appears before 10 seconds then the script will continue executing so we do not end up waiting for 10 seconds
Point to note implicit wait is global and in our case, it will wait for 10 seconds every time for finding elements before throwing no element found exception
[TestClass] public class WebdriverCourse { IWebDriver driver; [TestInitialize] public void Setup() { InternetExplorerOptions options = new InternetExplorerOptions(); options.IntroduceInstabilityByIgnoringProtectedModeSettings = true; options.RequireWindowFocus = true; driver = new InternetExplorerDriver(options); //Implicit Wait driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10); } [TestMethod] public void Verify_Wait_ImplicitWait() { driver.Url = "https://www.google.com/"; //Locate Element By partial link text IWebElement gmailLink = driver.FindElement( By.PartialLinkText("mail")); //Click gmail link gmailLink.Click(); //Driver close first instance driver.Quit(); }
}
In the above example, we have set up our driver object in the Setup method.
We have also set up implicit wait to 10 seconds
Now as discussed earlier implicit wait once set up will stay for the lifetime of WebDriver instance.
So for each test method, we will have an implicit wait of 10 seconds, which we may not want.
What if we want to wait only for certain conditions?
Is there a setting which is not global, so we can apply it wherever it is required?
Yes. you can use explicit waits
Explicit Waits
Explicit waits are smart waits which we can use to wait for certain condition to occur before proceeding with code execution
What can be those conditions?
Say you want to click the element only when it is visible, in our case the Gmail link
Do I need to write code to figure out what is visible/invisible?
No. ExpectedConditions class utility class is already there which can help us with that
We will use WebDriverWait and ExpectedConditions class to solve our wait concerns
Note- To use ExpectedConditions class, install 'DotNetSeleniumExtras' package using nuget
[TestClass] public class WebdriverCourse { IWebDriver driver; [TestInitialize] public void Setup() { InternetExplorerOptions options = new InternetExplorerOptions(); options.IntroduceInstabilityByIgnoringProtectedModeSettings = true; options.RequireWindowFocus = true; driver = new InternetExplorerDriver(options); } [TestMethod] public void Verify_Wait_ExplicitWait() { driver.Url = "https://www.google.com/"; //Explicit Wait WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); wait.Until(ExpectedConditions.ElementIsVisible(By.PartialLinkText("mail"))); //Locate Element By partial link text IWebElement gmailLink = driver.FindElement( By.PartialLinkText("mail")); //Click gmail link gmailLink.Click(); //Driver close first instance driver.Quit(); }
}
Conclusion
- Do not use Sleep method for waits
- Do not use implicit and explicit waits both as it can lead to unpredictable wait times
- Use explicit wait only in your code
- Decide the maximum wait time out wisely as it can increase your overall execution time of the test suite.
Comments
Post a Comment