Advanced

Playwright E2E dengan Claude Code

Pelajari tentang playwright e2e menggunakan Claude Code. Dilengkapi tips praktis dan contoh kode.

PlaywrightでE2Etestをotomatisasi

Playwright クロスbrowserdukungan E2Etestframework.Chromium、Firefox、WebKit 3つ browserエンジン サポートし、安定 test実行 実現.Claude Code testシナリオ 設計 dari halamanobjek pembangunanま 的確 サポート.

halamanobjekpola

Claude Code halamanobjek 設計 依頼し.

> Playwright dengan loginhalaman halamanobjek buatkan.
> errortampilan konfirmasi、berhasil時 リダイレクトkonfirmasi 含めて。
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("パスワード");
    this.submitButton = page.getByRole("button", { name: "login" });
    this.errorMessage = page.getByRole("alert");
    this.rememberMeCheckbox = page.getByLabel("login状態 保持");
  }

  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));
  }
}

implementasi testシナリオ

halamanobjek 使ったtest 記述.

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

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

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

  test("efektifな認証情報 login きる", async ({ page }) => {
    await loginPage.login("[email protected]", "password123");
    await loginPage.expectRedirectTo("/dashboard");

    const dashboard = new DashboardPage(page);
    await expect(dashboard.welcomeMessage).toContainText("ようこそ");
  });

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

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

berbagi 認証状態

test間 認証状態 berbagi 実行速度 向上させるpola.

// 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("パスワード").fill("password123");
  await page.getByRole("button", { name: "login" }).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"],
    },
  ],
});

APImockとネットワーク制御

test中 APIrequest インターセプト pola.

test("APIerror時 error画面 tampilanされる", 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("データ pengambilan gagalしま")).toBeVisible();
  await expect(page.getByRole("button", { name: "retry" })).toBeVisible();
});

test("遅いネットワーク ローディングtampilanされる", 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("loading中")).toBeVisible();
});

Visual Regression Testing

スクリーンショット比較 視覚的な変更 検出.

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

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

test("mobiletampilan ビジュアルチェック", async ({ page }) => {
  await page.setViewportSize({ width: 375, height: 812 });
  await page.goto("/dashboard");

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

pengaturan CI/CD

GitHub Actions 実行pengaturan.

# .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 クロスbrowserdukungan 安定 E2Etest環境 penyediaan.Claude Code pemanfaatanすれば、halamanobjek設計、認証フロー、ビジュアルtest dll. kompleksなtestシナリオ juga efisien pembangunandimungkinkan.

ユニットtest 高度な手法 Vitest上級テクニック 、APImock 詳細 MSW APImockpemanfaatanpanduan silakan lihat.Playwright公式dokumen juga konfirmasi おき.

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