Files
2026-07-13 21:36:47 +08:00

13 KiB
Raw Permalink Blame History

设备和环境模拟

适用场景:无需物理设备,全部在 CLI 中测试应用在不同设备、屏幕尺寸、地理位置、语言区域、时区、配色方案和网络条件下的表现。 前置条件core-commands.md 了解基本 CLI 用法,running-custom-code.md 了解 run-code 语法

快速参考

# 通过配置文件模拟设备
playwright-cli open https://example.com --config=iphone.json

# 调整视口大小
playwright-cli resize 375 812                    # iPhone 视口
playwright-cli resize 1920 1080                  # 桌面视口

# 地理位置
playwright-cli run-code "async page => {
  await page.context().grantPermissions(['geolocation']);
  await page.context().setGeolocation({ latitude: 40.7128, longitude: -74.0060 });
}"

# 配色方案
playwright-cli run-code "async page => {
  await page.emulateMedia({ colorScheme: 'dark' });
}"

视口模拟

设备测试的最简单形式——将视口大小设置为目标设备的尺寸:

常见视口尺寸

# 桌面
playwright-cli resize 1920 1080    # Full HD 显示器
playwright-cli resize 1440 900     # MacBook Pro 15"
playwright-cli resize 1366 768     # 常见笔记本电脑
playwright-cli resize 2560 1440    # QHD / 2K 显示器

# 平板
playwright-cli resize 1024 768     # iPad 横屏
playwright-cli resize 768 1024     # iPad 竖屏
playwright-cli resize 834 1194     # iPad Pro 11"
playwright-cli resize 1194 834     # iPad Pro 11" 横屏
playwright-cli resize 820 1180     # iPad Air

# 手机
playwright-cli resize 430 932      # iPhone 14 Pro Max
playwright-cli resize 393 852      # iPhone 14 Pro
playwright-cli resize 390 844      # iPhone 14 / 13 / 12
playwright-cli resize 375 812      # iPhone X / 11
playwright-cli resize 360 800      # Samsung Galaxy S21
playwright-cli resize 412 915      # Pixel 7
playwright-cli resize 320 568      # iPhone SE(第 1 代)

测试响应式断点

# 常见 CSS 断点
playwright-cli resize 320 568      # xs: 特小屏
playwright-cli screenshot --filename=responsive-xs.png

playwright-cli resize 576 768      # sm: 小屏
playwright-cli screenshot --filename=responsive-sm.png

playwright-cli resize 768 1024     # md: 中屏
playwright-cli screenshot --filename=responsive-md.png

playwright-cli resize 992 768      # lg: 大屏
playwright-cli screenshot --filename=responsive-lg.png

playwright-cli resize 1200 900     # xl: 特大屏
playwright-cli screenshot --filename=responsive-xl.png

playwright-cli resize 1400 900     # xxl: 超大屏
playwright-cli screenshot --filename=responsive-xxl.png

完整设备模拟

要进行精确的设备测试,仅设置视口是不够的——还需要设备缩放因子、User Agent、触摸支持和移动端行为。请使用配置文件或 run-code

配置文件方式

为特定设备创建配置文件:

iphone14.json

{
  "viewport": { "width": 390, "height": 844 },
  "deviceScaleFactor": 3,
  "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1",
  "isMobile": true,
  "hasTouch": true
}
playwright-cli open https://example.com --config=iphone14.json

pixel7.json

{
  "viewport": { "width": 412, "height": 915 },
  "deviceScaleFactor": 2.625,
  "userAgent": "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36",
  "isMobile": true,
  "hasTouch": true
}

ipad-pro.json

{
  "viewport": { "width": 834, "height": 1194 },
  "deviceScaleFactor": 2,
  "userAgent": "Mozilla/5.0 (iPad; CPU OS 16_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Mobile/15E148 Safari/604.1",
  "isMobile": true,
  "hasTouch": true
}

程序化设备模拟

使用 run-code 检查或修改设备属性:

# 检查当前设备属性
playwright-cli run-code "async page => {
  return await page.evaluate(() => ({
    userAgent: navigator.userAgent,
    viewport: { width: window.innerWidth, height: window.innerHeight },
    devicePixelRatio: window.devicePixelRatio,
    touchSupport: 'ontouchstart' in window,
    platform: navigator.platform
  }));
}"

地理位置

覆盖浏览器报告的 GPS 位置——测试门店定位器、配送区域、基于位置的内容。

设置位置

# 纽约
playwright-cli run-code "async page => {
  await page.context().grantPermissions(['geolocation']);
  await page.context().setGeolocation({ latitude: 40.7128, longitude: -74.0060 });
}"

# 伦敦
playwright-cli run-code "async page => {
  await page.context().grantPermissions(['geolocation']);
  await page.context().setGeolocation({ latitude: 51.5074, longitude: -0.1278 });
}"

# 东京
playwright-cli run-code "async page => {
  await page.context().grantPermissions(['geolocation']);
  await page.context().setGeolocation({ latitude: 35.6762, longitude: 139.6503 });
}"

# 悉尼
playwright-cli run-code "async page => {
  await page.context().grantPermissions(['geolocation']);
  await page.context().setGeolocation({ latitude: -33.8688, longitude: 151.2093 });
}"

# 圣保罗
playwright-cli run-code "async page => {
  await page.context().grantPermissions(['geolocation']);
  await page.context().setGeolocation({ latitude: -23.5505, longitude: -46.6333 });
}"

在会话中更新位置

模拟用户在不同位置之间移动:

# 从旧金山开始
playwright-cli run-code "async page => {
  await page.context().grantPermissions(['geolocation']);
  await page.context().setGeolocation({ latitude: 37.7749, longitude: -122.4194 });
}"

playwright-cli goto https://example.com/nearby-stores
playwright-cli screenshot --filename=sf-stores.png

# 移动到洛杉矶
playwright-cli run-code "async page => {
  await page.context().setGeolocation({ latitude: 34.0522, longitude: -118.2437 });
}"

playwright-cli reload
playwright-cli screenshot --filename=la-stores.png

清除地理位置覆盖

playwright-cli run-code "async page => {
  await page.context().clearPermissions();
}"

通过配置文件设置地理位置

在打开浏览器时设置地理位置:

geo-nyc.json

{
  "geolocation": { "latitude": 40.7128, "longitude": -74.006 },
  "permissions": ["geolocation"]
}
playwright-cli open https://example.com --config=geo-nyc.json

语言区域和时区

通过更改浏览器的语言区域和时区来测试国际化。

通过配置文件

locale-de.json

{
  "locale": "de-DE",
  "timezoneId": "Europe/Berlin"
}

locale-ja.json

{
  "locale": "ja-JP",
  "timezoneId": "Asia/Tokyo"
}
playwright-cli open https://example.com --config=locale-de.json

验证语言区域和时区

playwright-cli run-code "async page => {
  return await page.evaluate(() => ({
    language: navigator.language,
    languages: navigator.languages,
    timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
    dateFormat: new Date('2024-01-15').toLocaleDateString(),
    numberFormat: (1234567.89).toLocaleString(),
    currencyFormat: new Intl.NumberFormat(navigator.language, {
      style: 'currency',
      currency: 'USD'
    }).format(1234.56)
  }));
}"

常见语言区域 + 时区组合

区域 语言区域 时区
美国东部 en-US America/New_York
美国西部 en-US America/Los_Angeles
英国 en-GB Europe/London
德国 de-DE Europe/Berlin
法国 fr-FR Europe/Paris
日本 ja-JP Asia/Tokyo
中国 zh-CN Asia/Shanghai
印度 hi-IN Asia/Kolkata
巴西 pt-BR America/Sao_Paulo
澳大利亚 en-AU Australia/Sydney
阿拉伯地区 ar-SA Asia/Riyadh

配色方案

测试深色模式、浅色模式和高对比度:

# 深色模式
playwright-cli run-code "async page => {
  await page.emulateMedia({ colorScheme: 'dark' });
}"
playwright-cli screenshot --filename=dark-mode.png

# 浅色模式
playwright-cli run-code "async page => {
  await page.emulateMedia({ colorScheme: 'light' });
}"
playwright-cli screenshot --filename=light-mode.png

# 系统偏好(不覆盖)
playwright-cli run-code "async page => {
  await page.emulateMedia({ colorScheme: 'no-preference' });
}"

减少动画

测试偏好减少动画的用户的可访问性:

# 启用减少动画
playwright-cli run-code "async page => {
  await page.emulateMedia({ reducedMotion: 'reduce' });
}"

# 检查你的 CSS 是否遵循该设置
playwright-cli run-code "async page => {
  return await page.evaluate(() =>
    window.matchMedia('(prefers-reduced-motion: reduce)').matches
  );
}"

强制颜色(高对比度)

测试 Windows 高对比度模式:

playwright-cli run-code "async page => {
  await page.emulateMedia({ forcedColors: 'active' });
}"
playwright-cli screenshot --filename=high-contrast.png

权限

授予或拒绝浏览器权限:

# 授予多个权限
playwright-cli run-code "async page => {
  await page.context().grantPermissions([
    'geolocation',
    'notifications',
    'camera',
    'microphone'
  ]);
}"

# 为特定来源授予权限
playwright-cli run-code "async page => {
  await page.context().grantPermissions(['notifications'], {
    origin: 'https://example.com'
  });
}"

# 清除所有权限(重置为默认值)
playwright-cli run-code "async page => {
  await page.context().clearPermissions();
}"

可用权限:geolocationnotificationscameramicrophoneclipboard-readclipboard-writepayment-handlermidimidi-sysexambient-light-sensoraccelerometergyroscopemagnetometerbackground-sync

网络条件模拟

模拟慢速网络以测试加载状态和性能:

# 模拟慢速 3G
playwright-cli run-code "async page => {
  const client = await page.context().newCDPSession(page);
  await client.send('Network.emulateNetworkConditions', {
    offline: false,
    downloadThroughput: 500 * 1024 / 8,     // 500 kbps
    uploadThroughput: 500 * 1024 / 8,        // 500 kbps
    latency: 400                              // 400ms RTT
  });
}"

# 模拟离线模式
playwright-cli run-code "async page => {
  const client = await page.context().newCDPSession(page);
  await client.send('Network.emulateNetworkConditions', {
    offline: true,
    downloadThroughput: 0,
    uploadThroughput: 0,
    latency: 0
  });
}"

# 恢复正常网络
playwright-cli run-code "async page => {
  const client = await page.context().newCDPSession(page);
  await client.send('Network.emulateNetworkConditions', {
    offline: false,
    downloadThroughput: -1,
    uploadThroughput: -1,
    latency: 0
  });
}"

注意:CDP 会话仅适用于基于 Chromium 的浏览器。

常见模式

多设备截图套件

#!/bin/bash
URL="https://example.com"
playwright-cli open $URL

devices=("1920:1080:desktop" "768:1024:tablet" "375:812:mobile")
for device in "${devices[@]}"; do
  IFS=':' read -r w h name <<< "$device"
  playwright-cli resize $w $h
  playwright-cli screenshot --filename="device-$name.png"
done

playwright-cli close

基于地理位置的内容测试

locations=("40.7128:-74.0060:nyc" "51.5074:-0.1278:london" "35.6762:139.6503:tokyo")

for loc in "${locations[@]}"; do
  IFS=':' read -r lat lng name <<< "$loc"
  playwright-cli run-code "async page => {
    await page.context().grantPermissions(['geolocation']);
    await page.context().setGeolocation({ latitude: $lat, longitude: $lng });
  }"
  playwright-cli reload
  playwright-cli screenshot --filename="geo-$name.png"
done

可访问性模拟套件

playwright-cli open https://example.com

# 标准视图
playwright-cli screenshot --filename=a11y-standard.png

# 深色模式
playwright-cli run-code "async page => { await page.emulateMedia({ colorScheme: 'dark' }); }"
playwright-cli screenshot --filename=a11y-dark.png

# 高对比度
playwright-cli run-code "async page => { await page.emulateMedia({ forcedColors: 'active' }); }"
playwright-cli screenshot --filename=a11y-high-contrast.png

# 减少动画
playwright-cli run-code "async page => { await page.emulateMedia({ reducedMotion: 'reduce', forcedColors: 'none' }); }"
playwright-cli screenshot --filename=a11y-reduced-motion.png

playwright-cli close

提示

  • 仅设置视口不等于设备模拟——真正的设备测试需要通过配置文件设置 User Agent、触摸支持和设备缩放因子
  • 地理位置需要权限——在 setGeolocation() 之前务必先调用 grantPermissions(['geolocation'])
  • 语言区域/时区必须在打开时设置——使用配置文件,因为会话中途无法更改
  • CDP 功能仅限 Chromium——通过 CDP 实现的网络限速在 Firefox 或 WebKit 中不适用
  • 测试组合场景——深色模式 + 减少动画 + 特定语言区域组合在一起时,能发现单独测试无法暴露的问题