Selenium - waiting until element disappears last long - c#

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.

Related

C# Selenium - Explicitly waiting By.CssSelector(...)

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!

Selenium wait issue

I have an input box that pulls an autocomplete list. The list is a little slow to pull, so I need selenium to just wait before pressing the enter key, which will select the first item in the list. here is what I have so far
webDriver.FindElement(By.Id("seg-gl-1")).SendKeys("2");
webDriver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
webDriver.FindElement(By.Id("seg-gl-1")).SendKeys(Keys.Enter);
The issue is that selenium is hitting Enter too quickly. I believe I am using the implicitwait incorrectly. Can anyone shed some light on my issue?
When you use
webDriver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
You are only setting the default ImplicitWait time. If you want to actually perform a wait for, lets say 10sec, you could use
System.Threading.Thread.Sleep(5000);
Generally you should avoid this type of wait, but I'm guessing that there are javascript/ajax calls performed in the background of your application, and hence you should wait for these to execute before being able to assert the site behaviour (as these calls might update the DOM and such). For further help on that, please refer to my answer in this thread: https://stackoverflow.com/a/45033412/6220192

DefaultWait<T>.until behavior for polling

I have a piece of code such as
DefaultWait<IWebDriver> wait = new DefaultWait<IWebDriver>(driver);
wait.PollingInterval = TimeSpan.FromMilliseconds(250);
wait.Message = "Can't find element";
wait.Timeout = TimeSpan.FromSeconds(30);
driver.Navigate().GotoUrl('.....');
IWebElement elem = wait.Until(x => x.FindElement(By.ClassName("abc")));
Now lets say that the URL I navigated to does not contain that element with a class name "abc".
My understanding of DefaultWait is that it is supposed to find that element by polling every 250 milliseconds and timeout after 30 seconds. But I see that
it almost immediately returns that the element is not present or throws an exception.
I am a little confused because, technically after 10 seconds or so the DOM could have been altered to create an element of that class and the wait should have been successful/ or could have been successful.
So the question is what is the behavior of the DefaultWait? Should it wait until the given timeout or am I completely missing the behavior of the DefaultWait?
It is easiest to let the ElementExists expected condition handle this.
IWebElement elem = new WebDriverWait(Driver, TimeSpan.FromSeconds(30))
.Until(ExpectedConditions.ElementExists(By.ClassName("abc"));
The reason your example is not working as expected is because FindElement throws an exception on failure. You could rework your example to use FindElements, which will happily return an empty collection, but even then, you'd need to add logic to handle an empty collection, since DefaultWait.Until considers any non-null return value to be a success.
The easiest thing is to use the logic provided in ExpectedConditions to do all the heavy lifting for you.
The default polling interval is 500ms. You can set the polling interval by passing in the optional third parameter, like this:
IWebElement elem =
new WebDriverWait(Driver,
TimeSpan.FromSeconds(30), // time out
TimeSpan.FromMilliseconds(250)) // polling interval
.Until(ExpectedConditions.ElementExists(By.ClassName("abc"));

How can i minimize performance hit for Coded ui when using nested if statement in test method

Is there a way for me to minimize the performance hit when i'm either running or debugging my coded U.I test. Currently its taking me a long time to run my coded UI test because it takes to long to execute. I"ve timed it and too long means that for checking if a screen exist and doing an action it takes over 1min plus, so its taking me to long to debug and finish it out.
To give some more background. These if statements are all inside one test method, where i'm checking for different screens. Its very dynamic but takes to long to run. I've read i can do ordered test but i didn't think i can create ordered test with these dynamic screens(reason being i dont think ordered test can act as if statements to account for dynamic dialog and screens) and plus i think its too late in the process to go to that architecture.
I've tried the following playback settings with little or no improvements.
Here are my current playback settings
Playback.PlaybackSettings.WaitForReadyLevel = WaitForReadyLevel.Disabled;
//Playback.PlaybackSettings.SmartMatchOptions = SmartMatchOptions.None;
Playback.PlaybackSettings.MaximumRetryCount = 10;
Playback.PlaybackSettings.ShouldSearchFailFast = false;
Playback.PlaybackSettings.DelayBetweenActions = 1000;
Playback.PlaybackSettings.SearchTimeout = 2000;
None of these setting have helped either turning off smart options.
I could have sworn that i've read somewhere that if i replace my if statements
with try catch that this would help, but i maybe totally wrong since i'm just grabbing at straws to try to atleast increase performance by 40% or so.
Would anyone have any tips or tricks when dealing with ifs statements that you had to code in your coded ui code.
I'm guessing your if statements are of a kind:
if (uTtestControl.exists)
{
do something
}
if that's the case - your delays are a result of codedui searching for the control - a time costly operation - especially when searching for a control that doesn't exists.
there are a number of ways to handle this - if my guess is in the ball park - please confirm and i'll detail the options.
Updtae:
the main reason for delay is the MaximumRetryCount =10. in addition try the following settings:
Playback.PlaybackSettings.MaximumRetryCount = 3;
Playback.PlaybackSettings.DelayBetweenActions = 100;
Playback.PlaybackSettings.SearchTimeout = 15000;
when waiting for control to exists use the:
uiTtestControl.WaitForControlExist(5000)
this will tell the playback to search for the control for a max of 5 sec.
in addition - you should reduce the Playback.PlaybackSettings.SearchTimeout before searching for a control that you know might not exists:
var defaultTimeout = Playback.PlaybackSettings.SearchTimeout;
Playback.PlaybackSettings.SearchTimeout = 5000;
and after you finish searching return it to the default value:
Playback.PlaybackSettings.SearchTimeout = defaultTimeout;
this should do the trick

What's the alternative to use Thread.Sleep when working with Selenium in system testing?

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.

Categories