Playwright入門 - ローカルfixtureをChromiumで操作してテストする

中級 | 25分 で読める | 2025.12.02

公式ドキュメント

今回やること

Playwrightは、ブラウザを自動操作して画面の動きを検証できるテストツールです。

この記事では、小さなTodo画面をローカルfixtureとして作り、次の操作を1本のテストにします。

  1. ラベルを使って入力欄を見つける
  2. Todoの文章を入力する
  3. ボタンを押す
  4. 一覧、完了メッセージ、入力欄の状態を確認する
  5. HTMLレポートとtraceで操作履歴を見る

fixtureは、テスト専用に用意する固定の画面やデータです。今回はHTMLをpage.setContent()でブラウザへ直接読み込むため、Webサーバーは起動しません。

この練習で確認するのは、fixture内のUIとブラウザ操作です。実際の配信経路、ネットワーク、バックエンド、データベースまでを通す本来のEnd-to-End検証ではありません。

使用環境

2026年7月25日時点で、npmのlatest安定版は@playwright/test@1.61.1です。AlphaやBeta版は使いません。

この記事ではPlaywrightが対応するブラウザのうち、Chromiumだけを導入します。

node --version
npm --version

Node.jsとnpmのバージョン番号が表示されることを確認してください。

1. プロジェクトを作る

mkdir playwright-fixture-practice
cd playwright-fixture-practice
npm init -y
npm pkg set type=module
npm pkg set "scripts.test=playwright test"
npm install --save-dev @playwright/test@1.61.1
npx playwright install chromium
mkdir -p fixture tests

Windows PowerShellでは、最後の行の代わりに次を実行します。

New-Item -ItemType Directory -Force fixture, tests

ChromiumはPlaywrightがテスト用に管理するブラウザです。普段使っているGoogle Chromeとは別にダウンロードされます。

2. ローカルfixture画面を作る

fixture/index.htmlを作ります。

<!doctype html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Todo Fixture</title>
    <style>
      body {
        max-width: 40rem;
        margin: 3rem auto;
        padding: 0 1rem;
        font-family: system-ui, sans-serif;
      }
      form {
        display: grid;
        gap: 0.75rem;
      }
      input,
      button {
        padding: 0.75rem;
        font: inherit;
      }
      button {
        cursor: pointer;
      }
    </style>
  </head>
  <body>
    <main>
      <h1>やることリスト</h1>

      <form id="todo-form">
        <label for="todo-title">やること</label>
        <input id="todo-title" name="title" maxlength="100" required />
        <button type="submit">追加</button>
      </form>

      <ul aria-label="やること一覧"></ul>
      <p role="status" aria-live="polite"></p>
    </main>

    <script>
      const form = document.querySelector("#todo-form");
      const input = document.querySelector("#todo-title");
      const list = document.querySelector('[aria-label="やること一覧"]');
      const status = document.querySelector('[role="status"]');

      form.addEventListener("submit", (event) => {
        event.preventDefault();

        const title = input.value.trim();
        if (!title) {
          status.textContent = "やることを入力してください";
          return;
        }

        const item = document.createElement("li");
        item.textContent = title;
        list.append(item);

        form.reset();
        status.textContent = "1件追加しました";
      });
    </script>
  </body>
</html>

labelforと入力欄のidが一致しているため、利用者はラベルを押して入力欄へ移動でき、テストもgetByLabel()で要素を見つけられます。

role="status"aria-live="polite"は、更新されたメッセージを支援技術へ伝えるための指定です。

3. Chromium 1つに設定する

プロジェクト直下にplaywright.config.tsを作ります。

import { defineConfig, devices } from "@playwright/test";

export default defineConfig({
  testDir: "./tests",
  reporter: [
    ["list"],
    ["html", { open: "never" }],
  ],
  use: {
    trace: "on",
  },
  projects: [
    {
      name: "chromium",
      use: {
        ...devices["Desktop Chrome"],
        browserName: "chromium",
      },
    },
  ],
});
  • projectsはChromiumの1件だけです
  • html reporterはplaywright-reportフォルダーへ結果を作ります
  • trace: "on"は操作、DOM snapshot、ネットワークなどを毎回記録します

traceを毎回残すと実行時間と保存容量が増えます。これは1テストだけの学習用設定です。大きなテスト群では、失敗時や再試行時だけ残す設定を検討します。

4. 利用者視点のテストを書く

tests/todo.spec.tsを作ります。

import { readFileSync } from "node:fs";
import { expect, test } from "@playwright/test";

const fixtureHtml = readFileSync(
  new URL("../fixture/index.html", import.meta.url),
  "utf8",
);

test("入力したTodoを一覧へ追加できる", async ({ page }) => {
  await page.setContent(fixtureHtml);

  const titleInput = page.getByLabel("やること");
  await titleInput.fill("Playwrightを練習する");
  await page.getByRole("button", { name: "追加" }).click();

  await expect(page.getByRole("listitem")).toHaveText(
    "Playwrightを練習する",
  );
  await expect(page.getByRole("status")).toHaveText("1件追加しました");
  await expect(titleInput).toHaveValue("");
});

getByLabelとgetByRole

getByLabel("やること")は、画面上のラベルを手がかりに入力欄を探します。

getByRole("button", { name: "追加" })は、アクセシブルな役割と名前でボタンを探します。CSSクラスやHTMLの並び順より、利用者が認識する情報へ近いロケーターです。

web-first assertion

次の形はPlaywrightのweb-first assertionです。

await expect(page.getByRole("status")).toHaveText("1件追加しました");

画面が期待する状態になるまで、制限時間内で自動的に再確認します。要素を取得してすぐ文字列を比較するより、非同期に更新される画面で安定しやすい書き方です。

5. テストを実行する

npm test

次のように1件が成功すれば、Chromiumで入力、クリック、表示確認まで実行できています。

Running 1 test using 1 worker
✓ 1 [chromium] › todo.spec.ts:...
1 passed

テストはpage.setContent()でfixtureを読み込むため、別のターミナルで開発サーバーを起動する必要はありません。

6. HTMLレポートとtraceを見る

テスト後、HTMLレポートを開きます。

npx playwright show-report

レポートで「入力したTodoを一覧へ追加できる」を開き、次を確認します。

  1. Chromiumのテストが合格している
  2. 入力、クリック、3つのassertionが順番に並んでいる
  3. traceを開くリンクがある

traceを開くと、Actionsで操作順、Snapshotで各時点のDOMを確認できます。テストが失敗した時は、どの操作まで成功し、画面がどの状態だったかを追跡できます。

HTMLレポートやtraceには、テスト中の画面内容や通信情報が含まれる場合があります。実サービスで利用する時は、パスワード、トークン、個人情報をテストデータへ入れないでください。

成功確認

次の5点を確認できれば完了です。

  1. Chromiumだけがインストール・実行対象になっている
  2. getByLabelで入力欄を操作している
  3. getByRoleでボタン、list item、statusを特定している
  4. 3つのweb-first assertionが成功する
  5. HTMLレポートからtraceの操作履歴を確認できる

よくあるつまずき

Executable doesn't existと表示される

Playwright本体を入れても、ブラウザは別に導入する必要があります。

npx playwright install chromium

fixtureファイルが見つからない

次の構成になっているか確認します。

playwright-fixture-practice/
├── fixture/
│   └── index.html
├── tests/
│   └── todo.spec.ts
└── playwright.config.ts

テストファイルから見て../fixture/index.htmlにあることが重要です。

getByLabelが要素を見つけられない

HTMLのlabelinputを確認します。

<label for="todo-title">やること</label>
<input id="todo-title" />

foridは同じ値にします。

POSTやデータベースも検証できたと思ってしまう

今回のfixtureはブラウザ内のJavaScriptだけで動きます。ネットワークAPIやデータベースは存在しません。実アプリのE2Eでは、実際に配信されたURLへpage.goto()し、テスト用環境の境界を決める必要があります。

HTMLレポートが作られない

playwright.config.tsreporterhtmlがあるか確認し、設定ファイルがあるフォルダーでnpm testを実行してください。

練習

fixtureへ「完了」チェックボックスを追加する前に、今ある画面のテストを1つだけ強化します。

  1. Todoを追加した後、getByRole("list")の要素数を確認する
  2. もう1件追加する
  3. toHaveCount(2)でlist itemが2件になったことを確認する

ロケーターは引き続きgetByRoleまたはgetByLabelを優先し、CSSクラスへ依存しないようにします。

次のステップ

次は、小さな実アプリをローカルサーバーで起動し、page.goto()でアクセスするテストへ進むと、配信経路を含むE2Eへ近づきます。

認証状態、Page Object Model、API mock、visual regression、複数ブラウザ、CIは、最初の1テストを安定して実行できてから、それぞれ別の学習ゴールとして追加してください。

参考リソース

← 一覧に戻る
PR
PR
PR
PR