Cypress:セッションを保持した状態でテストする


はじめに

新天地で、社内システムの自動テスト化について取り組ませていただくことになりました。
テストは、独自ランナーが使いやすい、Cypressです。
英語がまったく読めないので、苦戦・・・
Chromeの翻訳機能に助けられながら、やったことをメモしておきます。
OSはMacです。

自動テストの概念

自動テストについて調べた結果、概念はこんな感じです。

  • できるだけ簡単なコードで作成する
  • 機能別・テスト名・コード単位で検索しやすい
  • 簡単に更新できる
  • ひとつのものをみんなで共有出来る
  • 誰かに依存しない

セッションを保持したまま、複数のテストを実施する

まずは、ログインIDとパスワードを入れ、セッションを保持したまま別のテストを行う。
という入り口的な部分。
試行錯誤をしましたが、以下の2点を活用しました。

1.Cookieをファイル経由で保存する

参照サイト:Cypressで送る快適E2Eライフ

上記サイト様を参考にして、Cookie情報を別のファイルに出力し、それを読み込むという手法。
ログイン処理をカスタムコマンドにし、ログイン〜Cookieの出力まで行います。

カスタムコマンドについてはこちら ▶ 公式ドキュメント

cypress/support/commands.js

Cypress.Commands.add('login, () => {

  cy.url().then(url => {
    if(url === 'http://...'){

        console.log('relogin')

        cy.clearCookie('session_id')

        const login_id = Cypress.env('login_id') 
        const password = Cypress.env('password')

        cy.get('[name=login_id]').type(login_id).should('have.value', login_id)
        cy.get('[name=password]'). type(password,{ log:false }).should(el$ => {
          if(el$.val() !== password){
            throw new Error('Different value of typed password')
          }
        })
        cy.get('.submit').click()

        //セッションを保持
        cy.getCookie('session_id').should('exist').then((cookie) => {
        cy.writeFile("cache/cookie/session_id.json", {
          value: cookie.value
        })

      })
    }
  })

});


cypress/support/commands.js
内容としては、もし、アクセスしたURLがログインフォームと同じだったらば、clearCookieして再ログインしてね。
セッションがあればスルーされる部分です。

また、ログインIDとパスワードは、cypress.jsonファイルに、環境変数としてセット。
真ん中の色々書いてある部分は、ログイン情報はセキュリティ上表示させないようにしてね、という処理。
ですので、ランナーのコマンドログにパスワードは表示されません。

 

cypress/integration/login_spec.js


describe('Login Action',() => {
    /**
     * セッション設定
     */
    before('Session Setting', () => {
        cy.readFile("cache/cookie/session_id.json").then(cs => {
            cy.setCookie("session_id", cs.value)
        });

        Cypress.Cookies.preserveOnce('session_id')
        cy.visit('URL')
    });

    /**
     * ログインチェック
     */
    beforeEach ('Login Check',() => {
          cy.login()

    })

    /**
     * テスト処理
     */
    it ('Test Case1', () => {
        // something assertion
        })
})

cypress/integration/login_spec.js
内容としては、セッションがあればテストを開始、
セッションが無ければ、再ログイン(カスタムコマンド)をしてからテスト開始。
beforeに、ファイルに出力されたCookie情報をreadさせて、beforeEachで再ログインの有無をチェック。
因みにbeforeEachはすべてのテスト(it)に当たるので、毎回再ログインチェックしている。
別に要らないんですけどね。。。
余計な処理も、Cypress速いからまあ良いでしょう。ということ。
 

2.Cypress.Cookies.preserveOnce('session_id') を使う

公式ドキュメント

cypress/integration/login_spec.js
ファイルに出力されたCookie情報を、保持しておくことが出来るコマンドです。
跨いで保持することは出来ないようです。

Cypress.Cookies.preserveOnce('session_id')
おわりに

他にも、セッションについては永続的に保持しておけるlocalStorageの利用もひとつの手段かと思いましたが、なかなか実装が出来ず。
Cypressは便利な分、不安定な要素や、実装できない要素等まだまだあるようです。
npmモジュールを入れると、ランナーが起動しなくなるし、正しく実行できるテストも、5回に1回はなんとかエラーが出ます。(ホットリロードすると正常)

まだまだ勉強することはたくさんありますが、セッションの保持が一個クリア出来たので、記録します。
シンプルな方法ですが、初心者なのでこれからこれから。
他に良い方法や、おすすめの方法があれば教えていただきたいです。