Repository navigation
fix(browser): preserve replay-critical browser contracts - #640
lanyue-llk wants to merge 15 commits into
Conversation
Sequential Navigation Soak A/B✅ HEAD completed the 200-navigation resilience and memory observation. One browser process, one target, and one CDP session navigate CSDN → SegmentFault → Huaban → example.com repeatedly. This run issued 200 Common ancestor Session resilience
A public-page failure is reported separately from an unrecoverable session. The soak requires all navigation attempts, zero failed recovery, zero lifecycle/network ordering violations, and complete resource evidence. Process-tree memory
HEAD memory by 50-navigation quarter
Raw reports and per-navigation boundary samples: workflow run and full Public-site timing and memory are observational. Use the A/B deltas and trend shape as evidence, not as a deterministic performance threshold. |
Spider Bench A/B✅ All benchmark browser service runs completed; results are informational. Public HEAD: 184 / 240 rows; 38 / 48 sites produced rows; 10 unexpected empty sites. ✅ Deterministic fixture contract is clean. Common ancestor Public 48-site run · informational
Public-site content, timing, and memory are noisy. This single A/B run reports evidence only; site outcome counts explain missing rows without treating them as a deterministic regression. CPU and memory timelinesThese are bounded 40-point views of the same complete process-tree samples used by the HTML report. CPU uses 100% per occupied logical core; memory lines are RSS first and PSS second when complete PSS samples are available. Basexychart-beta
title "Base CPU"
x-axis "Elapsed seconds" [1.035, 1.535, 2.535, 4.037, 5.539, 6.541, 8.042, 9.543, 10.545, 12.047, 13.55, 14.551, 16.053, 17.555, 18.557, 20.059, 21.562, 22.562, 24.063, 25.564, 26.565, 28.067, 29.569, 30.57, 32.071, 33.571, 34.573, 36.075, 37.577, 38.578, 40.08, 41.081, 41.581, 42.582, 44.082, 45.583, 46.584, 47.084]
y-axis "CPU percent" 0 --> 500
line [4, 115.96, 119.99, 117.83, 135.79, 169.55, 53.98, 151.85, 39.88, 67.81, 139.77, 41.97, 45.89, 109.73, 2, 47.99, 127.67, 72.05, 143.87, 111.87, 99.94, 153.8, 143.86, 99.88, 93.85, 116.03, 9.97, 111.68, 149.92, 85.95, 4, 0, 95.9, 125.78, 146, 104.07, 117.82, 202.07]
xychart-beta
title "Base memory: RSS then PSS"
x-axis "Elapsed seconds" [0.035, 1.035, 1.535, 2.535, 4.037, 5.539, 6.541, 8.042, 9.543, 10.545, 12.047, 13.55, 14.551, 16.053, 17.555, 18.557, 20.059, 21.562, 22.562, 24.063, 25.564, 26.565, 28.067, 29.569, 30.57, 32.071, 33.571, 34.573, 36.075, 37.577, 38.578, 40.08, 41.081, 41.581, 42.582, 44.082, 45.583, 46.584, 47.084, 47.712]
y-axis "Memory MiB" 0 --> 500
line [12.11, 61.36, 104.48, 125.19, 129.28, 170.3, 180.93, 172.32, 172.33, 147.6, 189.45, 191.95, 159.86, 158.89, 170.1, 158.18, 149.71, 182.96, 181.89, 166.78, 277.26, 209.98, 159.99, 168.34, 197.27, 174.03, 162.25, 150.73, 190.71, 243.73, 183.9, 166.02, 165.4, 177.34, 180.26, 177.54, 158.32, 179.16, 204.2, 0]
line [9.55, 58.51, 101.66, 122.15, 126.35, 167.69, 178.04, 169.5, 169.7, 144.69, 186.54, 188.9, 156.95, 155.96, 167.24, 155.27, 146.83, 180.02, 178.75, 163.88, 274.22, 207.3, 157.24, 165.73, 194.31, 171.17, 159.46, 147.89, 187.94, 240.9, 181.14, 163.17, 162.56, 174.53, 178.56, 175.91, 155.52, 176.33, 201.43, 0]
HEADxychart-beta
title "HEAD CPU"
x-axis "Elapsed seconds" [1.037, 1.538, 2.038, 2.539, 4.04, 5.543, 6.545, 8.046, 9.546, 10.548, 12.05, 13.552, 14.554, 16.056, 17.558, 18.559, 20.06, 21.561, 22.563, 24.065, 25.566, 26.567, 28.069, 29.071, 29.572, 30.573, 32.074, 33.575, 34.576, 36.077, 37.579, 38.58, 40.081, 41.583, 42.584, 44.086, 45.587, 46.588]
y-axis "CPU percent" 0 --> 500
line [19.96, 119.72, 0, 29.97, 119.85, 167.66, 137.7, 157.99, 192.08, 67.88, 35.9, 5.99, 7.98, 17.98, 163.78, 135.95, 4, 75.99, 7.98, 0, 111.92, 97.94, 147.86, 111.8, 107.75, 121.91, 43.95, 137.84, 157.85, 107.92, 9.99, 85.94, 103.95, 11.99, 7.99, 119.84, 67.95, 101.85]
xychart-beta
title "HEAD memory: RSS then PSS"
x-axis "Elapsed seconds" [0.036, 1.037, 1.538, 2.038, 2.539, 4.04, 5.543, 6.545, 8.046, 9.546, 10.548, 12.05, 13.552, 14.554, 16.056, 17.558, 18.559, 20.06, 21.561, 22.563, 24.065, 25.566, 26.567, 28.069, 29.071, 29.572, 30.573, 32.074, 33.575, 34.576, 36.077, 37.579, 38.58, 40.081, 41.583, 42.584, 44.086, 45.587, 46.588, 47.795]
y-axis "Memory MiB" 0 --> 500
line [12.27, 79.39, 110.52, 109.83, 106.44, 131.82, 148.03, 174.92, 171.65, 184.41, 174.25, 171.48, 167.09, 165.91, 165.49, 147.68, 151.93, 143.27, 141.06, 146.25, 146.71, 173.99, 189.86, 190.82, 305.94, 195.05, 218.6, 160.5, 161.54, 168.33, 163.08, 155.61, 162.46, 172.2, 176.6, 164.44, 192.85, 161.34, 186.17, 0]
line [9.65, 76.55, 107.68, 106.99, 103.62, 129.02, 145.19, 172.1, 168.7, 181.43, 172.34, 168.61, 164.21, 163.04, 162.65, 144.89, 149.06, 140.4, 138.4, 143.11, 143.48, 171.17, 184.31, 187.98, 303.08, 192.03, 215.71, 157.44, 159.33, 165.29, 160.02, 152.66, 159.4, 169.29, 173.54, 161.61, 189.94, 158.1, 183.15, 0]
Deterministic fixture · required contractThe fixture exercises 15 routes: 8 are expected to emit rows and 7 intentionally exercise empty, loading, or timeout behavior.
Full HTML, JSON, CSV, logs, and page snapshots: workflow run and full The public-web A/B is informational. The exact HEAD fixture contract runs as a separate required CI check; timing and public-site content deltas remain non-blocking. |
CI Regression ReportSource CI run · source state at render:
Release regression — ✅ HEAD/base failures 0/0; raw binary +0.043933%Package and image size
Startup latency and PSS
Concurrency matrix
Frontend differential — ✅ 1,020/1,020 cases matched; 0 issues
Agent episodes · Moli vs Chromium — ✅ 8/8 Moli episodes passed; 0 failures
Runtime and CDP session contracts — ✅ 26 contract cases; 0 failures
CDP smoke — ✅ 53/53 groups passed; 622 scenariosWorkers: 4 · cumulative group time: 202.24 s · failed groups: 0
WebMainBench · 545 pages — ✅ 545/545 completed; 0 unexpected failures
Frozen HTML · Linux · Diagnostics: All artifact fields are parsed by the trusted default-branch renderer; missing or invalid inputs remain visible as unavailable. |
|
已同步 main 56cd4dd,保留已有浏览器评测修复及指针按下触发导航后的页面替换处理,合并提交 39d75b6。验证:cargo fmt --all、cargo clippy --workspace --all-targets --all-features -- -D warnings 均通过;cargo nextest run --no-fail-fast:18,372 passed、14 skipped、0 failed。发布构建正在独立工作区执行。随后用同一套冻结轨迹顺序执行 90 题;已完成的 Chromium 为 90/90,Moli 1.1.8 发布版为 55/90。本轮不追加修复这两版 Moli 的评测失败,先发布新的完整对比报告。 |
|
同步 main 后的 39d75b6 发布构建已完成完整 90 题轨迹重放:90/90 通过。对照 Chromium 90/90,Moli 1.1.8 发布版 55/90。四站点组前恢复一次,题间不重置,题号顺序执行,无逐题重试或成绩拼接。三个完整 cohort 已通过证据校验。新报告正在生成,现有 PR 未合并。 |
|
三浏览器完整 90 题轨迹重放报告已独立发布:https://artifact-site.lexmount.cn/v/coY1pMVPbD6Z8cVLaUi_ZbpSnalfKpxY Chromium 90/90;发布版 Moli 1.1.8 55/90;本 PR 修复版 39d75b6 90/90。PR 版已在冻结前同步 main 56cd4dd 并重新 release 编译;fmt/clippy 通过,nextest 18372 passed、14 skipped。三种方法各自组前恢复站点一次,题间不重置,数值题号顺序执行,每题一次,无 Agent/model 调用。本轮保留发布版 35 个失败,没有追加修复或失败补跑。报告提供同题三方法轨迹、原始错误、网络验收和失败诊断。旧报告未覆盖。PR 保持未合并。 |
lanyue-llk
left a comment
There was a problem hiding this comment.
审查结论:建议暂不合入。已对 base 56cd4ddd1a63 → head 39d75b698312 的完整 126 文件差异(+7704/-531)进行分域审查,4 项已验证回归见逐行评论:默认模式点击失败、WebDriver Enter 换行丢失、部分可见元素点击被拒、内部空格 Range 几何丢失。
PR 目的与信息完整性
从代码可以归纳为:①脚本/指针/WebDriver 激活、焦点和隐式提交;②导航、取消、流式完成及 CDP 网络事件/响应体保留;③文本/JSON 文档解析与编码;④布局、根字体、样式状态和几何失效;⑤表单命名查询,以及 SQLite 路径测试和日志输出容错。目的能够还原,但正文的三个笼统条目不足以说明这些行为边界。
仓库没有发现专用 PR 模板;标题和 Summary/Validation 结构没有格式问题,git diff --check 通过。正文验证仍引用 a179ae6e、旧主线提交和 18,369 测试,后续评论才补齐 39d75b69、18,372 测试与报告链接。建议把当前 head、验证结果、关键复现→修复行为和相关证据入口更新到正文,避免读者自行拼接评论。正文“全部是一条不可拆分的跨层行为路径”也过强:SQLite 测试和日志容错等可以独立说明;无需机械按 crate 拆分,按行为契约分组即可。
通用性与额外审查问题
共享激活、按需几何失效和原生 DOM 单一事实来源的方向符合仓库定位;当前实现仍有接口契约未对齐:默认 Mock/OnDemand、CDP 字符阶段/WebDriver named key、文字/atomic inline、完整边界框/视口内点击点。四条意见均给出了共同入口的修复方向,不建议增加针对基准页面或单个 case 的分支。
另有一个已实测的遗漏修复:新增文本 MIME 分流只在主文档 streaming 路径生效。相同 HTTP URL 返回 Content-Type: text/plain 和 <script>window.executed=42</script><b>literal</b>,主文档正确显示完整原文;iframe 却只显示 literal,且 window.executed === 42。这是子文档的既有行为,按“实现是否通用”的问题提出,未计入四项新增回归。能否将 MIME→文档类型/decoder/parser 的选择复用于主、子文档,并加入相同响应的跨 browsing context 测试?
验证依据
- 精确 head 的现有 CI:fmt、clippy、nextest、CDP smoke、前端差分等通过;WebDriver smoke 实际失败,已追到上述默认点击回归。
- 本轮使用精确 head 的 release 二进制完成 Classic HTTP/CDP 实测;二进制 SHA-256 为
1c4dbbe67e4b97c903b3916fe65f8c5676c21810a1f4a9095cf6dfbd9d9286d4。 - 本轮运行布局
phase5_output_contract63/63、编码 80/80 通过;额外空格 Range 复现同一断言 base 通过、head 失败,证明已有测试未覆盖此边界。 - Sequential navigation soak 的失败根因是 base release 下载产物截断,日志为
gzip: unexpected end of file/tar: Unexpected EOF,测试尚未产生比较;需要恢复产物并重跑。它不构成浏览器导航回归证据。
现有基准和大规模测试通过仍遗漏上述确定性接口回归,建议修复四项后补充端到端回归覆盖,再核验当前 head 的 CI。
|
已在 ba5711a 补齐总评提出的主/子文档 MIME 一致性:共用 MIME 分类和 literal-text parser 初始化,解码器不再读取纯文本中的 HTML 编码声明,文本中的剩余 BOM 字符不会被解析器重复丢弃。同一个 HTTP 响应分别作为主文档和 iframe 的对照测试已通过,覆盖纯文本、JSON、JavaScript、HTML 和 BOM。 PR 正文现按行为契约分组,移除了“全部不可拆分”的说法,更新为当前提交的验证结果:全工作区 Clippy 通过,18,381 项 Rust 测试全部通过(14 项原配置跳过,Nextest 另报告 2 项 leaky)。历史 90 题数据明确保留为旧提交证据,未声称重跑了新版本。8 条逐行意见已有各自的修复说明,新提交 CI 继续在本 PR 检查区核验。 |
lanyue-llk
left a comment
There was a problem hiding this comment.
复审结论:建议先修复两处功能回归,再合入。本轮审查的是 ba5711aad25d37744d64e792d18f103c2394acc2,对照 base 56cd4ddd,覆盖全部 138 个修改文件(+8494/-587),同时检查了相对上轮 39d75b69 的增量。
功能与回归
上轮四个原始复现和主/iframe 文本 MIME 不一致现已修复,已做精确 head 的实测复核。进一步扩大使用场景后发现两处问题,已逐行评论:
- 默认 DOM-first 点击输入框返回成功,但焦点仍停在旧控件,后续键盘 actions 写入错误输入框。
- iframe 被父页面覆盖时,WebDriver 点击返回成功,实际激活父页面覆盖层。
这些是共享激活边界缺失,应修共同入口,不应按某个页面增加例外。
测试有没有被删掉或弱化
没有删除整个文件。已逐项检查原断言、测试改名、平台条件、ignore 和 CI 容错分支:
- 发现一处真实覆盖收窄:Linux 非 UTF-8 路径的完整 SQLite 快照测试被替换成路径拼接单测,详见逐行评论,应恢复完整场景。
- 新增了一项 ignore:
form_named_lookup_detached_document_and_adopted_wrappers。本轮在已发布 Moli 1.1.8 和精确 head 都复现 detached/adopted 两组 get/has/descriptor 均为 false,说明这一兼容性失败早已存在;它没有把原先通过的测试改成跳过。PR 验证说明建议单列这一新增跳过项,避免只用“14 preconfigured skips”笼统概括。 - 几何缓存测试由“修改后仍读旧布局”更新为“修改仅标脏,下一次读取刷新,后续复用”,保留并增加了布局次数约束;这是与 README 同步的行为修正。
- 布局绝对坐标改成字体稳定的基线/增量断言;滚动条测试同时覆盖有/无横向溢出;split inline 增加第三片段断言。未发现借修改期望值掩盖本轮回归。
- 子文档网络测试增强后改名,原始字节和长度断言仍在;MIME 集成测试真实覆盖主文档和 iframe。
- 下载步骤新增
continue-on-error仅允许一次重新下载,最终 gzip、checksum、revision 验证仍会失败退出。本轮 archive helper 三个测试均通过。CDP progress 包装会重新抛出失败;同步 XHR 只调整 fixture accepted socket 的阻塞模式,没有放宽浏览器超时或断言。
大段修改与可优化写法
新增代码中至少 5120 行位于明确的测试文件,其他实现文件还包含内嵌测试。重点审阅的较大文件包括 network agent(+259)、projection(+243)、main_document_progress(+220)、WebDriver server(+204)、streaming(+164)。文件本身较长,其中大量代码在 base 已存在,不能把总行数全算成本 PR 的增长。
Rust 的普通函数和 impl 方法都符合其惯用组织方式;for/if 的存在本身不代表缺少抽象。本轮没有依据要求把这些实现整体改成类层级或加入工具框架。已有 projection 职责拆分、逆矩阵外提、viewport 全失效提前返回都是有效简化。
仍有两项明确收益的改进:
- 批量删除统一实现:navigation/revocation 仍逐项调用会扫描 FIFO 的 remove;建议复用一个批量过滤原语。已附微基准和逐行建议,非阻断。
- 重定向规则去重:
moli-protocol/src/domains/network/redirect_request.rs:24–42与moli-fetch/src/request.rs:1068–1083独立维护同一方法重写与 body-header 规则。建议提取小型共享规则函数,保留传输层与 CDP 展示层各自的所有权边界,减少未来两处漂移;当前 POST→302 的实际 HTTP/CDP 对照通过,未将重复代码误报成已发生的功能错误。
本轮实测
- 从干净
ba5711aa工作树独立构建 CLI 成功;SHA-256:0827dde8a5d1118abc33465bb43f2b27d60be64800de811958b0a4bd715687a6。 - bounded-buffer/MIME/encoding/parser:236 个测试通过。
- layout phase4/phase5:36 + 65 个测试通过;额外空格/atomic 换行/双向文本对照也通过。
- Classic 真实 HTTP endpoint 复核点击、Enter、焦点和 iframe 遮挡;CDP/HTTP 复核主/子文档 MIME 与 POST→302 请求元数据。
- 该 head 远程 fmt、clippy、nextest、Windows storage、Python/Node 检查已通过;查询时 release 构建尚未全部完成。上述确定性回归在已有绿灯之外单独复现。
|
已在
最新本地验证:fmt、完整 Clippy 通过;Nextest 18,417 通过、0 失败、14 跳过,退出码 0,同时报告 2 leaky,已原样披露。新构建 CLI 的 WebDriver 7 组/165 检查及 CDP dom-input 27 场景全部通过。CI helper 13、WebDriver Python 7、WPT crashtest 10 项通过;CDP Python 39 项中有 1 项既有跳过,无失败。 原同步 XHR fixture 的 macOS accepted-socket 阻塞问题及严格 release 下载校验已在前一提交修复。旧 CDP 超时未在本地复现,保留逐操作定位和有界退出,未伪称找到未知超时的根因;旧 Agent job 的 Chromium renderer 退出发生于 Page.enable、尚未开始 episode,没有修改浏览器参数或验收标准来掩盖。按本次要求不等待远端 CI;远端最终状态仍以 PR checks 为准。 |
lanyue-llk
left a comment
There was a problem hiding this comment.
本轮审查 5524a9dc82ff689246a062a61d2cd24234697f8c,以当前 main 3ae44b51 为基线(142 个文件,+8692/-600),避免把新合入 main 的变化算成本 PR 引入。
结论:仍有 1 个已证实的新回归,以及 1 个通用性修复遗漏;建议修复后再合入。 两项已逐行评论,并说明了测试为什么遗漏它们。
- 新回归:祖先遮挡修复把合法的后代 frame 命中也拒绝了。相同 iframe/容器目标,顶层可以点击,嵌套后错误返回 intercepted;与
ba5711aa做了实际 A/B。 - 修复遗漏:Document adoptedStyleSheets 的安装/内容更新/移除没有使冻结布局失效。样式颜色变化但几何保持旧值,截图才能刷新。这是现有问题未被本次通用失效方案覆盖,不混称为新回归。
测试质量判断
不能把这些测试整体说成“必然通过的敷衍测试”。本轮检查和实测区分了几种情况:
- 焦点和真实祖先遮挡测试是有效的功能测试。 它们通过公开 Classic endpoint 操作,并断言输入落到哪个控件、目标/覆盖层是否收到事件;前轮问题的原始复现现已通过。问题在于场景维度仍不足:遮挡测试的目标都是普通 button,没有验证目标本身包含另一个 browsing context 的情形。应使用中性 iframe 封装前后的行为等价性,而不是继续围绕
frame_id == ...编写预期。 - 日志测试已明显改进。 现在子进程调用生产
telemetry::init并把 stderr 接到关闭的管道,检查进程是否存活;本轮执行通过。它覆盖实际初始化路径,不再只测试测试文件里重新组装的一份 subscriber。 - 批量 buffer 测试有实际约束。 本轮另用独立 Vec 状态模型做 100 个固定种子、共 100,000 次 insert/replace/缩放预算/retain/删除混合操作,覆盖零预算、空/Unicode key、值变化、FIFO和字节计费,均通过。最新共享 retain 修复了之前的重复扫描。
- 重定向矩阵不是恒真断言,但预期仍过于贴近公式。 用当前源码构造隔离 harness,两项原测试通过;仅把共享重写规则变为“不重写”,保持原测试不动,两项均失败,证明它能抓到行为破坏。不过测试中的 expected 仍复制了同一分类表达式,建议改成明确的状态码/方法/预期方法/预期body表,并保留真实 HTTP 记录 method/body/headers 的端到端对照,以减少实现和预期共同误解规则的风险。
- 布局测试需要按样式入口组织。 属性、
:has()、普通 CSSOM、style文本、media、rem、shadow slot、移除子节点等额外变体通过;Document adoptedStyleSheets 变体失败。测试应验证“等价规则从不同公开入口改变,首次几何读取得到相同新结果”,并避免先截图替失败的 dirty 通知补做刷新。
没有发现最新修复删除原有有效断言来换取通过:Linux 非UTF-8路径完整快照测试已恢复;日志测试用生产路径替换了模拟实现;新增 ignore 的历史问题已在正文单独列明。
其他验证
- 真实 Chromium 与当前 Moli 对照:HTML 已接收、解析器等待慢脚本时 stopLoading,均保留已解析前缀、丢弃未解析部分、不执行迟到脚本,随后导航正常。这类跨阶段操作适合固化为功能回归测试。
- 表单命名查询的 late insertion、外部form重关联、Unicode名称、重复→单项、expando冲突、重新挂接等独立场景通过。
- 当前精确 head 的远程 fmt、clippy、nextest、Windows storage、Python/Node检查通过;release任务查询时仍排队。功能缺陷是在这些绿灯之外复现的。
现有测试有价值,但上述两个公开功能场景说明覆盖尚不充分。下一步应补齐目标/文档层级和样式变更入口的契约测试,再修通用实现;无需为每个HTML标签增加特例分支。
|
本轮两条功能意见都成立,已在
测试写法建议也已采纳。 重定向预期改为明确的 30 行“状态码/原方法/结果方法/结果 body”表,逐项检查实际 headers,不再复制生产分类表达式;真实 HTTP 303/307 方法、请求体与头部对照保留。原日志、buffer、焦点测试有真实行为约束,评论并未说它们整体无效,因此没有为了形式重写或删掉这些有效测试。 新点击和样式测试在生产修复前均失败,修复后定向验证通过。最终完整 Clippy 通过;全量 18,419 项通过、14 项既有跳过、0 失败、无 leaky。新构建生产代码的真实服务测试:WebDriver 7 组/165 项,CDP 27 个 dom-input + 4 个 iframe-input 场景全部通过。 完整测试额外发现已有代理夹具在非阻塞 accept 上偶发 WouldBlock。 |
|
收尾检查发现 main 已前进到 3560c85,且滚动测试夹具与本分支存在一处文件冲突。已通过 87c87e9(chore(merge): sync main after review fixes)合并并解决:采用上游按视口高度构造占位内容的方法,保留本分支全部相关断言和诊断,没有重写历史。合并后 fmt、完整 Clippy 通过;全量18430项通过、14项跳过、1项leaky(具体名称已列入正文);新构建CLI的WebDriver165项与CDP输入31场景通过。本轮五个新提交均采用fix(scope)/test(scope)/chore(scope)格式。PR尚未合并,不等待远端CI。 |
|
已将最新 main(373edf56dde0975f92a59d1c80f14d354a59094c)合入,PR 当前提交为 de48681。合并保留原有修复,并同时保留 main 新增的 RequestHeaderOverride 与重定向辅助函数导出。 验证:cargo fmt --all 通过;cargo build --locked --release -p moli 成功;macOS ARM64 release 启动输出 moli 1.1.9,嵌入的 Git revision 为 de48681。编译有 main 已存在的 websocket_proxy_route_with_env 未使用警告。 本次未重跑本地测试套件或评测。此前 f315ff2 的 90/90 评测证据及二进制保持不变,不将该结果移用到新构建。 新 release 二进制 SHA-256:9af550cebb31a778c2fedb9204235439eb79580b04ef59d1280e85dc0aceea67。 |
lanyue-llk
left a comment
There was a problem hiding this comment.
基于最新 de4868119861ea768fad9807527d0c2042072f4c,对比 base 373edf56dde0975f92a59d1c80f14d354a59094c,复审 147 个变更文件(+9062/-676),重点检查模块边界、状态所有者、类型约束和扩展时的维护成本。
本轮新增 4 项局部维护建议,见逐行评论。其中缓存索引一致性有内部隔离红/绿对照,其余 3 项是明确的维护债务,不冒充已发生的功能故障;本轮没有新增已证实的公开接口回归结论。
依据与取舍:
- 仓库 README 的 native DOM + Stylo 单一来源、默认 Mock / opt-in OnDemand,以及冻结布局快照的生命周期,是本项目架构约束。保留单一 frozen tree、dirty 标记和用于 screencast 的 visual generation 职责不同,本次设计没有因此变成第二套 DOM 或持续增量布局系统,不建议为统一而合并它们。
- Rust 官方 API Guidelines 的 C-CUSTOM-TYPE / C-NEWTYPE、C-VALIDATE 支持把内部语义和有效状态表达在类型/边界中;C-STRUCT-PRIVATE 支持由所属类型维护约束,但明确允许被动数据结构公开字段。以上是设计指导,不是对所有 bool、JSON 或 public 字段的一刀切禁令。
- 仓库 clippy.toml 的同步锁约定及 AGENTS.md 的 fmt/clippy/nextest 要求属于明确工程规范;格式检查通过不能替代架构与行为检查。
- WebDriver 适配语义不应强塞进 HTMLElement.click();Taffy projection 的较大新增代码处理后端尺寸/relative inset 规则,不能仅凭行数大就删成简化公式。较大增量中也有大量功能测试,未以文件长度或总增量作为设计缺陷依据。
测试判断:现有测试不能整体称为敷衍测试。当前缺口更具体:缓存测试最后移除唯一 durable owner,清空分支掩盖了多会话撤销后的索引一致性;应增加基于保留/可见性/预算契约的混合生命周期测试。点击和文本解析的整理应沿用公开行为测试,而非为新 enum 或构造函数编写只验证内部字段的测试。
本轮验证:读取最新源码和相关调用链;使用实际 store/body/bounded-buffer 源码进行隔离失败复现,并仅在临时副本补齐索引清理后通过对照。未修改 PR 代码,未重跑全 workspace,因此不把旧提交或其他 checkout 的测试结果冒称为当前 head 的本轮验证。
PR 正文能说明修复目的,但验证说明仍以旧 87c87e95 为锚点;建议收敛为当前最终行为、架构边界以及明确对应提交的验证结果,历史修复过程留在提交/讨论中。
|
#640 已拆成七个可独立审查的 PR;原 PR 和所有原分支保留。审查报告、五张机制图、35 题归属与证据已移至 artifact-site 报告,仓库证据分支已移除报告和图片。
直接依赖为 734 → 735 → {736, 737},以及 734 → {738, 739, 740}。按 734、735、736、737、738、739、740 审查和合入。七个 PR 已对齐到 main@ 验收范围是 1.1.9 的 34 个失败任务,以及 1.1.8 已失败的 386,共 35 题。原 #640 的 148 个修改文件均有归属;新增的 131 个命名测试全部保留,六个旧测试由新名称承接。逐文件对账记录了与更新后 main 的八处明确差异。 归档已测二进制的结果分别为:输入 4/4、网络按显式就绪合同 3/3、文本 1/1;布局 27 题均有逐题成功证据,但来自同一二进制的 v3 完整轮 26/27 加 v4 单独 547 的 1/1,不能称为 v4 单轮 27/27。原合同布局 26/27、网络 2/3 的失败记录也保留。逐题来源。当前 rebased HEAD 已分别在独立新环境完成对应真实任务:#735 布局单轮 27/27、#736 输入 4/4、#737 网络 3/3、#740 文本 1/1,合计 35/35;各组零重试。四份逐题审计已更新至 artifact-site 报告,历史结果与当前提交严格区分。 |
aef156a to
65a2273
Compare
daf3936 to
2454712
Compare
83a0fd3 to
f380673
Compare
f380673 to
643ebf4
Compare
Keep shared response payloads with per-session accounting, eviction, and lookup. Add protocol regressions and CDP smoke coverage for independent session budgets and reconfiguration.
Verify trusted pointer events use the clipped first client rect center for multiline, fragmented, clipped, and fractional elements, and reject an obstructed first fragment. Run the element-click smoke group with real layout and document Chromium calibration.
643ebf4 to
2e05488
Compare
Purpose
Repair browser contracts exposed by replay and ordinary CDP/WebDriver clients: action activation, document loading, response retention and published geometry. This is the foundation of the stack.
Overall design
Full-size overview · All current PR diagrams
Implementation flow (Mermaid)
Actions use the shared activation path. Navigation retains cancellation and response ownership through document creation. Layout publishes a snapshot that geometry and input readers share.
Scope and ownership
Tests bind navigation milestones to the requested session and loader. Font-sensitive geometry uses the checked-in Ahem font and values independently checked in Chromium.
Dependencies
main → #640 → #731 → #853. This PR targets mainb21b4f056; head2e05488f8. The history was rebased onto main and remains linear.Reproduce affected cases
Local fixtures and expected behavior
Each case below is an existing regression test at this PR's pinned head. The fixtures create their own pages and local services; Rainbond, WebArena credentials and model calls are unnecessary. Follow the repository's Rust toolchain and install cargo-nextest before running. Initial compilation is still required; the filter runs only the listed cases.
native_element_click_reuses_first_fragment_in_view_center_for_all_pointer_phasesnative_element_click_reuses_frozen_layout_after_dom_and_style_changesnative_element_click_does_not_publish_after_scrolling_an_offscreen_targetchild_plain_text_document_uses_pre_and_standards_modechild_document_content_type_uses_resource_mimedurable_response_body_session_budgets_survive_peer_eviction_and_reconfigurationstop_loading_cancels_inflight_unpaused_navigation_transportstop_loading_during_xml_body_preserves_document_and_allows_next_navigationExpected result: all selected tests pass. To run one case, replace the expression after
-Ewithtest(the_case_name). Test failures print the expected/actual assertion. These are regression case identifiers, with inputs and assertions linked to the exact source version.Playwright reproduction through browser-eval
The existing local mechanism probe creates its own loopback HTTP fixture and launches Moli through CDP. It exercises form/fetch redirects, Enter submission, disabled controls, literal JSON documents, geometry observations, and HAR request headers.
Use separate baseline/fixed parent directories for the binaries so their logs remain distinct. The probe prints each binary's observations and an evidence directory; the native tests above supply assertions. Inspect:
belement;No website deployment or account is required for these local fixtures. For a before/after comparison, feed the same fixture to both binaries; the 812-task report remains evidence of its recorded builds.
Evaluation reports
Current-head validation
CI report for #640: all 20 checks passed, including formatting, Clippy, Nextest, CDP/WebDriver, the 1,020-case frontend differential, 545-page WebMainBench, navigation soak and release comparisons.
The complete local suite was run on the cumulative #640 + #731 + #853 tree: 19,809 passed, 14 ignored, with formatting and all-feature Clippy also passing. This cumulative result is separate from this PR's own CI.