Saturday, July 27, 2013

Waiting for Page Load to complete

Webdriver has ways for implict and exlict wait but that wont be useful when page is taking too long to load. Also, when an exception or error is occured in the flow, we end up waiting unnecessarily for "specified" time though page has already loaded and nothing is going to change in the remaining time period.

One of the limitation of Webdriver API is no support for WaitForPageLoad out of the box. But we can implement that using WebDriverWait class and readyState property of DOM.

Here is the solution:
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; } }

No comments:

Post a Comment