スキル一覧に戻る
doanchienthangdev

testing-with-playwright

by doanchienthangdev

Omega Vibecode Kit

2🍴 1📅 2026年1月21日
GitHubで見るManusで実行

SKILL.md


name: Testing with Playwright description: Claude writes reliable E2E tests using Playwright for browser automation. Use when writing end-to-end tests, implementing Page Object Model, visual regression testing, API mocking, or cross-browser testing.

Testing with Playwright

Quick Start

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

export default defineConfig({
  testDir: "./tests/e2e",
  fullyParallel: true,
  retries: process.env.CI ? 2 : 0,
  reporter: [["list"], ["html"]],
  use: {
    baseURL: "http://localhost:3000",
    trace: "on-first-retry",
    screenshot: "only-on-failure",
  },
  projects: [
    { name: "chromium", use: { ...devices["Desktop Chrome"] } },
    { name: "firefox", use: { ...devices["Desktop Firefox"] } },
    { name: "mobile", use: { ...devices["iPhone 12"] } },
  ],
  webServer: { command: "npm run dev", url: "http://localhost:3000" },
});

Features

FeatureDescriptionReference
Page Object ModelMaintainable test architecture patternPOM Guide
Auto-WaitingBuilt-in waiting for elements and assertionsAuto-Waiting
Network MockingIntercept and mock API responsesNetwork
Visual TestingScreenshot comparison for regression testingVisual Comparisons
Cross-BrowserChrome, Firefox, Safari, mobile devicesBrowsers
Trace ViewerDebug failing tests with timelineTrace Viewer

Common Patterns

Page Object Model

// tests/pages/login.page.ts
import { Page, Locator, expect } from "@playwright/test";

export class LoginPage {
  readonly emailInput: Locator;
  readonly passwordInput: Locator;
  readonly submitButton: Locator;

  constructor(private page: Page) {
    this.emailInput = page.getByLabel("Email");
    this.passwordInput = page.getByLabel("Password");
    this.submitButton = page.getByRole("button", { name: "Sign in" });
  }

  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.page.getByRole("alert")).toContainText(message);
  }
}

API Mocking

import { test, expect } from "@playwright/test";

test("mock API response", async ({ page }) => {
  await page.route("**/api/users", (route) =>
    route.fulfill({
      status: 200,
      contentType: "application/json",
      body: JSON.stringify({ users: [{ id: 1, name: "John" }] }),
    })
  );

  await page.goto("/users");
  await expect(page.getByText("John")).toBeVisible();
});

test("capture network requests", async ({ page }) => {
  const requestPromise = page.waitForRequest("**/api/analytics");
  await page.goto("/dashboard");
  const request = await requestPromise;
  expect(request.postDataJSON()).toMatchObject({ event: "page_view" });
});

Authentication Fixture

// tests/fixtures/auth.fixture.ts
import { test as base } from "@playwright/test";
import { LoginPage } from "../pages/login.page";

export const test = base.extend<{ authenticatedPage: Page }>({
  authenticatedPage: async ({ page }, use) => {
    // Fast auth via API
    const response = await page.request.post("/api/auth/login", {
      data: { email: "test@example.com", password: "password" },
    });
    const { token } = await response.json();

    await page.context().addCookies([
      { name: "auth_token", value: token, domain: "localhost", path: "/" },
    ]);

    await page.goto("/dashboard");
    await use(page);
  },
});

Visual Regression Testing

test("visual snapshot", async ({ page }) => {
  await page.goto("/");
  await page.addStyleTag({
    content: "*, *::before, *::after { animation-duration: 0s !important; }",
  });

  await expect(page).toHaveScreenshot("homepage.png", {
    fullPage: true,
    maxDiffPixels: 100,
  });

  // Mask dynamic content
  await expect(page).toHaveScreenshot("dashboard.png", {
    mask: [page.getByTestId("timestamp"), page.getByTestId("avatar")],
  });
});

Best Practices

DoAvoid
Use Page Object Model for maintainabilityFragile CSS selectors
Prefer user-facing locators (getByRole, getByLabel)Relying on arbitrary waits
Use API auth for faster test setupSharing state between tests
Enable traces and screenshots for debuggingTesting third-party services directly
Run tests in parallel for speedSkipping flaky tests without fixing
Mock external APIs for reliabilityHardcoding test data

References

スコア

総合スコア

60/100

リポジトリの品質指標に基づく評価

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

レビュー

💬

レビュー機能は近日公開予定です