编写自定义Commands

大多数情况下,你需要扩展Nightwatch commands以满足自己的应用程序需求。这样做只需要创建一个单独的文件夹并在其中定义自己的commands。

然后在nightwatch.json文件中设置custom__commands__path属性,command名是文件本身的名字。

有两种主要的方法来定义一个custom command:

Function-style commands(函数式命令)

这是命令commands的最简单的形式,但是它们也非常有限。你的command模块需要导出一个command函数,这需要至少调用一个夜Nightwatch api方法( 例如 .execute() ),这是由于commands的异步排队系统工作原理所限制,你还可以将所有内容封装在 .perform() 中来调用。诸如 execute 和 perform 的客户端命令可以通过 this 实现。

exports.command = function(file, callback) {
  var self = this;
  var imageData;
  var fs = require('fs');

  try {
    var originalData = fs.readFileSync(file);
    var base64Image = new Buffer(originalData, 'binary').toString('base64');
    imageData = 'data:image/jpeg;base64,' + base64Image;
  } catch (err) {
    console.log(err);
    throw "Unable to open file: " + file;
  }

  this.execute(
    function(data) { // execute application specific code
      App.resizePicture(data);
      return true;
    },

    [imageData], // arguments array to be passed

    function(result) {
      if (typeof callback === "function") {
        callback.call(self, result);
      }
    }
  );

  return this;
};

上面的例子定义了一个command(例如:resizePicture.js),它加载一个图像文件作为data-URI,并调用一个名为resizePicture的方法,在应用程序中定义。

有了这个command,测试就可以变成这样:

module.exports = {
  "testing resize picture" : function (browser) {
    browser
      .url("http://app.host")
      .waitForElementVisible("body")
      .resizePicture("/var/www/pics/moon.jpg")
      .assert.element(".container .picture-large")
      .end();
  }
};

Class-style commands(类方式命令)

这就是Nightwatch的大部分commands的编写方式。你的command模块需要使用一个command实例方法导出一个类构造函数,该方法表示command函数。像这样编写的command应该从EventEmitter继承,并手动发出完整的事件,以指示命令完成。

基于类的command方法在类实例的上下文中运行(this的值)。这个测试api对象提供了this.api或this.client.api,这个this.client是Nightwatch实例本身。

下面的例子是.pause()命令:

var util = require('util');
var events = require('events');

function Pause() {
  events.EventEmitter.call(this);
}

util.inherits(Pause, events.EventEmitter);

Pause.prototype.command = function(ms, cb) {
  var self = this;
  // If we don't pass the milliseconds, the client will
  // be suspended indefinitely
  if (!ms) {
    return this;
  }
  setTimeout(function() {
    // if we have a callback, call it right before the complete event
    if (cb) {
      cb.call(self.client.api);
    }

    self.emit('complete');
  }, ms);

  return this;
};

module.exports = Pause;

complete事件

需要在异步操作中完成对complete事件的信令 (例如:调用setTimeout),不扩展EventEmitter的command类将被视为与命令功能类似,要求command方法至少调用一个Nightwatch api方法才能完成。

目前还不支持使用ES6类作为自定义command。有关更多细节,请参见Nightwatch#1199

编写自定义Assertions

Nightwatch允许你甚至定义你自己的断言,扩展可用的断言 .assert 和 .verify 名称空间。

Assertions实现了一个简单的接口,该接口在内置assertions和自定义assertions之间共享:

exports.assertion = function() {

  /**
   * The message which will be used in the test output and
   * inside the XML reports
   * @type {string}
   */
  this.message;

  /**
   * A value to perform the assertion on. If a function is
   * defined, its result will be used.
   * @type {function|*}
   */
  this.expected;

  /**
   * The method which performs the actual assertion. It is
   * called with the result of the value method as the argument.
   * @type {function}
   */
  this.pass = function(value) {

  };

  /**
   * The method which returns the value to be used on the
   * assertion. It is called with the result of the command's
   * callback as argument.
   * @type {function}
   */
  this.value = function(result) {

  };

  /**
   * Performs a protocol command/action and its result is
   * passed to the value method via the callback argument.
   * @type {function}
   */
  this.command = function(callback) {

    return this;
  };

};

自定义断言也继承了EventEmitter。请在Github上查看更多的断言模块示例

自定义Reporter

如果你想要定义自己的repoter,除了内置的(stdout和junit-xml),你可以通过两种方式来实现:

--reporter命令行参数

接口

module.exports = {
  write : function(results, options, done) {
    done();
  }
};

reporter方法在你的外部全局文件里

参看globalsMobule.js文件,例如:

module.exports = {
  reporter : function(results, done) {
    console.log(results);
    done();
  }
};

results matching ""

    No results matching ""