Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selenium: How to make the web driver to wait for page to refresh before executing another test

I am writing Test Cases using Selenium web Driver in TestNG and I have a scenario where I am running multiple tests sequentially (refer below)

@Test(priority =1) public void Test1(){ } @Test(priority =2) public void Test2(){  } 

Both Tests are AJAX calls where a Dialog box opens, tests executes, then dialog box closes and then a notification message appears on top of page and after each successful test the page refreshes.

The problem is: Test2 do not wait for the page to refresh/reload. Suppose when Test1 gets successfully completed, Test2 will start before page refresh (ie it opens the dialog box, executes scenarios etc..) meanwhile the page refreshes (which was bound to happen after successful execution of Test1 ). Now since the page refreshes, the diaog box opened due to Test2 is no longer present and then Test2 fails.

(Also, I do not know how long it will take to refresh the page. Therefore, I do not want to use Thread.sleep(xxxx) before executing Test2)

Also, I don't think

driver.navigate().refresh() 

will solve my problem by putting it before Test2 as in that case my page will get refreshed twice. The problem is the refresh that is happening through the code (which is uncertain as it may take 1 sec or 3 sec or 5 sec)

like image 821
Bhuvan Avatar asked Nov 06 '12 04:11

Bhuvan


People also ask

What would you do to make the WebDriver wait for a page to refresh before executing the test?

until(conditionToCheck); This way you can wait for your element to be present before executing your test2.

How will you wait until a Web page has been loaded completely?

We can wait until the page is completely loaded in Selenium webdriver by using the JavaScript Executor. Selenium can run JavaScript commands with the help of the executeScript method. We have to pass return document.

Which wait tells the WebDriver to wait for a certain amount of time before it throws an exception?

Implicit Wait directs the Selenium WebDriver to wait for a certain measure of time before throwing an exception. Once this time is set, WebDriver will wait for the element before the exception occurs.


2 Answers

If you are waiting for element to present then

In selenium rc we used to do this using selenium.WaitForCondition("selenium.isElementPresent(\"fContent\")", "desiredTimeoutInMilisec")

In web driver U can achieve the same thing using this

WebDriverWait myWait = new WebDriverWait(webDriver, 45); ExpectedCondition<Boolean> conditionToCheck = new ExpectedCondition<Boolean>() {     @Override     public Boolean apply(WebDriver input) {         return (input.findElements(By.id("fContent")).size() > 0);     } }; myWait.until(conditionToCheck); 

This way you can wait for your element to be present before executing your test2.

UPDATED :

If you are waiting for page to load then in web driver you can use this code:

public void waitForPageLoaded(WebDriver driver) {     ExpectedCondition<Boolean> expectation = new ExpectedCondition<Boolean>()      {         public Boolean apply(WebDriver driver)         {             return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");         }     };     Wait<WebDriver> wait = new WebDriverWait(driver,30);     try     {         wait.until(expectation);     }     catch(Throwable error)     {         assertFalse("Timeout waiting for Page Load Request to complete.",true);     } } 
like image 183
Abhishek_Mishra Avatar answered Sep 22 '22 14:09

Abhishek_Mishra


Here is better and tested version of WaitForPageLoad implementation in C#.Net

public void WaitForPageLoad(int maxWaitTimeInSeconds) {     string state = string.Empty;     try {         WebDriverWait wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(maxWaitTimeInSeconds));          //Checks every 500 ms whether predicate returns true if returns exit otherwise keep trying till it returns ture         wait.Until(d = > {              try {                 state = ((IJavaScriptExecutor) _driver).ExecuteScript(@"return document.readyState").ToString();             } catch (InvalidOperationException) {                 //Ignore             } catch (NoSuchWindowException) {                 //when popup is closed, switch to last windows                 _driver.SwitchTo().Window(_driver.WindowHandles.Last());             }             //In IE7 there are chances we may get state as loaded instead of complete             return (state.Equals("complete", StringComparison.InvariantCultureIgnoreCase) || state.Equals("loaded", StringComparison.InvariantCultureIgnoreCase));          });     } catch (TimeoutException) {         //sometimes Page remains in Interactive mode and never becomes Complete, then we can still try to access the controls         if (!state.Equals("interactive", StringComparison.InvariantCultureIgnoreCase))             throw;     } catch (NullReferenceException) {         //sometimes Page remains in Interactive mode and never becomes Complete, then we can still try to access the controls         if (!state.Equals("interactive", StringComparison.InvariantCultureIgnoreCase))             throw;     } catch (WebDriverException) {         if (_driver.WindowHandles.Count == 1) {             _driver.SwitchTo().Window(_driver.WindowHandles[0]);         }         state = ((IJavaScriptExecutor) _driver).ExecuteScript(@"return document.readyState").ToString();         if (!(state.Equals("complete", StringComparison.InvariantCultureIgnoreCase) || state.Equals("loaded", StringComparison.InvariantCultureIgnoreCase)))             throw;     } } 
like image 45
Vishnu Avatar answered Sep 21 '22 14:09

Vishnu