GitHub Actions で Cypress の end-to-end test を実行する
LitElement を利用した Custom Element の開発をしていて、 enzyme や vue-test-utils のようなコンポーネントのテストを記述したい。
ただ Custom Element 開発はブラウザの文脈に依存するものが非常に多く、Open WC などがツールを出しているみたいだけれど、ちょっとしたコードを書くには1からキャッチアップするのも大変。ということで、 Cypress で End-to-End でテスティングすることにした。
Jest + Puppeteer で自作しても良かったけれど、Shadow DOM にうまくアクセスする方法を持ち合わせていなかったので、試しも兼ねてというところ。
ローカルで一通り動いたので、CI に載せたくなったのは良いものの setup が少しクセがあったのでまとめておく。
GitHub Actions で動作させるために必要なコード
Cypress を CI 上で動作させるにあたって、ネックになってくるのはアクセス先のサーバーが立ち上がるまで待つ部分。
色々方法はあるみたいだけど、オフィシャルのドキュメントの Issue トラッカーをみていたら start-server-and-test を利用する方法が見つかったので、これを採用した。
まずは start-server-and-test と http-server をパッケージとしてインストール。
$ yarn add -D http-server start-server-and-test
その上で読みやすいようにそれぞれのタスクの script を追加し、
{
"scripts": {
"test": "start-server-and-test 'test:serve' 1234 'test:cypress'",
"test:serve": "http-server ./dist/ -c-1 --silent --port 1234",
"test:cypress": "cypress run",
}
}
最後に yarn test
で OK。
start-server-and-test を利用すると、 $1 のタスクを実行したあとに、 $2 のポートが動くまで待機。対象ポートから 200 OK が返却されたら、 $3 のタスクを実行するまでをやってくれる。
今回はビルド環境に Parcel を利用しており、そのまま parcel index.html
という手段もあったかもしれないが、ビルドが増えるにあたってビルド中の画面のまま Cypress が走り出すリスクを考慮して、ビルド後に http-server で起動するようにした。
ここまででパラレルで何かを動作させる必要なく Cypress を実行する環境が整ったので、あとはこれを Workflow に適用するだけ。
こちらは特別なことはせず、以下のように設定した。parcel のビルドを NPM script に登録していないのは、 build タスク回りはライブラリとしての出力のための rollup の設定で埋まっているため。
name: test
on: [push]
jobs:
cypress-run:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Use Node.js 14.x
uses: actions/setup-node@v1
with:
node-version: 14.x
- name: Run End-to-End Test
run: |
yarn
yarn build
yarn parcel build ./example/index.html
yarn test
これで OK。実行すると、こんな感じでうまい具合に動いてくれる。
正直 start-server-and-test を入れたくない気持ちがあるので、 Jest の globalSetup みたいな方法を探したいところ。なんだかんだ Jest は最悪 beforeAll でもサボれて楽で良い。