How to use setTimeout in CasperJS - casperjs

In CasperJS there is a function called evaluate which is a way for entering the page and execute code as if you were using the browser console, if i use setTimeout, setInterval or another async function it doesnt work as spected.
Some of the asked questions in StackOverflow use the wait function, but the wait function can't be used inside evaluate. I need to use a setTimeout because i'm scraping a grid with many pages so when i change to the next page i need to wait some seconds and that is the problem

You cannot delay the CasperJS Environment through the Page DOM Environment.
In other words, you cannot use setTimeout() inside casper.evaluate() to delay your CasperJS program.
It's better to use one of the following CasperJS functions to delay your program:
casper.wait()
casper.waitFor()
casper.waitForAlert()
casper.waitForExec()
casper.waitForPopup()
casper.waitForResource()
casper.waitForUrl()
casper.waitForSelector()
casper.waitWhileSelector()
casper.waitForSelectorTextChange()
casper.waitForText()
casper.waitUntilVisible()
casper.waitWhileVisible()
Take a look at the diagram below to better understand how the two different environments work:
Image Source: CasperJS Documentation

Related

Capybara and Siteprism: Ignore element from loading

We have some tests written in Capybara (Ruby) + SitePrism + ChromeDriver.
In some of those test, there is a page involved which has some very slow-loading iframes and which is causing the tests to fail with Net::ReadTimeout exceptions.
I know that I can increase the timeout to wait for longer, but this would increase the total execution time of the tests by a big factor.
Also, we don't really care about the iframes themselves, only for the rest of the elements in that page.
Is there any way to tell Capybara to not wait for the iframes to load?
If that's not possible, would at least be possible to wait some predefined time and if that time expires, simulate a stop-page-loading (like pressing the escape button in an actual browser)?
The cleanest solution for issues like that when using the selenium driver is to use a programmable proxy like puffing-billy https://github.com/oesmith/puffing-billy to block the requests and return errors or static content. If you were using Poltergeist or capybara-webkit you could use their white/blacklist support to do the same thing.

Better way to execute Javascript in Jmeter

SetUp part of my Jmeter script contains steps to bypass login page of my Web Application before generating real load. As a result of these steps, server sets specific cookie that proves successful loginization.
To do that, my script should execute Javascript function injected in response by server. Since it's a one-time procedure, I do it using WebDriver and execute Javascript within browser instance.
But I definitely can't do the same as a part of load thread as WebDriver is not a good idea (at all) for performance testing.
However, I'm still wondering is it a way to calculate JS without creating a browser instance, because my JS script is nothing but arithmetic calculations (complex though). So,
Any ideas about how to execute JS without creating browser instance are very much appreciated. Since I can write BeanShell code, it shouldn't be a big issue (just share the lib name that can create "virtual" browser for calculations not related to DOM). Not sure that it'll be faster, but I'll try to.
If I'm right and browser usage is the only possible solution, then I'm looking for a way to share one single browser window between different threads (even with delay for those who waits for it). Tried to use JavascriptExecutor, but don't know how to convert WebDriver to JavascriptExecutor (beanshell is written using too old Java, and I'm not familiar with its syntax and functionality). Can't use WebDriver plugin too as it doesn't allow just to create window without get("pageUrl").
Thanks for any ideas in advance.
You can use JSR223 Sampler, choose javascript from "Language" dropdown and place your code in "Script" area
You can use single browser instance using WebDriver Sampler for all threads in a loop, something like:
var ctx = org.apache.jmeter.threads.JMeterContextService.getContext()
var vars = ctx.getVariables();
for (var i=0; i< THREADS_NUMBER; i++) {
WDS.browser.manage().deleteAllCookies()
WDS.browser.get('LOGIN_PAGE_URL')
var cookie = WDS.browser.manage().getCookieNamed("COOKIE_NAME").getValue();
vars.put("cookie" + i, cookie);
}
it will generate JMeter Variables like:
cookie1=foo
cookie2=bar
etc.
So you will be able to refer variable values using __threadNum() function where required like:
${__evalVar(cookie${__threadNum})}
See The WebDriver Sampler: Your Top 10 Questions Answered guide for more information on using the WebDriver Sampler.

without using DoEvents, how to detect if a button has been pressed?

Currently, I call DoEvents in order to check if Button Foo in Form Bar has been clicked. This approach works but it takes too much processing power, delaying the program.
I believe that the delay could be reduced if I could only check if Button Foo has been clicked, instead of all the other forms that DoEvents has to go through.
Any ideas on how can I check if Button Foo was clicked?
VB6 was not really designed for what you seem to be doing (some sort of long-running straight-line code that does not exit back to give the message loop control). Normally such a task would be delegated to a worker thread, and in VB6 this means some external component implemented in C++ most of the time.
There are only a very few kinds of approaches to take to do this for your ad-hoc logic:
Hacks creating separate threads via API calls, not very reliable in VB6 for a number of reasons.
A tricky thread-per-object ActiveX EXE implementing a class to handle your long-running workload.
A separate non-interactive worker process to be run and monitored by your GUI program.
That's pretty much it.
The prescribed method of doing this sort of thing is described in the VB6 documentation. You break your long-running loop up and invert the logic into a repeatable "quantum" of work (like n iterations of your processing loop), and maintain the state of your workload in Form-global data. Then you use a Timer control with its interval set to 1 or 16 (hardly matters, they normally take at least 16ms to trigger) and run your workload quantum within its event handler.
So if you simply had a loop that currently iterates 100,000 times doing something you might break it up so that it runs 500 times for each Timer tick. The quantum size will probably need to be tuned based on what is done within the loop - 500 is just a value chosen for illustration. You'll want to adjust this until it leaves the UI responsive without starving your background workload too much (slowing completion down).
If your code is heavy enough to not call DoEvents or just finish running periodically, then your app won't even know the button has been pressed. The DoEvents call allows windows, and your application to catch up on all notifications.
The correct way to resolve this is a worker thread (see this article on how to do something like this in VB6) but failing that, a periodic DoEvents is required and in turn, some re-entrancy blocking on the call into the long running code.

Why does it seem like the Capybara "wait for page to load" timer works for matchers but not finders?

I'm currently running a test that checks for a specific element and then do some stuff to it. The element takes a little for the javascript to finish kicking in, but well within the timer I've got Capybara set for.
For some reason
assert session.has_xpath?(xpath_route)
works fine, but
assert link=session.first(:xpath, xpath_route)
fails, saying it could not find the element. And quickly - long before the wait timer would run out.
I can only assume this means the timer only applies to matchers, not finders, which is fine, but how can I force it to keep looking until it finds the element I'm looking for?
You are correct assuming that the timeout does not apply when using first. But you can use the wait_until method, which will keep retrying until either the timeout expires, or the block returns something truthy, so:
page.wait_until() do
session.first(:xpath, xpath_route)
end

What is a browser event loop?

I have been doing some web application programming using GWT and have been confused by the term "browser event loop".
I have encountered situations where I need to execute deferred commands and "do something" after the browser event loop completes.
I would like to know as to what exactly it is and what happens during the event loop process and in which order?
A browser event loop is a thread started by the browser that is constantly scanning for and running different events, just like it sounds. As events occur they are put in the event queue and run in turn by the one event thread. Your javascript should not create its own loops waiting for it to complete or anything like that...it will block that one continuous event loop thread. Instead you would use something like setTimeout or setInterval and check for whatever conditions you are waiting for so the browser can do work while it 'waits'.
GWT is nice in that it can co-opt this process somewhat using the scheduler -- in your case where you want to run something after the event loop 'completes' you will probably want to use scheduleFinally or scheduleDeferred. It will inject a handler for a piece of code into the event queue so that it will run after all other code in the current execution context (current execution context == where ever you are in the current JavaScript object hierarchy with the window as the root object) is run but before the next event that is placed in the queue.

Resources