Advanced

Claude Code के साथ Playwright E2E

Claude Code का उपयोग करके playwright e2e सीखें। Practical tips और code examples शामिल हैं।

PlaywrightでE2Etestをautomationする

PlaywrightはクロスブラウザsupportのE2Etestframework है।Chromium、Firefox、WebKitのतीनのブラウザエンジンをサポートし、安定したtest実行を実現し है।Claude Codeはtestシナリオの設計 सेpageオブジェクトのbuild तक的確にサポートし है।

pageオブジェクトpattern

Claude Codeにpageオブジェクトの設計を依頼 करें।

> Playwrightでlogインpageのpageオブジェクトを作って。
> errordisplayのconfirm、成功時のredirectconfirmを含めて。
import { Page, Locator, expect } from "@playwright/test";

export class LoginPage {
  readonly page: Page;
  readonly emailInput: Locator;
  readonly passwordInput: Locator;
  readonly submitButton: Locator;
  readonly errorMessage: Locator;
  readonly rememberMeCheckbox: Locator;

  constructor(page: Page) {
    this.page = page;
    this.emailInput = page.getByLabel("メールアドレス");
    this.passwordInput = page.getByLabel("pathワード");
    this.submitButton = page.getByRole("button", { name: "logイン" });
    this.errorMessage = page.getByRole("alert");
    this.rememberMeCheckbox = page.getByLabel("logイン状態を保持");
  }

  async goto() {
    await this.page.goto("/login");
  }

  async login(email: string, password: string) {
    await this.emailInput.fill(email);
    await this.passwordInput.fill(password);
    await this.submitButton.click();
  }

  async expectError(message: string) {
    await expect(this.errorMessage).toContainText(message);
  }

  async expectRedirectTo(path: string) {
    await expect(this.page).toHaveURL(new RegExp(path));
  }
}

testシナリオのimplementation

pageオブジェクトを使ったtestの記述 है।

import { test, expect } from "@playwright/test";
import { LoginPage } from "./pages/login-page";
import { DashboardPage } from "./pages/dashboard-page";

test.describe("authenticationフロー", () => {
  let loginPage: LoginPage;

  test.beforeEach(async ({ page }) => {
    loginPage = new LoginPage(page);
    await loginPage.goto();
  });

  test("有効なauthentication情報でlogインできる", async ({ page }) => {
    await loginPage.login("[email protected]", "password123");
    await loginPage.expectRedirectTo("/dashboard");

    const dashboard = new DashboardPage(page);
    await expect(dashboard.welcomeMessage).toContainText(" तरहこそ");
  });

  test("無効なpathワードでerrorがdisplayされる", async () => {
    await loginPage.login("[email protected]", "wrong-password");
    await loginPage.expectError("メールアドレスまたはpathワードが正しくありません");
  });

  test("空のformでvalidationerrorがdisplayされる", async () => {
    await loginPage.submitButton.click();
    await expect(loginPage.emailInput).toHaveAttribute("aria-invalid", "true");
  });
});

authentication状態の共有

testबीचでauthentication状態を共有して実行速度を向ऊपरさせるpattern है।

// auth.setup.ts
import { test as setup, expect } from "@playwright/test";

const authFile = "playwright/.auth/user.json";

setup("authentication", async ({ page }) => {
  await page.goto("/login");
  await page.getByLabel("メールアドレス").fill("[email protected]");
  await page.getByLabel("pathワード").fill("password123");
  await page.getByRole("button", { name: "logイン" }).click();

  await page.waitForURL("/dashboard");
  await expect(page.getByText(" तरहこそ")).toBeVisible();

  await page.context().storageState({ path: authFile });
});

// playwright.config.ts
import { defineConfig } from "@playwright/test";

export default defineConfig({
  projects: [
    { name: "setup", testMatch: /.*\.setup\.ts/ },
    {
      name: "chromium",
      use: {
        storageState: "playwright/.auth/user.json",
      },
      dependencies: ["setup"],
    },
  ],
});

APIモックとnetwork制御

testमेंのAPIrequestをインターセプトするpattern है।

test("APIerror時にerror画面がdisplayされる", async ({ page }) => {
  await page.route("**/api/users", (route) =>
    route.fulfill({
      status: 500,
      contentType: "application/json",
      body: JSON.stringify({ error: "Internal Server Error" }),
    })
  );

  await page.goto("/users");
  await expect(page.getByText("dataのfetchに失敗しました")).toBeVisible();
  await expect(page.getByRole("button", { name: "再試行" })).toBeVisible();
});

test("遅いnetworkでローディングdisplayされる", async ({ page }) => {
  await page.route("**/api/users", async (route) => {
    await new Promise((resolve) => setTimeout(resolve, 3000));
    await route.continue();
  });

  await page.goto("/users");
  await expect(page.getByText("読み込みमें")).toBeVisible();
});

ビジュアルリグレッションtest

スクリーンショット比較で視覚的な変更を検出し है।

test("dashboard画面のビジュアルcheck", async ({ page }) => {
  await page.goto("/dashboard");
  await page.waitForLoadState("networkidle");

  await expect(page).toHaveScreenshot("dashboard.png", {
    maxDiffPixelRatio: 0.01,
    animations: "disabled",
  });
});

test("モバイルdisplayのビジュアルcheck", async ({ page }) => {
  await page.setViewportSize({ width: 375, height: 812 });
  await page.goto("/dashboard");

  await expect(page).toHaveScreenshot("dashboard-mobile.png");
});

CI/CDでのsettings

GitHub Actionsでの実行settings है।

# .github/workflows/e2e.yml
name: E2E Tests
on: [push, pull_request]

jobs:
  e2e:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npx playwright install --with-deps
      - run: npx playwright test
      - uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: playwright-report
          path: playwright-report/

Summary

Playwrightはクロスブラウザsupportの安定したE2Etest環境を提供し है।Claude Code का लाभ उठाकर、pageオブジェクト設計、authenticationフロー、ビジュアルtest आदिのcomplexなtestシナリオもefficientlybuildpossible है।

ユニットtestの高度な手法はVitestऊपर級テクニックを、APIモックके details के लिएMSW APIモックutilizationガイドをदेखें。Playwrightofficial documentationもconfirmしておきましょう。

#Claude Code #Playwright #E2Etest #自動test #quality assurance