Nightwatch 本身提供的功能雖然已經相當多了,不過或多或少都有些缺失。又或者我們希望能夠讓整個測試專案更貼合需要被測試的網站時,客製化指令就是一個很好的工具。
如果需要撰寫客製化指令,就必須先讓 Nightwatch 先知道指令們所放的位置:
const nightwatchConfig = {
custom_commands_path: './commands'
}
透過 nightwatchConfig 定義好位置後,就可以開始寫啦~
checkColorSafe()
昨天已經成功利用 getCssProperty()
湊出可以跨瀏覽器的功能了,不過如果只是把這樣的東西寫在單一一個測試檔案就太可惜了。
透過上一步的設定後,我們可以建立一個 commands 的資料夾,並加入 checkColorSafe.js
commands
|-- checkColorSafe.js
指令的寫法可以分為:
也都可以搭配 Promise, async/await 或是 Nightwatch 的 protocol actions。
如果是利用 Nightwatch 送出 emit 的方式,大概會長這樣:
const util = require('util');
const events = require('events');
function checkColorSafe() {
events.EventEmitter.call(this);
}
// 繼承 events class
util.inherits(checkColorSafe, events.EventEmitter);
// 客製化 command 要做的事,傳進 3 個參數 selector, cssProperty color
checkColorSafe.prototype.command = function commandFn(
_selector,
_cssProperty,
_color,
) {
this._stackTrace = commandFn.stackTrace;
const self = this;
let color = '';
// 呼叫原生 api: getCssProperty
// 把 rgb 轉成 rgba ( firefox, safari 專用)
// 當 command 完成時 emit 'complete' ,讓 command 可以繼續串接下去
self.client.api.getCssProperty(_selector, _cssProperty, function(result) {
color = result.value.includes('rgba(')
? result.value
: result.value.replace('rgb', 'rgba').replace(')', ', 1)');
if (color === _color) {
console.log('\x1b[33m%s\x1b[0m', `${result.value} color matched.`);
} else {
console.log('\x1b[31m%s\x1b[0m', `${color} not matched to ${_color}`);
throw new Error(`Wrong color ${color} not matched to ${_color}`);
}
self.emit('complete');
});
return this;
};
module.exports = checkColorSafe;
不過這樣的方式顯得相當的長,在較新的的 Nightwatch 中,可以直接利用 Function-style commands 的方式,將指令簡單化:
module.exports = {
command: async function(_selector, _cssProperty, _color) {
this.getCssProperty(_selector, _cssProperty, function(result) {
let color = result.value.includes('rgba(')
? result.value
: result.value.replace('rgb', 'rgba').replace(')', ', 1)');
if (color === _color) {
console.log('\x1b[33m%s\x1b[0m', `${result.value} color matched.`);
} else {
console.log('\x1b[31m%s\x1b[0m', `${color} not matched to ${_color}`);
throw new Error(`Wrong color ${color} not matched to ${_color}`);
}
});
},
};
雖然變得比較簡單,但也會有一些限制:
this
開頭,像是:module.exports = {
command: async function(_selector, _cssProperty, _color) {
this.waitForElementPresent('body');
this.pause(1000)
this.checkColorSafe('div', 'color', 'rgba(255, 255, 255, 1)')
};
這兩天透過建立客制化指令的方式,解決了跨瀏覽器比對顏色的情境,並了解指令不同的寫法與限制。
只不過,這還只是剛開始,接續還有更多不同瀏覽器的奇妙個性,需要一一克服,而 Firefox/Safari 也不是永遠都擔任特殊情境的角色,也有 Chrome 的雷點會在後面介紹