How to wait for a long period of time webdriver c# - c#

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
}

Related

Making A Cool Down Timer For Multiple Users

So I'm currently developing a Discord Bot, and I have a problem on how I could make a cool down timer for a command. So I want it so if they use a command, then they get added to a list, and have to wait amount of seconds until they can use the command. I have a somewhat idea on how to do this, but I'm mainly stuck at the part of having multiple cool down timers for different people. So lets say as a reference. User1 uses the command, now he has to wait 5 seconds until he uses it again. Then User2 uses the command, and he also has to wait 5 seconds. Well User2 used the command 3 seconds in of the cool down for User1. So basically I'm asking how could I make a timer that kept track of each users time. Then once that specific users cool down is done, he gets removed from a list. I planned to store the users that are on cool down into a list.
I might be overthinking this, so sorry.
The way that I did it was by making it so the program declares 2 empty lists near the start, one containing DateTimeOffset and the other SocketGuildUser. You could tie the two into a list of object instances, if you want your code to be a little more efficient and bug-resistant. For the sake of the example however:
Declare your lists at the start of your program.
public static List<DateTimeOffset> stackCooldownTimer = new List<DateTimeOffset>();
public static List<SocketGuildUser> stackCooldownTarget = new List<SocketGuildUser>();
Here's the rate limit code:
//Check if your user list contains who just used that command.
if (Program.stackCooldownTarget.Contains(Context.User as SocketGuildUser))
{
//If they have used this command before, take the time the user last did something, add 5 seconds, and see if it's greater than this very moment.
if (Program.stackCooldownTimer[Program.stackCooldownTarget.IndexOf(Context.Message.Author as SocketGuildUser)].AddSeconds(5) >= DateTimeOffset.Now)
{
//If enough time hasn't passed, reply letting them know how much longer they need to wait, and end the code.
int secondsLeft = (int) (Program.stackCooldownTimer[Program.stackCooldownTarget.IndexOf(Context.Message.Author as SocketGuildUser)].AddSeconds(5) - DateTimeOffset.Now).TotalSeconds;
await ReplyAsync($"Hey! You have to wait at least {secondsLeft} seconds before you can use that command again!");
return;
}
else
{
//If enough time has passed, set the time for the user to right now.
Program.stackCooldownTimer[Program.stackCooldownTarget.IndexOf(Context.Message.Author as SocketGuildUser)] = DateTimeOffset.Now;
}
}
else
{
//If they've never used this command before, add their username and when they just used this command.
Program.stackCooldownTarget.Add(Context.User as SocketGuildUser);
Program.stackCooldownTimer.Add(DateTimeOffset.Now);
}
From here, type whatever you want your code to do if they pass.

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

Strange Behavior with Threading and Timer

I explain my situation.
I have a producer 1 to N consumers pattern. I'm using blocking collections and everything is working well. Doing some test I noticed this strange behavior:
I was testing how long my manipulation of data took in my consumers.
I noticed this strange things, below you'll find the code cleaned of my manipulation and which produce the strange behavior.
I have 4 consumers for 1 producer.
For most of data, the Console doesn't print anything, because ts=0 (its under a tick) but randomly (between every 1 to 5sec) it plots something like this (not in this very specific order, but of the same kind):
10000
20001
10000
30002
10000
40003
10000
10000
It is of the order of 10,000 ticks so around 1ms. Always a number in the format (N)000(N-1)
Note that the BlockingCollection I consume is filled depending on some network events which occurred completely at random times. Nothing regular from here.
The timing is almost perfect, always a multiple of 10,000 ticks.
What could be behind this ? Thks !
while(IsAlive)
{
DataToFieldMapping item;
try
{
_CollectionToConsume.TryTake(out item, -1);
}
catch
{
item = null;
}
if (item != null)
{
long ts = (DateTime.Now.Ticks - item.TimeStamp.Ticks);
if(ts>10)
Console.WriteLine(ts);
}
}
What's going on here is that DateTime.Now has a fairly limited precision. It's not giving you the time to the nearest tick. It is only updated every 10,000 ticks or so, which is why you generally see multiples of 10k ticks in your prints.
If you really want to get a better feel for the duration of those events, use the StopWatch class, which has a much higher precision. That said, StopWatch is simply a diagnostic tool (hence why it's in the Diagnostics namespace). You should only be using it to help you diagnose what's going on, and should be using it in production code.
On a side note, there really isn't any need to use a timer here at all. It appears that you're creating several consumers that are polling the BlockingCollection for new content. There is no reason to do this. They can simply block until the collection has items. (Hence the name, BlockingCollection.
The easiest way is for the consumers to simply do this:
foreach(var item in _CollectionToConsume.GetConsumingEnumerable())
ProcessItem(item);
Then just run that code in a background thread.
if you write the following and run, you'll see that ticks do not roll one to one, but rather in relatively large chunks b/c ticks resolution is actually much smaller.
for(int i =0; i< 100; i++)
{
Console.WriteLine(DateTime.Now.Ticks);
}
Use Stopwatch class to measure performance as that one uses a high-resolution timer which is much more suitable for the purpose.

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.

.net section running real slow

Update: The answers from Andrew and Conrad were both equally helpful. The easy fix for the timing issue fixed the problem, and caching the bigger object references instead of re-building them every time removed the source of the problem. Thanks for the input, guys.
I'm working with a c# .NET API and for some reason the following code executes what I feel is /extremely/ slowly.
This is the handler for a System.Timers.Timer that triggers its elapsed event every 5 seconds.
private static void TimerGo(object source, System.Timers.ElapsedEventArgs e)
{
tagList = reader.GetData(); // This is a collection of 10 objects.
storeData(tagList); // This calls the 'storeData' method below
}
And the storeData method:
private static void storeData(List<obj> tagList)
{
TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
long timestamp = (long)t.TotalSeconds;
foreach (type object in tagList)
{
string file = #"path\to\file" + object.name + ".rrd";
RRD dbase = RRD.load(file);
// Update rrd with current time timestamp and data.
dbase.update(timestamp, new object[1] { tag.data });
}
}
Am I missing some glaring resource sink? The RRD stuff you see is from the NHawk C# wrapper for rrdtool; in this case I update 10 different files with it, but I see no reason why it should take so long.
When I say 'so long', I mean the timer was triggering a second time before the first update was done, so eventually "update 2" would happen before "update 1", which breaks things because "update 1" has a timestamp that's earlier than "update 2".
I increased the timer length to 10 seconds, and it ran for longer, but still eventually out-raced itself and tried to update a file with an earlier timestamp. What can I do differently to make this more efficient, because obviously I'm doing something drastically wrong...
Doesn't really answer your perf question but if you want to fix the rentrancy bit set your timer.AutoRest to false and then call start() at the end of the method e.g.
private static void TimerGo(object source, System.Timers.ElapsedEventArgs e)
{
tagList = reader.GetData(); // This is a collection of 10 objects.
storeData(tagList); // This calls the 'storeData' method below
timer.Start();
}
Is there a different RRD file for each tag in your tagList? In your pseudo code you open each file N number of times. (You stated there is only 10 objects in the list thought.) Then you perform an update. I can only assume that you dispose your RRD file after you have updated it. If you do not you are keeping references to an open file.
If the RRD is the same but you are just putting different types of plot data into a single file then you only need to keep it open for as long as you want exclusive write access to it.
Without profiling the code you have a few options (I recommend profiling btw)
Keep the RRD files open
Cache the opened files to prevent you from having to open, write close every 5 seconds for each file. Just cache the 10 opened file references and write to them every 5 seconds.
Separate the data collection from data writing
It appears you are taking metric samples from some object every 5 seconds. If you do not having something 'tailing' your file, separate the collection from the writing. Take your data sample and throw it into a queue to be processed. The processor will dequeue each tagList and write it as fast as it can, going back for more lists from the queue.
This way you can always be sure you are getting ~5 second samples even if the writing mechanism is slowed down.
Use a profiler. JetBrains is my personal recommendation. Run the profiler with your program and look for the threads / methods taking the longest time to run. This sounds very much like an IO or data issue, but that's not immediately obvious from your example code.

Categories