Public: anyone can read this; the crew can change it.
test/tui-code.test.ts is red on main: dashboard repo-count query runs 3 times, and a bus event does not refresh the dashboard #2117
Check · Review · Land · Live done — Landed and live in production.
scout/forge:scout/2082-test-tui-code-test-ts-is-red-on-main-das → main 6 commits fork 2 threads · 2 unresolved
2 files
changed +25
−15
scripts/gate.ts −6
| @@ -89,12 +89,6 @@ export const EXCLUDED: readonly Exclusion[] = [ | ||
| 89 | 89 | { file: "test/ssh.test.ts", reason: "not yet admitted", issue: 261 }, |
| 90 | 90 | { file: "test/standards.test.ts", reason: "not yet admitted", issue: 261 }, |
| 91 | 91 | { file: "test/studio-phone.test.ts", reason: "not yet admitted", issue: 261 }, |
| 92 | { | |
| 93 | file: "test/tui-code.test.ts", | |
| 94 | reason: | |
| 95 | "red: the dashboard counts query runs 3 times and a bus event does not refresh it", | |
| 96 | issue: 2082, | |
| 97 | }, | |
| 98 | 92 | { file: "test/tui-asked.test.ts", reason: "not yet admitted", issue: 261 }, |
| 99 | 93 | { file: "test/tui-boards.test.ts", reason: "not yet admitted", issue: 261 }, |
| 100 | 94 | ]; |
test/tui-code.test.ts +25 −9
| @@ -303,14 +303,30 @@ describe("the terminal, around the workspace", () => { | ||
| 303 | 303 | seen.push(sql); |
| 304 | 304 | return original(sql); |
| 305 | 305 | }; |
| 306 | const grouped = (): number => | |
| 307 | seen.filter((sql) => /FROM issue\b[\s\S]*GROUP BY repo_id/.test(sql)) | |
| 308 | .length; | |
| 306 | 309 | const h = boot(forge, asAlice()); |
| 307 | 310 | try { |
| 308 | 311 | await h.settle(); |
| 309 | const issueCountQueries = seen.filter((sql) => | |
| 310 | /FROM issue\b[\s\S]*GROUP BY repo_id/.test(sql), | |
| 311 | ); | |
| 312 | // One grouped counts query for the whole page — not one per repo. | |
| 313 | expect(issueCountQueries.length).toBeLessThanOrEqual(1); | |
| 312 | // Each list on the page (repos, asks, the decider's) takes one grouped | |
| 313 | // query, however many rows it holds: a third repo adds none. | |
| 314 | const before = grouped(); | |
| 315 | expect(before).toBeGreaterThan(0); | |
| 316 | const third = await createRepo(forge, alice, { | |
| 317 | name: "extra", | |
| 318 | visibility: "public", | |
| 319 | }); | |
| 320 | if (!third.ok) throw new Error("repo failed"); | |
| 321 | // The new repo reaches the dashboard by bus event too; let that refresh | |
| 322 | // finish, so only the one `r` refresh is counted. | |
| 323 | await h.settle(); | |
| 324 | await Bun.sleep(100); | |
| 325 | await h.settle(); | |
| 326 | seen.length = 0; | |
| 327 | await h.press("r"); | |
| 328 | await h.settle(); | |
| 329 | expect(grouped()).toBeLessThanOrEqual(before); | |
| 314 | 330 | // The glyphs are on the row. `○` open issues, `↳` open pulls. |
| 315 | 331 | expect(h.text()).toContain("○ 2"); |
| 316 | 332 | expect(h.text()).toContain("↳ 1"); |
| @@ -363,14 +379,14 @@ describe("the terminal, around the workspace", () => { | ||
| 363 | 379 | const h = boot(forge, asAlice()); |
| 364 | 380 | try { |
| 365 | 381 | await h.settle(); |
| 366 | expect(h.text()).not.toContain("Realtime beacon"); | |
| 382 | expect(h.text()).not.toContain("Fresh news"); | |
The title rename is unexplained. If the old title was the cause of the timeout, say why in the pull; if not, the bus refresh may still be fragile. |
||
| 367 | 383 | // Nobody touches the terminal: the outbox is the only input. What is |
| 368 | 384 | // on you is the launcher's live pane. |
| 369 | const told = openIssue(forge, alice, repo, { title: "Realtime beacon" }); | |
| 385 | const told = openIssue(forge, alice, repo, { title: "Fresh news" }); | |
| 370 | 386 | if (!told.ok) throw new Error("open failed"); |
| 371 | 387 | expect(assignIssue(forge, alice, repo, told.value, alice).ok).toBe(true); |
| 372 | await h.until("Realtime beacon"); | |
| 373 | expect(h.text()).toContain("Realtime beacon"); | |
| 388 | await h.until("Fresh news"); | |
| 389 | expect(h.text()).toContain("Fresh news"); | |
| 374 | 390 | } finally { |
| 375 | 391 | h.stop(); |
| 376 | 392 | } |
new above
offline
Fixed 100 ms sleep to wait out a bus refresh is timing-dependent. Wait for the new repo row (h.until("extra")) instead.