e2e Web测试疑难清单:12个常见失败场景与解决方案
【免费下载链接】e2eNext generation e2e testing framework for web and mobile apps.项目地址: https://gitcode.com/GitHub_Trending/e2e6/e2e
写Web端 E2E 测试时,最折磨人的往往不是业务逻辑,而是那些"看得见却点不到"的界面角落。本文基于 e2e 框架自带的 42 个"刁难场景"基准应用 apps/web-benchmark/,整理出 12 个高频失败场景与对应解法。e2e 是一个面向 Web 和移动端的新一代 E2E 测试框架:你可以用自然语言让 AI Agent 驱动应用完成操作,再用定位器(locators)和断言(assertions)在同一个测试里做确定性校验——两者结合,正是应对这些疑难场景的核心思路。
一、选择器打不到的场景(3个)
1. Shadow DOM 深层表单
表单被埋在多层 open/closed 影子根里,普通 CSS 选择器根本够不着。e2e 的screen查询可以穿透影子边界,直接按占位符和角色取值,无需手动拼接>>>选择器:
- 参考用例:apps/web-benchmark/tests/shadow-dom-form.e2e.ts
- 场景源码:apps/web-benchmark/app/src/Examples/
2. 跨 iframe 读写
验证码显示在一个 iframe,提交表单在另一个 iframe。用browser.frameLocator()定位到目标框架后再操作即可,注意每个框架内的元素属于该框架的"世界",跨框架的instanceof判断永远为假(这是经典坑):
- 参考用例:apps/web-benchmark/tests/iframe-form.e2e.ts
3. "撒谎"的可访问性树
aria-label被打乱、placeholder 张冠李戴,a11y 树与肉眼所见完全对不上。此时语义树不可信,应让 Agent 开启vision: true以像素证据为准,或用可见文本定位而非可访问名称。对应场景:LyingLabels 与 AriaHiddenFlow。
二、页面上根本没有 DOM(3个)
4. Canvas 纯画布界面
整个流程画在<canvas>上——没有 DOM、没有文本节点,选择器体系彻底失效。解法是走像素:用视觉观察(vision)+ 坐标点按完成流程,e2e 的 Web 引擎内置了像素级工具支持这类"纯视觉"页面:
- 参考用例:apps/web-benchmark/tests/canvas-only.e2e.ts
5. 图片化 UI
操作指引被渲染成图片、按钮只剩 icon,DOM 里零可读文本。处理方式与 Canvas 相同:依赖截图理解画面,按坐标交互,断言则校验成功页的像素或最终 URL。
6. CSS 伪元素"文字"
所有标签来自::before/::after的 content,DOM 里是一堆空 div。这些文字既不在文本节点里,也不在可访问树里,同样只能靠视觉识别后按坐标操作。
三、列表与滚动类(2个)
7. 无限滚动找目标
目标条目藏在几百条数据之后。不要写死"滚 N 次",而是用expect的轮询断言:持续滚动直到toHaveText/toBeVisible满足为止,既稳又快:
- 参考用例:apps/web-benchmark/tests/infinite-scroll.e2e.ts
8. 虚拟滚动表格
窗口化表格中屏幕外的行根本不在 DOM 里,直接定位必然LOCATOR_NOT_FOUND。正确姿势是滚动后等待,让目标行"进屏"再断言;配合expect的自动轮询,无需手写 sleep。
四、遮挡与时序类(3个)
9. 遮罩陷阱(Cookie 横幅 / 隐形拦截层)
目标按钮被 Cookie 横幅或一个透明的点击拦截层盖住,点击直接ACTION_FAILED。先关闭或滚动让开所有 overlay 再操作目标;Agent 模式(agent.act)会自动识别并先处理遮挡物:
- 参考用例:apps/web-benchmark/tests/overlay-trap.e2e.ts
10. 异步状态三件套(骨架屏 / 瞬时 Toast / 延迟启用按钮)
提交按钮要等骨架屏消失后才可点,成功提示一闪而过。e2e 的expect默认自动轮询,等状态"稳定落定"再判定;对瞬时 Toast,先expect(toast).toBeVisible()抓住它再读内容:
- 参考用例:apps/web-benchmark/tests/async-states.e2e.ts
11. 每秒重挂载的"过期 DOM"
列表节点每 1 秒销毁重建,拿到的节点引用秒变 stale。不要缓存节点引用,每次操作前重新解析定位器;expect的轮询机制天然适应这种"动起来的"页面:
- 参考用例:apps/web-benchmark/tests/stale-dom.e2e.ts
五、交互特殊机制(4个)
12. 防抖搜索 + Portal 下拉
输入触发防抖后,候选项渲染在 portal 里(挂在 body 末尾,不在输入框 DOM 里)。等防抖窗口过去再点选项即可,断言用toContainText匹配结果。
13. 仅悬停展开的菜单 / 原生对话框
嵌套下拉只在 hover 时展开,必须模拟真实鼠标悬停;而alert / confirm / prompt原生弹窗会阻塞整个页面,需要注册对话框处理器按脚本应答:
- 参考用例:apps/web-benchmark/tests/native-dialogs.e2e.ts
14. 指针拖拽(Kanban 看板)
看板只认 Pointer 事件且带拖拽阈值,HTML5 drag 事件完全无效。e2e 的 Web 引擎提供指针坐标与路径级操作(按下→移动→抬起),见 apps/testbed/ 中的 pointer 用例。
15. 纯 div 堆砌的登录页(Div Soup)
没有任何 role、label、testid 的"远古风格"页面,确定性定位几乎无解。这正是 AI Agent 的用武之地:一句agent.act("登录账号"),Agent 靠视觉+坐标完成操作,再用确定性断言收口结果。
附:失败时如何快速定位 🛠️
e2e 每次运行都会生成.e2e/report.json报告与截图/录屏产物,退出码可直接区分故障类型:1测试失败、2配置问题、3引擎/环境故障。常见错误码速查(完整清单见 docs/reference/errors.mdx):
| 错误码 | 常见原因 | 解法 |
|---|---|---|
LOCATOR_NOT_FOUND | 角色/名称不匹配、元素在 iframe 内、页面没打开 | 读可访问名称、exact: false、frameLocator |
LOCATOR_AMBIGUOUS | 多个匹配(隐藏副本、重名标签) | 加{ name }、容器内限定、first() |
ASSERTION_FAILED | 期望写错或状态 5s 后仍未落定 | 对照截图、加大{ timeout } |
ACTION_FAILED | 元素被遮挡/禁用/已卸载 | 先用expect等对条件、关闭遮罩 |
APP_UNREACHABLE | 应用没起来或端口不对 | 检查app.command日志、加大启动超时 |
排查三板斧:--headed开可见浏览器亲眼看着跑、--video录屏回放失败现场、--debug查看每步 Agent 的耗时与模型调用明细,详见 docs/debugging.mdx。
小结
- 选择器够不着(Shadow DOM / iframe / 假 a11y)→ 用穿透查询、
frameLocator、视觉证据 - 没有 DOM(Canvas / 图片 UI / CSS 文字)→ 视觉 + 坐标操作
- 页面在动(滚动 / 虚拟列表 / 遮罩 / 异步 / 重挂载)→
expect自动轮询,别缓存引用 - 交互特殊(拖拽 / 悬停 / 对话框 / 无标签页面)→ 指针手势、对话框处理器、AI Agent 兜底
- 失败看不懂→ 看
.e2e/report.json、对照错误码表、--headed+--video复现
场景目录与规则说明可以持续在 apps/web-benchmark/app/src/examples.ts 中查阅,每个场景都有对应的确定性测试与 Agent 测试双份覆盖,是学习"如何写稳 E2E 测试"的绝佳素材 📌
【免费下载链接】e2eNext generation e2e testing framework for web and mobile apps.项目地址: https://gitcode.com/GitHub_Trending/e2e6/e2e
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考