ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Puppeteer Browser.uninstallPWA() 深度解析:通过 CDP PWA.uninstall 卸载已安装 PWA 的完整机制

Puppeteer Browser.uninstallPWA() 深度解析:通过 CDP PWA.uninstall 卸载已安装 PWA 的完整机制 Puppeteer Browser.uninstallPWA() 深度解析:通过 CDP PWA.uninstall 卸载已安装 PWA 的完整机制【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteer本篇技术指南围绕 Puppeteer 的Browser.uninstallPWA()方法展开,完整覆盖其 API 签名、UninstallPWAOptions参数说明与仅限 pipe 连接这一关键使用限制,并结合仓库中 CDP/BiDi 双协议实现与真实测试用例,讲清该方法底层如何通过 CDPPWA.uninstall命令完成卸载、如何验证卸载结果,以及在配置网络限制(banklist/allowlist)时为何会直接抛错。读完后你将掌握:在自动化脚本中正确安装、卸载 PWA 的完整生命周期,以及如何排查uninstallPWA()抛出的典型异常。1. API 定义:签名、参数与返回值Browser.uninstallPWA()用于卸载一个此前已安装的渐进式 Web 应用(Progressive Web App, PWA)。其类型签名(见 api/Browser.ts 的抽象定义)如下:class Browser { abstract uninstallPWA(options: UninstallPWAOptions): Promisevoid; }参数只有一个options,类型为UninstallPWAOptions:属性类型说明默认值manifestIdstringWeb 应用 manifest 文件中的 id无(必填)返回值为Promisevoid,即调用成功不产生返回值,通过 Promise 的 resolve/reject 表示卸载成败。UninstallPWAOptions接口的完整定义位于 api/Browser.ts:/** * Options for {link Browser.uninstallPWA}. * * public */ export interface UninstallPWAOptions { /** * The id from the web apps manifest file. */ manifestId: string; }这里有一个关键点:manifestId就是之前调用Browser.installPWA()时传入并原样返回的那个 id。按照 installPWA 文档的说明,installPWA返回的 manifest id 会回显InstallPWAOptions.manifestId,因此它可以被直接传给Browser.launchPWA()、Browser.getPWAState()或Browser.uninstallPWA()——这构成了PWA 安装 → 查询状态 → 启动 → 卸载完整生命周期中各 API 的参数衔接关系。仓库测试中的实际用法可以印证这一点,测试把本地测试服务器上的目录式 URL 作为 manifest id:const manifestId ${server.PREFIX}/pwa/; await browser.installPWA({ manifestId, installUrlOrBundleUrl: startUrl, }); // ... await browser.uninstallPWA({manifestId});对应源码见 pwa.test.ts。仓库中还提供了真实的 PWA 测试站点资产,包括 index.html 与 manifest.webmanifest,可供理解一个最小可安装 PWA 的结构。2. 前置条件:只能通过 pipe 连接调用uninstallPWA()最重要的使用限制是:只有当 Puppeteer 通过 pipe 连接(进程管道)与浏览器通信时才可用。api/Browser.ts 的官方 remarks 与 installPWA 文档 一致地指出:需要在puppeteer.launch中设置pipe: true,该 launch 选项默认为false;底层的 CDPPWA域不会通过 WebSocket 连接暴露,因此用puppeteer.connect()走 WebSocket 连接已有浏览器时,无法使用这一组 PWA API。一个满足前置条件的最小脚本骨架如下:import puppeteer from puppeteer; // PWA 域要求 pipe 连接,默认值是 false,必须显式开启 const browser await puppeteer.launch({pipe: true}); try { const manifestId await browser.installPWA({ manifestId: https://example.com/app/, installUrlOrBundleUrl: https://example.com/app/index.html, }); // 卸载:参数就是安装时的 manifestId await browser.uninstallPWA({manifestId}); } finally { await browser.close(); }仓库的 PWA 测试套件正是以同样的方式搭建环境的——通过setupSeparateTestBrowserHooks({pipe: true})启动独立测试浏览器,并在源码注释中明确写道ThePWACDP domain is only available over a pipe connection,见 pwa.test.ts。此外,从 BiDi 实现可以看到该 API 的协议边界:BidiBrowser对 PWA 系列方法全部抛出UnsupportedOperation(见 bidi/Browser.ts),也就是说uninstallPWA()目前仅在 CDP 协议(protocol cdp)下可用,WebDriver BiDi 连接下调用会直接失败。3. 源码级实现:一次 CDPPWA.uninstall命令的发送CDP 协议下的实现在 cdp/Browser.ts,全文只有两个逻辑分支:override async uninstallPWA(options: UninstallPWAOptions): Promisevoid { if (this.#hasNetworkRestrictions) { throw new Error( PWA APIs are not supported when network restrictions are configured., ); } await this.#connection.send(PWA.uninstall, { manifestId: options.manifestId, }); }可以从中读出三层信息:协议层极薄:uninstallPWA()本身不维护任何本地状态,它只是把{manifestId}序列化后通过浏览器主连接(connection)发送一条 CDPPWA.uninstall命令,由 Chrome 端完成实际的 PWA 卸载。Promisevoid在浏览器确认命令执行完成后才 resolve。网络限制前置检查:与installPWA()、launchPWA()、getPWAState()完全相同,方法开头会检查#hasNetworkRestrictions。当启动参数中配置了blocklist或allowlist(即对页面访问施加了网络限制)时,会直接抛出错误PWA APIs are not supported when network restrictions are configured.,根本不会发送 CDP 命令。这一行为有专门的回归测试覆盖,见 network_restrictions.test.ts:在配置blocklist与配置allowlist两种场景下,都断言browser.uninstallPWA({manifestId})会 reject 并抛出上述错误消息。错误排查提示:如果你遇到的异常是这条消息,问题不在 manifestId,而在于 launch 参数中同时启用了网络限制——要么移除blocklist/allowlist,要么改用无限制的浏览器实例来执行 PWA 操作。4. 如何验证卸载结果:用getPWAState观察状态反转uninstallPWA()返回void,不提供任何卸载产物,因此验证卸载是否真正生效的惯用手段是查询 PWA 的 OS 层状态。仓库的集成测试 installs and uninstalls a PWA 给出了标准范式(见 pwa.test.ts):// 卸载前:getPWAState 正常 resolve const installedState await browser.getPWAState({manifestId}); expect(installedState.badgeCount).toBe(0); expect(Array.isArray(installedState.fileHandlers)).toBe(true); await browser.uninstallPWA({manifestId}); // 卸载后:查询应用状态应当 reject await expect(browser.getPWAState({manifestId})).rejects.toThrow();这个状态反转测试说明了卸载的语义边界:卸载成功后,Chrome 侧不再持有该 manifestId 对应的已安装应用记录,PWA.getOsAppState(即getPWAState底层命令,见 cdp/Browser.ts)随之失败。反过来,如果调用uninstallPWA之后getPWAState仍然成功 resolve,通常意味着卸载命令未真正完成。同一测试文件还展示了uninstallPWA在启动 PWA 后清理场景中的典型用法:launchPWA启动应用窗口、断言其display-mode: standalone,在finally块中关闭页面并附带.catch(() {})地卸载应用,保证无论断言成败都能清理测试环境,见 pwa.test.ts。5. 与 installPWA 的参数对照及适用边界将本文档的uninstallPWA与其对偶 APIinstallPWA放在一起看,两者的约束条件完全一致、参数形成闭环:维度installPWAuninstallPWA连接方式仅 pipe 连接(launch({pipe: true}))仅 pipe 连接(同左)协议CDP(发送PWA.install)CDP(发送PWA.uninstall)BiDi 支持抛UnsupportedOperation抛UnsupportedOperation网络限制(blocklist/allowlist)抛错,拒绝执行抛错,拒绝执行核心参数manifestIdinstallUrlOrBundleUrl(可选displayMode)仅manifestId返回值Promisestring(回显 manifestId)Promisevoid实现位置cdp/Browser.tscdp/Browser.ts适用边界总结如下:可用环境:本地启动 Chrome 且pipe: true的自动化场景(如 E2E 测试中安装/卸载/启动 PWA 的完整链路);不可用环境:通过 WebSocketconnect到远程浏览器、BiDi 协议连接、或配置了blocklist/allowlist的浏览器实例;manifestId 的来源:必须与installPWA时传入的值一致,通常取自测试/部署服务器上的 PWA 入口 URL。6. 相关文档与源码索引API 文档:Browser.uninstallPWA()、UninstallPWAOptions、Browser.installPWA()、Browser.getPWAState()、Browser.launchPWA()核心实现:CdpBrowser.uninstallPWA、抽象定义与 UninstallPWAOptions、BidiBrowser.uninstallPWA(UnsupportedOperation)测试依据:PWA 安装/卸载/启动集成测试、网络限制下 PWA API 抛错测试、PWA 测试站点资产【免费下载链接】puppeteerJavaScript API for Chrome and Firefox项目地址: https://gitcode.com/GitHub_Trending/puppeteer1/puppeteer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表