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);
Related
I want to start my Selenium script on a login page, wait for 30 seconds so I can manually resolve a captcha, and once the login is successful, start the actual work automation work.
I'm using the code below, and it works ok up to the line where it enter the email.
I supposed that this code will wait in a sort of pooling until it sees the H4 element with certain text in it (login successful), but it throws an exception when the element is not found.
IWebDriver driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
driver.Navigate().GoToUrl("URL");
var loginEmail = driver.FindElement(By.Id("LOGINTextBTTN"));
loginEmail.SendKeys("myEmail"); //this line works
IWebElement firstResult = wait.Until(ExpectedConditions.ElementExists(By.XPath(#"//h4[text()='H4 Text']"))); //this lines fails with an exception
Console.WriteLine(firstResult.GetAttribute("textContent"));
Write the code
driver.manage().timeouts().implicitlyWait(60,TimeUnit.SECONDS) ; // Wait for 60 Sec.
WebElement firstResult = wait.Until(ExpectedConditions.ElementExists(By.XPath(#"//h4[text()='H4 Text']")));
Or
You can use Fluentwait
Wait wait = new FluentWait(driver).withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS).ignoring(NoSuchElementException.class);
I had to deal with this a while back. The way I solved was with sleep:
time.sleep(seconds need to solve) #for me it was around 60ish seconds
Probably something like:
import code
code.interact(local=dict(globals(), **locals()))
Then Ctrl+D out after you solve the captcha
So I'm running automated UI tests with Selenium Web Driver (using PhantomJS as a headless browser) on a web application. When I get to a certain point in my test -- a page where the web app takes over a minute to load the next page (up to 3 minutes some times) -- It will fail.
I get below error message:
Result Message:
Test method UI_Tests.UT_GI_Template.Delivery_UI threw exception:
OpenQA.Selenium.WebDriverException: The HTTP request to the remote
WebDriver server for URL
http://localhost:45539/session/94ef38f0-a528-11e7-a7fd-69a0e29e333f/element/:wdc:1506697956275/value
timed out after 60 seconds. ---> System.Net.WebException: The request
was aborted: The operation has timed out.
I have set the wait time interval to 300 seconds yet it always times out after 60 seconds. Has anyone experienced this error? Here is my code:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.PhantomJS;
namespace UI_Tests
{
[TestClass]
public class UT_GI_Template {
private RemoteWebDriver wd;
[TestMethod]
public void Delivery_UI()
{
IWebDriver wd = new PhantomJSDriver();
try
{
WebDriverWait wait = new WebDriverWait(wd, new TimeSpan(0, 0, 300));
wd.Navigate().GoToUrl("example.com/QA");
wait.Until(d => (d.FindElements(By.CssSelector("#ctl00_ctl00_BodyContent_emailaddress")).Count != 0));
wd.FindElement(By.CssSelector("#ctl00_ctl00_BodyContent_emailaddress")).Click();
wd.FindElement(By.CssSelector("#ctl00_ctl00_BodyContent_emailaddress")).Clear();
wd.FindElement(By.CssSelector("#ctl00_ctl00_BodyContent_emailaddress")).SendKeys("coffutt#icom.com");
wait.Until(d => (d.FindElements(By.CssSelector("#ctl00_ctl00_BodyContent_emailpassword")).Count != 0));
wd.FindElement(By.CssSelector("#ctl00_ctl00_BodyContent_emailpassword")).Click();
wd.FindElement(By.CssSelector("#ctl00_ctl00_BodyContent_emailpassword")).Clear();
....
Test will always time out on step below -- Enter on next button triggers a new page to load (which takes up to 3 minutes) -- I have checked and the rest of my UI tests in the suite run fine with below step commented out.
wait.Until(d => (d.FindElements(By.CssSelector("#ctl00_ctl00_BodyContent_BodyContent_NextButton")).Count != 0));
wd.FindElement(By.CssSelector("#ctl00_ctl00_BodyContent_BodyContent_NextButton")).SendKeys(Keys.Enter);
wait.Until(d => (d.FindElements(By.XPath("//*[#class='grid8 alpha omega']/h1")).Count != 0)); //
string madeIt5 = wd.FindElement(By.XPath("//*[#class='grid8 alpha omega']/h1")).Text;
Is there something I don't know about time intervals or that I am doing wrong? I have included no ImplicitWaits anywhere else in the code and have not included any System.Sleep(s). Why do my tests always timeout after 60 seconds when i have the interval time set to 300 seconds with WebDriverWait wait = new WebDriverWait(wd, new TimeSpan(0, 0, 300));? Any help would be greatly appreciated, thanks!!
After a lot of investigation (and about a million google searches) I have figured out and fixed the problem affecting my automated Selenium tests. The 60 second HTTP timeout error was coming from the Selenium RemoteWebDriver's default settings, this line in the source code >
https://github.com/SeleniumHQ/selenium/blob/9ca04253b7ed337852d50d02c72cb44a13169b71/dotnet/src/webdriver/Remote/RemoteWebDriver.cs#L69
protected static readonly TimeSpan DefaultCommandTimeout = TimeSpan.FromSeconds(60);
The only way to change this value of 60 seconds is to do so when you instantiate your webdriver, in my case I am using PhantomJS and the code looked like this >
var timeOutTime = TimeSpan.FromMinutes(4);
var options = new PhantomJSOptions();
options.AddAdditionalCapability("phantomjs.page.settings.resourceTimeout", timeOutTime);
RemoteWebDriver wd = new PhantomJSDriver("C:\\Users\\MyName\\Source\\Workspaces\\ICompany\\Application\\packages\\PhantomJS.2.0.0\\tools\\phantomjs\\", options, timeOutTime);
My old tests were timing out because of an ASP.net __doPostBack button that would take longer than 60 seconds to fetch data from my database when I selected a lot of arguments/items and therefore would trigger the default command timeout for HTTP requests seen in the WebDriver source code. I know this was the problem because the test would never time out on the postback with under 3 arguments/items selected.
Hope this solution can help someone else, cheers!
update 24-10-2022:
webBrowser = new ChromeDriver(chromeDriverService, chromeOptions, TimeSpan.FromMinutes(5));
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.
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
I am doing an upload with Selenium, after the upload an elements gets invisible and I know its completed. The problem is this code throws a WebDriverException everytime after 1 minute and I don't know why since I set the timeout to 5 minutes.
It would be great if someone knows a solution for this. Thank you :)
var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(300));
wait.Until(ExpectedConditions.InvisibilityOfElementLocated(By.XPath(xpath)));