test(e2e): assert author-colored track changes render in the preview

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
BenStullsBets
2026-06-26 14:37:29 -07:00
parent 5d1000096a
commit c579f67a43
4 changed files with 87 additions and 22 deletions
+21 -11
View File
@@ -16,15 +16,16 @@ async function getApi(): Promise<CowritingApi> {
// F10 host E2E (no LLM): the rewrite of the obsolete F9 authorship-mode test.
// F9's "authorship" mode / renderAuthorship is gone — the on-state renderReview
// now author-colors Claude's landed prose. This suite confirms a Claude-landed
// span renders as a cw-by-claude span in the on-state preview HTML. Owns its own
// markdown doc, disjoint from the other suites' fixtures.
suite("F10 review preview — Claude-authored prose is cw-by-claude in the on-state (host E2E, no LLM)", () => {
// now author-colors Claude's PENDING proposal blocks as cw-ins-claude. After the
// proposal is accepted the baseline advances (INV-18/F12) and the text becomes
// "unchanged" → renders plain. The class to check is cw-ins-claude (proposal block),
// NOT cw-by-claude (the old F9 authorship render). Owns its own markdown doc.
suite("F10 review preview — pending Claude proposal renders cw-ins-claude in the on-state (host E2E, no LLM)", () => {
const DOC_REL = "docs/f10claude.md";
const TARGET = "The sentence Claude will compose over.";
const REPLACEMENT = "The sentence CLAUDE COMPOSED via the seam.";
test("an accepted Claude edit author-colors as cw-by-claude in the on-state render; mode defaults to on", async () => {
test("a pending Claude proposal carries cw-ins-claude; accepted proposal leaves attribution data intact; mode defaults to on", async () => {
const abs = path.join(WS, DOC_REL);
fs.mkdirSync(path.dirname(abs), { recursive: true });
fs.writeFileSync(abs, `# F10\n\n${TARGET}\n`, "utf8");
@@ -41,7 +42,7 @@ suite("F10 review preview — Claude-authored prose is cw-by-claude in the on-st
assert.ok(api.trackChangesPreviewController.isOpen(key), "preview open");
assert.strictEqual(api.trackChangesPreviewController.getMode(key), "on", "annotations default to on");
// Claude composes via the seam (propose → accept)
// Claude proposes via the seam (F12 optimistic-apply; proposal stays PENDING)
const start = doc.getText().indexOf(TARGET);
const id = await vscode.commands.executeCommand<string>("cowriting.proposeAgentEdit", {
uri: key,
@@ -52,17 +53,26 @@ suite("F10 review preview — Claude-authored prose is cw-by-claude in the on-st
sessionId: "e2e-f10",
turnId: "turn-f10",
});
assert.ok(id, "propose returns an id");
await settle();
// PENDING proposal: the preview renders the proposal block with cw-ins-claude.
// After accepting, the baseline advances (INV-18) → the text becomes "unchanged"
// and renders plain — so we check BEFORE accepting.
const pendingHtml = api.trackChangesPreviewController.renderHtmlFor(key);
assert.ok(
pendingHtml.includes("cw-ins-claude"),
"pending Claude proposal block carries cw-ins-claude in the on-state render",
);
// accept via the seam — baseline advances (machine-landing, INV-18/F12)
assert.ok(await api.proposalController.acceptById(DOC_REL, id!), "accept applies via the seam");
await settle();
// attribution recorded a Claude (agent) span (data layer intact)
const claudeSpan = api.attributionController.getSpans(DOC_REL).find((s) => s.authorKind === "agent");
assert.ok(claudeSpan, "Claude span recorded by F3");
assert.ok(claudeSpan, "Claude span recorded by F3 (data layer intact after accept)");
const spans = api.attributionController.spansFor(doc);
assert.ok(spans.some((s) => s.author === "claude"), "spansFor reports a Claude span for the preview");
// the on-state render author-colors the landed Claude text as cw-by-claude
const html = api.trackChangesPreviewController.renderHtmlFor(key);
assert.match(html, /<span class="cw-by-claude">/, "landed Claude prose is author-colored in the on-state render");
});
});