使用 Chrome Headless 进行自动化和测试的屏幕配置

Peter Kvitek
Peter Kvitek

我们很高兴地宣布,Chrome 无头模式 (chrome --headless) 和 Headless Shell (chrome-headless-shell) 现在都使用完全可配置的虚拟无头屏幕,该屏幕独立于系统运行 Chrome 时所连接的物理显示屏。可以使用 --screen-info 命令行开关指定初始无头屏幕配置。此开关用于定义每个显示屏的属性,例如原点、大小、缩放比例、屏幕方向和工作区。

当 Chrome 以无头模式运行时,可以使用 Chrome 开发者工具协议 (CDP) 命令 Emulation.addScreenEmulation.removeScreen 添加和移除虚拟无头屏幕。

Puppeteer 完全支持这些新的 Headless Chrome 功能,让您可以自动执行以前难以测试的复杂实际显示场景。无论您是需要验证在 3K 高分辨率显示屏上以全屏模式运行的自助服务终端应用,还是需要在双显示器设置中编排多窗口工作流,亦或是需要确保当用户突然断开连接辅助屏幕时,您的界面能够优雅地适应,现在,Headless Chrome 和 Puppeteer 都能满足您的需求。

测试静态屏幕配置

通过 --screen-info 开关使用静态屏幕配置,以便在静态屏幕环境中评估您的网站。以下列出了一些常见场景:

  • 使用 --start-maximized--start-fullscreen 开关测试行为,同时考虑屏幕工作区和缩放比例(例如,信息亭模式)。
  • 评估 element.requestFullscreen()document.exitFullscreen() 在各种屏幕尺寸和多屏配置中的行为。
  • 观察窗口跨越多个屏幕或在多个屏幕之间移动时的分屏行为。
  • 验证对各种显示设置的处理,包括缩放、分辨率和高 DPI 显示。
  • 评估主屏幕和辅助屏幕上窗口或弹出式窗口的打开情况。

双屏幕配置

以下 Puppeteer 脚本将 Chrome 配置为使用 --screen-info 开关在双屏幕配置中运行。主 800x600 屏幕配置为横向,而直接位于主屏幕右侧的辅助 600x800 屏幕配置为纵向。

import puppeteer from 'puppeteer-core';

const browser = await puppeteer.launch({
  args: ['--screen-info={800x600 label=1st}{600x800 label=2nd}'],
});

const screens = await browser.screens();
const screenInfos = screens.map(
    s =>  `Screen [${s.id}]`

+   ` ${s.left},${s.top} ${s.width}x${s.height}`
+   ` label='${s.label}'`
+   ` isPrimary=${s.isPrimary}`
+   ` isExtended=${s.isExtended}`
+   ` isInternal=${s.isInternal}`
+   ` colorDepth=${s.colorDepth}`
+   ` devicePixelRatio=${s.devicePixelRatio}`
+   ` avail=${s.availLeft},${s.availTop} ${s.availWidth}x${s.availHeight}`
+   ` orientation.type=${s.orientation.type}`
+   ` orientation.angle=${s.orientation.angle}`
);

console.log(`Number of screens: ${screens.length}\n` + screenInfos.join('\n'));

await browser.close();

输出结果

Number of screens: 2
Screen [1] 0,0 800x600 label='1st' isPrimary=true isExtended=true isInternal=false colorDepth=24 devicePixelRatio=1 avail=0,0 800x600 orientation.type=landscapePrimary orientation.angle=0
Screen [2] 800,0 600x800 label='2nd' isPrimary=false isExtended=true isInternal=false colorDepth=24 devicePixelRatio=1 avail=800,0 600x800 orientation.type=portraitPrimary orientation.angle=0

测试动态屏幕配置

动态配置屏幕环境,以测试网站对意外的显示器连接或断开连接的反应,从而模拟现实世界中的用户操作,例如将笔记本电脑连接到台式显示器。这些场景使用 CDP 命令(如 Emulation.addScreenEmulation.removeScreen)进行模拟。借助这些命令,您可以执行以下操作:

  • 验证连接新显示器后,网页是否可以在新显示器的工作区内打开新窗口和弹出式窗口。
  • 确保在网页处于活动状态时断开显示器连接时,其窗口大小和位置能够顺利适应剩余的显示器。

在新屏幕上打开窗口并将其最大化

以下 Puppeteer 脚本会在 800x600 屏幕上的默认位置打开一个窗口,然后将该窗口移动并最大化到新创建的屏幕。然后,将窗口恢复到正常状态。

import puppeteer from 'puppeteer-core';

const browser = await puppeteer.launch({
  args: ['--screen-info={800x600}'],
});

async function logWindowBounds() {
  const bounds = await browser.getWindowBounds(windowId);
  console.log(`${bounds.left},${bounds.top}` +
     ` ${bounds.width}x${bounds.height}` +
     ` ${bounds.windowState}`);
}

const page = await browser.newPage({type: 'window'});
const windowId = await page.windowId();
await logWindowBounds();

const screenInfo = await browser.addScreen({
  left: 800,
  top: 0,
  width: 1600,
  height: 1200,
});

await browser.setWindowBounds(windowId, {
  left: screenInfo.left + 50,
  top: screenInfo.top + 50,
  width: screenInfo.width - 100,
  height: screenInfo.height - 100,
});
await logWindowBounds();

await browser.setWindowBounds(windowId, {windowState: 'maximized'});
await logWindowBounds();

await browser.setWindowBounds(windowId, {windowState: 'normal'});
await logWindowBounds();

await browser.close();

输出结果

20,20 780x580 normal
850,50 1500x1100 normal
800,0 1600x1200 maximized
850,50 1500x1100 normal

更多使用场景、示例和适用范围

在 pptr.dev 上查找更多代码示例。如果您遇到问题,请通过 Puppeteer 在 GitHub 上的公开 bug 跟踪器告知我们。

无头屏幕配置功能已在 Chrome 稳定版中推出,版本号为 142 及更高版本。