はじめに
React+CypressでVisualRegressionを実現するのにやったこと
環境構築
react/storybook導入
npx create-react-app my-app
npx -p @storybook/cli sb init
Cypress導入
yarn add cypress @testing-library/cypress -D
// 不要なテストを削除
rm -rf cypress/integration/examples
Storybookのpreview-iframeを取得
Storybookのiframeを取得する
cypress/support/command.js
import '@testing-library/cypress/add-commands';
Cypress.Commands.add('getIframeBody', () => {
cy.log('getIframeBody');
return cy
.get('#storybook-preview-iframe')
.its('0.contentDocument.body').should('not.be.empty')
.then((body) => cy.wrap(body))
});
Cypress-VisualRegressionモジュールを追加
良さげだったのでこちらを利用させていただいた
https://www.npmjs.com/package/cypress-visual-regression
yarn add cypress-visual-regression -D
設定を追加する
cypress/support/command.js
const compareSnapshotCommand = require('cypress-visual-regression/dist/command');
compareSnapshotCommand();
cypress/plugin/index.js
const getCompareSnapshotsPlugin = require('cypress-visual-regression/dist/plugin');
module.exports = (on) => {
getCompareSnapshotsPlugin(on);
};
cypress.json
{
"screenshotsFolder": "./cypress/snapshots/actual",
"trashAssetsBeforeRuns": true
}
テスト用コンポーネント準備
Storyookのデフォルトコンポーネントを利用
src/stories/Button.js
export const Button = ({ primary, backgroundColor, size, label, ...props }) => {
const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
const [buttonLabel, setLabel] = React.useState(label);
const onClick = () => { setLabel("hoge"); }
return (
<button
type="button"
className={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
style={backgroundColor && { backgroundColor }}
data-testid="button"
{...props}
onClick={onClick}
>
{buttonLabel}
</button>
);
};
buttonのテストを追加
cypress/integration/button_spec.js
describe('Button Component', () => {
beforeEach(() => {
cy.visit('http://localhost:6006/?path=/story/example-button--primary');
});
it('Button Click', () => {
cy.getIframeBody().findByTestId('button').should('have.text', 'Button');
cy.getIframeBody().findByTestId('button').click().should('have.text', 'hoge');
});
it('should display the Button correctly', () => {
cy.getIframeBody().findByTestId('button').contains('Button');
cy.compareSnapshot('button');
});
});
PackageにScriptを追加
package.json
"scripts" : {
"cypress:base": "cypress run --env type=base --config screenshotsFolder=cypress/snapshots/base",
"cypress:run": "cypress run --env type=actual",
"cypress:open": "cypress open"
}
テストの実行
// Baseの作成
yarn cypress:base
// テストを実行
yarn cypress:run
結果
TestをTypeScriptで実行する
ルートのtscofing.jsonに下記を追加
"include": [
"node_modules/cypress/types/*.ts",
"cypress/*/*.ts"
]
サンプルリポジトリ
[https://github.com/resqnet/cypress-storybook-visualregression:embed:cite]