简体   繁体   中英

How to pass a parameter to a function in casperjs?

I have stored all the images url in an array, and am trying to test whether image has loaded properly. If you see the below code, i had to repeat few set of lines again and again. How can i write it to be generic?

casper.start()
var imagesArray = [];
imagesArray = ['https://www.google.co.in/images/srpr/logo11w.png',
'https://www.google.co.in/images/srpr/logo1w.png']; 

casper.thenOpen(imagesArray[0], function () {
    if (this.currentHTTPStatus === 404) {
        this.warn(imagesArray[0] + ' is missing (HTTP 404)');
    } else if (this.currentHTTPStatus === 500) {
        this.warn(imagesArray[0] + ' is broken (HTTP 500)');
    } else {
    this.echo(' is okay (HTTP %s)');
    }
});

casper.thenOpen(imagesArray[1], function () {
    if (this.currentHTTPStatus === 404) {
        this.warn(imagesArray[0] + ' is missing (HTTP 404)');
    } else if (this.currentHTTPStatus === 500) {
        this.warn(imagesArray[0] + ' is broken (HTTP 500)');
    } else {
    this.echo(' is okay (HTTP %s)');
    }
});


casper.run(function() {
this.echo('Image loading test finished');
this.exit();
}); 

I tried the below method, calling a function but its throwing parser error, what am i doing wrong, or how can i proceed with it?

function checkImages(item){
if (this.currentHTTPStatus === 404) {
this.warn(item + ' is missing (HTTP 404)');
} else if (this.currentHTTPStatus === 500) {
this.warn(item + ' is broken (HTTP 500)');
} else {
this.echo(' is okay (HTTP %s)');
}
}

      casper.thenOpen(imagesArray[0], function () {
    this.evaluate(checkImages(imagesArray[0]));
    });

      casper.thenOpen(imagesArray[1], function () {
    this.evaluate(checkImages(imagesArray[1]));
    });

Thanks in advance.

Since all then* function are asynchronous step function that insert a step into the queue, you can call them in a loop. Since imagesArray is a native array, it can be iterated over by using Array.prototype.forEach which PhantomJS supports:

var imagesArray = [
    'https://www.google.co.in/images/srpr/logo11w.png',
    'https://www.google.co.in/images/srpr/logo1w.png'
]; 

casper.start();

imagesArray.forEach(function(imageUrl){
    casper.thenOpen(imageUrl, function () {
        if (this.currentHTTPStatus === 404) {
            this.warn(imageUrl + ' is missing (HTTP 404)');
        } else if (this.currentHTTPStatus === 500) {
            this.warn(imageUrl + ' is broken (HTTP 500)');
        } else {
            this.echo(' is okay (HTTP %s)');
        }
    });
});

casper.run();

A simple for loop would have sufficed, but then you would have a problem with the imagesArray[i] inside of thenOpen . The i variable would never change, because every step is executed after the loop finished executing. So every imagesArray[i] would show the last url. Because JavaScript has function level scope the url bound to each iteration and never changes afterwards.

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. So you can't use evaluate on checkImages .

Use echo like this :

casper.thenOpen(imagesArray[0], function () {
    this.echo(checkImages(imagesArray[0]));
});

casper.thenOpen(imagesArray[1], function () {
    this.echo(checkImages(imagesArray[1]));
});

You don't have any need for thenOpen in this test case, since you only want to verify response code. you CAN do it that way, but it's incredibly wasteful of time/resources. this is how I achieved the same goal:

casper.test.begin('link tester', 73, function(test) {
  casper.start(url);

getLinks = function(){
     links = this.evaluate(function(){
        var links = document.getElementsByTagName('a');
        links = Array.prototype.map.call(links,function(link){
            return link.getAttribute('href');
        });
        return links;
    });
}

casper.then(getLinks);

casper.then(function(response) {
  for (q = 0; q < links.length; q++) {
    if (response == undefined || response.status >= 400) {
      this.test.fail("URL " + links[q] + " failed with response code " + (response.status));
    } else {
      this.test.pass((response.status + " ---- " + links[q]));
    }
  }
});

the only caveat with this would be that you can only have 1 failure per casper function. if you are testing 100 URLs on a page, and you fail on the 4th one, you will have to fix that one before you can see if the others failed. thus, you would need to nest a casper.then() within your if statement. In case you were wondering, it would look like this:

casper.then(function(response) {
  links.forEach(function(link){
    if (response == undefined || response.status >= 400) {
      casper.then(function() {
        this.test.fail("URL " + link + " failed with response code " + (response.status));
      })
    } else {
      this.test.pass((response.status + " ---- " + link));
    }
  });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM