【Playwright④】DOM操作を効率化するテクニック (Actions)

Playwrightを使ったテスト自動化では、DOM操作が重要なステップとなる。Playwrightの強力な「Actions」機能を使うことで、DOM要素に効率的かつ正確にアクセスし、操作が可能。本記事では、DOM操作を効率化するためのテクニックを紹介する。

具体的には以下のDOM操作に焦点を当てる。

  • テキスト入力の操作
  • チェックボックスとラジオボタンの操作
  • ドロップダウンメニューの操作
  • マウスクリックの操作
  • キー入力とショートカット
  • フォーカスとスクロール
  • ドラッグ&ドロップの操作

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

DOM操作を効率化するテクニック (Actions)

テキスト入力の操作

テキスト入力はWebアプリケーションで頻繁に行われる操作の一つ。 Playwrightではlocator.fill()メソッドを使用して、 テキストボックスやテキストエリアにテキストを入力できる。

HTML

<div class="mt-4">
  <label for="username">Username:</label>
  <input
    type="text"
    class="pa-2 ml-4 border-sm"
    id="username"
    placeholder="Enter your username"
  />
</div>
<div class="mt-4">
  <label for="password">Password:</label>
  <input
    type="password"
    class="pa-2 ml-4 border-sm"
    id="password"
    placeholder="Enter your password"
  />
</div>

テストコード

test("テキスト入力の操作", async ({ page }) => {
  await page.goto("http://localhost:3000/test/playwright/actions");

  // ユーザー名を入力
  await page.getByPlaceholder("Enter your username").fill("testuser");

  // パスワードを入力
  await page.getByPlaceholder("Enter your password").fill("password123");

  // 入力が正しく行われたか確認
  await expect(page.getByPlaceholder("Enter your username")).toHaveValue("testuser");
  await expect(page.getByPlaceholder("Enter your password")).toHaveValue("password123");
});

解説

このテストでは、getByPlaceholder メソッドを使用して、 テキストボックスに値を入力し、 その後、入力された値が正しいことを expect を使って確認している。


チェックボックスとラジオボタンの操作

チェックボックスやラジオボタンの操作も簡単に行える。 locator.check()メソッドを使用して、 これらの要素をチェックまたはチェック解除が可能。

HTML


<div class="mt-4">
  <label>
    <input type="checkbox" id="accept-terms" />
    Check
  </label>
</div>
<div class="mt-4">
  <label> <input type="radio" name="gender" value="male" /> Yes </label>
  <label> <input type="radio" name="gender" value="female" /> No </label>
</div>

テストコード

test("チェックボックスとラジオボタンの操作", async ({ page }) => {
  await page.goto("http://localhost:3000/test/playwright/actions");

  // チェックボックスをチェック
  await page.getByLabel("Check").check();
  await expect(page.getByLabel("Check")).toBeChecked();

  // ラジオボタンを選択
  await page.getByLabel("Yes").check();
  await expect(page.getByLabel("Yes")).toBeChecked();

  await page.getByLabel("No").check();
  await expect(page.getByLabel("No")).toBeChecked();
});

解説

このテストでは、 チェックボックスとラジオボタンにチェックを入れ、 その状態が反映されているかを確認している。 check() メソッドを使うと、要素にチェックを入れることができる。


セレクトボックスの操作

<select>要素のオプションを選択するには、 locator.selectOption()を使用する。 値やラベルに基づいてオプションを選択可能。

HTML


<div class="mt-4">
  <label>
    <input type="checkbox" id="accept-terms" />
    Check
  </label>
</div>
<div class="mt-4">
  <label> <input type="radio" name="gender" value="male" /> Yes </label>
  <label> <input type="radio" name="gender" value="female" /> No </label>
</div>

テストコード

test("ドロップダウンメニューの操作", async ({ page }) => {
  await page.goto("http://localhost:3000/test/playwright/actions");

  // ドロップダウンメニューから「カナダ」を選択
  await page.getByLabel("国籍").selectOption("ca");

  // 選択された値を確認
  await expect(page.getByLabel("国籍")).toHaveValue("ca");
});

解説

このテストでは、selectOption メソッドを使用して ドロップダウンメニューから選択し、 選択した値が反映されているかを確認している。


マウスクリックの操作

Playwrightでは、マウスクリックも容易にシミュレートできる。 locator.click()を使うことで、シンプルなクリックからダブルクリック、右クリック、シフト+クリックなど、様々なクリック操作が行える。

HTML

<div class="mt-4">
  <button id="submit-button" class="pa-2 ml-4 bg-primary">送信</button>
  <button id="cancel-button" class="pa-2 ml-4 bg-error">キャンセル</button>
</div>

テストコード

test("マウスクリックの操作", async ({ page }) => {
  await page.goto("http://localhost:3000/test/playwright/actions");

  // 送信ボタンをクリック
  await page.getByRole("button", { name: "送信" }).click();

  // キャンセルボタンをクリック
  await page.getByRole("button", { name: "キャンセル" }).click();
});

解説

このテストでは、getByRole メソッドを使用してボタンを特定し、クリック操作を行っている。ボタンのクリックに対するアクションの結果を確認する場合は、さらにアサーションを追加することが可能。


キー入力とショートカット

ページ内でキー入力をシミュレートする場合、locator.press()メソッドを使用する。このメソッドで特定のキーを押したり、キーボードショートカットをシミュレート可能。

HTML

<div class="mt-2">
  <label for="shortcut-input">Press a key combination:</label>
  <input type="text" id="shortcut-input" class="pa-2 ml-4 border-sm" />
</div>

テストコード

test("キー入力とショートカットの操作", async ({ page }) => {
  await page.goto("http://localhost:3000/test/playwright/actions");

  // キー入力をシミュレーション
  await page.getByLabel("Press a key combination").press("Control+S");

  // 特定のアクションがトリガーされたかのアサーションは、アプリの実装に依存する
  // 例えば、Control+Enterで送信処理を実行するなど
});

このテストでは、press メソッドを使用して、特定のキー入力やショートカットをシミュレートしている。アプリケーションがショートカットにどう反応するかによって、さらにアサーションを追加することが可能。


フォーカス

locator.focus()を使えば、要素にフォーカスを当てることができる。

HTML

<div class="mt-2">
  <label for="focus-input">Focus on this input:</label>
  <input type="text" id="focus-input" />
</div>

テストコード

test("フォーカス", async ({ page }) => {
  await page.goto("http://localhost:3000/test/playwright/actions");

  // フォーカスを移動
  await page.getByLabel("Focus on this input").focus();
  await expect(page.getByLabel("Focus on this input")).toBeFocused();
});

解説

このテストでは、focus メソッドを使用して特定の入力フィールドにフォーカスを当て、その状態が正しく反映されているかを確認している。

ドラッグ&ドロップの操作

Playwrightでは dragTo() メソッドを使用することで、要素をドラッグしてドロップする一連のアクションを簡単に実行することができる。

ドラッグ前

ドラッグ後

HTML(Vue)

<template>
  <v-container>
    <v-card class="mt-10 pa-4">
      <v-card-title class="px-0">ドラッグ&ドロップ</v-card-title>
      <div class="mt-2 drag-and-drop">
        <div id="draggable-item" draggable="true" @dragleave.prevent>ドラッグしなさい</div>
        <div
          id="dropzone"
          class="mt-4 pa-4 bg-grey"
          style="width: 300px; height: 100px"
          @dragover.prevent
          @drop.prevent="(e) => handleDropped(e)"
        >
          ここにドロップしなさい
        </div>
      </div>
    </v-card>
  </v-container>
</template>

<script setup lang="ts">
// ドロップを検知し、要素の背景色とテキストを変更する
const handleDropped = (e: Event) => {
  const target = e.target as HTMLDivElement;
  target.classList.remove("bg-grey");
  target.classList.add("bg-error");
  target.textContent = "ドロップされました";
};
</script>

テスト

import { test, expect } from "@playwright/test";

test("ドラッグ&ドロップの操作", async ({ page }) => {
  await page.goto("http://localhost:3000/test/playwright/actions");

  // ドラッグ元とドロップ先の要素を取得
  const draggable = page.locator("#draggable-item");
  const dropzone = page.locator("#dropzone");

  // ドラッグ&ドロップをシミュレート
  await draggable.dragTo(dropzone);

  await draggable.hover();
  await page.mouse.down();
  await dropzone.hover();
  await page.mouse.up();

  // ドロップ後にクラスが変更されていることを検証
  await expect(dropzone).toHaveClass(/bg-error/);
});

公式ドキュメントで指摘されているように、dragover イベントが正常に発火するためには、少なくとも2回の mouse.move()hover() が必要な場合がある。この理由から、hover 操作を2回繰り返すことで、イベントが確実に発火されるようにした。

If your page relies on the dragover event being dispatched, you need at least two mouse moves to trigger it in all browsers. To reliably issue the second mouse move, repeat your mouse.move() or locator.hover() twice. The sequence of operations would be: hover the drag element, mouse down, hover the drop element, hover the drop element second time, mouse up.

まとめ

本記事では、Playwrightを使ってDOM操作を効率的に行うためのテクニックを紹介した。これで、テキスト入力、チェックボックスやラジオボタンの操作、ドロップダウンメニューの選択、マウスクリック、キー入力とショートカット、フォーカスの設定、そしてドラッグ&ドロップの操作まで、幅広いシナリオに対応できるようになると思う。あなたのプロジェクトの参考になれば幸いだ。

次回の記事は、アサーションについて解説する。

この記事は役に立ちましたか?

もし参考になりましたら、下記のボタンで教えてください。

関連記事

コメント

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