PlaywrightでHTML5バリデーションをテストする方法

HTML5バリデーションとE2Eテストの課題

E2Eテストでは、実際のユーザー操作をシミュレートしてアプリケーションが正しく動作するかを検証します。HTML5のフォームバリデーションは多くのWebアプリケーションで使われている基本機能ですが、Playwrightなどのテストフレームワークで適切にテストするのは少し工夫が必要です。

特に以下のような課題があります:

  • HTML5バリデーションのエラーメッセージはブラウザによって異なる
  • エラーメッセージはDOMに直接表示されるわけではない
  • バリデーションのUI表示はブラウザによって制御される

今回は、PlaywrightでHTML5バリデーションをテストするいくつかの効果的な方法を紹介します。

よくあるテストケース

例えば、以下のようなテストケースがあるとします:

1
2
3
4
5
6
7
test('メールアドレスが空の場合はエラーが表示される', async ({ page }) => {
  await page.goto('/signup');
  
  await page.getByRole('button', { name: 'メールで新規登録' }).click();
  
  await expect(page.getByText('メールアドレスは必須です')).toBeVisible();
});

このテストはシンプルに見えますが、HTML5の標準バリデーションでは「メールアドレスは必須です」というテキストが直接DOMに表示されるわけではないため、失敗する可能性があります。

HTML5バリデーションをテストする3つの方法

方法1: invalid セレクタを使用する

最もシンプルな方法は、CSSの:invalid擬似クラスを使って無効な入力フィールドの存在を確認する方法です:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
test('メールアドレスが空の場合はバリデーションエラーが発生する', async ({ page }) => {
  await page.goto('/signup');
  
  // フォームを送信
  await page.getByRole('button', { name: 'メールで新規登録' }).click();
  
  // :invalid セレクタを使用して無効な入力フィールドの存在を確認
  await expect(page.locator('input:invalid')).toBeVisible();
  
  // 特定のフィールドが無効であることを確認
  await expect(page.locator('#email')).toHaveJSProperty('validity.valid', false);
});

この方法は特定のエラーメッセージをテストするわけではありませんが、バリデーションが機能していることを確認できます。

方法2: validationMessage プロパティをテストする

ブラウザのネイティブバリデーションメッセージを取得するには、JavaScriptのvalidationMessageプロパティを使用します:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
test('メールアドレスが空の場合はバリデーションメッセージが表示される', async ({ page }) => {
  await page.goto('/signup');
  
  // フォームを送信
  await page.getByRole('button', { name: 'メールで新規登録' }).click();
  
  // バリデーションメッセージを取得
  const validationMessage = await page.evaluate(() => {
    const emailInput = document.getElementById('email');
    return emailInput.validationMessage;
  });
  
  // バリデーションメッセージが存在することを確認
  expect(validationMessage).toBeTruthy();
  // 特定のテキストを含むことを確認(ブラウザによって異なるので注意)
  expect(validationMessage.length).toBeGreaterThan(0);
});

この方法はバリデーションメッセージの内容そのものをテストできますが、ブラウザごとに異なるメッセージが表示されるため、具体的なテキスト内容をアサートすることは避けたほうが良いでしょう。

方法3: カスタムバリデーションメッセージを設定する

テストの安定性を高めるには、フォームにカスタムバリデーションメッセージを設定するのが最も効果的です:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
// フォームコンポーネントの一部
<input
  id="email"
  name="email"
  type="email"
  required
  value={email}
  onChange={(e) => setEmail(e.target.value)}
  onInvalid={(e) => {
    // カスタムバリデーションメッセージを設定
    e.currentTarget.setCustomValidity('メールアドレスは必須です');
  }}
  onInput={(e) => {
    // 入力があった場合はメッセージをリセット
    e.currentTarget.setCustomValidity('');
  }}
/>

その後、テストでは次のようにメッセージを検証します:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
test('メールアドレスが空の場合はエラーが表示される', async ({ page }) => {
  await page.goto('/signup');
  
  await page.getByRole('button', { name: 'メールで新規登録' }).click();
  
  // カスタムバリデーションメッセージを取得
  const validationMessage = await page.evaluate(() => {
    const emailInput = document.getElementById('email');
    return emailInput.validationMessage;
  });
  
  expect(validationMessage).toBe('メールアドレスは必須です');
});

この方法ならブラウザに関係なく一貫したメッセージでテストできます。

HTML5バリデーションの詳細なテスト

より詳細なバリデーションをテストする場合は、validityオブジェクトのプロパティを確認する方法も有効です:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
test('無効なメールアドレス形式の場合はtype mismatchエラーが発生する', async ({ page }) => {
  await page.goto('/signup');
  
  // 無効なメールアドレスを入力
  await page.fill('#email', 'invalid-email');
  
  // フォームを送信
  await page.getByRole('button', { name: 'メールで新規登録' }).click();
  
  // validityStateのプロパティをチェック
  const typeMismatch = await page.evaluate(() => {
    const emailInput = document.getElementById('email');
    return emailInput.validity.typeMismatch;
  });
  
  expect(typeMismatch).toBeTruthy();
});

まとめ

PlaywrightでHTML5バリデーションをテストするには、以下の方法が効果的です:

  1. :invalidセレクタの使用: バリデーションの有無を簡単にテストできる
  2. validationMessageプロパティのチェック: 実際に表示されるメッセージをテストできる
  3. setCustomValidity()によるカスタムメッセージ設定: テストの安定性を高める
  4. validityオブジェクトのプロパティチェック: 詳細なバリデーション状態をテストできる

これらの方法を組み合わせることで、HTML5バリデーションの挙動を効果的にテストでき、ユーザー体験の品質を確保することができます。

フォームのバリデーション要件が複雑な場合は、HTML5の標準バリデーションだけでなく、カスタムのバリデーションロジックやUIフィードバックの実装も検討すると良いでしょう。

カテゴリ

comments powered by Disqus