スクリーンショット 2022-09-25 12.47.28

Jest で beforeunload イベントをテストする

beforeunload イベントをテストする方法を紹介します

beforeunload イベントはウインドウがアンロードされる直前に発生します。アンロードとはブラウザのダブを閉じたり、リロードしたときなどが含まれます。イベントハンドラーで preventDefault() を呼び出すことにより、以下のような確認ダイアログを表示できます。ユーザーが「キャンセル」をクリックするとページ遷移をキャンセルし、そうでない場合ンはブラウザは新しいページへ遷移します。

スクリーンショット 2022-09-25 12.47.28

beforeunload イベントのよくある使い道として、ユーザーがフォームを入力している最中に誤ってブラウザを閉じてしまい、入力内容が消失することを防ぐために使用されます。下記のフォームになにか入力してから更新を試してください。

この例ではフォームが変更された場合(=isDirtytrue)のみ beforeunload イベントの preventDefault() を呼び出してユーザーがページ遷移するのを防ごうとしています。この仕様をテストしたのですが、どのようにユーザーがアンロードしたことをシミュレーションすればよいのでしょうか?

beforeunload イベントのようにユーザーの挙動をシミュレーターするのが難しいイベントは window.dispatchEvent() を使用するとよいでしょう。 window.dispatchEvent() Event オブジェクトを引数に受け取り特定のイベントを実行できます。

ここでは new Event("beforeunload")beforeunload イベントを作成して引数に渡すことで呼び出すことができます。

window.dispatchEvent(new Event('beforeunlaod'));

さらに確認ダイアログが表示されるかどうかは preventDefault() が呼び出されているかどうかで確認できるので、モック関数を仕込んで渡すこで検査できます。

// beforeunloadEvent を作成する
const beforeUnloadEvent = new Event("beforeunload");
beforeUnloadEvent.preventDefault = jest.fn();
 
// フォームになにか入力して確認ダイアログが表示される条件を満たす
render(<Form initialValues={{ name: "" }} />);
const input = screen.getByLabelText("Name");
userEvent.type(input, "John Doe");
 
// beforeunload イベントをプログラム的に発行する
window.dispatchEvent(beforeUnloadEvent);
// 確認ダイアログを表示するため preventDefault が呼ばれるはず
expect(beforeUnloadEvent.preventDefault).toHaveBeenCalled();

全体のコードは次のようになります。


Contributors

> GitHub で修正を提案する
この記事をシェアする
はてなブックマークに追加

関連記事