ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Puppeteer Browser.screens() 深度解析:获取屏幕信息与屏幕模拟的 API 实现

Puppeteer Browser.screens() 深度解析:获取屏幕信息与屏幕模拟的 API 实现 Puppeteer Browser.screens() 深度解析获取屏幕信息与屏幕模拟的 API 实现【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteer在自动化浏览器时多显示器布局、设备像素比、屏幕方向等显示属性往往影响页面渲染结果但标准 API 并没有直接暴露这些信息。本文基于 Puppeteer 官方 API 文档中的Browser.screens()方法讲解如何从Browser实例获取完整的屏幕信息对象列表ScreenInfo[]并结合源码说明其底层如何通过 CDPEmulation域实现、在 BiDi 协议下的行为差异以及与addScreen/removeScreen构成的屏幕模拟能力全貌帮助读者在实际测试中准确掌握显示环境。1.Browser.screens()方法签名与返回值官方 API 文档puppeteer.browser.screens对该方法的定义非常明确Gets a list of screen information objects.class Browser { abstract screens(): PromiseScreenInfo[]; }要点接收方Browser实例通过puppeteer.launch()或puppeteer.connect()获得方法定义在抽象基类 packages/puppeteer-core/src/api/Browser.ts 中声明为abstract由各协议实现CDP / BiDi分别提供具体行为无参数调用时不需要任何配置返回值PromiseScreenInfo[]即浏览器当前可见的全部屏幕信息对象数组每个对象描述一块物理屏幕的几何位置、可用区域、像素密度、色彩深度、方向与主屏/扩展屏标识等。最直接的用法示例const puppeteer require(puppeteer); (async () { const browser await puppeteer.launch(); const screens await browser.screens(); for (const screen of screens) { console.log( 屏幕 ${screen.label}${screen.width}x${screen.height} (${screen.left}, ${screen.top}), 主屏: ${screen.isPrimary}DPR: ${screen.devicePixelRatio}, ); } await browser.close(); })();2.ScreenInfo屏幕信息对象全字段说明screens()返回的每个元素都是 ScreenInfo 接口对象。该接口在源码中定义于 packages/puppeteer-core/src/api/Browser.ts官方文档给出了完整的属性表Description/Default 列在文档中留空以下语义结合接口名与 Web 平台通用屏幕概念说明属于对接口字段的合理对应属性类型含义leftnumber屏幕左边缘在虚拟桌面坐标系中的 X 坐标topnumber屏幕上边缘在虚拟桌面坐标系中的 Y 坐标widthnumber屏幕宽度逻辑像素heightnumber屏幕高度逻辑像素availLeftnumber可用区域工作区左边缘坐标扣除任务栏等系统占用后availTopnumber可用区域上边缘坐标availWidthnumber可用区域宽度availHeightnumber可用区域高度devicePixelRationumber设备像素比即物理像素与 CSS 逻辑像素的比值如 2 表示 Retina 屏colorDepthnumber屏幕色彩位深orientationScreenOrientation屏幕方向包含angle旋转角度与type方向类型字符串两个字段定义见 packages/puppeteer-core/src/api/Browser.tsisExtendedboolean是否为扩展屏非主屏的附加显示器isInternalboolean是否为内置屏幕如笔记本内屏isPrimaryboolean是否为主屏labelstring屏幕标识/名称idstring屏幕唯一标识是后续调用removeScreen(screenId)的入参id字段与label字段是屏幕管理操作的关键获取屏幕列表后可凭id精确移除某块屏幕见第 5 节。3. 源码级实现CDP 路径下的screens()在 CDP 协议实现中screens()直接转发到 DevTools 协议的Emulation域命令。实现位于 packages/puppeteer-core/src/cdp/Browser.tsoverride async screens(): PromiseScreenInfo[] { const {screenInfos} await this.#connection.send( Emulation.getScreenInfos, ); return screenInfos; }调用链为browser.screens()→CDPBrowserpackages/puppeteer-core/src/cdp/Browser.ts→ 底层connection.send(Emulation.getScreenInfos)→ Chrome DevTools 协议返回screenInfos数组。也就是说该 API 本质是 ChromeEmulation域中屏幕模拟功能的只读查询接口——Chrome 内部的屏幕模拟状态可被addScreen动态修改的虚拟屏幕集合决定了这里返回的内容因此在自动化环境下查询结果反映的是被模拟的屏幕环境而非宿主机真实显示器配置这是使用该 API 时必须理解的前提。4. BiDi 路径下的行为差异UnsupportedOperation并非所有浏览器/协议组合都支持屏幕 API。在 WebDriver BiDi 实现中packages/puppeteer-core/src/bidi/Browser.ts 对屏幕三件套的实现是显式抛错override screens(): PromiseScreenInfo[] { throw new UnsupportedOperation(); } override addScreen(_params: AddScreenParams): PromiseScreenInfo { throw new UnsupportedOperation(); } override removeScreen(_screenId: string): Promisevoid { throw new UnsupportedOperation(); }从源码结构看BiDi 端尚未映射 Chrome 的Emulation屏幕模拟能力因此当Browser实例的底层协议为 BiDi 时调用screens()会抛出UnsupportedOperation错误。工程实践建议在跨浏览器Chrome Firefox via BiDi脚本中对屏幕相关调用做try/catch或先判断browser.browserVersion()/协议类型再执行该能力目前应以 CDP 连接Chrome/Chromium 系为准。5. 配套能力addScreen与removeScreen组成完整屏幕模拟闭环screens()的文档页中虽只描述只读查询但在同一Browser抽象类中packages/puppeteer-core/src/api/Browser.ts与之配套的是屏幕的增删操作abstract screens(): PromiseScreenInfo[]; // Adds a new screen, returns the added ScreenInfo. abstract addScreen(params: AddScreenParams): PromiseScreenInfo; abstract removeScreen(screenId: string): Promisevoid;其中addScreen的参数接口 AddScreenParams源码定义见 packages/puppeteer-core/src/api/Browser.ts字段如下参数类型必填说明leftnumber是新屏幕左边缘坐标topnumber是新屏幕上边缘坐标widthnumber是宽度heightnumber是高度workAreaInsetsWorkAreaInsets否可用区域四周的缩进top/left/bottom/right对应任务栏等系统 UI 占用devicePixelRationumber否设备像素比rotationnumber否屏幕旋转colorDepthnumber否色彩位深labelstring否屏幕名称isInternalboolean否是否标记为内置屏CDP 实现packages/puppeteer-core/src/cdp/Browser.ts分别映射到Emulation.addScreen与Emulation.removeScreen命令override async addScreen(params: AddScreenParams): PromiseScreenInfo { const {screenInfo} await this.#connection.send( Emulation.addScreen, params, ); return screenInfo; } override async removeScreen(screenId: string): Promisevoid { return await this.#connection.send(Emulation.removeScreen, {screenId}); }由此形成的典型多屏测试工作流是// 1. 添加一块副屏1920x1080位于主屏右侧DPR 2 const secondary await browser.addScreen({ left: 1920, top: 0, width: 1920, height: 1080, devicePixelRatio: 2, label: Test-Secondary, }); // 2. 查询当前全部屏幕确认布局 const screens await browser.screens(); // 3. 测试结束后按 id 精确清理 await browser.removeScreen(secondary.id);这一添加 → 查询 → 移除的模式可用于验证依赖window.screen、matchMedia或窗口放置逻辑的页面在多显示器场景下的表现。6. 使用注意与适用前提协议前提screens()在 CDP 实现中可用在 BiDi 实现中会抛出UnsupportedOperation见 packages/puppeteer-core/src/bidi/Browser.ts。跨协议脚本必须做防御性处理。返回的是模拟态屏幕集合CDP 实现查询的是Emulation域维护的屏幕状态addScreen修改的也是这一虚拟集合因此结果反映的是自动化环境下的模拟屏幕而非宿主机真实显示器由 CDP 命令实现可确认该调用路径具体返回内容以 ChromeEmulation域行为为准。id与label的用途区分label用于人类可读标识id是removeScreen的唯一有效入参自动化脚本中应保存addScreen返回值中的id以便清理。orientation子结构ScreenOrientation只有anglenumber与typestring两个字段见 packages/puppeteer-core/src/api/Browser.ts如需更细的方向枚举语义应结合被测页面的screen.orientationAPI 交叉验证。相关文档可进一步参考ScreenInfo 接口、ScreenOrientation、AddScreenParams、Browser.addScreen、Browser.removeScreen。7. 小结Browser.screens()是一个零参数、返回ScreenInfo[]的抽象方法其 CDP 实现直接调用 Chrome DevTools 协议的Emulation.getScreenInfos与addScreenEmulation.addScreen、removeScreenEmulation.removeScreen共同构成完整的屏幕模拟查询/变更能力BiDi 协议目前对该能力抛出UnsupportedOperation。掌握ScreenInfo的 16 个字段尤其是id、isPrimary、devicePixelRatio、orientation与AddScreenParams的可选参数即可在多显示器布局、DPR 差异、屏幕方向等显示相关测试场景中构造并校验受控的屏幕环境。【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表