Background / Issue
弊社では,PC・スマホ・タブレットサイトといったデバイス毎のEnd to End UIテストを自動化しています。
Nightwatch.jsを使ってPage Objectパターンで実装しているのですが,
デバイス毎にページHTMLが異なる場合に,デバイス数 × ページ数のページファイルを作成する必要がでてきました。
Page Objectパターンでは,シナリオとページを分離することでテストコードをシンプルにすることができるのですが,
Nighwatch.js((v0.9.11))のPage Object機能はデバイス別ページの概念が無いため,デバイス毎にページを切り替えるしくみがありません。
単純に対応するとすると,下記のようにデバイス別のファイルが大量に作られカオスになること必死です。
- pages/
- top-mobile.js
- top-tablet.js
- login-mobile.js
- login-tablet.js
Solution
まず,デバイス毎にシナリオは変わらないので,Page Objectパターンを利用しつつ,ページ内で完結する方法を考えました。
デバイス毎による差異はページ側で吸収させたいので,デバイス毎のelementsを各ページ内で定義し,オブジェクト生成時にelementsを生成するビルダーを作って対応しました。
-
element-builder.js on Gist
- どのデバイスのelementsを生成するかは,タスクランナー(Gulp)でprocess.env.DEVICEを定義しておく
- デバイス毎のelementsの差異があるページのみで使えばよく,element-builderは必須ではない
- mobile と tablet の2種類のデバイスを想定して実装
Usage
1 pageファイルで element-builder をrequireします
const builder = require('../utils/elements-builder');
2 elementsを定義します
const elements = {
link: {
mobile: 'div.mobile > a',
tablet: 'div.tablet > a'
}
};
3 pageファイルのelementsにビルダーをセットします
elements: builder.build(elements),
4 完成ページサンプル
const builder = require('../utils/elements-builder');
const elements = {
link: {
mobile: 'div.mobile > a',
tablet: 'div.tablet > a'
}
};
module.exports = {
url: function() {
return this.api.launchUrl + '/login';
},
elements: builder.build(elements)
};