Another possibilities than wait? - javascript

I am trying to automate a website where the testing environment is reduced and the page loads nearly two minutes(120000).
I don't want to use cy.wait(120000) or cy.pause() command.
Could anyone help by giving more suggestions to solve the issue even the testing environment gets slower than this.
I have tried should,intercept,etc..,Other than the normal ones can someone suggest me some ideas.It wil be more helpful if you post your answers with commands.
Advance Thanks for making a try to solve this.

cy.wait is not a good practice in most situations because it just hangs your program to wait till the end of the timeout.
I think you're looking for a solution to wait for an element appears in HTML, so I'd suggest you to check this part of the document
In your case, it should be like below
cy.get('.selector', { timeout: 120000 }).should('be.visible')
Even though the timeout is longer but whenever your .selector appears on the HTML, it will pass.
Note that, the default timeout is only 4 seconds, so if you want to have more timeout, you can modify it to longer (like 2 mins for your case).
Why do we need to have timeout? Well, basically, we don't want the program hangs forever, so that's why we need to have timeout.

Related

Why a web element throws CypressError with TimedOut reason, only randomly?

In my script, I am trying to locate and click one of the many document links, with this syntax:
cy.wait(3000); cy.get('a[href^="/articleDetail/"]').first().click();
I got this error:
CypressError: Timed out retrying: Expected to find element:
'a[href^="/articleDetail/"] but never found it'
The issue is this happens only few times, not all the times. Like 3 out 5 times. How should I solve this issue ?
Testing it via the Selector Playground (as N. suggested) is a good step. What you also can do is investigate screenshots which Cypress can make on failure. That shows the exact state of the application when the failure happened. That usually gives a good hint to the problem.
Besides that you can also try to set the wait to an absurt value like 10000. If Cypress can find the element at that case, the application is slow and therefor Cypress is not waiting long enough.
For different reasons (internet speed, CPU, Memory, errors) your page could take longer to load or not load at all. As a good practice, your page should have a loading system, where it is shown until the page is completely rendered. This way you could have something like cy.get('your-loading-element').should('not.be.visible'), which will hold the next command while the loading is in place.
Waiting is not the right approach as you never know exactly how long it will take and raising the time will only delay your tests.
It is very important to think of your test in the same way a test analyst would execute them, because one of the steps would be to wait the page to be rendered.
Here is some good testing good practices: UI test automation good practices

Easy way to refresh php function with js

I have a PHP function that checks for the occurence of a string. What I want is to have it checked continously at a certain interval(eg: 5 seconds). From what I've gathered, PHP would be lesst than optimal for this 'refresh' function so looking for a way to do it with JS.
Thanks in advance and sorry for the silly question!
I don't think PHP would be less than optimal, but either way, I don't know of an "Easy" way. Cron jobs would typically be perfect for what you need, but they do not run sub-minute (although I have seen interesting workarounds).
Node has a lot of packages for "cron" like functionality, but these take the same parameters, so no sub-minute.
You could utilize a setInterval() callback to accomplish this easily, but it would require you to a) keep a web client open 24/7 and b) monitor the web client to ensure it never freezes, fails, shuts down, etc.

is Javascript's setInterval loop a resource hog?

I'm designing an app to run on very low spec machine..and i needed it to be efficient as possible..
I needed to issue around 10 intervals at every second that simply makes an ajax call.. and then does a few add/remove classes and (think of it as SERVER Status monitor)
I know in FLASH (oh good old flash days) having a lot of intervals can cause processor spikes .. so i'm very conservative with issuing setIntervals in AS 2.0 before.
I was wondering if this is the same case with JS? or is it alright for JS to have a bunch of intervals (that does lightweight tasks) running? I noticed a lot of sites do this , even facebook has tons of intervals running, loading scripts, etc..
And oh, for one interval, I wanted to run it at 50ms (it loads as status.php link) ... this ok?
I could probably optimize my interval calls, no problem but i'm just wondering how "heavy" or "lightweight" background intervals are in JS..
Thanks all
10 intervals at every second meaning a call every 100ms should not be an issue in my opinion, but if you ask me I would fire a call every 250ms.There is not much difference between the two that the user will notice.
Also make sure that there is a mechanism to handle long running response from server in case there is a delay and stop the interval firing if there is drag.
As a matter of personal feeling, I tend to prefer setTimeout over setInterval -- to the point I don't use setInterval at all.
The issue that you might run into is if one process takes longer than it should -- let me give you an imaginary situation:
window.setInterval(takes100msToRun, 50);
window.setInterval(takes50msToRun, 50);
window.setInterval(takes20msToRun, 50);
The problem is that the first interval will take longer than it should, so the second two interval requests are now behind and the browser will try to catch up by running them as quickly as then can. The second interval takes 50ms, -- so its still running behind when the third interval hits.
This creates an ugly situation that can lead to a lot of drag.
On the other hand, if you setTimeout, then you aren't say "Run this every 50 ms", but rather "Run another one of these 50ms from we finish." (Assuming, of course, that the functions set up another setTimeout to re-execute.)
It is absolute rubbish for things that need good clock timing, but its superior for everything else.
setTimeout and setInterval will affect performance, but little.
Since there are lots of functions triggered/listening/running in the browser.
Even a tiny operation like move your mouse to vote up for this answer, there are thousands of events got triggered, and tens of functions start running.
Don't use setInterval. As a matter of fact, the library underscore doesn't use it either.
See how they implement the _.throttle without setInterval.
http://learningcn.com/underscore/docs/underscore.html#section-66

Can JavaScript talk to Selenium 2?

I know I can get Selenium 2's webdriver to run JavaScript and get return values but so much asynchronous stuff is happening I would like JavaScript to talk to Selenium instead of the other way around. I have done some searching and haven't found anything like this. Do people just generally use implicitly_wait? That seems likely to fail since it's not possible to time everything? Perfect example would be to let Selenium know when an XHR completed or an asynchronous animation with undetermined execution time.
Is this possible? We're using Selenium 2 with Python on Saucelabs.
You should look into the execute_async_script() method (JavascriptExecutor.executeAsyncScript in Java, IJavaScriptExecutor.ExecuteAsyncScript() in .NET), which allows you to wait for a callback function. The callback function is automatically appended to the arguments array in your JavaScript function. So, assuming you have a JavaScript function already on the page that waits until the condition you want, you could do something like the following (Java code below, C# and Python code should be similar):
String script = "var callback = arguments[arguments.length - 1];"
+ "callback(myJavaScriptFunctionThatWaitsUntilReady());";
driver.manage().timeouts().setScriptTimeout(15, TimeUnit.SECONDS);
((JavascriptExecutor)driver).executeAsyncScript(script);
It might be possible to be even more clever and pass the callback function directly to an event that returns the proper data. You can find more information on the executeAsyncScript() function in the project JavaDocs, and can find sample code for this in the project source tree. There's a great example of waiting for an XHR to complete in the tests in this file.
If this isn't yet available in the version of the Python bindings available for use with SauceLabs, I would expect it to be available before long. Admittedly, in a sense, this is pushing the "poll for desired state" from your test case into JavaScript, but it would make your test more readable.
Theoretically it is possible, but I would advise against it.
The solution would probably have some jQuery running on the site that sets a variable to true when the JavaScript processing has finished.
Set selenium up to loop through a getEval until this variable becomes true and then do something in Selenium.
It would meet your requirements but it's a really bad idea. If for some reason your jQuery doesn't set the trigger variable to true (or whatever state you expect) Selenium will sit there indefinetly. You could put a really long timeout on it, but then what would be the different in just getting Selenium to do a getEval and wait for a specific element to appear?
It sounds like you are trying to overengineer your solution and it will cause you more pain in the future will very few additional benefits.
Not to be overly blunt, but if you want your App to talk to your Test Runner, then you're doing it wrong.
If you need to wait for an XHR to finish, you could try displaying a spinner and then test that the spinner has disappeared to indicate a successful request.
In regards to the animation, when the animation has completed, maybe its callback could add a class indicating that the animation has finished and then you could test for the existence of that class.
Testing animation with selenium is opening a can of worms. The tests can be quite brittle and cause many false positives.
The problem is to do that the calls are asynchronous, and difficult to track the behaviour and change in state of the page.
In my experience the asynchronous call can be so quick that the spinner is never displayed, and the state of the page may skip a state entirely (that Selenium can detect).
Waiting for the state of the page to transition can make the tests less brittle, however the false positives cannot be removed entirely.
I recommend manual testing for animation.

IE displays Script error on recursive function

Hy guys!
I have a recursive function that takes time to perform. The IE is "thinking" that function is like a loop with no end.
What should I do to make IE don't show the error?
Thks guys!
You cannot, it is a functionality in most browsers to give the user a way out if he visits a webpage with javascript that ties up his cpu for too long and thus kills the browser.
The only way around it, is to performance optimize your code so it goes faster :)
I am assuming the "error" look like this, otherwise my answer is wrong:
Javascript in your browser runs in a single thread. If you have some kind of code running (recursive or otherwise) that does not yield to the browser every now and then, the browser will pause the script and ask the user whether they want to stop the code or continue. If this didn't happen there would be no way for the user to regain control (if you like your long-running code is running on the same thread as the UI, that is, the webpage). That's why ajax calls are structured in such a way that your code does not wait (that is, block) for the result, but instead a callback function is, well, called back with the results.
So how do you yield in a long-running piece of code? Several ways (ajax is one example) but the most popular is to use setTimeout in some way. Unfortunately it's just not that easy to explain how to use it without knowing what you are doing exactly. Any small examples I could give would be artificial.
So the strict answer to your question is "rewrite your code into execution chunks such t
hat there's no one chunk that takes a long time to execute".

Categories

Resources