Cypress で Firebase つかったログインをテストする
結論: jest-puppeteer で我慢できるならそっちのほうがいい
https://github.com/cypress-io/cypress/issues/408
を見てくださいで終わってしまう話なのだが、 Cypress はサードパーティーの cookie をクリアすることが出来ない。これは典型的にどういうときに問題になるかというと、 Firebase のような外部の認証プロバイダーを用いてアプリにログインしているとき、テストの実行事にログインセッションがクリアされない。
これが大きな問題であることは明らかで、↑のとおり Cypress の創業者もこれを改善する意思を示しているのだが、実際これを実装する難しさは issue で説明されてる通りで 3 年間放置されている。
https://github.com/cypress-io/cypress/issues/408#issuecomment-555394035
結局このコメントのとおりに回避をしていくしかない。
I found a workaround which is to have a logout call before each test.
である。
じゃあこういう処理を Cypress でどのように実装すべきかというと、
https://docs.cypress.io/guides/core-concepts/conditional-testing.html#Element-existence
が参考になるだろう。テストがどのようなシチュエーションで実行されるかはわからない(CI かもしれないし開発者のデスクトップかもしれない)ので、「ログインしてるかどうかを確認して、ログインしていればログアウトする」という処理を beforeEach 内で実行するとよい。
cy.get('body').then(($body) => {
$body.find(selector)
});
で DOM の有無を観測できるので、ログインしてるときにだけ発生する DOM があるかを確認して、ログインしているのであれば、ログアウトボタンかなにかをクリックする処理を書けばよい。
Cypress はあんまり難しくないことをしている限りは jest-puppeteer よりもはるかに書きやすくて気持ちがいいのだが、こういう風にちょっと複雑なことをしようとするとすぐに内部の気持ちを察したことをさせられる。また、ドキュメントの雰囲気からも察せられることと思うが案外 jQuery 的な価値観で全てが作られていてともするとレガシーさを感じることになる。
そのあたりも含めて SPA の E2E を書くなら jest-puppeteer より Cypress のほうが優れているとは思うが、よく注意して使ったほうがいい。