简体   繁体   中英

Selenium C# Maximum time to wait for Timeout Exception

What is the maximum explicit timeout that Selenium C# waits before it throws timeout exception?

Sometimes the application which we are testing becomes very slow and takes up to 4 mins to load .I want to add a wait time, so that it will wait a maximum upto 5 mins.

I have tried with this code

WebDriverWait wait1 = new WebDriverWait(WebDriver, TimeSpan.FromMinutes(5));

wait1.Until(x => (bool)((IJavaScriptExecutor)x).ExecuteScript("returnjQuery.active==0"));

But it throws timeout exception around 2 mins.

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.

WebDriverWait can wait for element. I afraid that WebDriverWait won't work on JavaScriptExecutor directly. you need to handle something like below

You can wait till document to be in ready state.

 string state = string.Empty;
state = ((IJavaScriptExecutor) _driver).ExecuteScript(@"return document.readyState").ToString();

The full code be like below

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;
    }
}

Source :-

https://automationoverflow.wordpress.com/2013/07/27/waiting-for-page-load-to-complete/

Refer below for

How to make Selenium WebDriver wait for page to load when new page is loaded via JS event

Hope it will help you :)

Answering straight if you are using ExplicitWait ie WebDriverWait while the page gets loaded through:

WebDriverWait wait1 = new WebDriverWait(WebDriver, TimeSpan.FromMinutes(5));

wait1.Until(x => (bool)((IJavaScriptExecutor)x).ExecuteScript("returnjQuery.active==0"));

IMO, it's a overhead.

It is worth to mention that once your script starts loading an url, by default the browser client returns document.readyState === "complete" . Then only your next line of code gets executed.

Page Loading:

Now let me get a bit specific now. Using Selenium, by default 3 (three) types of timeouts are implemented as follows:

  1. session script timeout : Specifies a time to wait for scripts to run. If equal to null then session script timeout will be indefinite. Otherwise it is 30,000 milliseconds.
  2. session page load timeout : Specifies a time to wait for the page loading to complete. Unless stated otherwise it is 300,000 milliseconds. [ document.readyState === "complete" ]
  3. session implicit wait timeout : Specifies a time to wait in milliseconds for the element location strategy when retreiving elements and when waiting for an element to become interactable when performing element interaction . Unless stated otherwise it is zero milliseconds.

Element Loading:

In case after an interaction with an element (elementA, which calls a jQuery ) you need to wait for a jQuery to be completed for another element to be interactable (elementB), the function you mentioned fits the bill.

Conclusion:

As you are looking for a solution to timeout after 5 mins while loading the url, it is already implemented by default through session page load timeout with a value 300,000 milliseconds or 5 minutes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM