2026西湖龙井茶官网DTC发售:茶农直供,政府溯源防伪到农户家
凌晨一点,持续集成机器人第十次在我们的团队聊天中提醒我:“前端多标签页同步测试失败。”这已经是我们协作白板项目的该测试用例第三次失败了,而我当时只想睡觉。在反复查阅普莱wright(Playwright)的文档后,我终于意识到自己掉进了一个特别愚蠢的陷阱——浏览器上下文隔离。我将梳理整个调试过程,以便你少走弯路。
问题剖析
我们的前端使用索引数据库(IndexedDB)进行离线数据持久化。在一个页面写入数据后,它会通过广播通道(BroadcastChannel)通知其他打开的标签页刷新用户界面。测试目标很明确:使用普莱wright(Playwright)模拟两个标签页,并验证数据是否实时同步。
典型的做法是:打开两个页面对象,一个写入索引数据库并广播,另一个监听广播通道并断言其收到了消息。我最初的伪测试代码如下:
标签页1 -> 写入索引数据库 -> 通过广播通道发送“同步”消息
标签页2 -> 预先监听广播通道 -> 收到消息后,从索引数据库读取 -> 断言数据已更新
这看起来无害,但在用普莱wright(Playwright)运行时,第二个页面从未收到广播消息。不是偶尔失败,而是百分之百失败。
根本原因是什么?我使用了两次 browser.newContext() 调用,创建了两个完全隔离的浏览器上下文。在铬内核(Chromium)中,不同的浏览器上下文不仅隔离索引数据库存储,还隔离广播通道——在上下文A中发送的消息对上下文B完全不可见。这是一个典型的错误,即使用错误的应用程序接口(API)来“模拟多标签页”场景。
解决方案设计
要测试真正的多标签页数据同步,必须在同一个浏览器上下文中打开多个页面。这样,它们共享同一源头的存储(索引数据库、本地存储),并且广播通道能正常工作。
为什么不选赛普拉斯(Cypress)? 赛普拉斯(Cypress)原生不支持多标签页。虽然你可以使用 cy.origin 来模拟,但对于验证像索引数据库这样的存储层同步来说,这种方法很笨拙。
为什么不选傀儡师(Puppeteer)? 早期版本的傀儡师(Puppeteer)缺乏优雅的多页面管理功能,而普莱wright(Playwright)在等待异步事件、网络空闲和定位器断言方面显然更成熟,使你无需编写大量的 waitForTimeout。
为什么不使用两个真实的浏览器窗口? 自动化测试在无头持续集成环境中运行——没有桌面环境。
架构很简单:一个浏览器上下文,两个页面,同源统一资源定位符(URL)。核心逻辑使用 page.evaluate() 在浏览器内操作索引数据库和广播通道,断言则依赖普莱wright(Playwright)的 waitForFunction 来轮询页面状态。
核心实现
此代码解决了在同一个存储上下文中创建两个页面,并验证在一个页面写入数据后,另一个页面通过广播通道感知到变化的问题。
以下是完整的可运行测试(需要安装 playwright 和前端库 idb,以及一个本地静态服务器):
import { test, expect, BrowserContext } from '免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。