I am trying to get the links from inside an iframe and return them as a function result, my simplified code looks something like this:
var casper = require("casper").create({
verbose: true,
logLevel: "debug",
webSecurityEnabled: false
});
var url = casper.cli.get(0);
casper.on('remote.message', function(msg) {
this.echo(msg);
})
casper.start(url, function () {
thelinks = getLinksFromIframes( casper );
console.log("doesn't work:" + thelinks);
});
function getLinksFromIframes( context ) {
var links = [];
var iframes = context.evaluate( function() {
var iframes = [];
[].forEach.call(document.querySelectorAll("iframe"), function(iframe, i) { iframes.push( i ); });
return iframes;
});
iframes.forEach( function( index ) {
context.withFrame(index, function() {
links = links.concat( this.getElementsAttribute( 'a', 'href' ) );
console.log("works: " + links);
});
});
return links;
}
casper.run(function() {
console.log('done');
this.exit();
});
The problem is that the function doesn't return anything, I can only read the links var inside withFrame
, i know there are other ways to get the links, but the code is this way because it part of something more complex that will analyze nested iframes, and the amount of iframes inside iframes is unknown. Is there any way I could wait on withFrame
or something that will allow me to return the links as the function result?
That's expected, because
casper.withFrame
is an asynchronous step function. Like all other functions that begin with eitherthen
orwait
, it schedules a step in the CasperJS execution queue.When those scheduled steps are executed (at the end of the current step, which is the
then
callback ofcasper.start
in your case),getLinksFromIframes
has long finished and returned an empty array.No, but you can use a callback: