测试画布补上对话框和滚动,门禁才能继续(BUG-1440)。
run 5404 的 Python 已过,前端 29 条画不出新零件。页面不改。 Co-Authored-By: Grok (agent loop)
This commit is contained in:
co-authored by
Grok (agent loop)
parent
1c428d7b6e
commit
58e5516fa8
@@ -19526,5 +19526,22 @@
|
||||
- 复发自:BUG-1029。上次是组件搬家后文件清单没跟上;这次是入口删了,断言还锁着旧标签。
|
||||
- 修复版本:分支 `codex/gate-birth-journey-contract-20261025`。
|
||||
- 断言三栏:原值是扫描面必须出现 `<BirthTimeRectification`;新值是扫描面不得出现该标签,且 `page.tsx` 必须挂载 `<ConversationalBirthTimeRectification`;原因是 BUG-1431 去掉了到不了的建档校正卡,校正仍从对话进入。
|
||||
- 后续:下一道门禁(run 5404)的 Python 检查已过。前端还有 29 条,另记 BUG-1440。测试网站仍未更新。
|
||||
|
||||
## BUG-1440 | 测试环境画不出组件库的对话框和滚动
|
||||
|
||||
- 状态:resolved(这 6 份检查已过;测试网站要等这次门禁通过才更新)
|
||||
- 首次发现:2026-10-25
|
||||
- 最近更新:2026-10-25
|
||||
- 影响面:测试环境发布。页面行为没有新的改动。
|
||||
- 用户现象:BUG-1439 合进测试分支之后,测试网站仍停在完整数据版(二)。
|
||||
- 触发条件:run 5404 的快速门。Python 已过。前端 5188 条里 29 条失败,发布镜像被跳过。
|
||||
- 根因:检查用的不是浏览器,是一套自己画的页面。组件库往页面上放对话框时会写入子节点、会读样式、会把确认框画到页面主体上;这套画布少了这三样,注销确认、滚动跟随和校正对话就中断。人物卡的名字改到「打开档案」上之后,点「另一位」点到了「更多操作」,新对话仍挂在本人名下。
|
||||
- 修复:画布补上子节点赋值、样式读取,并在加载组件库之前放好文档,布局效果才不会被关掉。注销确认改到页面主体里核对。打开人物改认「某某 打开档案」,不再点到「更多操作」。页面代码没有改。
|
||||
- 验证:`account-deletion.test.tsx`、`conversation-scroll-anchor-lifecycle.test.tsx`、`new-chat-from-people-lifecycle.test.tsx`、`rectification-dup-question-20260926.test.tsx`、`rectification-latency-20260926.test.tsx`、`rectification-opening-plain-20260926.test.tsx`,50 条通过,0 失败。没有登录浏览器,不把页面走查写成通过。
|
||||
- 防复发:组件库对话框和滚动跟随仍走这套画布。画布再少方法时,先补画布,不要改页面来迁就检查。
|
||||
- 相关记录:BUG-1439、BUG-1043、BUG-1044、BUG-1045、BUG-1046。issue #96。
|
||||
- 修复版本:分支 `codex/gate-birth-journey-contract-20261025`。
|
||||
- 断言三栏:原值是注销确认的字在挂载点里,人物按钮的可见文字里要有名字;新值是注销确认到页面主体里找,打开人物只认「某某 打开档案」;原因是确认框画在页面主体上,人物名字在卡片里,打开档案的按钮没有可见文字。
|
||||
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# PROGRESS · 出生时间合同跟上对话里的校正(2026-10-25)
|
||||
|
||||
没有新工单。测试分支已经含启程(二)到组件库收尾,测试网站仍停在完整数据版(二)。这一张只改一条检查,不改页面。
|
||||
没有新工单。测试分支已经含启程(二)到组件库收尾,测试网站仍停在完整数据版(二)。页面不改,只让检查能画出已经换上的零件。
|
||||
|
||||
## 结论
|
||||
|
||||
建档里的旧校正卡已经不在。校正从对话进入。Python 门禁还在找旧标签,所以从启程(二)那一笔起没有发布。
|
||||
建档里的旧校正卡已经不在。校正从对话进入。Python 那条已经跟上。下一道门禁卡在测试画布画不出新零件,画布已补上。测试网站要等这道门禁通过才更新。
|
||||
|
||||
## 断言改动(原值 / 新值 / 原因)
|
||||
|
||||
@@ -29,6 +29,14 @@
|
||||
|
||||
## 门禁事实
|
||||
|
||||
- 测试网站 `/api/health` 的 `deployment.gitCommit` 仍是 `0b8fcdb842499a2b38f4e618c8c190ffe92e9cf0`。
|
||||
- 测试网站 `/api/health` 的 `deployment.gitCommit` 仍是 `0b8fcdb842499a2b38f4e618c8c190ffe92e9cf0`。这一轮没有再去问健康检查。
|
||||
- #104 的检查通过,发布镜像时下载前端依赖超时,没有部署。
|
||||
- #96 到 #111 的快速门都停在这条 Python 检查。#111 是 1 条失败,其余通过。
|
||||
- BUG-1439 合入后的门禁是 run 5404。Python 已过。前端 5188 条里 29 条失败,镜像没有发布。失败都在测试画布:写不了子节点、读不了样式、注销确认不在挂载点里、人物卡点到了「更多操作」。画布补上之后,这 6 份检查 50 条通过。页面没有改。记 BUG-1440。
|
||||
|
||||
## 断言改动(BUG-1440,原值 / 新值 / 原因)
|
||||
|
||||
| 测试 | 原值 | 新值 | 原因 |
|
||||
| --- | --- | --- | --- |
|
||||
| `account-deletion.test.tsx` 待注销账号 | 注销确认的字和两个按钮在挂载点里 | 到页面主体里找 | 确认框画在页面主体上,挂载点是空的 |
|
||||
| `new-chat-from-people-lifecycle.test.tsx` 打开人物 | 按钮可见文字里要有名字 | 只认「某某 打开档案」 | 名字在卡片里。同名的「更多操作」不能当成点开这个人 |
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
| `TASK-rectification-explicit-open-20261023.md` | `PROGRESS-rectification-explicit-open-20261023.md` | **明说要校正只回一句话(issue #103)**:找会话直接读一张对服务角色撤权的表、必然失败被吞(真正进行中的也续不上);`candidate_accepted` 被算作进行中挡住入口和提议卡;兜底只给一句话。产品选 C;只改入口口径、经 RPC 找会话、删兜底,不改共享状态集合、不动表。BUG-1423 | 已合入 staging | 分支 `codex/rectification-explicit-open-20261023` |
|
||||
| `TASK-chart-table-span-20261023.md` | `PROGRESS-chart-table-span-20261023.md` | **星盘页本命 / 月亮行星表挤进左栏(issue #102)**:#87 给表包了 `ChartSymbolHelp` 后跨栏规则失配;根因修法是 `VedicLayout` 用固定整行容器承载表格,跨栏只认容器;加结构断言防复发。BUG-1422 | 已合入 staging | 分支 `codex/chart-table-span-20261023` |
|
||||
| `TASK-ui-kit-migration-20261023.md` | `PROGRESS-ui-kit-0-base-20261023.md`;`PROGRESS-ui-kit-1-shell-20261023.md`;`PROGRESS-ui-kit-2-chat-20261023.md`;`PROGRESS-ui-kit-3-chart-20261023.md`;`PROGRESS-ui-kit-4-people-20261023.md`;`PROGRESS-ui-kit-5-pages-20261023.md`;`PROGRESS-ui-kit-6-rectification-20261023.md`;`PROGRESS-ui-kit-7-cleanup-20261023.md` | **界面统一换成组件库**:shadcn base-nova(补 `shadcn/tailwind.css`)· Lucide · Motion · react-resizable-panels · dnd-kit · Zustand;lint 拦手写控件(白名单只减不增);对话旁星盘面板;会话、档案拖动排序(动表);长相不变。产品 2026-10-23 拍板 D1~D8;8 个 issue(K0~K7)串行,取代全站动效 #98 #100 #101 | K0–K7 已在测试环境,待验收 | 原型 https://claude.ai/artifact/PGnWsjHhu38KJseEfEMNWG |
|
||||
| —(门禁修复,无新任务书) | `PROGRESS-birth-journey-contract-20261025.md` | **出生时间合同仍要求建档里的旧校正卡(BUG-1439)**:#96 去掉到不了的卡片后,Python 门禁从那一笔起失败,测试网站停在完整数据版(二)。合同改为锁首页对话里的校正。页面不改 | 已合入 staging,等门禁 | `codex/gate-birth-journey-contract-20261025` |
|
||||
| —(门禁修复,无新任务书) | `PROGRESS-birth-journey-contract-20261025.md` | **测试分支过不了门禁,网站停在完整数据版(二)**:BUG-1439 让出生时间合同改锁对话里的校正。下一道门禁 Python 已过,前端 29 条画不出新对话框和滚动(BUG-1440),只补测试画布,页面不改 | 已合入 staging,等门禁 | `codex/gate-birth-journey-contract-20261025` |
|
||||
| `TASK-onboarding-journey-20261022.md` | `PROGRESS-onboarding-1-data-20261022.md`;`PROGRESS-onboarding-2-intake-20261022.md`;`PROGRESS-onboarding-4-motion-20261022.md` | **新用户启程**:建档加「先看谁的盘」(自己 / 帮别人看,本人资料可后补)、人物关系字段、首问免费(服务端原子)、起步三问、启程清单(七项从数据推导,收费项标价,老用户可见)、八条一次性提示(含星盘四页签)、启程流程专用动效。产品 2026-10-22 拍板 D1~D6;动表经产品同意进循环,拆四个 issue 串行。BUG-1420 已被文档去重占用,本轮首问免费记 BUG-1421。(一)T1+T2 在 `codex/onboarding-1-data-20261022`。(二)T3+T4 记 BUG-1431,在 `codex/onboarding-2-intake-20261022`。(四)T7 在 `codex/onboarding-4-motion-20261022` | (一)(二)(三)已在 staging;(四)本分支待验收 | 原型 https://claude.ai/artifact/PcTwMVb9RD611R3qStxv3U |
|
||||
| `TASK-site-motion-20261022.md` | — | **全站动效**:换页按侧栏方向滑入、选中块跟随、页签、盘型切换星体移宫、换人、翻日期、列表补位、弹窗从触发处长出、抽屉、顶部提示、点数滚动、中英交叉淡入;重写 DESIGN §6(推翻 180 ms 上限与 Spatial Instant),不引动画库,先验证 View Transitions。产品 2026-10-22 拍板;三个 issue,排在启程(三)之后、启程(四)之前;**2026-10-23 被 ui-kit-migration 取代** | 已取代 | 原型 https://claude.ai/artifact/7u9goivnmTNSGTNWNeVMQd |
|
||||
| `TASK-rectification-narrower-delivery-20261016.md` | `PROGRESS-rectification-narrower-delivery-fix-20261017.md` | **交付区间收窄**:显示改按活着的簇分段。第 1 次打回只补两处显示漏段(取整差 8 分、缺区间整段退回)。对半出题和门槛 8 改 6 仍不做。基线与对照各 924 条,12 格包含率都过红线。BUG-1367 起,本轮原记 BUG-1370,因与婚恋合盘保留号冲突改为 BUG-1392 | 待验收 | `codex/rectification-narrower-delivery-20261016` |
|
||||
|
||||
@@ -3,6 +3,7 @@ import { readFileSync } from "node:fs";
|
||||
import test from "node:test";
|
||||
import React from "react";
|
||||
|
||||
import { createClientLifecycleHarness } from "./react-client-lifecycle-test-support";
|
||||
import { AccountDeletionGate } from "../src/components/account-deletion-gate";
|
||||
import { AccountDeletionSection } from "../src/components/account-deletion-section";
|
||||
import {
|
||||
@@ -19,13 +20,17 @@ import {
|
||||
runAccountDeletionTick,
|
||||
} from "../src/lib/account-deletion-worker-core";
|
||||
import { LEGAL_ENTITY } from "../src/lib/legal-entity";
|
||||
import { createClientLifecycleHarness } from "./react-client-lifecycle-test-support";
|
||||
|
||||
// Self-service account deletion with a 7-day cooling-off period (2026-09-30).
|
||||
Object.assign(globalThis, { React });
|
||||
const read = (path: string) => readFileSync(new URL(path, import.meta.url), "utf8");
|
||||
const migration = read("../supabase/migrations/20260930020000_account_deletion_requests.sql");
|
||||
|
||||
type HostNode = { tagName: string; text: string; childNodes: HostNode[] };
|
||||
function walkHost(node: HostNode): HostNode[] {
|
||||
return node.childNodes.flatMap((child) => [child, ...walkHost(child)]);
|
||||
}
|
||||
|
||||
test("status parsing, confirmation word, date and error codes", () => {
|
||||
assert.deepEqual(parseAccountDeletionStatus(null), { status: "none" });
|
||||
assert.deepEqual(parseAccountDeletionStatus({ status: "none" }), { status: "none" });
|
||||
@@ -152,10 +157,15 @@ test("a pending account sees 「账号注销中」 with the date and a way back"
|
||||
try {
|
||||
await h.render(<AccountDeletionGate signedIn />);
|
||||
await h.idle();
|
||||
assert.match(h.container.text, /账号注销中/);
|
||||
assert.match(h.container.text, /10 月 7 日 永久删除/);
|
||||
assert.ok(h.elements().some((node) => node.tagName === "BUTTON" && node.text === "撤销注销"));
|
||||
assert.ok(h.elements().some((node) => node.tagName === "BUTTON" && node.text === "退出登录"));
|
||||
// 原值:这句话和两个按钮在挂载点里面。
|
||||
// 新值:到文档体里找。挂载点本身是空的。
|
||||
// 原因:注销确认改成组件库对话框,内容画在页面主体上,不留在原来的格子里。
|
||||
const surface = h.document.body;
|
||||
const surfaceNodes = [surface, ...walkHost(surface)];
|
||||
assert.match(surface.text, /账号注销中/);
|
||||
assert.match(surface.text, /10 月 7 日 永久删除/);
|
||||
assert.ok(surfaceNodes.some((node) => node.tagName === "BUTTON" && node.text === "撤销注销"));
|
||||
assert.ok(surfaceNodes.some((node) => node.tagName === "BUTTON" && node.text === "退出登录"));
|
||||
await h.render(<AccountDeletionGate signedIn={false} />);
|
||||
} finally {
|
||||
globalThis.fetch = originalFetch;
|
||||
|
||||
@@ -275,7 +275,11 @@ async function openDocument(tab: Tab, href: string, options: { mobile?: boolean
|
||||
// 原值:排除类名 `profile-trigger`
|
||||
// 新值:排除类名 `sidebar-account-trigger`
|
||||
// 原因:K1 账户按钮改名。页面上同文案的按钮仍可点,不被页脚账户按钮抢走
|
||||
const found = nodes().find((node) => node.tagName === "BUTTON" && node.text.includes(label)
|
||||
// 原值:按钮的可见文字里要有名字。
|
||||
// 新值:打开档案的按钮没有可见文字,名字在 aria-label「某某 打开档案」上。
|
||||
// 原因:K4 把名字放在卡片里。同名的「更多操作」不能被当成点开这个人。
|
||||
const found = nodes().find((node) => node.tagName === "BUTTON"
|
||||
&& (node.text.includes(label) || String(node.props["aria-label"] ?? "") === `${label} 打开档案`)
|
||||
&& !String(node.props.className ?? "").split(/\s+/).includes("sidebar-account-trigger"));
|
||||
assert.ok(found, `button ${label} is rendered`);
|
||||
return found;
|
||||
@@ -406,7 +410,7 @@ for (const person of [
|
||||
let doc: Awaited<ReturnType<typeof openDocument>> | undefined;
|
||||
try {
|
||||
doc = await openRectificationThenGoTo(tab, api, "星盘档案");
|
||||
await doc.settle(() => doc!.h.elements().some((node) => node.tagName === "BUTTON" && node.text.includes("阿澈")), "the people list");
|
||||
await doc.settle(() => doc!.h.elements().some((node) => node.tagName === "BUTTON" && String(node.props["aria-label"] ?? node.text).includes("阿澈")), "the people list");
|
||||
await doc.h.event(doc.button(person.row));
|
||||
await doc.h.event(doc.button("和 TA 对话"));
|
||||
const assigned = tab.location.assigned.at(-1);
|
||||
@@ -445,7 +449,7 @@ test("a stashed rectification session of the person you left is not reopened as
|
||||
doc = await openRectificationThenGoTo(tab, api, "星盘档案");
|
||||
// 原值: === RECT(离开时存根)。新值: === null。原因: BUG-1052 D3 不再存根;落点断言不变。
|
||||
assert.equal(tab.session.getItem("jyotisha.session-url-return"), null);
|
||||
await doc.settle(() => doc!.h.elements().some((node) => node.tagName === "BUTTON" && node.text.includes("阿澈")), "the people list");
|
||||
await doc.settle(() => doc!.h.elements().some((node) => node.tagName === "BUTTON" && String(node.props["aria-label"] ?? node.text).includes("阿澈")), "the people list");
|
||||
await doc.h.event(doc.button("阿澈"));
|
||||
await doc.h.event(doc.button("看星盘"));
|
||||
const assigned = tab.location.assigned.at(-1);
|
||||
|
||||
@@ -73,7 +73,18 @@ class HostElement {
|
||||
return this.parentNode?.closest(selector) ?? null;
|
||||
}
|
||||
get parentElement() { return this.parentNode; }
|
||||
get children() { return this.childNodes.filter((child) => child.nodeType === 1); }
|
||||
private hasAssignedChildren = false;
|
||||
private assignedChildren: unknown = undefined;
|
||||
get children() {
|
||||
// A test or a library may replace `children`. Until that happens, the live
|
||||
// element list is the child nodes.
|
||||
if (this.hasAssignedChildren) return this.assignedChildren;
|
||||
return this.childNodes.filter((child) => child.nodeType === 1);
|
||||
}
|
||||
set children(value: unknown) {
|
||||
this.hasAssignedChildren = true;
|
||||
this.assignedChildren = value;
|
||||
}
|
||||
matches() { return false; }
|
||||
querySelector() { return null; }
|
||||
querySelectorAll() { return []; }
|
||||
@@ -158,6 +169,17 @@ class HostDocument {
|
||||
createElementNS(_namespace: string, tag: string) { return this.createElement(tag); }
|
||||
}
|
||||
|
||||
// Base UI chooses `useLayoutEffect` or a no-op once, the first time it loads,
|
||||
// by reading `typeof document`. Tests import this harness before those
|
||||
// components so the choice sticks. Each test still installs its own document.
|
||||
if (typeof globalThis.document === "undefined") {
|
||||
Object.defineProperty(globalThis, "document", {
|
||||
value: new HostDocument(),
|
||||
writable: true,
|
||||
configurable: true,
|
||||
});
|
||||
}
|
||||
|
||||
export function createClientLifecycleHarness() {
|
||||
const document = new HostDocument();
|
||||
const frames = new Map<number, ReturnType<typeof setTimeout>>();
|
||||
@@ -184,6 +206,10 @@ export function createClientLifecycleHarness() {
|
||||
filter: "none",
|
||||
willChange: "auto",
|
||||
contain: "none",
|
||||
getPropertyValue(name: string) {
|
||||
if (name === "--space-4") return "16px";
|
||||
return "";
|
||||
},
|
||||
};
|
||||
class KeyboardEvent {}
|
||||
class FocusEvent {}
|
||||
|
||||
Reference in New Issue
Block a user