【Playwright⑤】ファイルアップロードのテスト (Actions)

ファイルアップロード機能のテストは、ウェブアプリケーション開発において重要なステップの一つ。特に、ユーザーが正しくファイルをアップロードできるかどうか、複数ファイルのアップロードやファイルクリア操作が正常に動作するかを確認する必要がある。この記事では、Playwrightを使ってファイルアップロードのテストを実装する方法を解説する。具体的なテストケースを用いて、どのようにして効率的にこれらの機能を検証するかを学ぶことができる。

公式ドキュメント: https://playwright.dev/docs/input#upload-files

前回の記事:「【Playwright④】DOM操作を効率化するテクニック (Actions)

前提

共通で使用するHTML

<div class="mt-4">
  <label for="file-upload">Upload a file:</label>
  <input
    type="file"
    id="file-upload"
    class="pa-2 ml-4 border-sm"
    multiple
  />
</div>

アップロードに使用するファイル

この記事の動作確認はNuxt3で行なっているため、
プロジェクトのルートから下記の場所にファイルを格納している。
tests/files/comming-soon.png
tests/files/HTML5_Logo.png

単一ファイルのアップロードのテスト

このテストの目的

単一ファイルのアップロードが正しく行われるかを確認するためのテスト。
特に、ユーザーが指定したファイルが正しくフォームに追加され、
そのファイルの情報が正しく取得できるかを検証する。

コード解説

test("ファイルの選択状態をテスト", async ({ page }) => {
  // テストページに移動
  await page.goto("http://localhost:3000/test/playwright/file-upload");

  // ファイルパスの取得
  const __filename = fileURLToPath(import.meta.url);
  const __dirname = path.dirname(__filename);
  const fileWithPath = path.join(__dirname, "files/comming-soon.png");

  // ファイルをアップロード
  await page.setInputFiles('input[type="file"]', fileWithPath);

  // アップロードされたファイルの名前を取得して確認
  const inputValue = await page.$eval('input[type="file"]', (input: HTMLInputElement) => {
    return input.files?.[0]?.name;
  });

  expect(inputValue).toBe("comming-soon.png");
});

このテストでは、まずテスト対象ページに移動し、setInputFiles メソッドを使って指定したファイルをファイル入力フィールドにセットする。その後、$eval メソッドでファイル名を取得し、それが期待した名前であるかを expect で検証する。


複数ファイルのアップロードのテスト

このテストの目的

複数ファイルを一度にアップロードする機能が正しく動作するかを確認するためのテスト。これは、複数ファイルの同時アップロードが必要なシーンや、ファイルの選択肢が複数ある場合に役立つ。

コード解説

test("複数ファイルのアップロード確認", async ({ page }) => {
  await page.goto("http://localhost:3000/test/playwright/file-upload");

  const __filename = fileURLToPath(import.meta.url);
  const __dirname = path.dirname(__filename);
  const file1 = path.join(__dirname, "files/comming-soon.png");
  const file2 = path.join(__dirname, "files/HTML5_Logo.png");

  await page.setInputFiles('input[type="file"]', [file1, file2]);

  const inputFiles = await page.$eval('input[type="file"]', (input: HTMLInputElement) => {
    return Array.from(input.files || []).map((file) => file.name);
  });

  expect(inputFiles).toContain("comming-soon.png");
  expect(inputFiles).toContain("HTML5_Logo.png");
});

このテストでは、複数のファイルを配列形式で指定し、setInputFiles メソッドでアップロードする。続いて、アップロードされたファイルのリストを取得し、それぞれのファイル名が期待通りであるかを確認する。複数ファイルのアップロードが必要なアプリケーションで、このテストは重要な役割を果たす。


ファイルのクリアのテスト

このテストの目的

アップロードされたファイルをフォームからクリア(削除)する機能が正しく動作するかを確認するためのテスト。ユーザーが間違ってファイルを選択した場合や、再度ファイルを選択し直す必要がある場合に、適切にファイルがクリアされるかを確認する。

コード解説

test("ファイルのクリア", async ({ page }) => {
  await page.goto("http://localhost:3000/test/playwright/file-upload");

  const __filename = fileURLToPath(import.meta.url);
  const __dirname = path.dirname(__filename);
  const fileWithPath = path.join(__dirname, "files/comming-soon.png");

  await page.setInputFiles('input[type="file"]', fileWithPath);

  // ファイルがアップロードされた状態を確認
  let inputValue = await page.$eval('input[type="file"]', (input: HTMLInputElement) => {
    return input.files?.[0]?.name;
  });
  expect(inputValue).toBe("comming-soon.png");

  // ファイルをクリア
  await page.setInputFiles('input[type="file"]', []);

  // ファイルがクリアされた状態を確認
  const fileCount = await page.$eval('input[type="file"]', (input: HTMLInputElement) => {
    return input.files?.length;
  });
  expect(fileCount).toBe(0);
});

このテストでは、まずファイルをアップロードし、その後 setInputFiles に空の配列を渡すことでファイルをクリアする。クリア後に、ファイル入力フィールドが空になっているかどうかを確認する。これにより、ユーザーが意図せずファイルを残したままフォームを送信することを防ぐことができる。


まとめ

この記事では、Playwrightを使ったファイルアップロード機能のテスト方法を解説した。単一ファイルのアップロード、複数ファイルのアップロード、そしてファイルのクリア操作について、それぞれのテストケースを紹介し、どのようにしてこれらの機能を検証するかを説明した。これらのテストを適切に実装することで、ユーザーにとって使いやすいファイルアップロード機能を提供し、バグの発生を未然に防ぐことができる。

関連記事

コメント

この記事へのトラックバックはありません。