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("[email protected]", "password123");
await loginPage.expectRedirectTo("/dashboard");
const dashboard = new DashboardPage(page);
await expect(dashboard.welcomeMessage).toContainText("ようこそ");
});
test("無効なパスワードでエラーが表示される", async () => {
await loginPage.login("[email protected]", "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("[email protected]");
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"],
},
],
});
API모크と네트워크制御
테스트中の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上級テクニックを、API모크의 상세 정보는MSW API모크활용가이드를 참고하세요.Playwright공식 문서도 확인해 두세요.
Related Posts
Claude Code MCP Server 설정 및 실전 활용 가이드
Claude Code의 MCP Server 기능을 종합적으로 소개합니다. 외부 도구 연결, 서버 설정, 실전 통합 사례까지 한 번에 알아보세요.
Claude Code Hooks 완전 정복: 자동 포맷팅, 자동 테스트 설정법
Claude Code Hooks로 자동 포맷팅과 자동 테스트를 설정하는 방법을 알아봅니다. 실용적인 설정 예제와 실전 활용 사례를 포함합니다.
CLAUDE.md 작성 완벽 가이드: 프로젝트 설정 베스트 프랙티스
효과적인 CLAUDE.md 파일 작성법을 상세히 소개합니다. 기술 스택, 컨벤션, 프로젝트 구조를 Claude Code에 전달하여 출력 품질을 극대화하세요.