Search code examples
javascriptcasperjswebautomation

Web automation, Events and Execution Flow in CasperJS


I'm new to CasperJS and I'm trying to figure out the execution flow.

This is what I'm trying to achieve:

  1. load a page

  2. stores an image of the page

  3. pass this image to a function and execute it (this process is quite long: ~15 seconds)

  4. wait for the function to return the result

  5. use the returned value to fill a field in the form in the loaded page

  6. submit the form

this is a code snippet which tries to explain the solution I came up with:

var globProcessedImage;

var casper = require('casper').create({
    viewportSize: {
        width: 1024,
        height: 768
    }
});

casper.start('http://example.com/');

casper.then(function() {
    this.captureSelector('./image.png', '#img-node');
});

casper.waitFor(function() {
    return globProcessedImage !== undefined;
}, function then() {
    this.sendKeys('#imagePassword', globProcessedImage);
});

casper.then(function() {
    this.capture('./page.png');
});

casper.run();

casper.on('image.processed', function() {
    setTimeout(function() {
        globProcessedImage = 'my_result';
    }, 15000);
});

This results in ReferenceError: Can't find variable: globProcessedImage.

It's still unclear to me how web automation and "external" functions mix together with CasperJS, as well as how parameters are passed between the page and casper/phantom environments.


Solution

  • Maybe something like that :

    var globProcessedImage ;
    
    var casper = require('casper').create({
        viewportSize: {
            width: 1024,
            height: 768
        }
    });
    
    casper.start('http://example.com/');
    
    casper.options.waitTimeout = 16000;
    
    casper.then(function() {
        this.captureSelector('./image.png', '#img-node');
        this.emit('image.processed');
    });
    
    /*
     * If you need to wait for a fix time, it's okay, but a better way would be to wait in Casper 
     * 'the thing you do with your image' in a waitFor. -> asynchronous. With this solution you combine two timers, this is not the optimized solution.
     */
    casper.waitFor(function() {
        return globProcessedImage !== undefined;
    }, function then() {
        this.sendKeys('#imagePassword', globProcessedImage);
    });
    
    casper.then(function() {
        this.capture('./page.png');
    });
    
    casper.run();
    
    casper.on('image.processed', function() {
        setTimeout(function() {
            //when you will emit this event in your script, it will set the value of globProcessedImage to 'my_result' after 15sec
            globProcessedImage = 'my_result';
        }, 15000);
    });