import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { currentId } from "../../stores/session"; import { resetStoreFields } from "../../stores/signal-field"; import { stream } from "../../stores/stream"; import { installNotebook } from "../notebook/install"; import { setNotebookRenderImpl } from "../notebook/scroll"; import { turnDone } from "../send/turn"; import { onEvent, resetWsHandlers } from "../ws/registry"; import { renderStored as renderOlderPage } from "../sessions/transcript"; import { renderStored } from "./list"; import { finishStoppedStream } from "./stopped"; import { feed, startStream, type LiveStream } from "./stream"; /** Just enough DOM for the stream and the stored renderer (no jsdom here). */ class FakeClassList { readonly tokens = new Set(); constructor(initial?: string) { if (initial) for (const t of initial.split(/\s+/).filter(Boolean)) this.tokens.add(t); } add(...names: string[]): void { for (const n of names) this.tokens.add(n); } remove(...names: string[]): void { for (const n of names) this.tokens.delete(n); } contains(name: string): boolean { return this.tokens.has(name); } toggle(name: string, force?: boolean): boolean { const on = force === undefined ? !this.tokens.has(name) : force; if (on) this.tokens.add(name); else this.tokens.delete(name); return on; } get value(): string { return [...this.tokens].join(" "); } } class FakeText { data: string; constructor(data: string) { this.data = data; } appendData(more: string): void { this.data += more; } get textContent(): string { return this.data; } } class FakeEl { tagName: string; id = ""; classList = new FakeClassList(); children: Array = []; parent: FakeEl | null = null; dataset: Record = {}; style: Record = {}; onclick: unknown = null; title = ""; scrollTop = 0; scrollHeight = 0; clientHeight = 0; private _text = ""; constructor(tag: string) { this.tagName = tag.toUpperCase(); } get className(): string { return this.classList.value; } set className(value: string) { this.classList = new FakeClassList(value); } get textContent(): string { if (this.children.length) return this.children.map((c) => c.textContent).join(""); return this._text; } set textContent(value: string) { this.children = []; this._text = value == null ? "" : String(value); } set innerHTML(value: string) { this.children = []; // Strip to a fixed point, as the other test doubles do: a single pass over // `<script>` leaves `