Playwright E2E:Claude Code 实战指南
了解playwright e2e:Claude Code 实战. 包含实用技巧和代码示例。
PlaywrightでE2E 测试を自动化する
Playwrightはクロス浏览器支持のE2E 测试框架です。Chromium、Firefox、WebKitの3つの浏览器エンジンをサポートし、安定した测试実行を実現します。Claude Code 测试シナリオの设计から页面对象の构建まで的確にサポートします。
页面对象パターン
让 Claude Code页面对象の设计を依頼吧。
> Playwrightで日志イン页面の页面对象を作って。
> 错误显示の确认、成功時のリダイレクト确认を含めて。
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: "ログイン" });
this.errorMessage = page.getByRole("alert");
this.rememberMeCheckbox = page.getByLabel("ログイン状態を保持");
}
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));
}
}
测试シナリオの实现
页面对象使用…的测试の記述です。
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("有効な認証情報でログインできる", async ({ page }) => {
await loginPage.login("admin@example.com", "password123");
await loginPage.expectRedirectTo("/dashboard");
const dashboard = new DashboardPage(page);
await expect(dashboard.welcomeMessage).toContainText("ようこそ");
});
test("無効なパスワードでエラーが表示される", async () => {
await loginPage.login("admin@example.com", "wrong-password");
await loginPage.expectError("メールアドレスまたはパスワードが正しくありません");
});
test("空のフォームでバリデーションエラーが表示される", async () => {
await loginPage.submitButton.click();
await expect(loginPage.emailInput).toHaveAttribute("aria-invalid", "true");
});
});
认证状態の共有
测试間で认证状態を共有して実行速度を向上させるパターンです。
// 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("test@example.com");
await page.getByLabel("パスワード").fill("password123");
await page.getByRole("button", { name: "ログイン" }).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と网络制御
测试中のAPI请求をインターセプトするパターンです。
test("APIエラー時にエラー画面が表示される", 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("データの取得に失敗しました")).toBeVisible();
await expect(page.getByRole("button", { name: "再試行" })).toBeVisible();
});
test("遅いネットワークでローディング表示される", 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("ダッシュボード画面のビジュアルチェック", async ({ page }) => {
await page.goto("/dashboard");
await page.waitForLoadState("networkidle");
await expect(page).toHaveScreenshot("dashboard.png", {
maxDiffPixelRatio: 0.01,
animations: "disabled",
});
});
test("モバイル表示のビジュアルチェック", async ({ page }) => {
await page.setViewportSize({ width: 375, height: 812 });
await page.goto("/dashboard");
await expect(page).toHaveScreenshot("dashboard-mobile.png");
});
CI/CDでの配置
GitHub Actionsでの実行配置です。
# .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/
总结
Playwrightはクロス浏览器支持の安定したE2E 测试環境を提供します。Claude Codeを活用すれば、页面对象设计、认证フロー、ビジュアル测试などの複雑な测试シナリオも高效地构建是可能的。
单元测试の高度な手法はVitest上級テクニックを、APIMock的详细信息请参阅MSW APIMock活用指南。Playwright官方文档也建议确认一下。
本文作者
Masa
深度使用 Claude Code 的工程师。运营 claudecode-lab.com——一个涵盖 10 种语言、超过 2,000 页内容的科技媒体。
相关文章
Claude Code Agent SDK入门 ― 快速构建自主智能代理
学习如何使用Claude Code Agent SDK构建自主AI代理。涵盖环境搭建、工具定义和多步执行,附带实践代码示例。
Claude Code 上下文管理技巧完全指南
详解如何最大限度地利用 Claude Code 的上下文窗口。涵盖 Token 优化、对话分割和 CLAUDE.md 的使用方法。
Claude Code Hooks 完全指南:自动格式化、自动测试等实用配置
详解如何通过 Claude Code Hooks 实现自动格式化和自动测试。包含实际配置示例和真实使用场景。