Selenium wait until element is not present - c#

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

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.

Waits randomly not working in selenium

We have some UI tests written in selenium running with Browserstack on TeamCity.
These tests randomly fail because (in my opinion) the wait.Untils are not working correctly as the error always is 'could not click element ... because element would receive the click. As you can see in the code i apply multiple waits and still it randomly ignores them.
driver.FindElement(By.XPath("//input[#value='Login']")).Click();
//wait for the page to be loaded, check the title and open a booking
wait.Until(ExpectedConditions.ElementExists(By.LinkText("To be completed")));
wait.Until(ExpectedConditions.ElementToBeClickable(By.LinkText("To be completed")));
Assert.AreEqual("Booking Overview", driver.Title);
wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60));
wait.Until(ExpectedConditions.ElementToBeClickable(By.XPath("//button")));
wait.Until(ExpectedConditions.ElementToBeClickable(By.LinkText("To be completed")));
driver.FindElement(By.LinkText("To be completed")).Click();
//wait for step 2 to load
wait.Until(ExpectedConditions.ElementExists(By.XPath("//div[#id='WiredWizardsteps']/div[2]/div/form/div/div[2]/label/span")));
wait.Until(ExpectedConditions.ElementToBeClickable(By.XPath("//div[#id='WiredWizardsteps']/div[2]/div/form/div/div[2]/label/span")));
//verify we are at step 2
var step2 = driver.FindElement(By.XPath("//ul[contains(#class, 'steps')]/li[contains(#class, 'active')]"));
Assert.AreEqual("2", step2.GetAttribute("data-target"));
//click the radiobutton with a movetoelement
var option = driver.FindElement(By.XPath("//div[#id='WiredWizardsteps']/div[2]/div/form/div/div[2]/label/span"));
new Actions(driver).MoveToElement(option).Click().Perform();
//retry programmatically
driver.FindElement(By.XPath("//div[#id='WiredWizardsteps']/div[2]/div/form/div/div[2]/label/span")).Click();
//wait for the textbox to appear
wait.Until(ExpectedConditions.ElementToBeClickable(By.Name("commodityNonOperative")));
anybody has a suggestion or had the same problems please let me know.

C# Selenium Loop When Element Is No Longer Active

I have a test case that is uploading a file and I am guessing I need a while loop to determine when the upload is complete.
There is an xpath //div[#class='media-upload-progress finished'] that appears when the file is finished or //div[#class='media-upload-progress uploading'] when the file is uploading.
I thought I could do something with a while loop and a SeleniumDriver.IsElementPresent but I have not been able to figure it out.
Any ideas?
Thanks for the help!
I would suggest you you give DefaultWait a try. PollingInterval would really help you since the finished element won't present unless the file is completely uploaded. The following code should poll the dom in every 100 ms and look for the intended element.
By bySelector = By.XPath("//div[#class='media-upload-progress finished']");
DefaultWait<IWebDriver> wait = new DefaultWait<IWebDriver>(driver);
wait.Timeout = TimeSpan.FromSeconds(1); // increase the timeout as needed
wait.PollingInterval = TimeSpan.FromMilliseconds(100);
wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
//Add more typrof() exceptions as needed
IWebElement element = wait.Until<IWebElement>((d) =>
{
return d.FindElement(bySelector );
});
Disclaimer: I have never personally implemented this. So this code is entirely untested from my side. But, theoretically this should solve the issue you are having

Page Load Timeout - Selenium Webdriver using C#

I am using Selenium 2.25 WebDriver
I'm having a issue with finding the elements on the page and some times my test cases able to find element and sometime the page is does not load and its due to page load and if i add this below line and it seems like working:
driver.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(2));
my question is, i dont want to have my code scatter with the above line of code, is there a way to make it centerlize in one place?
Any help would be greatly appreciated, thanks!
If you set the timeout once, it's set for the lifetime of the driver instance. You don't need to keep resetting it. You can set this immediately after creating the driver.
IWebDriver driver = new FirefoxDriver();
driver.Manage().Timeouts.SetPageLoadTimeout(TimeSpan.FromSeconds(2));
The only caveat for using this timeout is that not every browser may support it completely (IE does for sure, Firefox does too I think, but I don't think Chrome does).
You can try a workaround like this:
Observe the element that loads last in your page and find its id (or any other identifier). Then do something like this:
while (true)
{
try
{
IWebElement element = driver.FindElement(By.Id(...));
if (element.Displayed)
{
break;
}
}
catch (Exception)
{
continue;
}
}
This will keep looping till the element which is loaded last is displayed and breaks thereupon. The element not found exception is caught and loop is put into continuation till the element is not displayed.

Categories