C# Selenium ChromeDriver not waiting explicitly for timespan set - c#

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

Related

How to stop Selenium to allow manual captcha resolution?

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

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 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.

C# WPF Kill a Process after x time: IvalidOperationException: Process Terminated

I know, I know, there are many questions and good answers on how to kill a process after x time in C#.
However after reading and writing the code to achieve this task, I find that is impossible to kill a process after a X time. Due to my novice in C#, I find difficult to understand the cause of error and correct it.
The task I want to achieve is to kill a process after 40 minutes, that process is started by a button click. I'm writing to the console:
private void click_start(Object sender, RoutedEventArgs e) {
using(Process p = Process.Start(#"calc.exe");
{
try{
p.WaitForExit(5000);
if(!p.HasExited) {
p.kill();
Console.WriteLine("Kill process waitforexit is false");
} else {
Console.WriteLine("NO Kill, waitforexit is true");
}
}
catch (Exception ex) {
Messageox.Show(ex.Messaage);
}
}
Of all the answers in SO, this is the generalized accepted answer.
When running the code on VS 2015, the debugger gives me this error:
"Can't process the request because the Process is finished."
Also always get the same console line: No kill which indicates that WaitForExit is still true. This after waiting more than 10 minutes event the time to kill is set to less than one minute.
So I don't understand: I launched the process but when ordered to kill, it's yet finished?
Try it like this
if(!p.WaitForExit(5000))
p.kill();
I'm not sure about dynamics of your process, but, especially during debugging,
you might have relatively significant delays between one call or another, which may lead to this kind of behavior.
How about a good ole timer... The consensus is using WaitForExit though...
Process p = Process.Start(#"cal.exe");
using (var t = new Timer(delegate { p.Kill(); }, null, 5000, Timeout.Infinite))
{
//what to do?
}

Selenium and Internet Explorer Driver

I'm trying to run some tests with C# and InternetExplorerDriver.
This code is executed on Windows Server 2012, 64 bit.
Right after navigation to a new URL, I'm calling a function that waits until a page loads\20 seconds timeout.
private bool waitForPageToLoad()
{
try
{
int timeout = int.Parse(ConfigurationManager.AppSettings["TimeoutForCustomExpression"]);
IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(m_driver, TimeSpan.FromSeconds(timeout));
wait.Until(driver1 => ((IJavaScriptExecutor)m_driver).ExecuteScript("return document.readyState").Equals("complete"));
}
catch//(Exception e) //timeout
{
log(e.Message + e.StackTrace);
return false;
}
return true;
}
The function works great for every browser other than IE.
On IE, I the following error in my log:
JavaScript error (UnexpectedJavaScriptError) at
OpenQA.Selenium.Support.UI.DefaultWait1.PropagateExceptionIfNotIgnored(Exception
e) in
c:\Projects\WebDriver\trunk\dotnet\src\WebDriver.Support\UI\DefaultWait.cs:line
222 at OpenQA.Selenium.Support.UI.DefaultWait1.Until[TResult](Func`2
condition) in
c:\Projects\WebDriver\trunk\dotnet\src\WebDriver.Support\UI\DefaultWait.cs:line
180 at MainClass.waitForPageToLoad()
I have no idea why it happens.
Could somebody help me out here?
Sincerely,
Adam.
Without seeing all that extra information that Arran requested, it's hard to help you understand the error.
However if you're just looking for a quick fix that works in all browsers, I always just use
Thread.sleep(int milliseconds);
for my Selenium tests in C# that need to wait for a page to load or a certain element to render before continuing.

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

Categories