how to replace explicit wait calls in cypress? - wait

I am facing several situations where an element can't be clicked using cy.get().click() just because the elements have not loaded. However, if i add even the smallest of waits like cy.wait(100); the elements become clickable and my code runs fine.
Can this practice of explicitly calling cy.wait() be avoided?
I think if I can somehow set a fixed wait of cy.wait(100) i.e 0.1ms between all the steps my issue would be addressed but I don't know how to do it.

I've found a solution to this, posting it for others to use later
cy.get('<your-selector-here>').should('be.visible').then( ($el) => { $el.click() } )
you can simply use this assertion .should('be.visible') to replace the explicit wait calls.
However, there's a catch to it; this only works for the cases where you're 100% sure that the element would appear. If the element does not appear, the assertion will simply fail and the test won't continue further.

One Solution is, you can use
Cypress.config(defaultCommandTimeout: 10000) to increase default command time out for the specific situation.
This increased time out will work for all the lines, after the execution of this code.

Related

Do I always have to "wait" for page loads when using selenium on non-ajax pages?

I'm writing some BDD tests using Cucumber, Selenium and Xunit for a legacy ASP.Net application. The way the pages are designed, every "click" leads to a new page being fetched from the server. If I have to automate the tests for a particular page, should I have a line similar to the following after every "click"?
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeout));
wait.Until(...); //Wait until something about the page is true
I'm not sure if Selenium would wait implicitly for page loads without my explicitly having to state this all the time. What is the recommended pattern to handle this scenario?
It's cumbersome to always have an idea of "some element" so that I can put it in the Until method and that leads to brittle tests. The ASP.Net pages are littered with lots of dynamic controls and a whole slew of page refreshes which makes the test code quite unreadable.
My Proposed Solution: Write an extension method that does the waiting implicitly and that takes a parameter of an element-id to wait on. But I'm just refactoring the above problem into a more manageable place. I still have a wait be explicitly performed. Is there no way to eliminate it? Does selenium have some obvious default that would handle this case without the need for such an extension method or is this really a natural way of doing it?
If you want your tests be reliable and wait only the exactly needed time interval - then yes, Explicit Waits with WebDriverWait is a perfect solution. And, it's actually a very "natural" solution - think about how you, as a user, define that the page loaded - it's usually when you see the desired content, correct? When you look at the loading page, you are constantly reevaluating the state of the page, checking whether the desired content appeared or not. Explicit Waits follow the same logic - by default, every 500 ms it checks if the expected condition is true or not, but no more than X seconds you've configured when instantiating the
WebDriverWait.
If you need to use wait.until() calls often and want to follow the DRY principle, think about applying the "Extracting Method" or other refactoring methods.
You can set the implicit wait which would be applied on every element search, or introduce hardcoded "artificial" delays, but that's not going to be reliable and would be time-wasteful - you'll end up waiting more than needed and having occasional test failures.

Why does QTextEdit have sometimes document height 0?

For a QTextEdit* te I have noticed that sometimes te->document()->size() returns (0,0) and sometimes it returns the actual size. In both cases, te->toPlainText() returns non-empty text.
What can be done for it to return the size?
Is there some refresh method so the document will definitely return the size after it?
Try to call QApplication::processEvents() before checking size. It will cause processing of all pending Qt events, so after this call all sizes will be updated. Note that invisible documents still may not return correct size.
Calculating layout of text is heavy operation, especially when text is long, so this have to be delayed as possible. I'm pretty sure that you get this zero size somewhere in construction time.
How you can overcome this problem?
Best approach is lazy initialization. Do not perform calculation until some value is relay needed (it you do this properly you will never get zero size).
Other approach is to enforce calculation of document layout. You can do it by calling setTextWidth(), setPageSize() or idealWidth() depending on context of your task.
idealWidth() is perfect if you do not wrap lines and don't have page size.

AutoIt: Run next command after finishing the previous one

I'm currently writing a macro that performs a series of control sends and control clicks.
They must be done in the exact order.
At first I didn't have any sleep statements, so the script would just go through each command regardless whether the previous has finished or not (ie: click SUBMIT before finish sending the input string)
So I thought maybe I'll just put some sleep statements, but then I have to figure out how best to optimize it, AND I have to consider whether others' computers' speeds because a slow computer would need to have longer delays between commands. That would be impossible to optimize for everyone.
I was hoping there was a way to force each line to be run only after the previous has finished?
EDIT: To be more specific, I want the controlsend command to finish executing before I click the buttons.
Instead of ControlSend, use ControlSetText. This is immediate (like GuiEdit).
My solution: use functions from the user-defined library "GuiEdit" to directly set the value of the textbox. It appears to be immediate, thus allowing me to avoid having to wait for the keystrokes to be sent.

Problems with the Enterframe Event

I have been developing a game using Flex, and used the Timer class to keep the main loop going.
However, when I tried using the enterFrame event to do the main loop, there were a few problems.
First of all, physics simulation seemed way too fast. Is the enterFrame event called more than once per frame? I set the application's global frame rate to 24, so shouldn't the application set off the event every 1/24 of a second?
And the second problem is that when the game runs like this, some MXML components that are added are not shown. I have absolutely no idea why this happens.
Help me please?!?
Thanks.
Don't count on the framerate to be even, or that the enterframe is called at a fixed interval. Even the timer-class isn't 100% accurate.
When doing timings, always use the delta between frame-updates and use that delta for your calculations. Also be sure to put in a safe-guard that the delta never exceeds some value to avoid strange behavior when the flash application freezes up for some unexpected reason.
This article explains it all perfectly:
http://gafferongames.com/game-physics/fix-your-timestep/
The framerate is a desired value. If a user runs it on a slow machine, you might experience their output to be too slow. How about reverting to the good old
setInterval?

How to get IMediaControl.Run() to start a file playing with no delay

I am attempting to use DirectShow to play two AVI files consecutively (one after the other) so that there is no interruption in the audio or video when the player transitions from one file to the next.
I have two custom controls on my form. Each one is pre-loaded with an AVI file, and before playback begins I set up all the DirectShow interfaces, set the video windows and resize them, call IMediaControl.Run(), then IMediaControl.Pause(), then IMediaSeeking.SetPositions to reset to frame 0, on both controls. On the form, you can see that both files are paused at their initial frames.
I then call IMediaControl.Run() on the first control, and wait for it to complete before calling Run() on the second control. Initially, I hooked into the first video's EC_COMPLETE notification message, and used this to start the second. Thinking that this event might be slow to arrive (turns out it is, but for a weird reason), I tried two other approaches:
Check the first video's current position inside a timer that goes off every second or so (using IMediaPosition.get_CurrentPosition). When the current position is within a second of the video's stop time (known in advance from IMediaPosition.get_StopTime), I go into a tight while loop and wait for the current position to equal the stop time, and then call Run() on the second video.
Same as the first, except I replace the while loop with a call to timeSetEvent from winmm.dll, with a delay set so that it fires right when the first file is supposed to end. I use the callback to Run() the second file.
Either of these two methods substantially cuts down the delay between the end of the first file and the beginning of the second, indicating that the EC_COMPLETE message doesn't arrive immediately after the file is complete (I also tried hooking the EC_SEGMENT_COMPLETE message, which is supposed to be used for looping within a file, but apparently nobody supports this - it never occurs on my machine, at least).
Doing all of the above has cut the transition delay from as much as a second, down to a barely perceptible glitch; about a third of the time the files transition with no interruption at all, which suggests there's no fundamental reason I can't get this to work all the time.
The slight delay is still unacceptable, unfortunately. I assume (and I could easily be wrong) that the remaining delay is due to a slight variable delay between the call to IMediaControl.Run() and when the video actually starts playing.
Does anybody know anything I can do to eliminate this little lag? It would also help to be told this is fundamentally impossible for whatever reason, which wouldn't surprise me. I've never encountered a video player in Windows that doesn't have this problem, so it may not be doable.
More info: the AVI files I'm playing are completely uncompressed (video and audio are uncompressed), so I don't think the lag is due to DirectShow's having to uncompress the video ahead of play start, although it may still buffer ahead as matter of course (and this may be the source of the problem). I would have though that starting play, pausing and then rewinding to the beginning would fix this.
Also, the way I'm handling the transition is to actually have the second control underneath the first; when the first completes playing, I start the second and then call BringToFront on it, creating the appearance of a single video transitioning between the two originals. I don't think the glitch is due to this, because it works perfectly some of the time, and even if this were problematic, it wouldn't explain the matching audio glitch.
Even more: I just tried starting the second video 30-50 milliseconds "early" and that seemed to eliminate even more of the gap, so I'm guessing that the lag in Run() is about that long. It appears to be variable, though, so this is still not where I need it to be.
Still more: perhaps I could eliminate this delay by loading the AVIs from memory rather than from a file. Unfortunately, I have no idea how to do this. IMediaControl only has a RenderFile() method, not something like a RenderStream or RenderMemory method.
If you call IMediaControl::Run on a stopped graph, the graph manager will post the call to a worker thread (so there's some variability). On the worker thread, the graph will be paused. Render filters only complete a pause transition once they have received data, so once GetState() returns S_OK, the graph manager knows that the graph is fully cued. At this point, it picks a time roughly 10ms into the future, and calls Run on each filter with that time as the start point. Since it takes time to tell each filter to Run, the dshow Run method has a parameter which is the refclock time at which a sample timestamped zero should be played -- i.e. the time at which the actual transition to run mode should take place.
To synchronise this with another graph, you first have to ensure that both graphs have the same clock. Query the graph (not the filter) for IMediaFilter, and call GetSyncSource on one graph and SetSyncSource on the other. Then you need to pause the second graph, so that it is cued and ready. When you want to start it, call IMediaFilter::Run instead of IMediaControl::Run, and you can pass your own start time. This still has to be a few milliseconds into the future, so the best thing might be to set the start time of the second graph to be the first graph's start time plus its duration (for an indexed container of uncompressed streams, the duration should be accurate).
Another approach is to use multiple graphs. Separating source from rendering would allow you to switch seamlessly between sources since they feed into a common render graph. There is sample source code for this approach at www.gdcl.co.uk/gmfbridge.
G

Resources