T-CREATOR

Playwright のインストールから初テストまで完全ガイド

Playwright のインストールから初テストまで完全ガイド

E2E テスト自動化を始めたいけれど、「どこから手をつけて良いかわからない」「環境構築で躓いてしまう」という悩みを抱えている方も多いのではないでしょうか?

Playwright は現代的な Web アプリケーションのテスト自動化において最も注目されているツールの一つですが、初心者にとって最初の一歩を踏み出すのは意外と困難です。しかし、適切な手順を踏めば、驚くほど簡単に環境構築から初回テストの実行まで完了できます。

本記事では、完全にゼロの状態から Playwright を使った最初のテストを実行するまでの全工程を、実際のコマンドとスクリーンショットを交えながら詳しく解説します。この記事を読み終える頃には、あなたも自信を持って Playwright でテストを書けるようになっているでしょう。

環境準備と前提条件の確認

まず、Playwright を導入する前に必要な環境を整えましょう。適切な準備をすることで、後のトラブルを避けることができます。

Node.js のインストールと最適なバージョン選択

Playwright は Node.js 上で動作するため、まず Node.js のインストールが必要です。

推奨バージョンの確認

bash# 現在のNode.jsバージョンを確認
node --version

# npmのバージョンを確認
npm --version

Node.js の推奨バージョン

バージョン対応状況推奨度
Node.js 16.xサポート
Node.js 18.x推奨
Node.js 20.x最新対応

Node.js がインストールされていない場合

bash# Node Version Manager (nvm) を使用する場合
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash

# 最新のLTSバージョンをインストール
nvm install --lts
nvm use --lts

# インストール確認
node --version
npm --version

Windows の場合

  1. Node.js 公式サイト から LTS バージョンをダウンロード
  2. インストーラーを実行してセットアップ
  3. コマンドプロンプトまたは PowerShell で動作確認

開発エディタの準備と推奨設定

VS Code の設定(推奨)

json// .vscode/settings.json
{
  "typescript.preferences.includePackageJsonAutoImports": "on",
  "typescript.suggest.autoImports": true,
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.organizeImports": true
  }
}

推奨拡張機能

json// .vscode/extensions.json
{
  "recommendations": [
    "ms-playwright.playwright",
    "bradlc.vscode-tailwindcss",
    "esbenp.prettier-vscode",
    "ms-vscode.vscode-typescript-next"
  ]
}

Playwright 拡張機能の利点

  • テストの実行とデバッグが GUI で可能
  • テストケースの生成機能
  • スクリーンショットやトレースの確認
  • ブレークポイントでの詳細デバッグ

OS 別の事前準備項目

Windows

powershell# 開発者モードの有効化(推奨)
# Windows設定 > 更新とセキュリティ > 開発者向け > 開発者モード

# Windows Subsystem for Linux (WSL) の設定(オプション)
wsl --install

# Git のインストール確認
git --version

macOS

bash# Xcode Command Line Tools のインストール
xcode-select --install

# Homebrew のインストール(推奨)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# Git のインストール確認
git --version

Linux (Ubuntu/Debian)

bash# 必要なパッケージのインストール
sudo apt update
sudo apt install -y curl wget git

# 追加ライブラリのインストール
sudo apt install -y libnss3-dev libgconf-2-4 libxss1 libappindicator1 libindicator7

プロジェクトディレクトリの作成

新規プロジェクトの初期化

bash# プロジェクトディレクトリの作成
mkdir my-playwright-project
cd my-playwright-project

# package.jsonの初期化
npm init -y

# 基本的なディレクトリ構造の作成
mkdir tests
mkdir test-results
mkdir screenshots

package.json の基本設定

json{
  "name": "my-playwright-project",
  "version": "1.0.0",
  "description": "Playwright テストプロジェクト",
  "main": "index.js",
  "scripts": {
    "test": "playwright test",
    "test:headed": "playwright test --headed",
    "test:debug": "playwright test --debug",
    "report": "playwright show-report"
  },
  "keywords": ["playwright", "testing", "e2e"],
  "author": "Your Name",
  "license": "MIT"
}

Playwright のインストール手順

環境の準備が完了したら、実際に Playwright をインストールしていきます。

npm/yarn を使った基本インストール

npm を使用する場合

bash# Playwrightのインストール
npm install -D @playwright/test

# TypeScriptサポート(推奨)
npm install -D typescript

# 設定ファイルの生成
npx playwright install

Yarn を使用する場合

bash# Playwrightのインストール
yarn add -D @playwright/test

# TypeScriptサポート
yarn add -D typescript

# 設定ファイルの生成
yarn playwright install

インストール内容の確認

bash# インストールされたバージョンの確認
npx playwright --version

# 利用可能なコマンドの確認
npx playwright --help

ブラウザバイナリの自動インストール

Playwright は専用のブラウザバイナリを使用します。

bash# 全ブラウザのインストール
npx playwright install

# 特定のブラウザのみインストール
npx playwright install chromium
npx playwright install firefox
npx playwright install webkit

# システム依存関係のインストール(Linux)
npx playwright install-deps

インストール進行状況の例

scssDownloading Chromium 109.0.5414.46 (playwright build v1045) - 137.6 Mb [====================] 100%
Downloading Firefox 108.0.2 (playwright build v1371) - 78.9 Mb [====================] 100%
Downloading Webkit 16.4 (playwright build v1715) - 61.9 Mb [====================] 100%

インストール完了の確認方法

基本動作の確認

bash# Playwrightのバージョン確認
npx playwright --version

# ブラウザが正常にインストールされているか確認
npx playwright install --dry-run

簡単な動作テスト

bash# 設定ファイルの生成とサンプルテストの作成
npx playwright init

# サンプルテストの実行
npx playwright test

正常なインストールの出力例

bashRunning 6 tests using 1 worker

✓ tests/example.spec.ts:3:1 › has title (chromium)
✓ tests/example.spec.ts:3:1 › has title (firefox)
✓ tests/example.spec.ts:3:1 › has title (webkit)
✓ tests/example.spec.ts:8:1 › get started link (chromium)
✓ tests/example.spec.ts:8:1 › get started link (firefox)
✓ tests/example.spec.ts:8:1 › get started link (webkit)

6 passed (15s)

よくあるインストールエラーと対処法

エラー 1: 権限不足

bash# エラー内容
Error: EACCES: permission denied

# 対処法:権限の確認と修正
sudo chown -R $(whoami) ~/.npm
npm cache clean --force

エラー 2: ブラウザダウンロード失敗

bash# エラー内容
Error: Failed to download browser

# 対処法:手動でのブラウザインストール
npx playwright install --with-deps chromium

# または、プロキシ設定
export HTTPS_PROXY=your-proxy-url
npx playwright install

エラー 3: 依存関係の問題(Linux)

bash# エラー内容
Error: Host system is missing dependencies

# 対処法:システム依存関係のインストール
sudo npx playwright install-deps

# 個別パッケージのインストール
sudo apt-get install libnss3 libnspr4 libatk-bridge2.0-0

エラー 4: Node.js バージョン不適合

bash# エラー内容
Error: Node.js version 14.x is not supported

# 対処法:Node.jsのアップデート
nvm install 18
nvm use 18
npm install -D @playwright/test

初期設定とプロジェクト構成

インストールが完了したら、プロジェクトの設定を行います。

playwright.config.js の基本設定

基本設定ファイルの作成

javascript// playwright.config.js
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  // テストディレクトリ
  testDir: './tests',

  // テストファイルのパターン
  testMatch: '**/*.spec.{js,ts}',

  // 並列実行の設定
  fullyParallel: true,

  // CI環境での設定
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,

  // レポーター設定
  reporter: [
    ['html'],
    ['json', { outputFile: 'test-results.json' }],
  ],

  // 全テストで共通の設定
  use: {
    // ベースURL
    baseURL: 'http://localhost:3000',

    // トレース記録
    trace: 'on-first-retry',

    // スクリーンショット
    screenshot: 'only-on-failure',

    // 動画録画
    video: 'retain-on-failure',

    // タイムアウト設定
    actionTimeout: 30000,
    navigationTimeout: 30000,
  },

  // ブラウザ設定
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
    {
      name: 'firefox',
      use: { ...devices['Desktop Firefox'] },
    },
    {
      name: 'webkit',
      use: { ...devices['Desktop Safari'] },
    },
  ],

  // ローカル開発サーバーの設定
  webServer: {
    command: 'npm run dev',
    url: 'http://localhost:3000',
    reuseExistingServer: !process.env.CI,
  },
});

テストディレクトリ構造の作成

推奨ディレクトリ構造

perlmy-playwright-project/
├── tests/
│   ├── auth/                 # 認証関連のテスト
│   ├── e2e/                  # エンドツーエンドテスト
│   ├── integration/          # 統合テスト
│   └── fixtures/             # テストフィクスチャ
├── test-results/             # テスト結果
├── playwright-report/        # HTMLレポート
├── screenshots/              # スクリーンショット
├── playwright.config.js     # Playwright設定
└── package.json

ディレクトリ作成コマンド

bash# テスト関連ディレクトリの作成
mkdir -p tests/{auth,e2e,integration,fixtures}
mkdir -p test-results
mkdir -p screenshots

# サンプルファイルの作成
touch tests/e2e/homepage.spec.js
touch tests/auth/login.spec.js

最初の設定ファイル作成

環境変数設定ファイル

bash# .env
BASE_URL=http://localhost:3000
TEST_USER_EMAIL=test@example.com
TEST_USER_PASSWORD=password123
API_BASE_URL=http://localhost:3001/api

TypeScript 設定(推奨)

json// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "types": ["node", "@playwright/test"]
  },
  "include": ["tests/**/*"],
  "exclude": ["node_modules"]
}

Git 無視設定

gitignore# .gitignore
node_modules/
test-results/
playwright-report/
playwright/.cache/
screenshots/
videos/
.env.local
.DS_Store

開発環境の最適化

VS Code の設定

json// .vscode/settings.json
{
  "playwright.reuseBrowser": true,
  "playwright.showTrace": true,
  "typescript.preferences.includePackageJsonAutoImports": "on"
}

npm scripts の追加

json// package.json の scripts セクション
{
  "scripts": {
    "test": "playwright test",
    "test:headed": "playwright test --headed",
    "test:ui": "playwright test --ui",
    "test:debug": "playwright test --debug",
    "test:chromium": "playwright test --project=chromium",
    "test:firefox": "playwright test --project=firefox",
    "test:webkit": "playwright test --project=webkit",
    "report": "playwright show-report",
    "codegen": "playwright codegen localhost:3000"
  }
}

最初のテストケース作成

設定が完了したら、実際にテストケースを作成してみましょう。

シンプルな画面遷移テスト

基本的なページアクセステスト

javascript// tests/e2e/homepage.spec.js
import { test, expect } from '@playwright/test';

test.describe('ホームページのテスト', () => {
  test('ページが正常に表示される', async ({ page }) => {
    // ページにアクセス
    await page.goto('/');

    // ページタイトルの確認
    await expect(page).toHaveTitle(/ホーム/);

    // ページが完全に読み込まれるまで待機
    await page.waitForLoadState('networkidle');

    // メインコンテンツが表示されているか確認
    await expect(page.locator('main')).toBeVisible();
  });

  test('ナビゲーションリンクが機能する', async ({
    page,
  }) => {
    await page.goto('/');

    // ナビゲーションリンクをクリック
    await page.click('nav a[href="/about"]');

    // URLが変更されたことを確認
    await expect(page).toHaveURL('/about');

    // About ページのコンテンツを確認
    await expect(page.locator('h1')).toContainText('About');
  });
});

要素操作の基本パターン

様々な要素操作の例

javascript// tests/e2e/interactions.spec.js
import { test, expect } from '@playwright/test';

test.describe('要素操作のテスト', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/contact');
  });

  test('入力フィールドの操作', async ({ page }) => {
    // テキスト入力
    await page.fill('#name', '山田太郎');
    await page.fill('#email', 'yamada@example.com');

    // テキストエリアへの入力
    await page.fill(
      'textarea[name="message"]',
      'テストメッセージです。'
    );

    // 入力値の確認
    await expect(page.locator('#name')).toHaveValue(
      '山田太郎'
    );
    await expect(page.locator('#email')).toHaveValue(
      'yamada@example.com'
    );
  });

  test('選択要素の操作', async ({ page }) => {
    // セレクトボックスの選択
    await page.selectOption('#category', '一般');

    // ラジオボタンの選択
    await page.check(
      'input[name="priority"][value="high"]'
    );

    // チェックボックスの操作
    await page.check('#newsletter');

    // 選択状態の確認
    await expect(page.locator('#category')).toHaveValue(
      '一般'
    );
    await expect(
      page.locator('input[name="priority"][value="high"]')
    ).toBeChecked();
    await expect(page.locator('#newsletter')).toBeChecked();
  });

  test('ボタンクリックと操作', async ({ page }) => {
    // 通常のクリック
    await page.click('#submit-button');

    // ダブルクリック
    await page.dblclick('#edit-button');

    // 右クリック
    await page.click('#context-menu', { button: 'right' });

    // ホバー
    await page.hover('#tooltip-trigger');

    // ツールチップの表示確認
    await expect(page.locator('#tooltip')).toBeVisible();
  });
});

アサーション(検証)の書き方

様々な検証パターン

javascript// tests/e2e/assertions.spec.js
import { test, expect } from '@playwright/test';

test.describe('アサーションのテスト', () => {
  test('テキスト内容の検証', async ({ page }) => {
    await page.goto('/');

    // 完全一致
    await expect(page.locator('h1')).toHaveText('ようこそ');

    // 部分一致
    await expect(
      page.locator('.description')
    ).toContainText('テスト');

    // 正規表現での一致
    await expect(page.locator('.version')).toHaveText(
      /v\d+\.\d+\.\d+/
    );
  });

  test('要素の状態検証', async ({ page }) => {
    await page.goto('/form');

    // 表示・非表示の確認
    await expect(
      page.locator('#visible-element')
    ).toBeVisible();
    await expect(
      page.locator('#hidden-element')
    ).toBeHidden();

    // 有効・無効の確認
    await expect(
      page.locator('#enabled-button')
    ).toBeEnabled();
    await expect(
      page.locator('#disabled-button')
    ).toBeDisabled();

    // フォーカスの確認
    await page.focus('#name-input');
    await expect(page.locator('#name-input')).toBeFocused();
  });

  test('属性の検証', async ({ page }) => {
    await page.goto('/links');

    // 属性値の確認
    await expect(
      page.locator('#external-link')
    ).toHaveAttribute('href', 'https://example.com');
    await expect(
      page.locator('#main-link')
    ).toHaveAttribute('target', '_blank');

    // CSS クラスの確認
    await expect(page.locator('.active-tab')).toHaveClass(
      'tab active'
    );
    await expect(page.locator('.error-field')).toHaveClass(
      /error/
    );
  });

  test('数値とカウントの検証', async ({ page }) => {
    await page.goto('/list');

    // 要素数の確認
    await expect(page.locator('.list-item')).toHaveCount(5);

    // リストが空でないことの確認
    await expect(
      page.locator('.list-item')
    ).not.toHaveCount(0);

    // 範囲での確認
    const itemCount = await page
      .locator('.list-item')
      .count();
    expect(itemCount).toBeGreaterThan(0);
    expect(itemCount).toBeLessThanOrEqual(10);
  });
});

テスト実行とレポート確認

基本的なテスト実行

bash# 全テストの実行
npm run test

# 特定のテストファイルのみ実行
npx playwright test homepage.spec.js

# 特定のブラウザでのみ実行
npm run test:chromium

# ヘッドフルモードでの実行(ブラウザが表示される)
npm run test:headed

# デバッグモードでの実行
npm run test:debug

レポートの確認

bash# HTMLレポートの表示
npm run report

# テスト結果をJSONで出力
npx playwright test --reporter=json

実行結果の例

bashRunning 6 tests using 3 workers

✓ tests/e2e/homepage.spec.js:4:3 › ページが正常に表示される (chromium) (2s)
✓ tests/e2e/homepage.spec.js:4:3 › ページが正常に表示される (firefox) (3s)
✓ tests/e2e/homepage.spec.js:4:3 › ページが正常に表示される (webkit) (2s)
✓ tests/e2e/homepage.spec.js:13:3 › ナビゲーションリンクが機能する (chromium) (1s)
✓ tests/e2e/homepage.spec.js:13:3 › ナビゲーションリンクが機能する (firefox) (2s)
✓ tests/e2e/homepage.spec.js:13:3 › ナビゲーションリンクが機能する (webkit) (2s)

6 passed (12s)

To open last HTML report run:
  npx playwright show-report

実践的なテストシナリオの実装

基本的なテストケースが作成できたら、より実践的なシナリオを実装してみましょう。

フォーム入力とボタンクリック

お問い合わせフォームのテスト

javascript// tests/e2e/contact-form.spec.js
import { test, expect } from '@playwright/test';

test.describe('お問い合わせフォーム', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/contact');
  });

  test('正常なフォーム送信', async ({ page }) => {
    // フォームデータの入力
    await page.fill('#name', '田中花子');
    await page.fill('#email', 'tanaka@example.com');
    await page.selectOption('#subject', 'inquiry');
    await page.fill(
      '#message',
      'お問い合わせの内容です。詳細な説明をここに記載します。'
    );

    // プライバシーポリシーに同意
    await page.check('#privacy-agreement');

    // 送信ボタンのクリック
    await page.click('#submit-button');

    // 成功メッセージの確認
    await expect(
      page.locator('#success-message')
    ).toBeVisible();
    await expect(
      page.locator('#success-message')
    ).toContainText('送信が完了しました');

    // 確認ページへのリダイレクト
    await expect(page).toHaveURL('/contact/success');
  });

  test('必須項目のバリデーション', async ({ page }) => {
    // 必須項目を空のまま送信
    await page.click('#submit-button');

    // エラーメッセージの確認
    await expect(page.locator('#name-error')).toBeVisible();
    await expect(page.locator('#name-error')).toContainText(
      '名前は必須項目です'
    );

    await expect(
      page.locator('#email-error')
    ).toBeVisible();
    await expect(
      page.locator('#email-error')
    ).toContainText('メールアドレスは必須項目です');
  });

  test('メールアドレス形式のバリデーション', async ({
    page,
  }) => {
    // 不正な形式のメールアドレスを入力
    await page.fill('#email', 'invalid-email');
    await page.fill('#name', '山田太郎'); // 他の必須項目も入力
    await page.click('#submit-button');

    // メールアドレス形式エラーの確認
    await expect(
      page.locator('#email-error')
    ).toBeVisible();
    await expect(
      page.locator('#email-error')
    ).toContainText(
      '正しいメールアドレス形式で入力してください'
    );
  });
});

複数ページにまたがるテスト

ショッピングカートのテスト

javascript// tests/e2e/shopping-cart.spec.js
import { test, expect } from '@playwright/test';

test.describe('ショッピングカート機能', () => {
  test('商品追加から購入完了まで', async ({ page }) => {
    // 商品一覧ページから開始
    await page.goto('/products');

    // 商品を選択
    await page.click(
      '.product-card:first-child .product-link'
    );

    // 商品詳細ページで数量を指定
    await page.selectOption('#quantity', '2');

    // カートに追加
    await page.click('#add-to-cart');

    // カート追加成功の確認
    await expect(
      page.locator('#cart-notification')
    ).toBeVisible();
    await expect(page.locator('#cart-count')).toContainText(
      '2'
    );

    // カートページに移動
    await page.click('#cart-link');
    await expect(page).toHaveURL('/cart');

    // カート内容の確認
    await expect(page.locator('.cart-item')).toHaveCount(1);
    await expect(
      page.locator('.cart-item .quantity')
    ).toContainText('2');

    // チェックアウトページに進む
    await page.click('#checkout-button');
    await expect(page).toHaveURL('/checkout');

    // 配送情報の入力
    await page.fill('#shipping-name', '佐藤次郎');
    await page.fill(
      '#shipping-address',
      '東京都渋谷区1-1-1'
    );
    await page.fill('#shipping-phone', '090-1234-5678');

    // 支払い方法の選択
    await page.check('#payment-credit-card');
    await page.fill('#card-number', '4111111111111111');
    await page.fill('#card-expiry', '12/25');
    await page.fill('#card-cvc', '123');

    // 注文確定
    await page.click('#place-order');

    // 注文完了ページの確認
    await expect(page).toHaveURL(/\/order\/complete/);
    await expect(
      page.locator('#order-success')
    ).toBeVisible();
    await expect(
      page.locator('#order-number')
    ).toBeVisible();
  });
});

動的コンテンツの待機処理

API からデータを取得する画面のテスト

javascript// tests/e2e/dynamic-content.spec.js
import { test, expect } from '@playwright/test';

test.describe('動的コンテンツのテスト', () => {
  test('データ読み込み完了の待機', async ({ page }) => {
    await page.goto('/dashboard');

    // ローディング表示の確認
    await expect(
      page.locator('#loading-spinner')
    ).toBeVisible();

    // データ読み込み完了まで待機
    await page.waitForSelector('#loading-spinner', {
      state: 'hidden',
    });

    // コンテンツが表示されることを確認
    await expect(
      page.locator('#dashboard-content')
    ).toBeVisible();
    await expect(page.locator('.data-card')).toHaveCount(4);
  });

  test('リアルタイムデータの更新', async ({ page }) => {
    await page.goto('/live-data');

    // 初期データの確認
    const initialValue = await page
      .locator('#current-value')
      .textContent();

    // データ更新を待機(最大30秒)
    await page.waitForFunction(
      (initial) => {
        const current = document.querySelector(
          '#current-value'
        ).textContent;
        return current !== initial;
      },
      initialValue,
      { timeout: 30000 }
    );

    // 更新されたデータの確認
    const updatedValue = await page
      .locator('#current-value')
      .textContent();
    expect(updatedValue).not.toBe(initialValue);
  });

  test('無限スクロールのテスト', async ({ page }) => {
    await page.goto('/infinite-scroll');

    // 初期アイテム数の確認
    let itemCount = await page
      .locator('.scroll-item')
      .count();
    expect(itemCount).toBeGreaterThan(0);

    // ページ下部までスクロール
    await page.evaluate(() => {
      window.scrollTo(0, document.body.scrollHeight);
    });

    // 新しいアイテムが読み込まれるまで待機
    await page.waitForFunction((initialCount) => {
      return (
        document.querySelectorAll('.scroll-item').length >
        initialCount
      );
    }, itemCount);

    // アイテム数が増加したことを確認
    const newItemCount = await page
      .locator('.scroll-item')
      .count();
    expect(newItemCount).toBeGreaterThan(itemCount);
  });
});

スクリーンショット活用

ビジュアルテストの実装

javascript// tests/e2e/visual-testing.spec.js
import { test, expect } from '@playwright/test';

test.describe('ビジュアルテスト', () => {
  test('ページ全体のスクリーンショット', async ({
    page,
  }) => {
    await page.goto('/');

    // ページ全体のスクリーンショット
    await expect(page).toHaveScreenshot(
      'homepage-full.png'
    );
  });

  test('特定要素のスクリーンショット', async ({ page }) => {
    await page.goto('/pricing');

    // 料金表のスクリーンショット
    await expect(
      page.locator('#pricing-table')
    ).toHaveScreenshot('pricing-table.png');
  });

  test('モバイル表示のスクリーンショット', async ({
    page,
  }) => {
    // ビューポートをモバイルサイズに設定
    await page.setViewportSize({ width: 375, height: 667 });
    await page.goto('/');

    // モバイル表示のスクリーンショット
    await expect(page).toHaveScreenshot(
      'homepage-mobile.png'
    );
  });

  test('ホバー状態のスクリーンショット', async ({
    page,
  }) => {
    await page.goto('/buttons');

    // ボタンにホバー
    await page.hover('#primary-button');

    // ホバー状態のスクリーンショット
    await expect(
      page.locator('#primary-button')
    ).toHaveScreenshot('button-hover.png');
  });

  test('エラー状態の記録', async ({ page }) => {
    await page.goto('/form');

    // エラーを発生させる
    await page.fill('#email', 'invalid-email');
    await page.click('#submit');

    // エラーメッセージが表示された状態をキャプチャ
    await expect(
      page.locator('#form-container')
    ).toHaveScreenshot('form-error-state.png');
  });
});

スクリーンショット設定の調整

javascript// playwright.config.js(一部抜粋)
export default defineConfig({
  use: {
    // スクリーンショットの設定
    screenshot: {
      mode: 'only-on-failure',
      fullPage: true,
    },
  },

  projects: [
    {
      name: 'visual-tests',
      use: {
        ...devices['Desktop Chrome'],
        // ビジュアルテスト用の設定
        screenshot: 'always',
        video: 'retain-on-failure',
      },
    },
  ],
});

まとめ

本記事では、Playwright のインストールから初回テストの実行まで、段階的に実践的な手順を解説しました。

習得した内容の振り返り

段階内容重要なポイント
環境準備Node.js インストール、エディタ設定推奨バージョンの確認
インストールPlaywright とブラウザの導入エラー対処法の理解
初期設定設定ファイルとディレクトリ構造プロジェクト規模に応じた構成
基本テスト画面遷移と要素操作アサーションの適切な使用
実践テスト複合シナリオと動的コンテンツ実際の使用パターンの理解

次のステップへの提案

  1. Page Object Model の導入: より保守性の高いテストコード構造の学習
  2. CI/CD 統合: GitHub Actions や他の CI サービスとの連携
  3. API テスト: REST API エンドポイントのテスト自動化
  4. パフォーマンステスト: ページ読み込み速度の監視とテスト

継続的な学習のために

  • 公式ドキュメントの定期的な確認
  • コミュニティでの情報収集
  • 実際のプロジェクトでの継続的な実践
  • 新機能やベストプラクティスの追跡

Playwright を使ったテスト自動化は、最初の一歩さえ踏み出せば、非常に強力で効率的なツールとして活用できます。本記事で学んだ基礎を土台として、ぜひ継続的にスキルを向上させていってください。

テスト自動化は一朝一夕で完璧になるものではありませんが、小さく始めて段階的に改善していくことで、確実に価値のあるテストスイートを構築できるでしょう。

関連リンク