
e2e 对话框处理实战3个技巧搞定 alert、confirm 与 beforeunload【免费下载链接】e2eNext generation e2e testing framework for web and mobile apps.项目地址: https://gitcode.com/GitHub_Trending/e2e6/e2e在e2e 测试框架下一代 Web 与移动端 e2e 测试框架中browser.onDialog是处理浏览器原生对话框的核心 API无论是alert提示、confirm确认还是离开页面时的beforeunload挽留弹窗都能用一个统一的路由机制接管。本文面向新手带你快速掌握三种对话框处理姿势让你的 e2e 测试不再被弹窗卡死。为什么 e2e 测试要专门处理对话框浏览器原生对话框alert/confirm/prompt/beforeunload会阻塞页面。在测试里如果没人应答页面就停在那儿后续的点击、断言全部超时——而且报错往往是莫名其妙的 action 超时排查成本很高。e2e 框架的做法是把对话框交给一个DialogRouter统一路由测试通过browser.onDialog注册处理器新注册的优先生效页面弹出对话框时路由到最新的处理器没有注册处理器时框架自动关闭弹窗并在下一步明确报错unhandled … dialog而不是让它静默消失处理器忘了调用accept/dismiss同样会被判定为失败——因为开着不关的对话框必然阻塞页面。这套路由逻辑的源码在 packages/web/src/dialogs.ts官方文档说明见 docs/reference/web.mdx。三种对话框处理方式onDialog支持三种处理器注册后返回一个退订函数用完记得调用避免处理器泄漏到下一个用例一键 acceptaccept字符串处理器适合点确认就完事的场景比如删除确认框const dispose await browser.onDialog(accept); await screen.getByRole(button, Delete everything).tap(); await dispose();一键 dismissdismiss字符串处理器对称地处理取消分支验证取消后订单确实被中止const dispose await browser.onDialog(dismiss); await screen.getByRole(button, Place order).tap(); await expect(screen.getByTestId(error-message)).toHaveText(Order was cancelled); await dispose();这两个用例可以直接参考 apps/testbed/tests/dialogs-frames.e2e.ts 和 apps/web-benchmark/tests/native-dialogs.e2e.ts。自定义函数处理器按消息内容应答prompt输入框、需要根据文案区分场景时注册一个函数即可。处理器收到的Dialog对象有三个成员dialog.message对话框文案可用它做分支判断dialog.accept(text?)接受prompt场景下把text作为输入值提交dialog.dismiss()拒绝。下面这段来自 apps/web-benchmark/tests/native-dialogs.e2e.ts一次点按连续弹出 confirm → prompt → alert 三个框处理器按消息精确应答const dispose await browser.onDialog(async (dialog) { if (dialog.message Enter your gift code) { await dialog.accept(GIFT-7); // prompt填入礼品码 return; } await dialog.accept(); // 其余 confirm/alert接受 });⚠️ 两条契约必须遵守每个对话框只能被应答一次函数返回前必须调用 accept 或 dismiss否则框架会替你关闭弹窗并让下一步失败。beforeunload 离开确认实战beforeunload是页面未保存就离开时的浏览器挽留框本质上同样是原生对话框因此复用同一套onDialog路由在触发页面跳转前注册处理器把挽留框 accept 掉即可让导航完成。// 先注册再导航——顺序不能反 const dispose await browser.onDialog(accept); await app.open(/other-page); // 触发 beforeunload 挽留框 await dispose();新手最常见的坑就是顺序先触发导航再注册处理器挽留框就成了 unhandled dialog下一步报INVALID_STATE。另外注意挽留框文案由浏览器决定不要断言dialog.message的精确文案如果测试本身就是要验证用户取消离开注册dismiss处理器再断言 URL 没有变化处理器是最新注册者胜出所以测试里后注册的临时策略会覆盖先前的用完后调用退订函数还原。常见错误码速查现象错误原因弹窗没人应答INVALID_STATEunhandled dialog未注册onDialog框架已自动关闭弹窗处理器没做决定INVALID_STATE函数返回前未调用accept/dismiss处理器里断言失败ASSERTION_FAILED断言错误原样透传便于定位处理器里抛了普通异常ENGINE_FAILURE未分类异常被框架归类这些行为在 packages/web/src/dialogs.ts 的throwPending与route中实现文档中的完整契约见 docs/reference/web.mdx。小结browser.onDialog一个 API 通吃alert、confirm、prompt与beforeunload简单场景用accept/dismiss复杂场景用函数处理器 dialog.message分支注册要先于触发用完记得退订漏应答、顺序反了都会得到清晰的INVALID_STATE报错而不是玄学超时。更多可运行的对话框用例可浏览 apps/web-benchmark/tests/native-dialogs.e2e.ts、apps/web-benchmark/tests/deferred-dialog.e2e.ts双触发只弹一次的防抖场景与 apps/testbed/tests/dialogs-frames.e2e.ts配套文档入口在 docs/。【免费下载链接】e2eNext generation e2e testing framework for web and mobile apps.项目地址: https://gitcode.com/GitHub_Trending/e2e6/e2e创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考