695b51f903
The review preview (`cowriting.showTrackChangesPreview`) was only reachable from the command palette and `ctrl+alt+r` — neither where a writer's hand naturally goes. Add the obvious right-click entry points to the plugin's central surface: - `explorer/context` + `editor/title/context` menu items gated on `resourceLangId == markdown`, both invoking `showTrackChangesPreview`. - The command now resolves the *clicked* document: it opens the passed Uri if it isn't already an open document (the Explorer case), instead of falling back to the active editor. No-arg invocation (palette / keybinding) is unchanged. - Retitle the command to "Open Cowriting Review Panel" so the menus read the operator's wording (palette shows "Cowriting: Open Cowriting Review Panel"). E2E: clicked-doc resolution (open + not-yet-open + no-arg fallback), both menu contributions present + markdown-gated, title, and keybinding unchanged. Closes #41. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
117 lines
5.6 KiB
TypeScript
117 lines
5.6 KiB
TypeScript
import * as assert from "assert";
|
|
import * as fs from "fs";
|
|
import * as path from "path";
|
|
import * as vscode from "vscode";
|
|
import type { CowritingApi } from "../../../src/extension";
|
|
|
|
const WS = process.env.E2E_WORKSPACE!;
|
|
const settle = () => new Promise((r) => setTimeout(r, 400));
|
|
|
|
async function getApi(): Promise<CowritingApi> {
|
|
const ext = vscode.extensions.getExtension("benstull.vscode-cowriting-plugin")!;
|
|
const api = (await ext.activate()) as CowritingApi;
|
|
assert.ok(api?.trackChangesPreviewController, "exports preview controller");
|
|
return api;
|
|
}
|
|
|
|
/** Write a markdown file under WS and return its uri (without opening it). */
|
|
function writeFile(rel: string, body: string): vscode.Uri {
|
|
const abs = path.join(WS, rel);
|
|
fs.mkdirSync(path.dirname(abs), { recursive: true });
|
|
fs.writeFileSync(abs, body, "utf8");
|
|
return vscode.Uri.file(abs);
|
|
}
|
|
|
|
function pkg(): any {
|
|
return JSON.parse(fs.readFileSync(path.join(__dirname, "../../../../package.json"), "utf8"));
|
|
}
|
|
|
|
// #41 (story): "Open Cowriting Review Panel" reachable from the markdown
|
|
// file/tab right-click menu. The review surface (showTrackChangesPreview) is the
|
|
// plugin's central affordance; this adds explorer/context + editor/title/context
|
|
// entry points and makes the command open the *clicked* document — not merely
|
|
// the active editor — so the explorer right-click works even when the file is
|
|
// not already open.
|
|
suite("#41 review-panel right-click entry (host E2E — menu wiring + clicked-doc resolution)", () => {
|
|
test("command with a Uri previews the CLICKED doc, not the active editor", async () => {
|
|
// Two markdown docs; A is the active editor, B is the right-clicked target.
|
|
const aUri = writeFile("docs/menu-active.md", "# Active\n\nThe active editor's document.\n");
|
|
const bUri = writeFile("docs/menu-clicked.md", "# Clicked\n\nThe right-clicked document.\n");
|
|
const aDoc = await vscode.workspace.openTextDocument(aUri);
|
|
await vscode.window.showTextDocument(aDoc);
|
|
const bDoc = await vscode.workspace.openTextDocument(bUri); // open but NOT active
|
|
await settle();
|
|
const api = await getApi();
|
|
|
|
await vscode.commands.executeCommand("cowriting.showTrackChangesPreview", bUri);
|
|
await settle();
|
|
|
|
assert.strictEqual(api.trackChangesPreviewController.isOpen(bUri.toString()), true, "preview opened for the clicked doc");
|
|
assert.strictEqual(
|
|
api.trackChangesPreviewController.isOpen(aUri.toString()),
|
|
false,
|
|
"the active editor's doc did NOT get a preview",
|
|
);
|
|
assert.ok(bDoc, "clicked doc handle held");
|
|
});
|
|
|
|
test("command with a Uri for a not-yet-open file opens it and previews (explorer case)", async () => {
|
|
// Write a file but do not openTextDocument it — mimics an Explorer right-click.
|
|
const uri = writeFile("docs/menu-unopened.md", "# Unopened\n\nNever opened before the right-click.\n");
|
|
const key = uri.toString();
|
|
const api = await getApi();
|
|
assert.ok(
|
|
!vscode.workspace.textDocuments.some((d) => d.uri.toString() === key),
|
|
"precondition: the file is not an open document",
|
|
);
|
|
|
|
await vscode.commands.executeCommand("cowriting.showTrackChangesPreview", uri);
|
|
await settle();
|
|
|
|
assert.strictEqual(api.trackChangesPreviewController.isOpen(key), true, "the clicked-but-unopened file got a preview");
|
|
});
|
|
|
|
test("no-arg invocation still falls back to the active editor (palette / keybinding unchanged)", async () => {
|
|
const uri = writeFile("docs/menu-noarg.md", "# No-arg\n\nActive editor for the no-arg path.\n");
|
|
const doc = await vscode.workspace.openTextDocument(uri);
|
|
await vscode.window.showTextDocument(doc);
|
|
await settle();
|
|
const api = await getApi();
|
|
|
|
await vscode.commands.executeCommand("cowriting.showTrackChangesPreview");
|
|
await settle();
|
|
|
|
assert.strictEqual(api.trackChangesPreviewController.isOpen(uri.toString()), true, "no-arg previews the active editor");
|
|
});
|
|
|
|
test("explorer/context contributes the review-panel item for markdown only", () => {
|
|
const items = (pkg().contributes.menus["explorer/context"] ?? []) as Array<{ command: string; when?: string }>;
|
|
const entry = items.find((m) => m.command === "cowriting.showTrackChangesPreview");
|
|
assert.ok(entry, "explorer/context has a showTrackChangesPreview entry");
|
|
assert.match(entry!.when ?? "", /resourceLangId == markdown/, "gated on markdown resources");
|
|
});
|
|
|
|
test("editor/title/context (tab right-click) contributes the review-panel item for markdown only", () => {
|
|
const items = (pkg().contributes.menus["editor/title/context"] ?? []) as Array<{ command: string; when?: string }>;
|
|
const entry = items.find((m) => m.command === "cowriting.showTrackChangesPreview");
|
|
assert.ok(entry, "editor/title/context has a showTrackChangesPreview entry");
|
|
assert.match(entry!.when ?? "", /resourceLangId == markdown/, "gated on markdown tabs");
|
|
});
|
|
|
|
test("the command title reads 'Open Cowriting Review Panel'", () => {
|
|
const cmd = (pkg().contributes.commands as Array<{ command: string; title: string }>).find(
|
|
(c) => c.command === "cowriting.showTrackChangesPreview",
|
|
);
|
|
assert.ok(cmd, "command is contributed");
|
|
assert.strictEqual(cmd!.title, "Open Cowriting Review Panel", "menus render this title");
|
|
});
|
|
|
|
test("the ctrl+alt+r keybinding still targets the command (unchanged)", () => {
|
|
const kb = (pkg().contributes.keybindings as Array<{ command: string; key: string; when?: string }>).find(
|
|
(k) => k.command === "cowriting.showTrackChangesPreview",
|
|
);
|
|
assert.ok(kb, "keybinding still present");
|
|
assert.strictEqual(kb!.key, "ctrl+alt+r", "key unchanged");
|
|
});
|
|
});
|