Javascript 如何将对象传递给CasperJS函数

Javascript 如何将对象传递给CasperJS函数,javascript,phantomjs,casperjs,Javascript,Phantomjs,Casperjs,我正在为工作编写一些测试代码,并试图找出它抛出错误的原因。我使用面向对象的方法来实现这一点,以便尽可能保持我的主脚本干净。我有一个包含所有元素路径的脚本,名为elements.js。我使用phantom将该脚本注入到另一个文件中,该文件包含名为click.js的click方法。例如: function Click() { phantom.page.includeJs('/my/path/to/elements.js'); var element = new Elements();

我正在为工作编写一些测试代码,并试图找出它抛出错误的原因。我使用面向对象的方法来实现这一点,以便尽可能保持我的主脚本干净。我有一个包含所有元素路径的脚本,名为elements.js。我使用phantom将该脚本注入到另一个文件中,该文件包含名为click.js的click方法。例如:

function Click() {

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

   this.clickElement = function() {
      casper.then( function() {
         casper.click(element.nameOfElement);
      });
   };
}
以这种方式运行脚本会引发未定义的错误,但是如果我在click.js脚本中直接声明元素的路径,则测试运行正常:

function Click() {

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

  this.clickElement = function() {
     casper.then( function() {
         casper.click(nameOfElement);
     });
  };
}
我想从一个源调用所有元素路径,只是为了保持我的脚本干净,正如您可以想象的那样,它们可能会变长,这取决于我们测试的元素数量。我还有其他一些文件需要在这个测试中使用元素的路径,但是它们遵循与上面我的click.js脚本相同的原则

更新

下面是我的element.js脚本的样子:

function Elements() {

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

}
PhantomJS(和CasperJS)有两个上下文
page.includeJs()
page.injectJs()
是两个PhantomJS函数,它们将一个JavaScript文件包含到DOM中,然后在页面上下文中对DOM进行计算,但您希望访问页面上下文之外的元素路径

我假设您的elements.js如下所示:

function Elements(){
    this.someElement = "css path";
    ...
}
然后您需要读取文件并对其进行评估:

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

var elements = new Elements();
console.log(elements.someElement);
您可能应该以不同的方式定义elements.js,以利用PhantomJS的require功能:

作为模块

elements.js

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

var elements = new require("/path/to/elements.js");
var elements = require("/path/to/elements.js");
作为对象

elements.js

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

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

您可能不希望每次单击都读取文件,因此可以

var elements = require("/path/to/elements.js");
casper.clickElement = function(nameOfElement) {
    this.thenClick(elements[nameOfElement]);
};
以后像这样使用它

casper.clickElement("someOtherElement");

我解决了这个问题,通过一个新手的大脑放屁。在我的element.js脚本中,我添加了一个简单的get方法,它现在可以工作了

function Elements() {

    var someElement = "css path";

    this.getSomeElementPath = function() {
        return someElement;
    };
}
在我的click.js脚本中将其称为:

function Click() {

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

    this.clickSomeElement = function() {
        casper.then( function() {
            casper.click(element.getSomeElementPath());
        });
    };
}
在我的主要剧本中:

'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();
    });
});

现在,测试正常运行。

假设我的元素脚本很接近。我没有使用“this”前缀,我只是声明为someElement=(“css路径”);在这种情况下,这些都是全局变量,您根本不需要
new Elements()
。我还需要在其他脚本中包含element.js脚本才能使用它吗?是的,您可能需要这样做。我将路径插入到element.js脚本中,只使用在element.js中创建的变量的名称(即someElement)然后运行测试,它会在找不到某个元素时返回。