I am doing an explicit wait with a TimeSpan of 30 seconds and wait.Until(By.CssSelector("#content .data-grid > .data-row")).
I obviously have a data-grid that is being populated here.
Result:
The wait.Until(...) is returned right away (it does not wait for this CssSelector to evaluate with satisfactory results).
Expected result:
I expect there to be a wait until the data is asynchronously returned.
Is this a valid scenario for explicitly waiting?
wait.Until(By.CssSelector("#content .data-grid > .data-row"))
I think you are missing the ExpectedConditions...
You declare the wait:
WebDriverWait wait = new WebDriverWait(driver.driver, TimeSpan.FromSeconds(30));
Then you add ExpectedConditions here I am using ElementIsVisible for the example:
wait.Until(ExpectedConditions.ElementIsVisible(By.CssSelector("#content .data-grid > .data-row")));
Hope this does the trick!
I am looking for better solution to wait until element disappear. Now I am using:
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeout));
wait.Until((ExpectedConditions.InvisibilityOfElementLocated(element)));
This method is working, but it last long. Element is invisible in dom after ~2sec but driver is waiting for this condition <20 sec. I was looking for another solutions, but couldn't find one which will work in .net.
I am using IE to run my tests.
I'd assume that you're mixing implicit and explicit waits, which causes collision. You should make sure that implicit waits are set to 0 in case of using WebDriverWait.
Wait.Until gets a selector and returns an element.
First Question
How can you wait (poll) for multiple conditions to be met?
Problem:
DefaultWait<IWebDriver> wait = new WebDriverWait(driver, timeout);
IWebElement element = wait.Until(ExpectedConditions.ElementExists(selector));
Wait.Until doesn't have an overload or a constructor with params...
Second Question
Wait.Until appears to get only one condition per each poll.
Is there a way to poll over multiple conditions?
Meaning, in that same polling, check if element exists and also check if its visible (which are two different things..)
in 1 polling sequence,
Something like the following:
DefaultWait<IWebDriver> wait2 = new DefaultWait<IWebDriver>(driver);
IWebElement element = wait2.Until<IWebElement>((d) =>
{
ExpectedConditions.ElementExists(selector);
ExpectedConditions.ElementIsVisible(selector);
return d.FindElement(selector);
});
Ok so my question is 'How should I wait for an extended period of time say 15 min with webdriver'. Is it viable to use Thread.Sleep(60*1000*15)? What potential issues could come from having the driver just wait for a long time does it get stale?
The reason I have to write a test with such a wait is that I am testing some integration with one of our 3rd parties. We submit some work to them and generally speaking it can take anywhere from a few min to around 15 min for the work to be picked up and processed.
That being said I have been thinking about the more costly approach and use explicit waits with expected conditions and just use Driver.Navigate().Refresh() until I see the elements I expect. My concern here is that if I take this approach there will be a portion of the test where it would be refreshing the browser ever 10 or so seconds for a duration of 5-10 min. Which of these approaches seems better. Are there dangers of refreshing the browser so much could the driver 'loose' the browser? Not really a fan of either of these approaches so any other suggestions id be open to.
Is there any other indication that the integration has finished processing aside from the element/s showing up on the web page? E.g. a file being created somewhere etc.
If not, then I would definitely be taking the second approach - it is a much better approach since you will only wait roughly the amount of time you need to wait and also it will not bomb if for some reason it takes more than the maximum amount you specified. I would still set an upper limit e.g. 20 or 30 minutes for the test to fail if the element is not showing.
There should be no issue with keeping your browser open and refreshing as long as the web application is stable. And BTW this is actually quite a common scenario in test automation, unfortunately for third party integration there is not much else you can do.
in C# it looks something like this-
/// <summary>
/// Returns an element if found, otherwise returns null
/// </summary>
/// <param name="by"></param>
/// <returns></returns>
internal IWebElement FindElementIfExists(By by)
{
IWebElement element = null;
try
{
element = FindElement(#by);
}
catch (NoSuchElementException)
{
}
return element;
}
public void Test()
{
var stopwatch = Stopwatch.StartNew();
var timeout = 30 // in minutes
browser.GoTo<Page>();
while (FindElementIfExists(By.Id("id")) == null && stopwatch.Elapsed.TotalMinutes < timeout)
{
Thread.Sleep(30); // sleep for 30 seconds
browser.GoTo<Page>();
}
if (stopwatch.Elapsed.TotalMinutes >= timeout)
// fail test
// continue test
}
I have a TestMethod using Selenium as below:
[TestMethod]
public void ShouldSendPasswordReminder()
{
// go to loginregister url
_fireFoxWebDriver.Navigate().GoToUrl(UkPaBaseUrl + "loginregister.aspx");
Thread.Sleep(1000);
// click the forgotten password
_fireFoxWebDriver.FindElement(By.LinkText("Forgotten your password?")).Click();
Thread.Sleep(1000);
// enter your email address
_fireFoxWebDriver.FindElement(By.Id("PasswordResetRequest1_PasswordResetRequest_Username"))
.SendKeys("username.lastname#domain.com");
Thread.Sleep(1000);
// click submit
_fireFoxWebDriver.FindElement(By.Id("PasswordResetRequest1_PasswordResetRequest_PasswordResetRequestSubmit")).Click();
Thread.Sleep(5000);
// assert
Assert.IsTrue(_fireFoxWebDriver.Url.Contains("ThankYou"));
}
As you can see, I'd have to call Thread.Sleep many times (because the page might take some time to finish what it does due to javascript, etc) almost after each action because Selenium doesn't seem to be able to handle page loads and delays unlike WatiN.
This makes the code rather ugly and not very much reliable.
What's the better way to handle such scenarios? Do you write frequent Thread.Sleep calls in your tests as well?
Thanks,
You could use the manage functionality to set the base line time you want FindElement() to wait for before failing:
_fireFoxWebDriver.Manage()
.Timeouts()
.ImplicitlyWait(TimeSpan.FromSeconds(1000));
Explicit wait.
According to official documentation (http://www.seleniumhq.org/docs/0...), Thread.sleep() is the worst case of explicit wait.
In explicit wait, without waiting for the maximum time to get over, it proceeds as soon as the condition occurs, if that condition occurs before the specified maximum time gets over. Hence having to wait till the maximum time (because the condition did not occur during the specified maximum time) is the worst case of explicit wait.
I think Thread.sleep() is considered as the worst case of explicit wait because, for Thread.sleep(), it has to wait for the full time specified as the argument of Thread.sleep(), before proceeding further.
You may think why Thread.sleep() isn't implicit wait. I think that is because effect of Thread.sleep() is only at the place where it is written, like explicit wait. Effect of implicit wait however, is for the entire lifetime of the driver instance.
**JAVA**
WebDriver driver = new FirefoxDriver();
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));
**C#**
using (IWebDriver driver = new FirefoxDriver())
{
driver.Url = "http://somedomain/url_that_delays_loading";
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
IWebElement myDynamicElement = wait.Until<IWebElement>(d => d.FindElement(By.Id("someDynamicElement")));
}
This waits up to 10 seconds before throwing a TimeoutException or if it finds the element will return it in 0 - 10 seconds.
My sample code, my test case wanted me to wait for a maximum of 10 seconds, earlier I was waiting for 10 seconds before finding my next element using Thread.Sleep. Now I use the the WebDriverWait so if the element is found it proceeds, this speeds up my day to day activities and also saves time.
using (IWebDriver driver = new ChromeDriver(options))
{
TimeSpan t = TimeSpan.FromSeconds(10);
WebDriverWait wait = new WebDriverWait(driver,t);
try
{
driver.Navigate().GoToUrl("URL");
//IWebElement username = driver.FindElement(By.Name("loginfmt"));
IWebElement username = wait.Until(ExpectedConditions.ElementIsVisible(By.Name("loginfmt")));
username.SendKeys(dictionaryItem);
//Thread.Sleep(10000); Removed my Thread.Sleep and tested my wait.Until and vola it works awesome.
IWebElement next = wait.Until(ExpectedConditions.ElementIsVisible(By.Id("idSIButton9")));
//IWebElement nextdriver.FindElement(By.Id("idSIButton9"));
next.Click();
My general heuristic on introducing delays when my script gets faster than my app is to really think about what I'm waiting for. In my opinion, sleep type calls are really only appropriate in cases where I'm actually waiting for time to elapse. A case where I was testing an automatic timeout might make sense to have a Thread.sleep type call in it, because I'm actually waiting for a specific amount of time to elapse. Usually, however, I'm waiting for other things to occur - pages to load, javascript to execute, etc. In these cases, waiting for a set period of time is an easy way to seem to get past the potentially greater complexity of checking for what I'm actually waiting for. This has multiple pitfalls though - you may be slowing down your tests too much (what if each of your waits above only needed to be 200ms, for example - now even the brief snippet above takes an extra 2.5 seconds (and that's without adjusting the 5 second wait at the end). That may not seem like much by itself but it adds up as your suite gets bigger.) Another pitfall happens when you move to a slower machine or environmental things slow down your app - what if it took 1.5 seconds before you could click the Forgotten your password? link on one machine. Your test would fail, but that may still be within acceptable performance thresholds for your app, so you now have a false failure. This is often dealt with by simply increasing the wait time, but that leads back to the first pitfall I mentioned again.
To break out of this cycle, I find it's very important to be as specific as possible when I'm waiting for things. Selenium provides a Wait class that can be used to wait until a particular condition is met. I don't know if the .Net bindings include it, but i would go into using them expecting it. In the Ruby version, we give Wait a block of code - it can look for the presence of an element or whatever else we need to check. The wait method takes a timeout value and an interval value, and then runs the block every interval seconds until either the block returns true or the timeout period has elapsed. Setting up a class like this allows you to set your timeout values high enough to handle the low end of the performance scale but not to incur the penalty of waiting a lot longer than you really need to in a given run.