一键导入
web-app-testing
Test web applications using Playwright for E2E testing, component testing, and visual regression
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Test web applications using Playwright for E2E testing, component testing, and visual regression
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | Web App Testing |
| description | Test web applications using Playwright for E2E testing, component testing, and visual regression |
| allowed-tools | ["Bash","Read","Write","Edit","Grep","Glob"] |
| tags | ["testing","playwright","e2e","automation"] |
You are an expert at testing web applications for gens.team using Playwright.
┌─────────────────────────────────────────────┐
│ E2E Testing: Playwright │
│ Component Testing: React Testing Library │
│ Unit Testing: Jest/Vitest │
│ Visual Regression: Playwright Screenshots │
└─────────────────────────────────────────────┘
frontend/
├── e2e/ # E2E tests
│ ├── fixtures/ # Test fixtures
│ ├── pages/ # Page objects
│ └── *.spec.ts # Test specs
├── playwright.config.ts # Playwright config
└── components/__tests__/ # Component tests
backend/
├── test/ # E2E API tests
└── src/**/*.spec.ts # Unit tests
// playwright.config.ts
import { defineConfig, devices } from "@playwright/test";
export default defineConfig({
testDir: "./e2e",
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: "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: "webkit", use: { ...devices["Desktop Safari"] } },
],
webServer: {
command: "npm run dev",
url: "http://localhost:3000",
reuseExistingServer: !process.env.CI,
},
});
// e2e/pages/LoginPage.ts
import { Page, Locator } from "@playwright/test";
export class LoginPage {
readonly page: Page;
readonly emailInput: Locator;
readonly passwordInput: Locator;
readonly submitButton: Locator;
constructor(page: Page) {
this.page = page;
this.emailInput = page.getByLabel("Email");
this.passwordInput = page.getByLabel("Password");
this.submitButton = page.getByRole("button", { name: "Sign in" });
}
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();
}
}
import { test, expect } from "@playwright/test";
test("should navigate to dashboard after login", async ({ page }) => {
await page.goto("/login");
await page.getByLabel("Email").fill("user@example.com");
await page.getByLabel("Password").fill("password");
await page.getByRole("button", { name: "Sign in" }).click();
await expect(page).toHaveURL("/dashboard");
await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible();
});
import { test, expect } from "@playwright/test";
test("should display resources from API", async ({ page }) => {
// Mock API response
await page.route("**/api/resources", async (route) => {
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify([
{ id: "1", title: "Resource 1", type: "article" },
{ id: "2", title: "Resource 2", type: "video" },
]),
});
});
await page.goto("/resources");
await expect(page.getByText("Resource 1")).toBeVisible();
await expect(page.getByText("Resource 2")).toBeVisible();
});
import { test, expect } from "@playwright/test";
test("dashboard visual regression", async ({ page }) => {
await page.goto("/dashboard");
await expect(page).toHaveScreenshot("dashboard.png", {
maxDiffPixels: 100,
});
});
// e2e/fixtures/auth.ts
import { test as base } from "@playwright/test";
type AuthFixtures = {
authenticatedPage: Page;
};
export const test = base.extend<AuthFixtures>({
authenticatedPage: async ({ page }, use) => {
// Perform login
await page.goto("/login");
await page.getByLabel("Email").fill("test@example.com");
await page.getByLabel("Password").fill("password");
await page.getByRole("button", { name: "Sign in" }).click();
await page.waitForURL("/dashboard");
await use(page);
},
});
# Run all E2E tests
npx playwright test
# Run specific test file
npx playwright test e2e/login.spec.ts
# Run in headed mode (see browser)
npx playwright test --headed
# Run in debug mode
npx playwright test --debug
# Update snapshots
npx playwright test --update-snapshots
# Show report
npx playwright show-report
Use Locators Wisely
getByRole, getByLabel, getByTextWait for Elements
expect(locator).toBeVisible() instead of arbitrary waitspage.waitForURL() for navigationIsolate Tests
Handle Async Operations
page.waitForResponse() for API callsMission 唯一最终负责人;M0 plan / M1 assess-research / M6 foreword / M7 sign-off 4 个 milestone 全程在场
报告撰稿人;2 种 mode(single-shot / chapter pipeline)+ 3 个 duty(chapter / dimension-outline / mission-outline / single-shot)
Mission 唯一最终负责人;M0 plan / M1 assess-research / M6 foreword / M7 sign-off 4 个 milestone 全程在场
报告撰稿人;2 种 mode(single-shot / chapter pipeline)+ 3 个 duty(chapter / dimension-outline / mission-outline / single-shot)
Manage Git operations, branches, commits, and pull requests following gens.team conventions
Perform comprehensive code reviews for security, performance, maintainability, and best practices