Playwright 自动化测试:跨浏览器与移动模拟

FreeGuideOnline 最新 2026-06-15

Playwright 自动化测试:从入门到跨浏览器移动端模拟

Playwright 是由微软开源的一个自动化测试框架,它通过单一 API 支持 Chromium、Firefox 和 WebKit 三大引擎,并能轻松模拟移动设备、处理网络拦截,是端到端测试领域的现代利器。本教程将带你从零搭建环境,掌握多浏览器测试与移动端模拟的核心技能。


1. 什么是 Playwright,为什么选择它

Playwright 能够自动操控浏览器进行页面跳转、表单填写、点击、截图等操作,常用于:

  • 端到端(E2E)测试:验证用户真实操作路径
  • 爬虫与数据抓取:处理动态渲染页面
  • 自动化任务:生成 PDF、监控页面状态

相比 Selenium 等传统工具,Playwright 具备以下优势:

  • 自带浏览器,无需额外安装驱动
  • 自动等待元素可操作,减少 flaky 测试
  • 网络拦截、修改请求和响应
  • 原生支持移动端模拟、地理位置、权限控制
  • 多页面、多上下文隔离,运行速度快

2. 环境准备与第一个脚本

2.1 安装 Node.js

Playwright 官方推荐使用 Node.js 环境。请确保已安装 Node.js 16 以上版本。 在终端执行:

node -v

2.2 初始化项目并安装 Playwright

mkdir playwright-demo && cd playwright-demo
npm init -y
npm install playwright

安装完成后,执行浏览器安装命令(会下载 Chromium、Firefox、WebKit):

npx playwright install

2.3 编写第一个测试脚本

创建 example.js 文件:

const { chromium } = require('playwright');

(async () => {
  // 启动浏览器(默认无头模式,设为 false 可看到界面)
  const browser = await chromium.launch({ headless: false });
  const page = await browser.newPage();
  await page.goto('https://example.com');
  // 获取页面标题
  const title = await page.title();
  console.log('页面标题:', title);
  await browser.close();
})();

运行:

node example.js

3. 基本元素定位与交互

Playwright 提供了强大的选择器引擎,支持文本、CSS、XPath、角色等定位方式。

3.1 点击与输入

// 文本选择器(推荐,语义清晰)
await page.click('text=登录');

// CSS 选择器
await page.fill('#username', 'myuser');

// 按占位文字填写
await page.fill('input[placeholder="密码"]', '123456');

// 通过角色定位(无障碍树)
await page.click('button:has-text("提交")');

3.2 自动等待机制

Playwright 在执行动作前会自动检查元素是否附着到 DOM、是否可见、是否稳定,无需显式 sleep

// 点击后页面可能跳转,playwright 会等待新页面加载完成
await page.click('a[href="/next"]');

4. 跨浏览器测试:同一脚本运行于三大引擎

Playwright 的精华在于一套代码同时测试 Chromium、Firefox、WebKit。

4.1 启动不同浏览器

const { chromium, firefox, webkit } = require('playwright');

(async () => {
  for (const browserType of [chromium, firefox, webkit]) {
    const browser = await browserType.launch();
    const page = await browser.newPage();
    await page.goto('https://whatsmyua.com');
    // 打印用户代理,验证不同浏览器环境
    const ua = await page.evaluate(() => navigator.userAgent);
    console.log(`${browserType.name()} UA:`, ua);
    await browser.close();
  }
})();

4.2 复用测试逻辑

实际项目中,通常使用测试运行器(如 Playwright Test)组织用例,但核心思想是通过参数化浏览器类型来覆盖多引擎。


5. 移动设备模拟与视口定制

Playwright 内置了数十种设备的预设(iPhone、Pixel、iPad 等),可模拟屏幕尺寸、userAgent、触摸事件等。

5.1 使用内置设备描述符

const { chromium, devices } = require('playwright');
const iPhone = devices['iPhone 12'];

(async () => {
  const browser = await chromium.launch();
  const context = await browser.newContext({
    ...iPhone,           // 展开设备配置
    locale: 'zh-CN',     // 语言/地区
    permissions: ['geolocation'],
    geolocation: { longitude: 116.4074, latitude: 39.9042 },
  });
  const page = await context.newPage();
  await page.goto('https://www.baidu.com');
  await page.screenshot({ path: 'iphone-baidu.png' });
  await browser.close();
})();

5.2 自定义视口与 UserAgent

如果没有预设的设备,你可以手动指定:

const context = await browser.newContext({
  viewport: { width: 375, height: 812 },
  userAgent: 'Mozilla/5.0 (Linux; Android 10; SM-G980F) AppleWebKit/537.36 ...',
  isMobile: true,
  hasTouch: true,
});

5.3 模拟网络条件

通过 context.setOffline()page.route() 可实现离线测试或网络节流:

const context = await browser.newContext({
  ...iPhone,
  offline: false,
});
// 注意:真正的网络节流需要在上下文创建后使用 CDPSession(仅Chromium)
// 但大多数移动模拟场景中,关注点是视口与交互

6. 典型测试场景实战

6.1 自动登录与状态验证

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com/login');
  await page.fill('#email', 'user@test.com');
  await page.fill('#password', 'pass123');
  await page.click('button[type="submit"]');
  // 等待导航到用户首页
  await page.waitForURL('**/dashboard');
  const welcomeText = await page.textContent('.welcome');
  console.log('欢迎信息:', welcomeText);
  await browser.close();
})();

6.2 移动端触摸滑动

在模拟移动设备时,可以直接使用触摸操作:

const { webkit, devices } = require('playwright');
const iPhone = devices['iPhone 13'];

(async () => {
  const browser = await webkit.launch();
  const context = await browser.newContext(iPhone);
  const page = await context.newPage();
  await page.goto('https://m.baidu.com');
  // 触摸滑动:从 (x1, y1) 滑动到 (x2, y2)
  await page.touchscreen.tap(100, 200); // 单点触摸
  // 模拟滑动搜索框聚焦
  await page.tap('input[name="word"]');
  await page.fill('input[name="word"]', 'Playwright');
  await page.click('button[type="submit"]');
  await page.screenshot({ path: 'mobile_search.png' });
  await browser.close();
})();

7. 进阶技巧:网络拦截与断言

7.1 拦截请求并修改响应

await page.route('**/*.png', route => route.abort()); // 拦截所有图片

// 模拟 API 返回
await page.route('**/api/user', route => {
  route.fulfill({
    status: 200,
    contentType: 'application/json',
    body: JSON.stringify({ name: 'MockUser', id: 1 })
  });
});

7.2 常用断言(需配合 @playwright/test 或手动)

即使不用测试运行器,也可以手动断言:

const { expect } = require('@playwright/test'); // 需要安装
// 或使用 Node 内置 assert
const assert = require('assert');
const title = await page.title();
assert.strictEqual(title, '预期标题');

8. 常见问题与调试

  • 元素找不到:使用 page.pause() 进入调试模式,或在启动时设置 { headless: false, slowMo: 100 } 观察操作流程。
  • 移动端点击失效:确认 context 配置了 isMobile: true,并使用 page.tap() 而非 page.click()
  • 等待超时:提高默认超时 browser.newPage({ timeout: 60000 }),或使用更智能的等待如 page.waitForResponse()

9. 总结与学习路径

通过本教程,你已经掌握:

  • Playwright 的环境搭建与基本操作
  • 跨 Chromium、Firefox、WebKit 的测试执行
  • 移动设备模拟与触摸交互
  • 网络拦截与断言思路

下一步建议:

  • 学习 Playwright Test Runner 编写结构化的测试用例
  • 探索 Trace Viewer 分析测试步骤时间线
  • 研究 Page Object Model 提升代码可维护性

Playwright 让你以贴近用户的方式验证应用质量,无论是 Web 还是移动 Web,一套代码即可全平台覆盖。