Playwright 速查表

Playwright 速查表

1. 安装与运行

bash 复制代码
# 初始化
npm init playwright@latest

# 安装依赖后补装浏览器
npx playwright install

# 运行全部测试
npx playwright test

# 跑指定文件
npx playwright test tests/demo.spec.ts

# 跑指定浏览器
npx playwright test --project=chromium

# 有头模式
npx playwright test --headed

# 调试模式
npx playwright test --debug

# 可视化 UI
npx playwright test --ui

# 录制脚本
npx playwright codegen https://example.com

2. 基础模板

ts 复制代码
import { test, expect } from '@playwright/test';

test('example test', async ({ page }) => {
  await page.goto('https://example.com');
  await expect(page).toHaveTitle(/Example/);
});

3. 常用对象

  • test:定义测试
  • expect:断言
  • page:当前页面
  • browser:浏览器实例
  • context:浏览器上下文,类似独立用户会话

4. 页面操作

打开页面

ts 复制代码
await page.goto('https://example.com');

刷新

ts 复制代码
await page.reload();

后退/前进

ts 复制代码
await page.goBack();
await page.goForward();

获取标题/URL

ts 复制代码
await page.title();
page.url();

5. 常用定位器

推荐写法

ts 复制代码
page.getByRole('button', { name: '登录' })
page.getByLabel('用户名')
page.getByPlaceholder('请输入内容')
page.getByText('提交')
page.getByTestId('submit-btn')

通用定位

ts 复制代码
page.locator('.class-name')
page.locator('#id')
page.locator('//button')

链式定位

ts 复制代码
page.locator('.card').getByText('详情')
page.getByRole('dialog').getByRole('button', { name: '确认' })

第几个元素

ts 复制代码
page.locator('.item').first()
page.locator('.item').last()
page.locator('.item').nth(2)

6. 常用交互

点击

ts 复制代码
await page.getByRole('button', { name: '提交' }).click();

输入

ts 复制代码
await page.getByLabel('用户名').fill('admin');

清空后输入

ts 复制代码
await page.locator('#input').fill('');
await page.locator('#input').fill('new value');

按键

ts 复制代码
await page.locator('#search').press('Enter');
await page.keyboard.press('Escape');

勾选/取消勾选

ts 复制代码
await page.locator('#agree').check();
await page.locator('#agree').uncheck();

选择下拉框

ts 复制代码
await page.locator('select').selectOption('option1');
await page.locator('select').selectOption({ label: '北京' });

悬停

ts 复制代码
await page.locator('.menu').hover();

双击/右键

ts 复制代码
await page.locator('.item').dblclick();
await page.locator('.item').click({ button: 'right' });

7. 常用断言

标题

ts 复制代码
await expect(page).toHaveTitle(/Playwright/);

URL

ts 复制代码
await expect(page).toHaveURL(/dashboard/);

文本可见

ts 复制代码
await expect(page.getByText('登录成功')).toBeVisible();

元素隐藏

ts 复制代码
await expect(page.locator('.loading')).toBeHidden();

输入框值

ts 复制代码
await expect(page.locator('#username')).toHaveValue('admin');

文本内容

ts 复制代码
await expect(page.locator('.title')).toHaveText('欢迎');
await expect(page.locator('.title')).toContainText('欢迎');

数量

ts 复制代码
await expect(page.locator('.item')).toHaveCount(3);

勾选状态

ts 复制代码
await expect(page.locator('#agree')).toBeChecked();

启用/禁用

ts 复制代码
await expect(page.locator('button')).toBeEnabled();
await expect(page.locator('button')).toBeDisabled();

8. 获取数据

文本

ts 复制代码
const text = await page.locator('.title').textContent();
const innerText = await page.locator('.title').innerText();

输入框值

ts 复制代码
const value = await page.locator('input').inputValue();

属性

ts 复制代码
const href = await page.locator('a').getAttribute('href');

全部文本

ts 复制代码
const texts = await page.locator('.item').allTextContents();

9. 等待

等元素出现

ts 复制代码
await page.locator('.result').waitFor();

等 URL

ts 复制代码
await page.waitForURL('**/dashboard');

等响应

ts 复制代码
await page.waitForResponse(resp => resp.url().includes('/api/user') && resp.status() === 200);

等请求

ts 复制代码
await page.waitForRequest('**/api/login');

不推荐

ts 复制代码
await page.waitForTimeout(3000);

10. Hooks

ts 复制代码
test.beforeEach(async ({ page }) => {
  await page.goto('https://example.com/login');
});

test.afterEach(async () => {
  // 清理
});

test.beforeAll(async () => {
  // 全局初始化
});

test.afterAll(async () => {
  // 全局收尾
});

11. 分组与单测控制

分组

ts 复制代码
test.describe('登录模块', () => {
  test('正确登录', async ({ page }) => {});
  test('错误密码提示', async ({ page }) => {});
});

只跑一个

ts 复制代码
test.only('只跑这个测试', async ({ page }) => {});

跳过

ts 复制代码
test.skip('先跳过', async ({ page }) => {});

标记慢测试

ts 复制代码
test.slow();

12. 文件上传下载

上传

ts 复制代码
await page.locator('input[type="file"]').setInputFiles('./a.png');

清空已上传文件

ts 复制代码
await page.locator('input[type="file"]').setInputFiles([]);

下载

ts 复制代码
const downloadPromise = page.waitForEvent('download');
await page.getByText('下载').click();
const download = await downloadPromise;
await download.saveAs('./downloads/report.xlsx');

13. 弹窗处理

alert / confirm / prompt

ts 复制代码
page.on('dialog', async dialog => {
  console.log(dialog.message());
  await dialog.accept();
});

拒绝

ts 复制代码
page.on('dialog', async dialog => {
  await dialog.dismiss();
});

14. 新窗口 / 新标签页

ts 复制代码
const [newPage] = await Promise.all([
  page.waitForEvent('popup'),
  page.getByText('打开新窗口').click(),
]);

await newPage.waitForLoadState();
await expect(newPage).toHaveURL(/target/);

15. iframe

ts 复制代码
const frame = page.frameLocator('#my-frame');
await frame.getByRole('button', { name: '提交' }).click();

16. 截图 / 视频 / Trace

截图

ts 复制代码
await page.screenshot({ path: 'page.png', fullPage: true });

配置里保留失败证据

ts 复制代码
use: {
  screenshot: 'only-on-failure',
  video: 'retain-on-failure',
  trace: 'on-first-retry',
}

查看 trace

bash 复制代码
npx playwright show-trace trace.zip

17. 调试

暂停

ts 复制代码
await page.pause();

运行调试

bash 复制代码
npx playwright test --debug

18. 网络拦截 / Mock

Mock 接口

ts 复制代码
await page.route('**/api/user', async route => {
  await route.fulfill({
    status: 200,
    contentType: 'application/json',
    body: JSON.stringify({ name: '老张' }),
  });
});

放行请求

ts 复制代码
await page.route('**/*', route => route.continue());

终止请求

ts 复制代码
await page.route('**/ads/**', route => route.abort());

19. 登录态复用

保存状态

ts 复制代码
await page.context().storageState({ path: 'playwright/.auth/user.json' });

使用状态

ts 复制代码
use: {
  storageState: 'playwright/.auth/user.json',
}

20. 常见配置

playwright.config.ts

ts 复制代码
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './tests',
  timeout: 30_000,
  retries: 1,
  use: {
    baseURL: 'https://example.com',
    headless: true,
    screenshot: 'only-on-failure',
    trace: 'on-first-retry',
  },
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
  ],
});

使用 baseURL

ts 复制代码
await page.goto('/login');

21. API 测试

ts 复制代码
import { test, expect } from '@playwright/test';

test('api test', async ({ request }) => {
  const resp = await request.get('https://example.com/api/user');
  expect(resp.ok()).toBeTruthy();
  const data = await resp.json();
  expect(data.name).toBe('Tom');
});

22. POM 模式最小模板

ts 复制代码
import { Page } from '@playwright/test';

export class LoginPage {
  constructor(private page: Page) {}

  async goto() {
    await this.page.goto('/login');
  }

  async login(username: string, password: string) {
    await this.page.getByLabel('用户名').fill(username);
    await this.page.getByLabel('密码').fill(password);
    await this.page.getByRole('button', { name: '登录' }).click();
  }
}

23. 最常见坑

不要滥用 waitForTimeout

ts 复制代码
await page.waitForTimeout(5000); // 尽量别这么写

优先语义定位

ts 复制代码
page.getByRole(...)
page.getByLabel(...)
page.getByTestId(...)

一个测试只验证一个核心目标

别把整条业务链全塞一个 case 里。

测试尽量独立

不要强依赖上一个测试生成的数据。


24. 最实用模板

ts 复制代码
import { test, expect } from '@playwright/test';

test('登录成功', async ({ page }) => {
  await page.goto('/login');
  await page.getByLabel('用户名').fill('admin');
  await page.getByLabel('密码').fill('123456');
  await page.getByRole('button', { name: '登录' }).click();

  await expect(page).toHaveURL(/dashboard/);
  await expect(page.getByText('欢迎你')).toBeVisible();
});

25. 定位器优先级建议

推荐顺序:

  1. getByRole
  2. getByLabel
  3. getByPlaceholder
  4. getByTestId
  5. locator(css)
  6. xpath(最后再用)
相关推荐
草青工作室1 小时前
AI主流大模型参数量和收费情况参考(26年4月)
人工智能
Y敲键盘的地方1 小时前
第1章:从命令行到智能体
人工智能
雷工笔记1 小时前
读书笔记|《AI知识库:个人与企业的智慧玩法》
人工智能
李可以量化2 小时前
【2026 量化工具选型】通达信 TdxQuant vs 迅投 QMT/miniQMT 深度对比:新手该怎么选?
大数据·人工智能·区块链·通达信·qmt·量化 qmt ptrade
互联科技报2 小时前
零售数字化:高准确率客流分析系统优质推荐
大数据·人工智能
互联科技报2 小时前
成熟零售客流系统该怎么选?决定门店效率的关键选择
人工智能·零售
北京耐用通信2 小时前
国产优选:耐达讯自动化EtherCAT转RS232在工业协议转换中的卓越表现
人工智能·科技·物联网·网络协议·自动化
沃垠AI2 小时前
万字干货!Agent Skills从入门到精通
人工智能
mit6.8242 小时前
设计系统的智慧
人工智能