|
17 | 17 | * 真 `SessionViewHost` + 真惰性三轨视图(与 `SessionDetailPanel.test.tsx` 同一形态)。 |
18 | 18 | */ |
19 | 19 | import { act, cleanup, render, screen } from "@testing-library/react"; |
| 20 | +import { readFileSync } from "node:fs"; |
| 21 | +import { dirname, join } from "node:path"; |
| 22 | +import { fileURLToPath } from "node:url"; |
20 | 23 | import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; |
21 | 24 | import type { SessionDetail } from "../types"; |
22 | 25 |
|
@@ -99,7 +102,8 @@ describe("SessionsPage · [[ts:ms]] 深链(T17 · C27.4 的 M3 的页面层闭 |
99 | 102 | onOpenNote={noop} |
100 | 103 | />, |
101 | 104 | ); |
102 | | - await screen.findByTestId("session-tritrack-view"); |
| 105 | + // 惰性三轨视图的 chunk 在并行跑多文件时可能 >1s(`findBy*` 缺省 1s)⇒ 显式放宽等待 |
| 106 | + await screen.findByTestId("session-tritrack-view", undefined, { timeout: 5000 }); |
103 | 107 | expect(invokeMock.mock.calls.filter((c) => c[0] === "get_session_detail"), "深链必须拉目标会话详情") |
104 | 108 | .toEqual([["get_session_detail", { id: 1042 }]]); |
105 | 109 | expect(playheads(container), "深链的 ms 没落到播放头上(「定位到 ms」不可感知)").toEqual(["5000"]); |
@@ -134,8 +138,25 @@ describe("SessionsPage · [[ts:ms]] 深链(T17 · C27.4 的 M3 的页面层闭 |
134 | 138 | await act(async () => { |
135 | 139 | pending.resolve(detailOf(2043, "会话乙")); |
136 | 140 | }); |
137 | | - await screen.findByTestId("session-tritrack-view"); |
| 141 | + // 惰性三轨视图的 chunk 在并行跑多文件时可能 >1s(`findBy*` 缺省 1s)⇒ 显式放宽等待 |
| 142 | + await screen.findByTestId("session-tritrack-view", undefined, { timeout: 5000 }); |
138 | 143 | expect(onFocusSeekConsumed).toHaveBeenCalledTimes(1); |
139 | 144 | expect(playheads(view.container)).toEqual(["5000"]); |
140 | 145 | }); |
| 146 | + |
| 147 | + /** |
| 148 | + * ③ **源码级锚**(补深链的**第一跳**):`App.goSessions` 把 ms 写进焦点载体。 |
| 149 | + * @ai_context 形态取自已有的同类仪器 `shell/CommandPalette.kb.test.tsx`(它同样把 `App.tsx` |
| 150 | + * 当源码文本读、按正则钉 `const [focusSeekMs, setFocusSeekMs]` 的声明与入口函数表)—— |
| 151 | + * `App` 没有渲染级测试(渲染它 = 拉起整棵应用树),而这一跳是深链的**唯一入口**, |
| 152 | + * 丢了 ms 会让下面所有判据都「绿得毫无意义」。故用**源码级**锚把它钉住(诚实边界: |
| 153 | + * 它证明的是「这一行还在」,不是「运行期真的写进去了」——后者由 ① 的页面级判据接续)。 |
| 154 | + */ |
| 155 | + it("③ 源码级锚:`goSessions` 把 ms 逐字写进焦点载体(丢了它整条深链失效)", () => { |
| 156 | + const app = readFileSync(join(dirname(fileURLToPath(import.meta.url)), "..", "App.tsx"), "utf8"); |
| 157 | + const body = /const goSessions = \([\s\S]*?\n {2}\};/.exec(app)?.[0] ?? ""; |
| 158 | + expect(body, "App.tsx 里找不到 `goSessions` 的定义体(锚漂了 ⇒ 本判据失效,先修锚)").not.toBe(""); |
| 159 | + expect(body, "`goSessions` 又丢了 ms(`[[ts:ms]]` 深链的第一跳断在这里)") |
| 160 | + .toMatch(/setFocusSeekMs\(ms === undefined \? null : \{ ms, key \}\)/); |
| 161 | + }); |
141 | 162 | }); |
0 commit comments