概要
Cypressを案件に導入しいくつかテストケースを書いてみて溜まったtips
以前、ログインさせるだけでちょっとハマった話はこちら
Tips
難しそうだができたこと
スマホのswipe
- swipeの実現方法は、touchmoveイベントをJSで拾ってstyleに描画する、という泥臭い実装をしていた部分
- scrollTo や mouse event を試したが動かなかった
サンプルコード
cy.get('main > svg')
.swipe({delay: 100}, [180,200],[40,10])
.wait(1000) // wait('@some_intercept'); したいがswipeの場合はできなかった
注意: interceptはできない
コメントアウトに書いてる通り、swipe
後にAPI通信が走るので、それをcy.intercept()で監視したかったが、waitしてくれなかった。なので、ここは渋々 .wait(Integer)
画像アップロード
-
公式にサンプルコードがあるので、そのままでok- だったが CI環境 (GithubActions)上で、動作しないことが判明
- plugin: cypress-file-upload で解決した
非同期通信を待つ
- クリック等のイベント後のajaxな処理は cy.interceptでレスポンス完了を待てる
- 複数のリクエストとんで、それらの完了を全て待つ、ってのは単純には行かなそう→できた
- 複数wait書けばそれぞれが各interceptを待つ
cy.get('target_dom')
.wait('@intercept1')
.wait('@intercept2')
各interceptの時間を変えて終了する順番を変えてみるなどの詳細な動作検証までは未実施
ダウンロードファイル
CSVファイル(Zipファイル)ダウンロードして内容の検証できた
-
cypress/downloads/
に保存するので、そこからファイル読み取る
サンプルコード
const node_zip = require('node-zip')
// 中略
const filename = 'cypress/downloads/some_data.zip';
cy.readFile(filename, 'binary').then(buffer => {
// zip解凍
const zip = new node_zip(buffer);
let csv = "";
for (const fileinzip in zip.files) {
// 解凍ファイルの中身を取得(Uint8Array形式)
const uint8arr = zip.files[fileinzip]["_data"].getContent();
// Uint8ArrayをUTF8に変換
csv = (new TextDecoder).decode(Uint8Array.from(uint8arr))
}
expect(csv).includes("CSVの中の文字列");
});
注意: 文字化け対策が必要
node-zip
を使った解凍方法を調べて出てるサンプルコードを参考にしたが、それだと、csvファイル(UTF8)の文字化けが発生した。色々試行錯誤した結果
- new node_zip の optionは何も渡さない
- zip.files[fileinzip]["_data"].getContent() で Uint8Array形式のデータを取得
- それをUTF8にエンコード
で、解決。(あと、もっとリファクタできるなw)
できなかった
npm module browser-image-compression
が使えない
本案件では、ブラウザ側で画像圧縮をしており、そのライブラリに browser-image-compression
を利用していた。画像アップロード自体は上記の通り実施できたが、この圧縮処理はエラーになった。
- cypressの"自動"実行時にだけ
利用できない画像
エラー。手動実行は問題なかった。 -
imageObject instanceof Blob === false
になるためだがその原因は不明 - 回避策として、自動実行時は圧縮しない
if (imageObject instanceof Blob) {
// browser-image-compressionをコール
}
プロダクト側のコードをテスト用に変える苦渋の決断が必要。
コツ
DOMの指定方法
Open Selector Playgroud
は使いにくい
- jsで表示非表示が切り替わるUIでは、要素がうまく取得できないことあり
- 親要素にフォーカス当たって、子要素を指定できないことあり
- 通常のブラウザでclassを確認するのが安定
子要素指定は、 :nth-child(n)
が安定かも
- 例)
.parent-dom > :nth-child(2)'
-
.parent-dom > li
とかしてもDOM取得できないことがある - この場合は、
Open Selector Playgroud
が楽。
余談
検証したい要素をclassやidを指定するのが良いか?
https://blog.autify.com/ja/why-id-should-not-be-used
基本方針はhtmlの内部構造に影響を受けないようロケータを使う感じ。