概要
E2Eテストで、現在時刻を決め打ちしたく、ブラウザ上で時間をモックする方法を試行錯誤した。その過程と解決方法をメモしておく。フレームワークはNightwatchを使っている。
プロセス
sinon.jsとwebpackの相性が悪い
sinon.jsにFake timerというのがあったのでそれを使おうと試みた。
Nightwatchでできるのが、ブラウザの中でサードパーティを読み込む感じのことではなかったため、webpackでサーバーを立てるときに、NODE_ENV=e2eTest
の時だけsinon.jsをglobalに読み込もうとした。
そこで以下のissueにあるような問題が生じた・・・。一通り試したが、どうもブラウザに読み込むのは難しいようだった(ここで結構時間を消耗しすぎた感があった)。
- Sinon causing issues again · Issue #304 · webpack/webpack
- Webpack build issues · Issue #47 · airbnb/enzyme
lolexを試してみることに
そもそもsinon.jsのFake timerはlolexというライブラリを使用しているらしい。今回はsinon.jsすべての機能が必要だったわけではないので、時間操作だけできるlolexを使用してみることに。
結果的には以下の様なコードでlolexを読み込むことができた。ワークアラウンドっぽいですが・・・。
// アプリケーション側のコード
if (__E2E__) {
window.lolex = require('lolex');
}
これをE2E側の必要な箇所で使用する。Nightwatchの実行環境はNode.jsなので、ブラウザ側で実行するためにexecute
を使う必要がある。
// テストコード
browser
.execute(function () {
const clock = window.lolex.createClock(new Date(2015, 7, 20, 19, 45));
window.Date = clock.Date;
});
これにてブラウザ側でも時間を自由に操作することができた。注意点として、moment.jsをアプリケーション側で使っている場合、以下のように書く必要がある。
// NG
moment();
// OK
moment(new Date());
詳細な理由は以下のissueに書いてあった。
まとめ
解決のプロセスにも問題があったと思うが、E2Eはけっこう独特なスキルが必要だなと改めて感じた・・・。どうにかいい感じに付き合ってゆく方法を見つけたい