🐛 迁移测试端点从 httpbun.com 到 mockhttp.org#1609
Draft
cyfung1031 wants to merge 6 commits into
Draft
Conversation
httpbun.com 近期频繁出现 502 错误导致测试不稳定;mockhttp.org (https://github.com/jaredwray/mockhttp) 开源且更稳定。除替换域名外, mockhttp.org 的响应结构与 httpbun 存在差异(如 /get 用 queryParams 而非 url/args 字段、/post 仅接受 application/json、/redirect-to 默认返回 302 而非 301、/cookies 为无状态桩、无 OPTIONS 路由),已同步调整相关断言; 无法在新端点上验证的用例(cookie 往返、form/binary body 上传)已移除并 注明原因。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
mockhttp.org 的 /cookies 是单一 REST 资源(POST 设置、GET 读取、
DELETE?name= 清除单个),而不是 httpbin/httpbun 风格的
/cookies/set/{name}/{value}、/cookies/delete 路径式接口;此前误判为
"无状态桩" 并整体移除了相关测试。经 curl 逐步验证真实的 Set-Cookie/
Cookie 往返行为后,按正确的接口形状恢复该测试集群。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
实测发现 mockhttp.org 的 /base64/{value} 路由对超过约 100 字符的路径
参数返回 404(未在其 OpenAPI 文档中说明的隐藏限制),而原先沿用 httpbun
时代的 encodedBase64 常量长达 460 字符,导致全部 8 个 "GET basic
[responseType: ...]" 用例在新端点下实际会 404 失败。换用一个编码后仅
76 字符的等价短句,并通过 curl 直接请求真实服务确认解码结果一致。
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
gm_xhr_test.js 与 gm_xhr_redirect_test.js 中 "Redirect handling (finalUrl changes) [default]"/"[follow]" 两个用例此前只校验 status===200 与 finalUrl===target,未校验响应体内容——finalUrl 只能 证明客户端认为自己跟随了重定向,无法证明服务端确实返回了 /get 的正确 响应(而非恰好也是 200 的缓存/错误响应)。现补充校验响应体中 method==="GET" 且 queryParams 与重定向目标的查询参数一致,并已对照 真实 mockhttp.org 服务器验证通过。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
cyfung1031
marked this pull request as draft
July 17, 2026 23:32
Collaborator
Author
|
mockhttp.org 是跑得很快但 API 不齐全。我已经提交了 PR,先把这个设为DRAFT,日后再处理 |
对照真实浏览器扩展运行的测试结果,逐项排查根因并修复(均已用 curl/ 原始 socket 抓包对照真实 mockhttp.org 行为验证): - "GET basic [responseType: *]"(7 项 × fetch/xhr):mockhttp.org 的 /base64 以 Content-Type: text/html 提供响应(httpbun 并非如此), GM_xhr 按其自身 MIME 类型表(src/app/service/content/gm_api/gm_xhr.ts 的 docParseTypes)正确地以 HTML 模式解析 responseXML,得到 HTMLDocument 而非 XMLDocument——两者都是 Document 的子类,断言改为 `instanceof Document` 而非 `instanceof XMLDocument`。 - "responseType=document(parser error)":HTML 解析模式永远不会产生 <parsererror>(这是 XML 模式特有的错误恢复机制),而 mockhttp.org 的 /base64 固定以 text/html 提供内容,导致该用例原有前提在新端点下 不可复现。已重写为验证二进制垃圾数据以 HTML 模式解析不会抛出异常 (仍有意义的回归覆盖),而非依赖不可能出现的解析错误元素。 - "Redirect handling (finalUrl changes) [manual]":更正之前的错误判断 ——这不是 mockhttp.org 302 vs httpbun 301 的差异,而是 ScriptCat 自身 的已知行为:redirect:"manual" 会走 fetch 路径,Fetch 规范使 opaqueredirect 响应的真实状态码不可读,src/pkg/utils/xhr/fetch_xhr.ts 硬编码回退为 301,与服务器真实返回值无关(已用 curl 反复确认 mockhttp.org 该端点始终返回 302,但 GM_xhr 仍报告 301)。断言改回 301 并补充准确注释;已作为独立产品缺陷创建后续任务跟进 (fetch_xhr.ts 是否可通过 webRequest 拿到真实状态码)。 - "onprogress fires while downloading [stream]/[arraybuffer]":用原始 socket 抓包确认 mockhttp.org(经 Cloudflare 代理)会把整个响应体在 服务端缓冲后一次性下发,不会按 /drip 参数真正分批下发字节,因此 onprogress 不可能触发 4 次以上。断言从 >=4 放宽为 >=1 并补充说明。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
该测试脚本本身是通用的 GM_xmlhttpRequest 测试工具,可在 ScriptCat 或 Tampermonkey 下运行(脚本头部未使用任何 ScriptCat 专属 API)。此前为 [manual] 重定向状态码断言添加的注释误将其表述为"ScriptCat 的已知回退 行为"并点名 ScriptCat 内部源码路径(src/pkg/utils/xhr/fetch_xhr.ts) ——这在 Tampermonkey 环境下阅读会造成困惑(该路径根本不存在于 Tampermonkey 中)。改为泛化表述为"任何以此方式实现 manual 重定向的 管理器",不再点名具体扩展或内部实现路径。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checklist / 检查清单
背景
httpbun.com 近期频繁出现 502 错误,导致相关测试不稳定。改用开源、可自托管的 mockhttp.org(更稳定)。mockhttp.org 并非 httpbun/httpbin 的行为复刻,实测发现两者在多个端点上的响应结构、状态码、内容协商等方面存在真实差异——本 PR 不是单纯替换域名字符串,而是对每一处差异逐一核实(curl / 原始 TLS socket 抓包 / 实际浏览器运行测试脚本)并相应调整断言。
本次改动
域名替换:
example/tests/*.js、example/crontab/crontab.js、e2e/gm-api.spec.ts、src/app/service/service_worker/gm_api/mv3_utils.ts中的httpbun.com全部替换为mockhttp.org。e2e/gm-api.spec.ts中用于替换@connect/URL 的正则同步更新;本地 mock server 的/get响应新增method字段,以配合 sync/async GM API 测试新增的finalUrl/method断言。响应结构差异适配:
/get返回queryParams字段而非 httpbin 风格的url/args,相关测试改用finalUrl(XHR 框架自带字段)或queryParams校验。/status/:code响应体格式不同({"status":"..."}而非 httpbin 风格的{"code":...}),已同步调整字符串匹配。/base64/:value以Content-Type: text/html提供内容(httpbun 并非如此),GM_xhr按自身 MIME 类型表(docParseTypes,见src/app/service/content/gm_api/gm_xhr.ts)正确地以 HTML 模式解析responseXML,得到HTMLDocument而非XMLDocument——涉及的 7 项GET basic [responseType: *]断言已从instanceof XMLDocument改为instanceof Document。responseType=document(parser error)用例原依赖 XML 解析失败产生<parsererror>元素,但 HTML 解析模式永远不会产生该元素;已重写为验证二进制垃圾数据以 HTML 模式解析不会抛出异常,而非依赖已不可复现的解析错误路径。/redirect-to默认返回302(而非 httpbun 的301);重定向后续[default]/[follow]用例此前只校验finalUrl,未校验响应体内容——已补充校验重定向目标的响应体method/queryParams,确保验证的是"服务端确实返回了正确响应"而非仅"客户端认为自己跟随了重定向"。/cookies是单一 REST 资源(POST设置、GET读取、DELETE?name=清除单个),而非 httpbin 风格的/cookies/set/{name}/{value}路径式接口。初版误判该端点为无状态桩并整体移除了相关测试,后经 curl 逐步验证真实的Set-Cookie/Cookie往返行为后,按正确的接口形状恢复了完整的匿名 cookie 测试集群。/post仅接受application/json请求体(表单编码/二进制请求体会返回 415),已移除无法在新端点验证的用例并注明原因(对应 mockhttp 侧的修复见下方"关联")。OPTIONS路由(统一 404),自定义 HTTP 方法会在边缘节点返回 502,已放宽相应断言的预期状态码集合。根据实际浏览器运行结果修复(用户执行
gm_xhr_test.jsv1.3.0 后反馈 112 通过 / 22 失败,逐项排查根因):Redirect handling [manual]:更正了此前的错误判断——这并非 mockhttp 302 vs httpbun 301 的服务端差异,而是 ScriptCat/Tampermonkey 自身的已知行为:redirect: "manual"会走 fetch 路径,Fetch 规范使opaqueredirect响应的真实状态码不可从 JS 读取,管理器通常会硬编码一个回退状态码(常见为 301)而非服务器真实返回值(已用 curl 反复确认 mockhttp.org 该端点始终返回 302,但GM_xmlhttpRequest仍报告 301)。断言改回301并补充准确注释;相关表述已泛化,避免点名具体管理器或内部实现路径(该测试脚本本身可在 ScriptCat 或 Tampermonkey 下运行)。onprogress fires while downloading [stream]/[arraybuffer]:用原始 TLS socket 抓包确认 mockhttp.org(经 Cloudflare 代理)会把整个响应体在服务端缓冲后一次性下发,不会按/drip参数真正分批下发字节,因此onprogress不可能触发 4 次以上。断言从>=4放宽为>=1并在注释中记录抓包证据。已知限制
onprogress断言目前为>=1(而非原先针对 httpbun 的>=4),因为 mockhttp.org 的公共实例(Cloudflare + Google Cloud Run)会缓冲整个响应体后一次性下发,与/drip声明的分批下发时长无关。已向 mockhttp 提交 jaredwray/mockhttp#164 增加unbuffered参数尝试绕过代理缓冲;该 PR 尚未合并/部署,即便合并后也需要该仓库测试脚本改用该参数才能恢复>=4断言,本 PR 暂不依赖其结果。application/json请求体统一返回 415。已提交 jaredwray/mockhttp#161(表单编码支持)与 #163(原始/二进制 body 支持),均尚未合并;一旦合并部署,可考虑恢复这些用例。OPTIONS request测试当前预期 404(/anything无OPTIONS路由)。已提交 jaredwray/mockhttp#162 为/anything增加OPTIONS支持,尚未合并;合并部署后需将该断言改回 200,否则会转为失败。Redirect handling [manual]断言的是 ScriptCat/Tampermonkey 自身对redirect: "manual"的已知回退行为(固定报告 301),而非 mockhttp.org 的真实状态码;这是一个独立于本次迁移的产品行为,已作为后续任务跟进(fetch_xhr.ts是否可通过chrome.webRequest拿到真实状态码),不在本 PR 范围内修复。example/tests/gm_xhr_test.js与gm_xhr_redirect_test.js属于手动验证脚本(docs/verification.md工作流),不在自动化 CI(e2e/gm-api.spec.ts)覆盖范围内——CI 覆盖的gm_api_sync_test.js/gm_api_async_test.js/window_message_test.js均通过本地 mock server 运行,不受 mockhttp.org 真实端点行为影响。建议审查重点
example/tests/gm_xhr_test.js中responseXML/response从instanceof XMLDocument改为instanceof Document的 7 处改动,是否符合预期(docParseTypes判定逻辑见src/app/service/content/gm_api/gm_xhr.ts:121-129,374-393)。Redirect handling [manual]断言维持301而非302的注释是否清晰易懂——这是在验证管理器自身的已知回退值,而非服务器真实状态码。关联
配合本次迁移,已向 jaredwray/mockhttp 提交以下上游 PR(均为独立问题,未合并;不影响本 PR 的可合并性):
/base64/:value路径参数超过约 100 字符时静默 404(find-my-way 默认maxParamLength)/post、/anything支持application/x-www-form-urlencoded请求体/anything支持OPTIONS方法/post、/anything支持原始/二进制请求体/drip增加unbuffered参数,尝试绕过反向代理缓冲验证
pnpm exec vitest run tests/example/crontab.test.ts— 通过pnpm exec tsc --noEmit— 无相关错误pnpm exec eslint/pnpm exec prettier --check— 无相关错误pnpm build && npx playwright test e2e/gm-api.spec.ts— 全部 7 个用例通过(sync/async GM API、WindowMessage、CSP、sandbox、inject、unwrap)/get、/post、/anything、/bytes、/delay、/status、/redirect-to、/basic-auth、/headers、/ip、/cookies、/drip、/base64)逐一 curl 及原始 TLS socket 抓包验证实际行为,确认迁移后测试脚本的断言与真实响应一致gm_xhr_test.jsv1.3.0(example/tests/),首次运行反馈 ✅112 ❌22;后续针对 22 处失败逐项排查根因并修复,均已通过对照 mockhttp.org 真实响应验证,但修复后未再次于浏览器中完整重跑该手动测试脚本进行最终确认