How to wait until an element is not changing in Selenium Webdriver? - selenium-webdriver

I have begun to use explicit wait more and more to deal with asynchronous event on the page. For example i will wait for an element to be clickable before clicking it.
However many time i also face the situation when i need to wait an element to become stable, i.e. stop changing, before i will act on it. For example, i may do a query on a page, and wait for the search result (either shown in a list or a table) to stop changing, and then retrieve the results.
Off course, there will be a timeout period for this wait. So in a nutshell, i want to wait for a list or table while its values are not changed, say for 5 sec.
How to implement this kind of wait? Could anyone give a simple example in code, if possible?
Thanks,

Using FluentWait will do the job. Its advantage to implicitWait and explicitWait is that it uses polling and timeout frequency. For example, we have a timeout value of 5 seconds and 1 second for polling frequency. The element will be checked for every 1 second until it reaches the timeout value (5 sec). An exception is thrown if the timeout value is exceeded without having any result.
FluentWait is helpful in AJAX applications as well as in scenarios when element load time fluctuates often because it ignores specific types of exceptions like NoSuchElementExceptions while waiting for an element.
You can check the sample code for FluentWait here

I would do something like this. Basically you want to count what is changing, e.g. table rows, list elements, etc., wait X seconds, count again. If the count didn't change, you are done. If it did change, wait again.
int count = 0;
int newCount = 0;
boolean done = false;
while (!done)
{
newCount = driver.findElements(...).size();
if (newCount > count)
{
count = newCount;
}
else
{
// no new results, stop waiting
done = true;
}
Thread.sleep(2000);
}
Depending on your scenario, you might want to add an overall timeout so that you never exceed X minutes or whatever. Just add that to the while condition.

Related

Running more than one delay at the same time ? (C)

I'm trying to write this program where anytime a sensor is triggered I want to have a delay of lets say 3 seconds then do some action, that should be very simple.
Ideally it should go (sensor triggered) 3... 2... 1... (Do Something), what I'm struggling with is the scenario where countdown begins 3... 2... (sensor triggered again) 1... (Do Something) , now that's where things fall apart because I need another delay to begin the countdown from 3 concurrently but I don't know how to achieve that. I wish I could post that part of the code but the entire thing is linked together. Is there a way to do this with a simple C code or does this need advanced techniques ?
There are many ways:
Use threads. The sensor thread will read the sensor and the sleep for 3 seconds.
Use not blocking delays
unsigned getTick(void); // for example 1000 ticks per second
vooid foo(void)
{
unsigned sensor1StartTime = 0;
while(1)
{
if(!sensor1StartTime || (getTick() - sensor1StartTime >= 3000))
{
handleSensor1(); // it will be executed every ~three seconds
sensor1StartTime = getTick();
}
// do something else
// "something else" will not be blocked by delay.
}
}
Whenever a sensor triggers, start a thread, delay (do your count down) and do some thing (whatever you want to do) inside the thread function.

Swift threading issue in Array

In my project, have a data provider, which provides data in every 2 milli seconds. Following is the delegate method in which the data is getting.
func measurementUpdated(_ measurement: Double) {
measurements.append(measurement)
guard measurements.count >= 300 else { return }
ecgView.measurements = Array(measurements.suffix(300))
DispatchQueue.main.async {
self.ecgView.setNeedsDisplay()
}
guard measurements.count >= 50000 else { return }
let olderMeasurementsPrefix = measurements.count - 50000
measurements = Array(measurements.dropFirst(olderMeasurementsPrefix))
print("Measurement Count : \(measurements.count)")
}
What I am trying to do is that when the array has more than 50000 elements, to delete the older measurement in the first n index of Array, for which I am using the dropFirst method of Array.
But, I am getting a crash with the following message:
Fatal error: Can't form Range with upperBound < lowerBound
I think the issue due to threading, both appending and deletion might happen at the same time, since the delegate is firing in a time interval of 2 millisecond. Can you suggest me an optimized way to resolve this issue?
So to really fix this, we need to first address two of your claims:
1) You said, in effect, that measurementUpdated() would be called on the main thread (for you said both append and dropFirst would be called on main thread. You also said several times that measurementUpdated() would be called every 2ms. You do not want to be calling a method every 2ms on the main thread. You'll pile up quite a lot of them very quickly, and get many delays in their updating, as the main thread is going to have UI stuff to be doing, and that always eats up time.
So first rule: measurementUpdated() should always be called on another thread. Keep it the same thread, though.
Second rule: The entire code path from whatever collects the data to when measurementUpdated() is called must also be on a non-main thread. It can be on the thread that measurementUpdated(), but doesn't have to be.
Third rule: You do not need your UI graph to update every 2ms. The human eye cannot perceive UI change that's faster than about 150ms. Also, the device's main thread will get totally bogged down trying to re-render as frequently as every 2ms. I bet your graph UI can't even render a single pass at 2ms! So let's give your main thread a break, by only updating the graph every, say, 150ms. Measure the current time in MS and compare against the last time you updated the graph from this routine.
Fourth rule: don't change any array (or any object) in two different threads without doing a mutex lock, as they'll sometimes collide (one thread will be trying to do an operation on it while another is too). An excellent article that covers all the current swift ways of doing mutex locks is Matt Gallagher's Mutexes and closure capture in Swift. It's a great read, and has both simple and advanced solutions and their tradeoffs.
One other suggestion: You're allocating or reallocating a few arrays every 2ms. It's unnecessary, and adds undue stress on the memory pools under the hood, I'd think. I suggest not doing append and dropsFirst calls. Try rewriting such that you have a single array that holds 50,000 doubles, and never changes size. Simply change values in the array, and keep 2 indexes so that you always know where the "start" and the "end" of the data set is within the array. i.e. pretend the next array element after the last is the first array element (pretend the array loops around to the front). Then you're not churning memory at all, and it'll operate much quicker too. You can surely find Array extensions people have written to make this trivial to use. Every 150ms you can copy the data into a second pre-allocated array in the correct order for your graph UI to consume, or just pass the two indexes to your graph UI if you own your graph UI and can adjust it to accommodate.
I don't have time right now to write a code example that covers all of this (maybe someone else does), but I'll try to revisit this tomorrow. It'd actually be a lot better for you if you made a renewed stab at it yourself, and then ask us a new question (on a new StackOverflow) if you get stuck.
Update As #Smartcat correctly pointed this solution has the potential of causing memory issues if the main thread is not fast enough to consume the arrays in the same pace the worker thread produces them.
The problem seems to be caused by ecgView's measurements property: you are writing to it on the thread receiving the data, while the view tries to read from it on the main thread, and simultaneous accesses to the same data from multiple thread is (unfortunately) likely to generate race conditions.
In conclusion, you need to make sure that both reads and writes happen on the same thread, and can easily be achieved my moving the setter call within the async dispatch:
let ecgViewMeasurements = Array(measurements.suffix(300))
DispatchQueue.main.async {
self.ecgView.measurements = ecgViewMeasurements
self.ecgView.setNeedsDisplay()
}
According to what you say, I will assume the delegate is calling the measuramentUpdate method from a concurrent thread.
If that's the case, and the problem is really related to threading, this should fix your problem:
func measurementUpdated(_ measurement: Double) {
DispatchQueue(label: "MySerialQueue").async {
measurements.append(measurement)
guard measurements.count >= 300 else { return }
ecgView.measurements = Array(measurements.suffix(300))
DispatchQueue.main.async {
self.ecgView.setNeedsDisplay()
}
guard measurements.count >= 50000 else { return }
let olderMeasurementsPrefix = measurements.count - 50000
measurements = Array(measurements.dropFirst(olderMeasurementsPrefix))
print("Measurement Count : \(measurements.count)")
}
}
This will put the code in an serial queue. This way you can ensure that this block of code will run only one at a time.

Delaying time using SystemcurrentTimeMillis

The code i'm working on deals with a flock of birds moving around fast on the canvas. What I need to do is slow down how fast the birds refresh on the screen by using the System.currentTimeMillis() method. I need to use it in a while loop so that it waits 20 milliseconds before it makes the birds move around again. I'm not quite sure on how to do this.
Here is the current code:
while(NeWorld.isAlive())
{
NeWorld.updateWorld();
}
NewWorld.isAlive allows the birds to move around, and the NeWorld.updateWorld() refreshes it. It refreshes too fast and I need to slow it down with the System.currentTimeMillis() method so that it only refreshes every 20 milliseconds.
If you put your updateWorld() logic in a separate function, you can call it with certain intervals. Here is an example.
boolean iShouldStillUpdateWorld = true;
while (iShouldStillUpdateWorld) {
if (System.currentTimeMillis() % 20 == 0) {
updateWorld();
}
iShouldStillUpdateWorld = checkIfIShouldUpdateWorld();
}
This simply sits in a loop and checks if 20 millis has passed. If so, it calls your updateWorld() function then checks if it should continue to repeat this process.

Why does it increase each time?

I want to understand why the number of timer keeps increasing whenever it is in use.
Should it start from a fresh number each time?
And why does it increase 2 or 4 each but not 1?
$(document).ready(function(){
endAndStartTimer();
});
var timer;
function endAndStartTimer() {
window.clearTimeout(timer);
//var millisecBeforeRedirect = 10000;
timer = window.setTimeout(function(){alert('Hello!');},1000);
alert(timer);
}
Do I need window.clearTimeout(timer); inside the function? What would it be wrong if I d
you can try it here.
Thanks.
Some simple facts
You don't have to call clearTimeout before setting one. At least not in the code you provided.
When I run your JSFiddle in FF4 it always reports 2
Timer IDs are generated by Javascript engine implemented in the browser so you don't have much control over it. Whatever it returns is value that you have to use to clear it. I haven't tested it but it may as well be that these ID generators are implement in a different way. Although the simplest (=fastest) way is by simply incrementing the ID of the last timer ID.
The method returns unique timer ID. The only purpose is to give you a handle to use it with clearTimeout. You can't control what id is generated.

WPF: How to call Dispatcher.BeginInvoke *only* when there is nothing on the queue to be called?

I have an import file method in a WPF app that reads a file and inserts some records in a DB.
This method runs in a BackgroundWorker object.
I have a progress bar being updated inside a Dispatcher.Invoke call. If I run as is, it takes ~1 minute to import 200k records, if I just don't show any progress, it takes just 4 to 5 seconds! And if I use Dispatcher.BeginInvoke with Background priority, it takes the same 4 to 5 seconds, but the progress bar + a counter are being updated and takes ~1 minute. So, obviusly, the UI is the problem here.
And the other problem is that I need to show a progress, so I was thinking if there is any way to use Dispatcher.BeginInvoke but first check if there is anything on the queue and if so, I just skip it, which would behave like: in the 1st second, 1% done, 2 secs later 50% done and in the 4th second 100% done).
Any help on this?
thanks!!!
The problem is that your callbacks are queuing up on the Dispatcher. Each one will cause the screen to repaint, and because they are at Background priority the next one will wait for that repaint to complete before being processed, so you will have to repaint once per callback, which can be slow.
Instead of trying to wait until nothing at all is in the dispatcher queue, just wait until the previous progress callback has been handled before posting a new one. This will ensure you never have more than one active at a time, so they can't queue up.
You can do this by setting a flag when you post the callback and clearing it once it has been processed. For example:
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
var pending = false;
for (int i = 0; i < 1000000; i++)
{
// Do some work here
// ...
// Only report progress if there is no progress report pending
if (!pending)
{
// Set a flag so we don't post another progress report until
// this one completes, and then post a new progress report
pending = true;
var currentProgress = i;
Dispatcher.BeginInvoke(new Action(() =>
{
// Do something with currentProgress
progressBar.Value = currentProgress;
// Clear the flag so that the BackgroundWorker
// thread will post another progress report
pending = false;
}), DispatcherPriority.Background);
}
}
}
I would simply update a progress counter in the background thread (it only writes to the counter), and have the UI read (only read) the timer every 500 ms or so... There is no reason to update faster than that. Also, because one thread is write only, and one is read only there is no threading issues required. The code becomes massively simpler, cleaner, and more maintainable.
-Chert Pellett
Impossible to say without seeing code, but
I have a progress bar being updated inside a Dispatcher.Invoke call
Why? That's what ReportProgress is for.
If I had to guess (and I do), I'd say you're reporting progress to often. For example, don't report progress after every record, but after batches of 100 or whatever.
I just solved the same case, but using the object returned by BeginInvoke, and I think it’s quite elegant too!
DispatcherOperation uiOperation = null;
while (…)
{
…
if (uiOperation == null || uiOperation.Status == DispatcherOperationStatus.Completed || uiOperation.Status == DispatcherOperationStatus.Aborted)
{
uiOperation = uiElement.Dispatcher.BeginInvoke(…);
}
}
The progress bars become a little choppier (less smooth), but it flies. In my case, the code parses line-by-line from a text file using StreamReader.ReadLine(). Updating the progress bar after reading every line would cause the read operations to complete before the progress bar was even halfway filled. Using the synchronous Dispatcher.Invoke(…) would slow down the entire operation to 100 KiB/s, but the progress bar would accurately track the progress. Using the solution above, my application finished parsing 8,000 KiB in a second with just 3 progress bar updates.
One difference from using BackgroundWorker.ReportProgress(…) is that the progress bar can show finer detail in longer-running operations. BackgroundWorker.ReportProgress(…) is limited to reporting progress in increments of 1% from 0% to 100%. If your progress bar represents more than 100 operations, finer values are desirable. Of course, that could also be achieved by not using the percentProgress argument and passing in a userState to BackgroundWorker.ReportProgress(…) instead.

Resources