# 设备和环境模拟 > **适用场景**:无需物理设备,全部在 CLI 中测试应用在不同设备、屏幕尺寸、地理位置、语言区域、时区、配色方案和网络条件下的表现。 > **前置条件**:[core-commands.md](core-commands.md) 了解基本 CLI 用法,[running-custom-code.md](running-custom-code.md) 了解 `run-code` 语法 ## 快速参考 ```bash # 通过配置文件模拟设备 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' }); }" ``` ## 视口模拟 设备测试的最简单形式——将视口大小设置为目标设备的尺寸: ### 常见视口尺寸 ```bash # 桌面 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 代) ``` ### 测试响应式断点 ```bash # 常见 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`** ```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 } ``` ```bash playwright-cli open https://example.com --config=iphone14.json ``` **`pixel7.json`** ```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`** ```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` 检查或修改设备属性: ```bash # 检查当前设备属性 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 位置——测试门店定位器、配送区域、基于位置的内容。 ### 设置位置 ```bash # 纽约 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 }); }" ``` ### 在会话中更新位置 模拟用户在不同位置之间移动: ```bash # 从旧金山开始 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 ``` ### 清除地理位置覆盖 ```bash playwright-cli run-code "async page => { await page.context().clearPermissions(); }" ``` ### 通过配置文件设置地理位置 在打开浏览器时设置地理位置: **`geo-nyc.json`** ```json { "geolocation": { "latitude": 40.7128, "longitude": -74.006 }, "permissions": ["geolocation"] } ``` ```bash playwright-cli open https://example.com --config=geo-nyc.json ``` ## 语言区域和时区 通过更改浏览器的语言区域和时区来测试国际化。 ### 通过配置文件 **`locale-de.json`** ```json { "locale": "de-DE", "timezoneId": "Europe/Berlin" } ``` **`locale-ja.json`** ```json { "locale": "ja-JP", "timezoneId": "Asia/Tokyo" } ``` ```bash playwright-cli open https://example.com --config=locale-de.json ``` ### 验证语言区域和时区 ```bash 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` | ## 配色方案 测试深色模式、浅色模式和高对比度: ```bash # 深色模式 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' }); }" ``` ## 减少动画 测试偏好减少动画的用户的可访问性: ```bash # 启用减少动画 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 高对比度模式: ```bash playwright-cli run-code "async page => { await page.emulateMedia({ forcedColors: 'active' }); }" playwright-cli screenshot --filename=high-contrast.png ``` ## 权限 授予或拒绝浏览器权限: ```bash # 授予多个权限 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(); }" ``` 可用权限:`geolocation`、`notifications`、`camera`、`microphone`、`clipboard-read`、`clipboard-write`、`payment-handler`、`midi`、`midi-sysex`、`ambient-light-sensor`、`accelerometer`、`gyroscope`、`magnetometer`、`background-sync` ## 网络条件模拟 模拟慢速网络以测试加载状态和性能: ```bash # 模拟慢速 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 的浏览器。 ## 常见模式 ### 多设备截图套件 ```bash #!/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 ``` ### 基于地理位置的内容测试 ```bash 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 ``` ### 可访问性模拟套件 ```bash 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 中不适用 - **测试组合场景**——深色模式 + 减少动画 + 特定语言区域组合在一起时,能发现单独测试无法暴露的问题