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
Related
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.
I have made a number of tests and I'm using selenium to run them. For a certain test I need to use a number of shortcuts. However for some reason my keyUp doesn't work which then knocks off my other shortcuts. Not sure if I'm doing something wrong here.
Has anyone got any ideas why?
My code is as follows
Actions action = new Actions(driver);
action.KeyDown(Keys.Control).KeyDown(Keys.Alt).SendKeys(Keys.Tab).KeyUp(Keys.Shift).KeyUp(Keys.Alt).Build().Perform();
Thread.Sleep(4000);
excelSession.FindElementByName("elementName").Click();
action.KeyDown(Keys.Alt).SendKeys("CFNC").KeyUp(Keys.Alt).Build().Perform();
Thread.Sleep(4000);
Thread.Sleep(4000);
TearDown();
Code wise it seems fine, does the form you are sending keys to have a 4 character limit? It could be that typing that fourth character makes the current form non-active and switches it another object.
For this scenario you could also replace that line with
WebElement typeInto = excelSession.FindElementByName("elementName");
typeInto.sendKeys("CFNC" + Keys.ALT);
Or something like that.
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
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.
What's the best way if you have a big script with a large process and you get an Error, then how to tell the script, wait 1min and begin again from top.
It's written in asp.net, c#.
Example
protected void doAll() {
FirstFunction();
// If I get in this function an error it should stop wait 1min. and start doAll() again.
NextFunction();
// END
}
Try the code that may cause an error inside FirstFunction(). Catch the resulting error, sleep for a minute and call doAll(). I am not sure how it is done in ASP.NET/C#.
Think about what you are saying. Do you really want the user to wait 1, 2, 3 or even more minutes for a web page to download and render on their screen?
I strongly suggest you think about some other way of handling errors in this routine. Perhaps if you explained to us why you want to wait 1 minute, we might be able to suggest a better approach.