Fanch
Fanch

Reputation: 3274

CasperJs, how to repeat a step X times onWaitTimeout?

So what I want to do is create a casperJS function which allows us to repeat a step X times, by refreshing the page first, when this step function reaches the timeout.

For unreliable test due to a specific page bug/freeze at the moment and reduce the percentage of false negative.

I have just a problem, I don't know how to break this loop, because I'm in IIFE scope, see following code :

var echoTest = function(){
    casper.echo('Hi');
};
var trueFunction = function(){
    return true;
};

var verifyFailedTest = function(number, trueReturn, thenFunction){
    var i = 0;
    //outer:       <-------
    for (; i <= number; i++){   // <------ how to break this loop in my function then()
        //IIFE
        (function(index){
            if (index < number-1){
                //Execute 'number-1' times the then() step (reload the page each time) if timeout or until trueReturn returns true
                casper.then(function(){
                    casper.waitFor(function checkReturnTrue(){
                            return trueReturn();
                        }
                        , function then() {
                            thenFunction();
                            //break outer; break; return false;    <------ here where I want to break the loop
                        }
                        , function timeout() { 
                            casper.reload();
                        });
                });
            }
            //last execution, will return the normal error if it fails each time
            else if (index === number){
                casper.then(function(){
                    casper.waitFor(function checkReturnTrue(){
                            return trueReturn();
                        }
                        , function then() {
                            console.log('else');
                            thenFunction();
                        });
                });
            }
            else{console.log('verifyFailedTest() bug');}
        })(i);
    }
};

I tried with label, but I got a syntax error.

Execution :

casper.test.begin('\n*************** Suite of planned test : scenario 1 **************\n', 1, function suite(test) {
    casper.start('https://www.google.fr/', function() {
        verifyFailedTest(3, trueFunction, echoTest);
    });

    casper.run(function() {
        test.done();
    });
});

});

Upvotes: 0

Views: 2459

Answers (2)

Geremia
Geremia

Reputation: 5612

Use CasperJS's repeat(int times, Function then) function.

Upvotes: 0

Artjom B.
Artjom B.

Reputation: 61892

I think can do this without a for loop, by clustering your code into parts and do this recursively:

var verifyFailedTest = function(number, repeatStep, trueReturn){
    var index = 0;
    function intermediate(){
        casper.then(function(){
            repeatStep();
            casper.waitFor(function checkReturnTrue(){
                    return trueReturn();
                }
                , function then() {
                    this.test.pass("Test passes after " + (index+1) + " try");
                }
                , function timeout() { 
                    casper.reload();
                    if (index < number-1) {
                        intermediate();
                    } else {
                        lastTry();
                    }
                    index++;
                });
        });
    }
    function lastTry(){
        casper.then(function(){
            repeatStep();
            casper.waitFor(function checkReturnTrue(){
                    return trueReturn();
                }
                , function then() {
                    this.test.pass("Test passes after " + (index+1) + " try");
                });
        });
    }
    intermediate();
};

You'll have an error only after the number'th try.

But if you want to use your IIFE, the following might work by redefining thenFunction and skipping then block after you know that it is unnecessary (doBreak === true):

var verifyFailedTest = function(number, trueReturn, thenFunction){
    var i = 0, doBreak = false;
    var oldThenFunction = thenFunction;
    thenFunction = function(){
        doBreak = true;
        oldThenFunction();
    };
    for (; i <= number; i++){
        if (doBreak) {
            break;
        }
        // your IIFE here
        (function(index){
            if (index < number-1){
                //Execute 'number-1' times the then() step (reload the page each time) if timeout or until trueReturn returns true
                casper.then(function(){
                    if (doBreak) { return; }
                    casper.waitFor(...);
                });
            }
            //last execution, will return the normal error if it fails each time
            else if (index === number){
                casper.then(function(){
                    if (doBreak) { return; }
                    casper.waitFor(...);
                });
            }
            else{console.log('verifyFailedTest() bug');}
        })(i);
    }
};

Upvotes: 1

Related Questions