简体   繁体   中英

How to pass an object to a CasperJS function

I'm writing some test code for work and am trying to figure out why it throws an error. I'm using an object oriented approach to this so to keep my main script as clean as possible. I have one script that contains all my element paths called elements.js. I'm using phantom to inject that script into another file that contains click methods called click.js. Example:

function Click() {

   phantom.page.includeJs('/my/path/to/elements.js');
   var element = new Elements();

   this.clickElement = function() {
      casper.then( function() {
         casper.click(element.nameOfElement);
      });
   };
}

Running my script this way throws undefined errors, however if I directly declare the element's path in my click.js script, my test runs fine:

function Click() {

  var nameOfElement = ('css > path > to > element');

  this.clickElement = function() {
     casper.then( function() {
         casper.click(nameOfElement);
     });
  };
}

I'm wanting to call all element paths from one source just to keep my scripts clean, as you can imagine they can get long depending on how many elements we're testing. I also have other files that require the use of an element's path for this test, but they follow the same principle as the piece of my click.js script above.

UPDATE

Here is what my element.js script looks like:

function Elements() {

   var nameOfElement = ("css path");
   var anotherElement = ("css path");

}

PhantomJS (and CasperJS) has two contexts. page.includeJs() and page.injectJs() are two PhantomJS functions that include a JavaScript file into the DOM which is then evaluated in the page context, but you want to access your elements paths outside of the page context.

I assume your elements.js looks like this:

function Elements(){
    this.someElement = "css path";
    ...
}

then you need to read the file and evaluate it:

var fs = require("fs");
var el = fs.read("/path/tp/elements.js");
eval(el);

var elements = new Elements();
console.log(elements.someElement);

You probably should define your elements.js differently to leverage PhantomJS's require capability:

As module

elements.js

module.exports = function(){
    this.someElement = "css path";
    ...
}

script.js

var elements = new require("/path/to/elements.js");

As object

elements.js

exports.someElement = "css path";
exports.someOtherElement = "css path";

script.js

var elements = require("/path/to/elements.js");

You probably don't want to read the file on every click, so you can

var elements = require("/path/to/elements.js");
casper.clickElement = function(nameOfElement) {
    this.thenClick(elements[nameOfElement]);
};

and use it later like this

casper.clickElement("someOtherElement");

I solved this by getting through a rookie brain fart I was in. In my element.js script, I added a simple get method and it works now.

function Elements() {

    var someElement = "css path";

    this.getSomeElementPath = function() {
        return someElement;
    };
}

Called it in my click.js script as:

function Click() {

    phantom.page.injectJs('path/to/element.js');
    var element = new Elements();

    this.clickSomeElement = function() {
        casper.then( function() {
            casper.click(element.getSomeElementPath());
        });
    };
}

And, in my main script:

'use strict':

phantom.page.injectJs('/path/to/element.js');
phantom.page.injectJs('/path/to/click.js');

var element = new Element();
var click = new Click();

casper.test.begin("Test", function (test) {

    var url = www.url.com;

    console.log(url);

    casper.start(url);

    casper.then(function() {
       click.clickSomeElement();
    });

    ....//rest of code

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

Now, the test runs as it should.

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