Selenium C# Maximum time to wait for Timeout Exception - c#

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 i.e. 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:
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.
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"]
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.

Related

C# Selenium ChromeDriver not waiting explicitly for timespan set

I have no implicit waits set up at all. I run the following code:
try
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
var something = wait.Until(ExpectedConditions.ElementIsVisible(By.Name("__CONFIRM__")));
}
catch (Exception ex)
{
var something = ex.Message;
}
The exception is thrown after 60 seconds, not 5 seconds. Is there some default implicit wait I need to clear first?
Having gone through the documentation for Selenium, I know you shouldn't mix implicit and explicit waits, but I am sure I am not doing that here?
So turns out that because in some instances the window the driver is running in is closed, the driver wasn't finding what it should and was timing out after the implicit 60 seconds built in.
Pro Tip: if the window can close, be sure to detect this and use the
Driver.SwitchTo()...
Function to get you out of a jam

Selinium: Wait function and if condition to repeat

In my automation project.
Browser: Firefox
I would like add a wait function without any specific time
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(7));
IWebElement query1 = driver.FindElement(By.("continue"));
How can do that?
Also to verify that if another page did not load then repeat the previous function. The reason why I am doing this is because sometimes browser does not change the page. It actually stays on that same page.
Besides this is below thing possible in Selenium
Clear Cache and Cookie for last hour
Opening URL in new tab (In already opened browser rather then opening new window)
One thing that has worked consistently for me (regarding waits) is used in the conductor framework..
Here's some pseudo-code you can attempt to recreate in C#:
while (size == 0) {
size = driver.findElements(by).size();
if (attempts == MAX_ATTEMPTS) fail(String.format("Could not find %s after %d seconds",
by.toString(),
MAX_ATTEMPTS));
attempts++;
try {
Thread.sleep(1000); // sleep for 1 second.
} catch (Exception x) {
fail("Failed due to an exception during Thread.sleep!");
x.printStackTrace();
}
}
basically this loops through the size of the selector passed, and will poll each second. Another way you can do it, is just by conditions.
Some more pseudo-code:
function waitForElement(element) {
Wait.Until(ExpectedConditions.elementIsClickable(element), 10.Seconds)
}
And to your questions -
Can Selenium...
Clear Cache and Cookie for last hour
Opening URL in new tab (In already opened browser rather then opening new window)
Opening URL in new tab (In already opened browser rather then opening new window)
If you write your tests cases correctly by making them independent of one-another and not re-using the same browser over and over, this happens automatically. When Selenium opens a new window, it starts fresh with an entirely fresh profile - meaning it has "nothing" in the cache from the start.
Selenium does not (and will never) know the difference between a tab and a window. To Selenium, it's just a handle.
Source:

How to test whether an element on the page or not under Selenium Webdriver, C#

I searched on uncountable webpages, and did not get a good answer to my question. I'm on Selenium 2.30 using C#.
I tried
if (browser.FindElement(By.XPath("xpath")).Displayed)
I tried
if (browser.FindElements(By.XPath("xpath")).Count !=0)
And also
IWebElement element = browser.FindElement(By.XPath("xpath"));
if (element.Displayed == true)
They only work when the element exist, but if not, it will pull out the exception. But that's not necessary an exception, I have something in else{} statement to handle it, I don't want the webdriver just stop me at the first point.
What I'm doing right now is
IWebElement element = null;
try
{
element = browser.FindElement(By.XPath("xpath"));
}
catch
{
}
if (element != null)
This way works so far, but I don't think this is the best solution. I appreciate if someone can show me a better way.
The way you are doing it is acceptable, but at times you will be trying to run this after performing a prior action (eg. navigating to a page) and it is usually best to give a timeout value and utilise the following WebDriverWait method:
WebDriverWait _wait = new WebDriverWait(_driver, new TimeSpan(0, 0, timeout));
element = _wait.Until(x => x.FindElement(By.XPath(searchAttribute.attributeValue)));
This allows you to wait until the element exists on the page up to the timeout value (I use 5 seconds on the application I test). However, simple you can just use your code of if(element == null) then it is was not found. If you use the WebDriverWait, you will have to catch the exception if you do not want it to throw after the timeout.

Selenium WebDriver - How to set Page Load Timeout using C#

I am using Selenium 2.20 WebDriver to create and manage a firefox browser with C#. To visit a page, i use the following code, setting the driver timeouts before visiting the URL:
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5)); // Set implicit wait timeouts to 5 secs
driver.Manage().Timeouts().SetScriptTimeout(new TimeSpan(0, 0, 0, 5)); // Set script timeouts to 5 secs
driver.Navigate().GoToUrl(myUrl); // Goto page url
The problem is that sometimes pages take forever to load, and it appears that the default timeout for a page to load using the selenium WebDriver is 30 seconds, which is too long. And i don't believe the timeouts i am setting apply to the loading of a page using the GoToUrl() method.
So I am trying to figure out how to set a timeout for a page to load, however, i cannot find any property or method that actually works. The default 30 second timeout also seems to apply to when i click an element.
Is there a way to set the page load timeout to a specific value so that when i call the GoToUrl() method it will only wait my specified time before continuing?
driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(5);
Note: driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(5)) is now deprecated.
In case this helps anyone still looking for the answer to this, the C# WebDriver API now contains the appropriate method.
driver.Manage().Timeouts().SetPageLoadTimeout(timespan)
With this you should be able to declare a wait explicitly.
WebDriverWait wait = new WebDriverWait(browser, new TimeSpan(time in seconds));
wait.until(Your condition)
you could also change the implicit wait time
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
I think that is the syntax in C#. (not to sure)
In ruby it is
#driver.manage.timeouts.implicit_wait = 30
#wait = Selenium::WebDriver::Wait.new(:timeout => 30)
i found the solution this this issue. When creating a new FirefoxDriver, there are overloads in the constructor that allow you to specify a command timeout which is the maximum time to wait for each command, and it seems to be working when calling the GoToUrl() method:
driver = new FirefoxDriver(new FirefoxBinary(), profile, new TimeSpan(0, 0, 0, timeoutSeconds));
link to FirefoxDriver constructor documentation for reference:
http://selenium.googlecode.com/svn/trunk/docs/api/dotnet/html/M_OpenQA_Selenium_Firefox_FirefoxDriver__ctor_2.htm
Hope this helps someone else who runs into this problem.
We brazilians have a word for crappy workarounds "Gambiarra"... Well... at least they do the job...
Here is mine:
var url = "www.your.url.here"
try {
DRIVER.Navigate().GoToUrl(url);
} catch {
// Here you can freely use the Selenium's By class:
WaitElement(By.Id("element_id_or_class_or_whatever_to_be_waited"), 60);
}
// rest of your application
What my WaitElement(By, int) does:
/// <summary>
/// Waits until an element of the type <paramref name="element"/> to show in the screen.
/// </summary>
/// <param name="element">Element to be waited for.</param>
/// <param name="timeout">How long (in seconds) it should be waited for.</param>
/// <returns>
/// False: Never found the element.
/// True: Element found.
/// </returns>
private bool WaitElement(By element, int timeout)
{
try {
Console.WriteLine($" - Waiting for the element {element.ToString()}");
int timesToWait = timeout * 4; // Times to wait for 1/4 of a second.
int waitedTimes = 0; // Times waited.
// This setup timesout at 7 seconds. you can change the code to pass the
do {
waitedTimes++;
if (waitedTimes >= timesToWait) {
Console.WriteLine($" -- Element not found within (" +
$"{(timesToWait * 0.25)} seconds). Canceling section...");
return false;
}
Thread.Sleep(250);
} while (!ExistsElement(element));
Console.WriteLine($" -- Element found. Continuing...");
// Thread.Sleep(1000); // may apply here
return true;
} catch { throw; }
}
After this, you can play with timeout...
Make By the things you notice that loads last in the page (like javascript elements and captchas) remembering: it will start working the // rest of your application before the page fully loads, therefore may be nice to put a Thread.Sleep(1000) at the end just to be sure...
Also notice that this method will be called AFTER the 60 seconds standard timeout from Selenium's DRIVER.Navigate().GoToUrl(url);
Not the best, but... as I said: A good gambiarra gets the job done...
Page load timeouts are not implemented in the .NET bindings yet. Hopefully they will be soon.
As of 2018:
Besides these:
driver.Manage().Timeouts().ImplicitWait.Add(System.TimeSpan.FromSeconds(5));
driver.Manage().Timeouts().PageLoad.Add(System.TimeSpan.FromSeconds(5));
driver.Manage().Timeouts().AsynchronousJavaScript.Add(timespan));
wait for searching for an item, loading a page, and waiting for script respectively.
There is:
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
For anyone who wants the opposite effect: setting timeout longer than 60s.
You need both use:
new FirefoxDriver(FirefoxDriverService.CreateDefaultService(), new FirefoxOptions(), TimeSpan.FromSeconds(120))
and
driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(120);
The new FirefoxDriver(binary, profile, timeSpan) has been obsolete.
driver.Manage().Timeouts().SetPageLoadTimeout(timespan)
does not work.
This works. Use a property setter syntax.
driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(15);

Update MVC 2 view every few seconds

I am using MVC 2, I have view which simply displays label with current time on it.
I want to update this View(label) every 5 seconds so time will update. I am using below (taken from here) but doesn't seem to be working.
public ActionResult Time()
{
var waitHandle = new AutoResetEvent(false);
ThreadPool.RegisterWaitForSingleObject(
waitHandle,
// Method to execute
(state, timeout) =>
{
// TODO: implement the functionality you want to be executed
// on every 5 seconds here
// Important Remark: This method runs on a worker thread drawn
// from the thread pool which is also used to service requests
// so make sure that this method returns as fast as possible or
// you will be jeopardizing worker threads which could be catastrophic
// in a web application. Make sure you don't sleep here and if you were
// to perform some I/O intensive operation make sure you use asynchronous
// API and IO completion ports for increased scalability
ViewData["Time"] = "Current time is: " + DateTime.Now.ToLongTimeString();
},
// optional state object to pass to the method
null,
// Execute the method after 5 seconds
TimeSpan.FromSeconds(5),
// Set this to false to execute it repeatedly every 5 seconds
false
);
return View();
}
Thanks for help in advance!
What you are doing won't work as once the initial response is sent to the client, the client will no longer be listening for data from your server for that request. What you want to do is have the client initiate a new request every 5 seconds, then simply return the data for each request. One way to do this is with a refresh header.
public ActionResult Time()
{
this.HttpContext.Response.AddHeader( "refresh", "5; url=" + Url.Action("time") );
return View();
}
You need to put your recurring loop on the client side so that it reloads the page every five seconds.
One way, using Javascript:
<script>setTimeout("window.location.reload();",5000);</script>
The code you provided, runs at server, and when a page (View in this case) is sent to the client, the server will forgot it! You should create a client side code for refreshing the page every 5 seconds. You can use a header command (refresh) or a script:
<script>
setTimeout("window.location.reload();", /* time you want to refresh in milliseconds */ 5000);
</script>
But if you just want to refresh the page for updating the Time, I never suggest you to refresh page completely. Instead, you can create a javascript function, to tick every 5 seconds, and calculate the current time and update the label.

Categories