在无头模式下配置虚拟屏幕

Peter Kvitek
Peter Kvitek

Chrome 无头模式 (chrome --headless)(以及旧版无头 Shell (chrome-headless-shell))使用完全可配置的虚拟无头屏幕,该屏幕独立于运行 Chrome 的系统所连接的物理显示屏。可以使用 --screen-info 命令行开关指定初始无头屏幕配置。 此开关为每个显示屏定义了来源、大小、缩放比例、屏幕方向和工作区等属性。

当 Chrome 以无头模式运行时,可以使用 Chrome DevTools Protocol (CDP) 命令 Emulation.addScreenEmulation.removeScreen 添加和移除虚拟无头屏幕。

Puppeteer 完全支持这些新的无头 Chrome 功能,让您可以自动执行以前难以测试的复杂真实显示场景。无论您是需要验证在 3K 高分辨率显示屏上以全屏模式运行的信息亭应用,在双显示器设置中编排多窗口模式工作流,还是确保当用户突然断开辅助屏幕时界面能够优雅地适应,无头 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。如果您 遇到问题,请通过 GitHub 上的 Puppeteer 公开 bug 跟踪器告知我们

从 Chrome 稳定版 142 开始,即可使用无头屏幕配置功能。