iT邦幫忙

2021 iThome 鐵人賽

DAY 3
0
Modern Web

自動化 End-End 測試 Nightwatch.js系列 第 3

自動化 End-End 測試 Nightwatch.js 之踩雷筆記:檢查顏色 II

客製化指令

Nightwatch 本身提供的功能雖然已經相當多了,不過或多或少都有些缺失。又或者我們希望能夠讓整個測試專案更貼合需要被測試的網站時,客製化指令就是一個很好的工具。

建立環境

如果需要撰寫客製化指令,就必須先讓 Nightwatch 先知道指令們所放的位置:

const nightwatchConfig = {
    custom_commands_path: './commands'
}

透過 nightwatchConfig 定義好位置後,就可以開始寫啦~

checkColorSafe()

昨天已經成功利用 getCssProperty() 湊出可以跨瀏覽器的功能了,不過如果只是把這樣的東西寫在單一一個測試檔案就太可惜了。

透過上一步的設定後,我們可以建立一個 commands 的資料夾,並加入 checkColorSafe.js

commands
 |-- checkColorSafe.js

指令的寫法可以分為:

  • Class-style commands
  • Function-style commands

也都可以搭配 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}`);
      }
    });
  },
};

雖然變得比較簡單,但也會有一些限制:

  1. 指令是以 asynchronous 的方式進行
  2. 如果需要呼叫多項 api,每項都必須是 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 的雷點會在後面介紹


上一篇
自動化 End-End 測試 Nightwatch.js 之踩雷筆記:檢查顏色
下一篇
自動化 End-End 測試 Nightwatch.js 之踩雷筆記:輸入
系列文
自動化 End-End 測試 Nightwatch.js30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言