ReactコンポーネントテストでのJSXの使用
概要
バージョン2.4以降、NightwatchはJSXを使用し、Component Story Format (CSF) サブセットで記述されたReactコンポーネントテストの実行をサポートしています。
Component Story Formatとは
Component Story Format(CSF)は、オープンスタンダードであり、Storybookチームによって、コンポーネントストーリーを作成するための宣言的なモデルとして導入されたES6モジュールに基づいています。
ストーリーは、props、args、またはテスト機能とともに、コンポーネントのインスタンスである名前付きexport
です。コンポーネントテストファイルには、1つ以上のストーリーが含まれています。
ファイル名には拡張子として.jsx
または.tsx
を使用する必要があります。最も単純な形式では、コンポーネントテストは次のようになります
import Form from '../components/Form.jsx';
export default {
title: 'Form',
component: Form,
}
export const FormStory = () => <Form />
上記の例を考慮して、コンポーネントテストの2番目のストーリーを追加しましょう。
import Form from '../components/Form.jsx';
export default {
title: 'Form Component',
component: Form
}
export const EmptyForm = () => <Form />
export const AnotherForm = Object.assign(() => <Form addTask={function(value) {
console.log('Add Task', value);
}} />, {
// additional parameters
});
インタラクションテストの追加
各コンポーネントストーリー(つまり、名前付きexport)は、実行する必要があるテストを定義するいくつかの(async
)関数プロパティを受け取ります。テスト機能は、次の関数を使用して記述できます
play({canvasElement, args})
– DOMコンテキストで実行され、コンポーネントストーリー要素を受け取りますtest(browser, {component, result})
– Nodeコンテキストで実行され、Nightwatch apiオブジェクト(browser
)を受け取ります。Nightwatch互換の要素インスタンスとしてcomponent
要素オブジェクトを受け取りますpreRender()
– コンポーネントがレンダリングされる前に実行されますpostRender()
– コンポーネントがレンダリングされた後に実行されます
さらに、コンポーネントレベルのテストフックは、最上位レベルのdefault export
セクションで宣言できます。
例
下の例では、play()
関数は、Testing LibraryのDOMユーティリティを使用しています。
import { fireEvent, within } from '@testing-library/dom';
import Form from '../components/Form.jsx';
export default {
title: 'Form Component',
component: Form,
// executed before all the individual component stories; runs in Node context
async setup(browser) {
console.log('global setup hook', browser.capabilities)
},
// executed after all the individual component stories; runs in Node context
async teardown(browser) {
console.log('global teardown hook')
},
// executed before each individual component story; runs in Node context
async preRender(browser, context) {
// context is made of {id, name, title}
console.log('preRender', context.id);
},
// executed after each individual component story; runs in Node context
async postRender(browser, context) {
// context is made of {id, name, title}
console.log('postRender', context.id);
}
}
export const AnotherForm = Object.assign(() => <Form addTask={function(value) {
console.log('Add Task', value);
}} />, {
async preRender() {},
async postRender() {
console.log('after mount', window);
},
async play({canvasElement, args}) {
console.log('play function', args);
const root = within(canvasElement);
const input = root.getByTestId('new-todo-input');
fireEvent.change(input, {
target: {
value: 'another one bites the dust'
}
});
return {
fromPlay: input
}
},
test: async (browser, {component, result}) => {
console.log('Result from play', result)
await expect(component).to.be.visible;
await expect(component.find('input')).to.have.property('value').equal('another one bites the dust');
}
});
静的アセットのロード
コンポーネントを個別にロードする場合、コンポーネントで使用されるスタイルを含むCSSファイルなど、追加の静的アセットをロードする必要があることがよくあります。
(JSX)テストファイルにアセットを直接ロードする以外に、Nightwatchにはこれを実現する2つの方法が用意されています
- 現在のプロジェクトに
nightwatch/index.jsx
ファイルを作成する - まったく新しいテストレンダラーファイルを作成し、Viteプラグインで
renderPage
オプションを使用する
プロジェクト例
Reactで記述され、Viteの上に構築された基本的なTo-doアプリを、ボイラープレートとして使用できるようにまとめました。https://github.com/nightwatchjs-community/todo-reactで確認できます