playwright-testing by aehrc/pathling
npx skills add https://github.com/aehrc/pathling --skill playwright-testing具备自动等待、Web 优先断言和多浏览器支持的端到端测试框架。
import { test, expect } from "@playwright/test";
test("user can log in", async ({ page }) => {
await page.goto("/login");
await page.getByLabel("Email").fill("user@example.com");
await page.getByLabel("Password").fill("secret");
await page.getByRole("button", { name: "Sign in" }).click();
await expect(page.getByText("Welcome")).toBeVisible();
});
page.getByRole('button', { name: 'Submit' }) — ARIA 角色(最健壮)page.getByLabel('Email') — 表单标签page.getByText('Welcome') — 可见文本page.getByTestId('user-menu') — 测试 ID(明确的约定)广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
page.getByPlaceholder('Search') — 占位符文本避免使用 CSS 选择器和 XPath——它们会因 DOM 变更而失效。
链式调用和过滤:
// 链式调用以缩小范围
page.locator(".modal").getByRole("button", { name: "Save" });
// 通过文本或子元素过滤
page.getByRole("listitem").filter({ hasText: "Product" });
page.getByRole("listitem").filter({ has: page.getByRole("button") });
完整的定位器 API 请参阅 references/locators.md。
自动重试(用于 Web 元素):
await expect(locator).toBeVisible();
await expect(locator).toHaveText("Hello");
await expect(locator).toHaveValue("input text");
await expect(locator).toBeChecked();
await expect(page).toHaveURL(/dashboard/);
非重试(用于静态值):
expect(value).toBe(5);
expect(array).toContain("item");
expect(obj).toEqual({ key: "value" });
所有断言类型请参阅 references/assertions.md。
await locator.click();
await locator.fill("text"); // 清空并输入
await locator.pressSequentially("t"); // 逐个字符输入
await locator.selectOption("value");
await locator.check(); // 复选框
await locator.setInputFiles("file.pdf");
await page.keyboard.press("Enter");
所有操作都会自动等待元素可见、稳定且可用。
完整的操作参考请参阅 references/actions.md。
import { test, expect } from "@playwright/test";
test.describe("Feature", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/");
});
test("scenario one", async ({ page }) => {
// Arrange - Act - Assert
});
test("scenario two", async ({ page }) => {
// ...
});
});
test.beforeEach() / test.afterEach() — 在每个测试之前/之后运行test.beforeAll() / test.afterAll() — 每个工作进程运行一次最小化的 playwright.config.ts:
import { defineConfig, devices } from "@playwright/test";
export default defineConfig({
testDir: "./tests",
fullyParallel: true,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 2 : undefined,
reporter: "html",
use: {
baseURL: "http://localhost:3000",
trace: "on-first-retry",
},
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,
},
});
所有配置选项请参阅 references/configuration.md。
npx playwright test # 运行所有测试
npx playwright test --ui # 交互式 UI 模式
npx playwright test --headed # 显示浏览器
npx playwright test --debug # 逐步调试器
npx playwright test -g "login" # 按标题过滤
npx playwright test --project=chromium # 指定浏览器
npx playwright test --last-failed # 仅重试失败的测试
npx playwright codegen # 生成测试
npx playwright show-report # 查看 HTML 报告
await page.route("**/api/users", (route) =>
route.fulfill({ json: [{ id: 1, name: "Mock User" }] }),
);
await page.route("**/api/error", (route) => route.fulfill({ status: 500 }));
// 登录后保存认证状态
await page.context().storageState({ path: "auth.json" });
// 在配置中复用
use: {
storageState: "auth.json";
}
const test = base.extend<{ userPage: Page }>({
userPage: async ({ browser }, use) => {
const context = await browser.newContext();
const page = await context.newPage();
await page.goto("/login");
// ... 登录
await use(page);
await context.close();
},
});
网络模拟、认证模式、夹具和页面对象模型请参阅 references/advanced.md。
getByRole() 对变更最健壮await expect(locator).toBeVisible() 而非 locator.isVisible()expect.soft() 在失败后继续执行以生成全面的报告每周安装量
1
代码仓库
GitHub 星标数
121
首次出现
1 天前
安全审计
已安装于
amp1
cline1
opencode1
cursor1
kimi-cli1
codex1
End-to-end testing framework with auto-waiting, web-first assertions, and multi-browser support.
import { test, expect } from "@playwright/test";
test("user can log in", async ({ page }) => {
await page.goto("/login");
await page.getByLabel("Email").fill("user@example.com");
await page.getByLabel("Password").fill("secret");
await page.getByRole("button", { name: "Sign in" }).click();
await expect(page.getByText("Welcome")).toBeVisible();
});
page.getByRole('button', { name: 'Submit' }) — ARIA roles (most resilient)page.getByLabel('Email') — Form labelspage.getByText('Welcome') — Visible textpage.getByTestId('user-menu') — Test IDs (explicit contracts)page.getByPlaceholder('Search') — Placeholder textAvoid CSS selectors and XPath—they break with DOM changes.
Chaining and filtering:
// Chain to narrow scope
page.locator(".modal").getByRole("button", { name: "Save" });
// Filter by text or child elements
page.getByRole("listitem").filter({ hasText: "Product" });
page.getByRole("listitem").filter({ has: page.getByRole("button") });
See references/locators.md for complete locator API.
Auto-retrying (use these for web elements):
await expect(locator).toBeVisible();
await expect(locator).toHaveText("Hello");
await expect(locator).toHaveValue("input text");
await expect(locator).toBeChecked();
await expect(page).toHaveURL(/dashboard/);
Non-retrying (for static values):
expect(value).toBe(5);
expect(array).toContain("item");
expect(obj).toEqual({ key: "value" });
See references/assertions.md for all assertion types.
await locator.click();
await locator.fill("text"); // Clear and type
await locator.pressSequentially("t"); // Character by character
await locator.selectOption("value");
await locator.check(); // Checkbox
await locator.setInputFiles("file.pdf");
await page.keyboard.press("Enter");
All actions auto-wait for elements to be visible, stable, and enabled.
See references/actions.md for complete action reference.
import { test, expect } from "@playwright/test";
test.describe("Feature", () => {
test.beforeEach(async ({ page }) => {
await page.goto("/");
});
test("scenario one", async ({ page }) => {
// Arrange - Act - Assert
});
test("scenario two", async ({ page }) => {
// ...
});
});
test.beforeEach() / test.afterEach() — Run before/after each testtest.beforeAll() / test.afterAll() — Run once per workerMinimal playwright.config.ts:
import { defineConfig, devices } from "@playwright/test";
export default defineConfig({
testDir: "./tests",
fullyParallel: true,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 2 : undefined,
reporter: "html",
use: {
baseURL: "http://localhost:3000",
trace: "on-first-retry",
},
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,
},
});
See references/configuration.md for all options.
npx playwright test # Run all tests
npx playwright test --ui # Interactive UI mode
npx playwright test --headed # Show browser
npx playwright test --debug # Step-through debugger
npx playwright test -g "login" # Filter by title
npx playwright test --project=chromium # Specific browser
npx playwright test --last-failed # Retry failures only
npx playwright codegen # Generate tests
npx playwright show-report # View HTML report
await page.route("**/api/users", (route) =>
route.fulfill({ json: [{ id: 1, name: "Mock User" }] }),
);
await page.route("**/api/error", (route) => route.fulfill({ status: 500 }));
// Save auth state after login
await page.context().storageState({ path: "auth.json" });
// Reuse in config
use: {
storageState: "auth.json";
}
const test = base.extend<{ userPage: Page }>({
userPage: async ({ browser }, use) => {
const context = await browser.newContext();
const page = await context.newPage();
await page.goto("/login");
// ... login
await use(page);
await context.close();
},
});
See references/advanced.md for network mocking, auth patterns, fixtures, and Page Object Model.
getByRole() is most resilient to changesawait expect(locator).toBeVisible() not locator.isVisible()expect.soft() continues after failure for comprehensive reportsWeekly Installs
1
Repository
GitHub Stars
121
First Seen
1 day ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
amp1
cline1
opencode1
cursor1
kimi-cli1
codex1
Skills CLI 使用指南:AI Agent 技能包管理器安装与管理教程
33,600 周安装
PostgreSQL 数据库架构设计模板 - Claude 代码模板库,提升数据库设计效率
210 周安装
合规审查工具 - 自动检查业务计划、产品功能、营销活动的法律合规性 | GDPR/CCPA/HIPAA
425 周安装
代码质量审计员 - 自动化代码复杂度、算法效率与常量管理审计工具
275 周安装
VSCode Agent Sessions 窗口开发指南:架构、布局与AI自定义规范
384 周安装
HTML标题标签优化指南:提升SEO排名与点击率的完整策略
301 周安装
Python代码质量工具速查:Ruff代码检查与格式化、ty类型检查完整指南
252 周安装