Skip to content

Instantly share code, notes, and snippets.

@craftgear
Last active June 15, 2021 08:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save craftgear/cda895e40459622a1baeb9909c77eb9b to your computer and use it in GitHub Desktop.
Save craftgear/cda895e40459622a1baeb9909c77eb9b to your computer and use it in GitHub Desktop.
Cypressを導入してe2eテストをかけるようにするまでにやったこと

Cypress導入手順

インストール

  1. npm install cypress --save-dev
  2. npx cypress open →自動でcypress.jsonとcypress用のディレクトリが作られる
  3. cypress.json に設定を追加する
{
  "baseUrl": "http://localhost:8080",
  "viewportWidth": 1280,
  "video": true,
  "videoCompression": 16,
  "ignoreTestFiles": ["**/examples/*", "**/__snapshots__/*"],
}

クッキーを保持するようにする

cypress/support/commands.jsに以下を追加する

// keep session across tests
Cypress.Cookies.defaults({
  preserve: 'connect.sid', // express用 クッキー名は変えること
});

localStorageの内容を保持するようにする

  1. cypress/support/commands.jsに以下を追加する
const LOCAL_STORAGE_MEMORY = {};

Cypress.Commands.add('saveLocalStorageCache', () => {
  Object.keys(localStorage).forEach(key => {
    LOCAL_STORAGE_MEMORY[key] = localStorage[key];
  });
});

Cypress.Commands.add('restoreLocalStorageCache', () => {
  Object.keys(LOCAL_STORAGE_MEMORY).forEach(key => {
    localStorage.setItem(key, LOCAL_STORAGE_MEMORY[key]);
  });
});
  1. スペックのbeforeEachrestoreLocalStorage()を、afterEachsaveLocalStorage() を呼ぶ
  2. スペックの afterclearLocalStorage() を呼ぶ

カスタムコマンドを追加する

// テキスト取得のカスタムコマンドを追加する
 Cypress.Commands.add('getText', path => {
   cy.get(path)
     .invoke('text')
     .then(x => cy.wrap(x));
 });


// 複数要素のテキスト取得のカスタムコマンドを追加する
Cypress.Commands.add('getTexts', { prevSubject: true }, elem => {
  const texts = [];
  elem.each((_, e) => {
    texts.push(e.textContent);
  });
  return cy.wrap(texts);
});

// 値取得のカスタムコマンドを追加する
 Cypress.Commands.add('getVal', path => {
   cy.get(path)
     .invoke('val')
     .then(x => cy.wrap(x));
 });

// 必要なら MaterialUIのselectのためのカスタムコマンドを追加する
Cypress.Commands.add('selectForMui', (path, index) => {
  cy.get(path).click({ force: true });
  cy.wait(200);
  const pathToSelect = `ul[role="listbox"] li:nth-child(${index})`;
  cy.get(pathToSelect)
    .invoke('text')
    .then(text => {
      cy.get(pathToSelect).click({ force: true });
      cy.wait(200);
      return cy.wrap(text);
    });
});

Cypress.Commands.add('selectForMuiByText', (path, text) => {
  cy.get(path).click({ force: true });
  cy.wait(200);
  const pathToSelect = `ul[role="listbox"] li`;
  cy.get(pathToSelect)
    .contains(text)
    .click({ force: true })
    .then(() => {
      cy.wait(200);
      return cy.wrap(text);
    });
});

eslintの設定

  1. npm install --save-dev eslint-plugin-cypress
  2. .eslintrc.json に以下を追加
{
   "extends": [
      "plugin:cypress/recommended"
   ],
   "overrides": {
     {
       "files": ["cypress/integration/**/*"],
       "env": { "browser": true, "cypress/globals": true },
       "rules": {
         "cypress/no-unnecessary-waiting": "warn",
         "no-return-assign": "warn"
       }
     }
   }
}

オプション:ビジュアルリグレッションテスト用のプラグインを追加する

インストール

  1. npm install --save-dev cypress-plugin-snapshots
  2. cypress/plugins/index.jsに以下を追加
 const { initPlugin } = require('cypress-plugin-snapshots/plugin');

 module.exports = (on, config) => {
   // `on` is used to hook into various events Cypress emits
   // `config` is the resolved Cypress config
   //
   initPlugin(on, config);
   return config;
 };

  1. cypress/support/commands.jsに以下を追加
import 'cypress-plugin-snapshots/commands';

run allで全てのスペックを実行すると、スナップショットの保存場所が変わるというバグがあるので、それを回避する

参照:meinaart/cypress-plugin-snapshots#10

  1. cypress/support/index.jsに以下を追加
 // a workaround to run image snapshots for run all tests.
 import path from 'path';
 export const fixCypressSpec = filename => {
   const projectRoot = Cypress.config('projectRoot');
   const absolute = path.join(projectRoot, filename);
   Cypress.spec = {
     absolute,
     name: path.basename(filename),
     filename,
   };
 };

  1. fixCypressSpec(__filename)beforeEach で呼ぶ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment