Use casper function inside casper.evaluate()

2019-08-29 06:24发布

问题:

it's possible using casper function inside casper.evaluate() with jquery code inside? I need to iterare elements in a way similar to how jquery does.

I'm loading jquery.js lib

This is my try script:

casper.evaluate(function(){
    $('#size-modal .size-panel-title a').each(function(){
        $(this).click();    
        accordionTab = $(this).attr('href');
        casper.capture(screenShotOutput + "PDP-" + accordionTab +".png");
    });
});

in this page there are 2 accordion and i want a screenshot for each opened accordion. It seems to works but no feedback is given and it exit form evaluate() on the first capture() iteration. the test pass without making screenshot.

If i add after evaluate()

casper.capture(screenShotOutput + "PDP-accordion.png");

and comment the capture() inside the evaluate(), i can see that the code before works well, the screenshot is made and each accordion is open.

The problem is that casper use javascript selector so if i specify only

casper.click('#size-modal .size-panel-title a');
casper.capture(screenShotOutput + "PDP-" + accordionTab +".png");

without using casper.evaluate() only one accordion will be opened.

Thanks

回答1:

What ever you do in "casper.evaluate" is simillar to writing the same piece of code in the console of the browser.Think of it this way and you will know what mistake you have made.

  1. "casper.capture" is a casper specific syntax and no browser understand it.

also this is the reference from the doc's

The concept behind this method is probably the most difficult to understand when discovering CasperJS. As a reminder, think of the

evaluate() method as a gate between the CasperJS environment and the one of the page you have opened;

Everytime you pass a closure to evaluate(), you’re entering the page and execute code as if you were using the browser console.

I hope the picture might help:

And i Agree with whatever @Artjom B. has suggested.



回答2:

casper.evaluate() is the sandboxed page context. It has no access to casper or other variables that are defined outside.

There are two possibilities to solve this.

Move the loop outside of the page context

var a = '#size-modal .size-panel-title a';
var len = casper.getElementsInfo(a).length;
for(var i = 0; i < len; i++) {
    casper.evaluate(function(i, a){
        var el = $($(a)[i]);
        el.click();    
        return el.attr('href');
    }, i, a);
    casper.capture(screenShotOutput + "PDP-" + accordionTab +".png");
}

Trigger capture from the page context

There is the PhantomJS function callPhantom which makes it possible to trigger an event on the outside from the page context:

casper.page.onCallback = function(data){
    casper.capture(screenShotOutput + "PDP-" + data +".png");
};
casper.evaluate(function(){
    $('#size-modal .size-panel-title a').each(function(){
        $(this).click();
        window.callPhantom($(this).attr('href'));
    });
});