Playwright でファイルアップロードできないときの回避方法
はじめに
こんにちは、クラウドエース 第 2 開発部の坂本です。
最近、Playwright で E2E テストを書いていて、ファイルアップロードのテストで少し詰まりました。
具体的には、react-dropzone
を使用してファイルアップロードを実装している場合に、Playwright の 公式ドキュメント に記載されている filechooser
イベントを使った方法で、タイムアウトが発生しました。
そこで、本記事ではこの問題の回避方法をご紹介します。
Playwright の入門記事も弊社が出しておりますので、こちらもご覧ください。
前提条件
-
@playwright/test
<=1.48.1
-
react-dropzone
<=14.2.10
詰まったところ
Playwright を使用して React で作られた Web アプリケーションのファイルアップロード処理をテストするため、公式ドキュメントを参考に以下のコードを書きました。
const fileChooserPromise = page.waitForEvent('filechooser');
const selector = "input[type="file"]";
await page.locator(selector).click();
const fileChooser = await fileChooserPromise;
await fileChooser.setFiles(path.join(__dirname, "test.jpg"));
コードを実行すると、ファイル選択の直前までは問題なく動いていたのですが、ファイル選択の段階で Timeout 30000ms exceeded.
というエラーメッセージが表示されました。
原因
同様の事象がないか検索してみると、このような Issues が見つかりました。
これを見ると、 react-dropzone
は内部で Window.showOpenFilePicker()
を使用しており、 Window.showOpenFilePicker()
の使用時に Playwright の filechooser
イベントが発生しないことが原因のようです。
回避方法
react-dropzone
では filechooser
イベントが発生しないため、別の方法を取る必要があります。
まず、先ほどの Issue 内のコメントで紹介されている回避方法を試してみましたが、結果は変わりませんでした。
そこで、react-dropzone
のデフォルトで挿入される input 要素を使用することにしました。
<input multiple="" type="file" tabindex="-1" style="display: none;">
しかし、react-dropzone
では input 要素が非表示になっているため、まずはこの要素を表示させる必要があります。
Playwright では、 page.evaluate
を使用することで、 対象の DOM 操作を行うことができます。
今回は page.evaluate
を使用し、表示されていない input 要素を テスト時のみ display: block
に変更することで、Playwright から操作できるようにします。
page.evaluate
についての詳細は公式ドキュメントをご参照ください。
回避方法を反映したテストコードを以下に示します。
const fileChooserPromise = page.waitForEvent('filechooser');
const selector = "input[type="file"]";
/* DOM 操作 */
await page.evaluate(() => {
const inputElement = document.querySelector(selector)
if (inputElement instanceof HTMLInputElement) {
/* 非表示の input 要素 を表示させる */
inputElement.style.display = 'block';
}
})
/* 表示させた input 要素 をクリックする */
await page.locator(selector).click()
const fileChooser = await fileChooserPromise;
await fileChooser.setFiles(path.join(__dirname, "test.jpg"));
おわりに
今回はreact-dropzone
を使用したアプリケーションで、 Playwright を用いてファイルアップロードの E2E テストを行う際に遭遇した問題と、その回避方法について解説しました。
現状では、 filechooser
イベントが発生しないという問題に対しては、react-dropzone
の内部実装に依存した回避策をとるしかありません。
しかし、Playwright は活発に開発が進められているツールなので、将来的にはよりシンプルで安定したファイルアップロードのテストの方法が提供される可能性があります。
もし、この記事で紹介した方法で問題が解決しない場合は、Playwright の公式ドキュメント や Issues を参照するか、react-dropzone
の Issues を確認してみてください。
この記事が、同じ問題に直面している方の助けになれば幸いです。
Discussion