Playwright 1.60で、ドラッグ&ドロップをテストするためのlocator.drop()が追加されました。
ファイルアップロードのテストでは、これまでsetInputFiles()を使うことが多かったと思います。これは便利なのですが、画面上のドロップゾーンが本当に動いているかまでは確認できません。
setInputFiles()だけでは足りない場面
ファイル選択ダイアログを開かずに、input要素へファイルを渡すならsetInputFiles()で十分です。
await page.getByLabel('画像').setInputFiles('fixtures/photo.png');
ただし、実際のアプリがドロップゾーンのdragenter、dragover、dropイベントで処理している場合は話が変わります。隠れたinputにファイルを入れても、ドロップ時のイベント処理が壊れていることは見つかりません。
locator.drop()でドロップする
ではドロップゾーンをテストしてみましょう。対象のロケーターに対してdrop()を呼び出します。
const dropZone = page.getByRole('region', { name: '画像をドロップ' });
await dropZone.drop();
drop()は、外部からファイルやデータがドロップされた場面をシミュレートします。Playwrightの公式リリースノートでは、合成されたDataTransferを使い、dragenter、dragover、dropを発火すると説明されています。
これでドロップしたときだけ表示されるプレビューや、エラーメッセージの確認につなげられます。
どちらを使うか
隠れたinputにファイルを渡すだけならsetInputFiles()です。ドロップゾーンのイベント処理を確認したいならlocator.drop()を使います。
両方を同じテストに入れる必要はありません。入力経路ごとに、壊れたら困る振る舞いを1つ選ぶのがよいです。
テストで確認すること
test('画像をドロップするとプレビューが表示される', async ({ page }) => {
await page.goto('/upload');
await page.getByRole('region', { name: '画像をドロップ' }).drop();
await expect(page.getByRole('img', { name: 'プレビュー' })).toBeVisible();
});
実際のアプリがファイル本体を必要とする場合は、アプリの実装に合わせてDataTransferを作るテストや、アップロード処理の統合テストを追加してください。drop()を呼べたからといって、サーバーへの保存まで確認できるわけではありません。
ここは大事です。UIイベントのテストと、アップロードAPIのテストは分けた方が失敗した場所が分かります。
まとめ
setInputFiles()はinputへのファイル設定に向いています。locator.drop()はドロップゾーンのイベント処理を確認できます。- UIイベントとサーバー保存の検証は別のテストに分けます。
ファイルアップロードは、選択ダイアログ経由とドラッグ&ドロップ経由で入口が違います。入口が違うなら、テストも分けておく。これだけで、画面だけ動かないタイプの不具合を早く見つけられます。

コメント