From 5a769dbe3d037bd5d14e00cbaf1b3ab601c078c8 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 12 Mar 2026 18:19:41 +0100 Subject: [PATCH 1/8] Started working on reuse sing editor for tests --- .../src/suite/recorded.vscode.test.ts | 22 ++++++++----- .../src/testUtil/openNewEditor.ts | 31 ++++++++++++++++--- 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/packages/cursorless-vscode-e2e/src/suite/recorded.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/recorded.vscode.test.ts index 7244dff658..dda071aefd 100644 --- a/packages/cursorless-vscode-e2e/src/suite/recorded.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/recorded.vscode.test.ts @@ -5,9 +5,11 @@ import { asyncSafety, } from "@cursorless/common"; import { getRecordedTestPaths, runRecordedTest } from "@cursorless/node-common"; +import type { VscodeTestHelpers } from "@cursorless/vscode-common"; import { getCursorlessApi, openNewEditor, + reuseEditor, runCursorlessCommand, } from "@cursorless/vscode-common"; import * as vscode from "vscode"; @@ -46,19 +48,23 @@ suite("recorded test cases", async function () { ); }); +let testHelpers: VscodeTestHelpers | undefined; +let vsTextEditor: vscode.TextEditor | undefined; + async function openNewTestEditor( content: string, languageId: string, ): Promise { - const { fromVscodeEditor } = (await getCursorlessApi()).testHelpers!; - - const editor = await openNewEditor(content, { - languageId, - openBeside: false, - }); + if (vsTextEditor == null) { + vsTextEditor = await openNewEditor(content, { languageId }); + } else { + vsTextEditor = await reuseEditor(vsTextEditor, content, languageId); + } // Override any user settings and make sure tests run with default tabs. - editor.options = DEFAULT_TEXT_EDITOR_OPTIONS_FOR_TEST; + vsTextEditor.options = DEFAULT_TEXT_EDITOR_OPTIONS_FOR_TEST; + + testHelpers ??= (await getCursorlessApi()).testHelpers!; - return fromVscodeEditor(editor); + return testHelpers.fromVscodeEditor(vsTextEditor); } diff --git a/packages/vscode-common/src/testUtil/openNewEditor.ts b/packages/vscode-common/src/testUtil/openNewEditor.ts index 5df456dad8..d7aca90b60 100644 --- a/packages/vscode-common/src/testUtil/openNewEditor.ts +++ b/packages/vscode-common/src/testUtil/openNewEditor.ts @@ -10,6 +10,8 @@ export async function openNewEditor( content: string, { languageId = "plaintext", openBeside = false }: NewEditorOptions = {}, ): Promise { + await closeUiElements(); + if (!openBeside) { await vscode.commands.executeCommand("workbench.action.closeAllEditors"); } @@ -35,9 +37,6 @@ export async function openNewEditor( await editor.edit((editBuilder) => editBuilder.setEndOfLine(eol)); } - // Many times running these tests opens the sidebar, which slows performance. Close it. - vscode.commands.executeCommand("workbench.action.closeSidebar"); - return editor; } @@ -45,12 +44,27 @@ export async function reuseEditor( editor: vscode.TextEditor, content: string, language: string = "plaintext", -) { +): Promise { + await closeUiElements(); + + // If the editor is not already active, make it active and close all other editors + if (editor !== vscode.window.activeTextEditor) { + editor = await vscode.window.showTextDocument(editor.document); + // Close other groups + await vscode.commands.executeCommand( + "workbench.action.closeEditorsInOtherGroups", + ); + // Close other editors in the same group + await vscode.commands.executeCommand("workbench.action.closeOtherEditors"); + } + + // If the editor is not already the right language, change its language and reload the parse tree if (editor.document.languageId !== language) { await vscode.languages.setTextDocumentLanguage(editor.document, language); await (await getParseTreeApi()).loadLanguage(language); } + // Replace the entire contents of the editor with the new content await editor.edit((editBuilder) => { editBuilder.replace( new vscode.Range( @@ -67,6 +81,8 @@ export async function reuseEditor( editBuilder.setEndOfLine(eol); } }); + + return editor; } /** @@ -124,3 +140,10 @@ function waitForEditorToOpen(): Promise { }, 100); }); } + +async function closeUiElements() { + // Many times running these tests opens the sidebar, which slows performance. Close it. + await vscode.commands.executeCommand("workbench.action.closeSidebar"); + // Close the find widget as well, since it can also be open and cause performance issues. + await vscode.commands.executeCommand("closeFindWidget"); +} From ae954998cb888ad5413cd65c7347f4b06d15486f Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 12 Mar 2026 18:44:05 +0100 Subject: [PATCH 2/8] fix up --- .../src/suite/fold.vscode.test.ts | 8 +-- .../src/suite/followLink.vscode.test.ts | 7 ++- .../suite/instanceAcrossSplit.vscode.test.ts | 4 +- .../src/suite/keyboard/basic.vscode.test.ts | 12 +--- .../src/suite/performance.vscode.test.ts | 2 +- .../src/suite/pourAcrossSplit.vscode.test.ts | 2 +- .../src/suite/recorded.vscode.test.ts | 18 ++---- .../scopeProvider/runBasicScopeInfoTest.ts | 4 +- .../runBasicMultilineContentTest.ts | 4 +- .../runNestedMultilineContentTest.ts | 4 +- .../src/suite/visible.vscode.test.ts | 4 +- .../wrapWithSnippetAcrossSplit.vscode.test.ts | 2 +- packages/vscode-common/src/index.ts | 1 + .../src/testUtil/closeUiElements.ts | 8 +++ .../src/testUtil/getReusableEditor.ts | 59 ++++++++++++++++++ .../src/testUtil/openNewEditor.ts | 61 +------------------ 16 files changed, 93 insertions(+), 107 deletions(-) create mode 100644 packages/vscode-common/src/testUtil/closeUiElements.ts create mode 100644 packages/vscode-common/src/testUtil/getReusableEditor.ts diff --git a/packages/cursorless-vscode-e2e/src/suite/fold.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/fold.vscode.test.ts index 46ddc58fa5..5c92d01c6c 100644 --- a/packages/cursorless-vscode-e2e/src/suite/fold.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/fold.vscode.test.ts @@ -12,9 +12,7 @@ suite("fold", async function () { }); async function foldMade() { - const editor = await openNewEditor("function myFunk() {\n\n}", { - languageId: "typescript", - }); + const editor = await openNewEditor("function myFunk() {\n\n}", "typescript"); await runCursorlessCommand({ version: LATEST_VERSION, @@ -38,9 +36,7 @@ async function foldMade() { } async function unfoldMade() { - const editor = await openNewEditor("function myFunk() {\n\n}", { - languageId: "typescript", - }); + const editor = await openNewEditor("function myFunk() {\n\n}", "typescript"); await vscode.commands.executeCommand("editor.fold", { selectionLines: [0], }); diff --git a/packages/cursorless-vscode-e2e/src/suite/followLink.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/followLink.vscode.test.ts index f992c10208..4716be0da8 100644 --- a/packages/cursorless-vscode-e2e/src/suite/followLink.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/followLink.vscode.test.ts @@ -13,9 +13,10 @@ suite("followLink", async function () { }); async function followDefinition() { - const editor = await openNewEditor("const foo = 'hello';\nconst bar = foo;", { - languageId: "typescript", - }); + const editor = await openNewEditor( + "const foo = 'hello';\nconst bar = foo;", + "typescript", + ); await vscode.commands.executeCommand("revealLine", { lineNumber: 1, at: "top", diff --git a/packages/cursorless-vscode-e2e/src/suite/instanceAcrossSplit.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/instanceAcrossSplit.vscode.test.ts index 502a659c0a..2af9157b2f 100644 --- a/packages/cursorless-vscode-e2e/src/suite/instanceAcrossSplit.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/instanceAcrossSplit.vscode.test.ts @@ -103,9 +103,7 @@ async function runTest( /** The editor containing the "instance" */ const instanceEditor = spyIde.activeTextEditor!; /** The editor in which "from" is run */ - const fromEditor = await openNewEditor(" aaa bbb aaa aaa", { - openBeside: true, - }); + const fromEditor = await openNewEditor(" aaa bbb aaa aaa", "plaintext", true); const { document: fromDocument } = fromEditor; fromEditor.selections = [new Selection(0, 0, 0, 0)]; diff --git a/packages/cursorless-vscode-e2e/src/suite/keyboard/basic.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/keyboard/basic.vscode.test.ts index 50bfd0d5a2..b22c086629 100644 --- a/packages/cursorless-vscode-e2e/src/suite/keyboard/basic.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/keyboard/basic.vscode.test.ts @@ -202,9 +202,7 @@ async function checkKeyboardStartup() { async function basic() { const { hatTokenMap } = (await getCursorlessApi()).testHelpers!; - const editor = await openNewEditor("function foo() {}\n", { - languageId: "typescript", - }); + const editor = await openNewEditor("function foo() {}\n", "typescript"); await hatTokenMap.allocateHats(); editor.selection = new vscode.Selection(1, 0, 1, 0); @@ -251,9 +249,7 @@ async function noAutomaticTokenExpansion() { async function sequence(t: TestCase) { const { hatTokenMap } = (await getCursorlessApi()).testHelpers!; - const editor = await openNewEditor(t.initialContent, { - languageId: "typescript", - }); + const editor = await openNewEditor(t.initialContent, "typescript"); await hatTokenMap.allocateHats(); editor.selection = new vscode.Selection(1, 0, 1, 0); await vscode.commands.executeCommand("cursorless.keyboard.modal.modeOn"); @@ -264,9 +260,7 @@ async function sequence(t: TestCase) { async function vscodeCommand() { const { hatTokenMap } = (await getCursorlessApi()).testHelpers!; - const editor = await openNewEditor("aaa;\nbbb;\nccc;\n", { - languageId: "typescript", - }); + const editor = await openNewEditor("aaa;\nbbb;\nccc;\n", "typescript"); await hatTokenMap.allocateHats(); editor.selection = new vscode.Selection(0, 0, 0, 0); diff --git a/packages/cursorless-vscode-e2e/src/suite/performance.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/performance.vscode.test.ts index 1aedf6f762..16547ef570 100644 --- a/packages/cursorless-vscode-e2e/src/suite/performance.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/performance.vscode.test.ts @@ -212,7 +212,7 @@ async function testPerformanceCallback( callback: () => Promise, beforeCallback?: (editor: vscode.TextEditor) => Promise, ) { - const editor = await openNewEditor(testData, { languageId: "json" }); + const editor = await openNewEditor(testData, "json"); // This is the position of the last json key in the document const position = new vscode.Position(editor.document.lineCount - 3, 5); const selection = new vscode.Selection(position, position); diff --git a/packages/cursorless-vscode-e2e/src/suite/pourAcrossSplit.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/pourAcrossSplit.vscode.test.ts index 28d064cc00..d7543e5109 100644 --- a/packages/cursorless-vscode-e2e/src/suite/pourAcrossSplit.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/pourAcrossSplit.vscode.test.ts @@ -17,7 +17,7 @@ async function runTest() { const { hatTokenMap } = (await getCursorlessApi()).testHelpers!; const { document: document1 } = await openNewEditor("hello world"); - const { document: document2 } = await openNewEditor("", { openBeside: true }); + const { document: document2 } = await openNewEditor("", undefined, true); await hatTokenMap.allocateHats(); diff --git a/packages/cursorless-vscode-e2e/src/suite/recorded.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/recorded.vscode.test.ts index dda071aefd..7739a0d9dc 100644 --- a/packages/cursorless-vscode-e2e/src/suite/recorded.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/recorded.vscode.test.ts @@ -8,8 +8,7 @@ import { getRecordedTestPaths, runRecordedTest } from "@cursorless/node-common"; import type { VscodeTestHelpers } from "@cursorless/vscode-common"; import { getCursorlessApi, - openNewEditor, - reuseEditor, + getReusableEditor, runCursorlessCommand, } from "@cursorless/vscode-common"; import * as vscode from "vscode"; @@ -48,23 +47,16 @@ suite("recorded test cases", async function () { ); }); -let testHelpers: VscodeTestHelpers | undefined; -let vsTextEditor: vscode.TextEditor | undefined; - async function openNewTestEditor( content: string, languageId: string, ): Promise { - if (vsTextEditor == null) { - vsTextEditor = await openNewEditor(content, { languageId }); - } else { - vsTextEditor = await reuseEditor(vsTextEditor, content, languageId); - } + const editor = await getReusableEditor(content, languageId); // Override any user settings and make sure tests run with default tabs. - vsTextEditor.options = DEFAULT_TEXT_EDITOR_OPTIONS_FOR_TEST; + editor.options = DEFAULT_TEXT_EDITOR_OPTIONS_FOR_TEST; - testHelpers ??= (await getCursorlessApi()).testHelpers!; + const testHelpers = (await getCursorlessApi()).testHelpers!; - return testHelpers.fromVscodeEditor(vsTextEditor); + return testHelpers.fromVscodeEditor(editor); } diff --git a/packages/cursorless-vscode-e2e/src/suite/scopeProvider/runBasicScopeInfoTest.ts b/packages/cursorless-vscode-e2e/src/suite/scopeProvider/runBasicScopeInfoTest.ts index 1bd4beb106..5b78b94b5d 100644 --- a/packages/cursorless-vscode-e2e/src/suite/scopeProvider/runBasicScopeInfoTest.ts +++ b/packages/cursorless-vscode-e2e/src/suite/scopeProvider/runBasicScopeInfoTest.ts @@ -21,9 +21,7 @@ export async function runBasicScopeInfoTest() { try { await assertCalledWithScopeInfo(fake, unsupported); - const editor = await openNewEditor("", { - languageId: "typescript", - }); + const editor = await openNewEditor("", "typescript"); await assertCalledWithScopeInfo(fake, supported); await editor.edit((editBuilder) => { diff --git a/packages/cursorless-vscode-e2e/src/suite/scopeVisualizer/runBasicMultilineContentTest.ts b/packages/cursorless-vscode-e2e/src/suite/scopeVisualizer/runBasicMultilineContentTest.ts index da6f577a8f..bf87cda415 100644 --- a/packages/cursorless-vscode-e2e/src/suite/scopeVisualizer/runBasicMultilineContentTest.ts +++ b/packages/cursorless-vscode-e2e/src/suite/scopeVisualizer/runBasicMultilineContentTest.ts @@ -10,9 +10,7 @@ import type { ExpectedArgs } from "./scopeVisualizerTest.types"; * like `./runBasicMultilineContentTest.png`. */ export async function runBasicMultilineContentTest() { - await openNewEditor(contents, { - languageId: "typescript", - }); + await openNewEditor(contents, "typescript"); const fakes = await injectFakes(); diff --git a/packages/cursorless-vscode-e2e/src/suite/scopeVisualizer/runNestedMultilineContentTest.ts b/packages/cursorless-vscode-e2e/src/suite/scopeVisualizer/runNestedMultilineContentTest.ts index e5ebb54a72..6d6c249d0e 100644 --- a/packages/cursorless-vscode-e2e/src/suite/scopeVisualizer/runNestedMultilineContentTest.ts +++ b/packages/cursorless-vscode-e2e/src/suite/scopeVisualizer/runNestedMultilineContentTest.ts @@ -10,9 +10,7 @@ import type { ExpectedArgs } from "./scopeVisualizerTest.types"; * `./runNestedMultilineContentTest.png`. */ export async function runNestedMultilineContentTest() { - await openNewEditor(contents, { - languageId: "typescript", - }); + await openNewEditor(contents, "typescript"); const fakes = await injectFakes(); diff --git a/packages/cursorless-vscode-e2e/src/suite/visible.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/visible.vscode.test.ts index 67de4fb4e5..6690b1abbb 100644 --- a/packages/cursorless-vscode-e2e/src/suite/visible.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/visible.vscode.test.ts @@ -35,9 +35,7 @@ function myFunk() { `; function openEditor() { - return openNewEditor(content, { - languageId: "typescript", - }); + return openNewEditor(content, "typescript"); } function foldRegion() { diff --git a/packages/cursorless-vscode-e2e/src/suite/wrapWithSnippetAcrossSplit.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/wrapWithSnippetAcrossSplit.vscode.test.ts index eb63c0aa08..b14215c45f 100644 --- a/packages/cursorless-vscode-e2e/src/suite/wrapWithSnippetAcrossSplit.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/wrapWithSnippetAcrossSplit.vscode.test.ts @@ -23,7 +23,7 @@ async function runTest() { const { hatTokenMap } = (await getCursorlessApi()).testHelpers!; const { document: document1 } = await openNewEditor("hello world"); - const { document: document2 } = await openNewEditor("", { openBeside: true }); + const { document: document2 } = await openNewEditor("", undefined, true); await hatTokenMap.allocateHats(); diff --git a/packages/vscode-common/src/index.ts b/packages/vscode-common/src/index.ts index 8a2d65a10d..d53f56b71b 100644 --- a/packages/vscode-common/src/index.ts +++ b/packages/vscode-common/src/index.ts @@ -4,6 +4,7 @@ export * from "./runCommand"; export * from "./ScopeVisualizerColorConfig"; export * from "./SpyWebViewEvent"; export * from "./TestHelpers"; +export * from "./testUtil/getReusableEditor"; export * from "./testUtil/openNewEditor"; export * from "./VscodeApi"; export * from "./vscodeUtil"; diff --git a/packages/vscode-common/src/testUtil/closeUiElements.ts b/packages/vscode-common/src/testUtil/closeUiElements.ts new file mode 100644 index 0000000000..864dc79d3a --- /dev/null +++ b/packages/vscode-common/src/testUtil/closeUiElements.ts @@ -0,0 +1,8 @@ +import { commands } from "vscode"; + +export async function closeUiElements() { + // Many times running these tests opens the sidebar, which slows performance. Close it. + await commands.executeCommand("workbench.action.closeSidebar"); + // Close the find widget as well, since it can also be open and cause performance issues. + await commands.executeCommand("closeFindWidget"); +} diff --git a/packages/vscode-common/src/testUtil/getReusableEditor.ts b/packages/vscode-common/src/testUtil/getReusableEditor.ts new file mode 100644 index 0000000000..c6e11c95a8 --- /dev/null +++ b/packages/vscode-common/src/testUtil/getReusableEditor.ts @@ -0,0 +1,59 @@ +import { + commands, + EndOfLine, + languages, + Range, + window, + type TextEditor, +} from "vscode"; +import { getCursorlessApi, getParseTreeApi } from "../getExtensionApi"; +import { closeUiElements } from "./closeUiElements"; +import { openNewEditor } from "./openNewEditor"; + +let editor: TextEditor | undefined; + +export async function getReusableEditor( + content: string, + languageId: string = "plaintext", +): Promise { + await closeUiElements(); + + if (editor == null) { + editor = await openNewEditor(content, languageId); + } + + // If the editor is not already active, make it active and close all other editors + if (editor !== window.activeTextEditor) { + editor = await window.showTextDocument(editor.document); + // Close other groups + await commands.executeCommand("workbench.action.closeEditorsInOtherGroups"); + // Close other editors in the same group + await commands.executeCommand("workbench.action.closeOtherEditors"); + } + + // If the editor is not already the right language, change its language and reload the parse tree + if (editor.document.languageId !== languageId) { + await languages.setTextDocumentLanguage(editor.document, languageId); + await (await getParseTreeApi()).loadLanguage(languageId); + } + + (await getCursorlessApi()).testHelpers!.clearCache(); + + // Replace the entire contents of the editor with the new content + await editor.edit((editBuilder) => { + editBuilder.replace( + new Range( + editor!.document.lineAt(0).range.start, + editor!.document.lineAt(editor!.document.lineCount - 1).range.end, + ), + content, + ); + + const eol = content.includes("\r\n") ? EndOfLine.CRLF : EndOfLine.LF; + if (eol !== editor!.document.eol) { + editBuilder.setEndOfLine(eol); + } + }); + + return editor; +} diff --git a/packages/vscode-common/src/testUtil/openNewEditor.ts b/packages/vscode-common/src/testUtil/openNewEditor.ts index d7aca90b60..d1de4de5d0 100644 --- a/packages/vscode-common/src/testUtil/openNewEditor.ts +++ b/packages/vscode-common/src/testUtil/openNewEditor.ts @@ -1,14 +1,11 @@ import * as vscode from "vscode"; import { getCursorlessApi, getParseTreeApi } from "../getExtensionApi"; - -interface NewEditorOptions { - languageId?: string; - openBeside?: boolean; -} +import { closeUiElements } from "./closeUiElements"; export async function openNewEditor( content: string, - { languageId = "plaintext", openBeside = false }: NewEditorOptions = {}, + languageId = "plaintext", + openBeside = false, ): Promise { await closeUiElements(); @@ -40,51 +37,6 @@ export async function openNewEditor( return editor; } -export async function reuseEditor( - editor: vscode.TextEditor, - content: string, - language: string = "plaintext", -): Promise { - await closeUiElements(); - - // If the editor is not already active, make it active and close all other editors - if (editor !== vscode.window.activeTextEditor) { - editor = await vscode.window.showTextDocument(editor.document); - // Close other groups - await vscode.commands.executeCommand( - "workbench.action.closeEditorsInOtherGroups", - ); - // Close other editors in the same group - await vscode.commands.executeCommand("workbench.action.closeOtherEditors"); - } - - // If the editor is not already the right language, change its language and reload the parse tree - if (editor.document.languageId !== language) { - await vscode.languages.setTextDocumentLanguage(editor.document, language); - await (await getParseTreeApi()).loadLanguage(language); - } - - // Replace the entire contents of the editor with the new content - await editor.edit((editBuilder) => { - editBuilder.replace( - new vscode.Range( - editor.document.lineAt(0).range.start, - editor.document.lineAt(editor.document.lineCount - 1).range.end, - ), - content, - ); - - const eol = content.includes("\r\n") - ? vscode.EndOfLine.CRLF - : vscode.EndOfLine.LF; - if (eol !== editor.document.eol) { - editBuilder.setEndOfLine(eol); - } - }); - - return editor; -} - /** * Open a new notebook editor with the given cells * @param cellContents A list of strings each of which will become the contents @@ -140,10 +92,3 @@ function waitForEditorToOpen(): Promise { }, 100); }); } - -async function closeUiElements() { - // Many times running these tests opens the sidebar, which slows performance. Close it. - await vscode.commands.executeCommand("workbench.action.closeSidebar"); - // Close the find widget as well, since it can also be open and cause performance issues. - await vscode.commands.executeCommand("closeFindWidget"); -} From 63e2c6e1de34216ca18178651b0433df1449090e Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 12 Mar 2026 18:52:45 +0100 Subject: [PATCH 3/8] Widespread use of reuseEditor in tests --- .../src/suite/backwardCompatibility.vscode.test.ts | 4 ++-- .../src/suite/breakpoints.vscode.test.ts | 10 +++++----- .../src/suite/containingTokenTwice.vscode.test.ts | 4 ++-- .../src/suite/explicitMark.vscode.test.ts | 4 ++-- .../src/suite/fold.vscode.test.ts | 6 +++--- .../src/suite/followLink.vscode.test.ts | 6 +++--- .../src/suite/performance.vscode.test.ts | 4 ++-- .../src/suite/prePhraseSnapshot.vscode.test.ts | 4 ++-- .../src/suite/recorded.vscode.test.ts | 1 - .../src/suite/revealRange.vscode.test.ts | 6 +++--- .../src/suite/scopeProvider/runBasicScopeInfoTest.ts | 4 ++-- .../src/suite/scopeVisualizer/runUpdateTest.ts | 4 ++-- .../src/suite/scroll.vscode.test.ts | 6 +++--- .../src/suite/testCaseRecorder.vscode.test.ts | 4 ++-- .../src/suite/toggleDecorations.vscode.test.ts | 4 ++-- .../src/suite/visible.vscode.test.ts | 11 +++++------ .../src/ide/vscode/textLine.vscode.test.ts | 4 ++-- .../vscode-common/src/testUtil/getReusableEditor.ts | 7 ++++++- 18 files changed, 48 insertions(+), 45 deletions(-) diff --git a/packages/cursorless-vscode-e2e/src/suite/backwardCompatibility.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/backwardCompatibility.vscode.test.ts index 0510e5d23b..f42242e7b7 100644 --- a/packages/cursorless-vscode-e2e/src/suite/backwardCompatibility.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/backwardCompatibility.vscode.test.ts @@ -1,5 +1,5 @@ import { CURSORLESS_COMMAND_ID } from "@cursorless/common"; -import { getCursorlessApi, openNewEditor } from "@cursorless/vscode-common"; +import { getCursorlessApi, getReusableEditor } from "@cursorless/vscode-common"; import * as assert from "assert"; import * as vscode from "vscode"; import { endToEndTestSetup } from "../endToEndTestSetup"; @@ -13,7 +13,7 @@ suite("Backward compatibility", async function () { async function runTest() { const { hatTokenMap } = (await getCursorlessApi()).testHelpers!; - const editor = await openNewEditor(""); + const editor = await getReusableEditor(""); editor.selections = [new vscode.Selection(0, 0, 0, 0)]; diff --git a/packages/cursorless-vscode-e2e/src/suite/breakpoints.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/breakpoints.vscode.test.ts index 4d1dd7ebfb..0b499f1cf8 100644 --- a/packages/cursorless-vscode-e2e/src/suite/breakpoints.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/breakpoints.vscode.test.ts @@ -1,7 +1,7 @@ import { LATEST_VERSION } from "@cursorless/common"; import { getCursorlessApi, - openNewEditor, + getReusableEditor, runCursorlessCommand, } from "@cursorless/vscode-common"; import * as assert from "assert"; @@ -27,7 +27,7 @@ suite("breakpoints", async function () { async function breakpointAdd() { const { hatTokenMap } = (await getCursorlessApi()).testHelpers!; - await openNewEditor(" hello"); + await getReusableEditor(" hello"); await hatTokenMap.allocateHats(); await toggleBreakpoint(); @@ -40,7 +40,7 @@ async function breakpointAdd() { async function breakpointTokenAdd() { const { hatTokenMap } = (await getCursorlessApi()).testHelpers!; - await openNewEditor(" hello"); + await getReusableEditor(" hello"); await hatTokenMap.allocateHats(); await toggleTokenBreakpoint(); @@ -53,7 +53,7 @@ async function breakpointTokenAdd() { async function breakpointRemove() { const { hatTokenMap } = (await getCursorlessApi()).testHelpers!; - const editor = await openNewEditor(" hello"); + const editor = await getReusableEditor(" hello"); await hatTokenMap.allocateHats(); vscode.debug.addBreakpoints([ @@ -71,7 +71,7 @@ async function breakpointRemove() { async function breakpointTokenRemove() { const { hatTokenMap } = (await getCursorlessApi()).testHelpers!; - const editor = await openNewEditor(" hello"); + const editor = await getReusableEditor(" hello"); await hatTokenMap.allocateHats(); vscode.debug.addBreakpoints([ diff --git a/packages/cursorless-vscode-e2e/src/suite/containingTokenTwice.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/containingTokenTwice.vscode.test.ts index 5c8a0bb377..cca12c1b9a 100644 --- a/packages/cursorless-vscode-e2e/src/suite/containingTokenTwice.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/containingTokenTwice.vscode.test.ts @@ -1,7 +1,7 @@ import { LATEST_VERSION } from "@cursorless/common"; import { getCursorlessApi, - openNewEditor, + getReusableEditor, runCursorlessCommand, } from "@cursorless/vscode-common"; import { assert } from "chai"; @@ -19,7 +19,7 @@ suite("Take token twice", async function () { async function runTest() { const { hatTokenMap } = (await getCursorlessApi()).testHelpers!; - const editor = await openNewEditor("a)"); + const editor = await getReusableEditor("a)"); await hatTokenMap.allocateHats(); for (let i = 0; i < 2; ++i) { diff --git a/packages/cursorless-vscode-e2e/src/suite/explicitMark.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/explicitMark.vscode.test.ts index 6eabe5f935..96df5198f0 100644 --- a/packages/cursorless-vscode-e2e/src/suite/explicitMark.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/explicitMark.vscode.test.ts @@ -1,7 +1,7 @@ import { LATEST_VERSION } from "@cursorless/common"; import { getCursorlessApi, - openNewEditor, + getReusableEditor, runCursorlessCommand, } from "@cursorless/vscode-common"; import * as assert from "assert"; @@ -16,7 +16,7 @@ suite("Explicit mark", async function () { async function explicitMark() { const { ide } = (await getCursorlessApi()).testHelpers!; - const editor = await openNewEditor("foo bar baz"); + const editor = await getReusableEditor("foo bar baz"); const editorId = ide.visibleTextEditors[0].id; await runCursorlessCommand({ diff --git a/packages/cursorless-vscode-e2e/src/suite/fold.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/fold.vscode.test.ts index 5c92d01c6c..de039ef918 100644 --- a/packages/cursorless-vscode-e2e/src/suite/fold.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/fold.vscode.test.ts @@ -1,5 +1,5 @@ import { LATEST_VERSION } from "@cursorless/common"; -import { openNewEditor, runCursorlessCommand } from "@cursorless/vscode-common"; +import { getReusableEditor, runCursorlessCommand } from "@cursorless/vscode-common"; import * as assert from "node:assert"; import * as vscode from "vscode"; import { endToEndTestSetup } from "../endToEndTestSetup"; @@ -12,7 +12,7 @@ suite("fold", async function () { }); async function foldMade() { - const editor = await openNewEditor("function myFunk() {\n\n}", "typescript"); + const editor = await getReusableEditor("function myFunk() {\n\n}", "typescript"); await runCursorlessCommand({ version: LATEST_VERSION, @@ -36,7 +36,7 @@ async function foldMade() { } async function unfoldMade() { - const editor = await openNewEditor("function myFunk() {\n\n}", "typescript"); + const editor = await getReusableEditor("function myFunk() {\n\n}", "typescript"); await vscode.commands.executeCommand("editor.fold", { selectionLines: [0], }); diff --git a/packages/cursorless-vscode-e2e/src/suite/followLink.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/followLink.vscode.test.ts index 4716be0da8..eacddee35a 100644 --- a/packages/cursorless-vscode-e2e/src/suite/followLink.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/followLink.vscode.test.ts @@ -1,5 +1,5 @@ import { getFixturePath, isWindows } from "@cursorless/node-common"; -import { openNewEditor, runCursorlessCommand } from "@cursorless/vscode-common"; +import { getReusableEditor, runCursorlessCommand } from "@cursorless/vscode-common"; import * as assert from "assert"; import * as vscode from "vscode"; import { endToEndTestSetup } from "../endToEndTestSetup"; @@ -13,7 +13,7 @@ suite("followLink", async function () { }); async function followDefinition() { - const editor = await openNewEditor( + const editor = await getReusableEditor( "const foo = 'hello';\nconst bar = foo;", "typescript", ); @@ -49,7 +49,7 @@ async function followLink() { const linkTextContent = isWindows() ? `file:///${filename}` : `file://${filename}`; - await openNewEditor(linkTextContent); + await getReusableEditor(linkTextContent); await runCursorlessCommand({ version: LATEST_VERSION, diff --git a/packages/cursorless-vscode-e2e/src/suite/performance.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/performance.vscode.test.ts index 16547ef570..f4c55ca8d0 100644 --- a/packages/cursorless-vscode-e2e/src/suite/performance.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/performance.vscode.test.ts @@ -5,7 +5,7 @@ import type { SimpleScopeTypeType, } from "@cursorless/common"; import { asyncSafety } from "@cursorless/common"; -import { openNewEditor, runCursorlessAction } from "@cursorless/vscode-common"; +import { getReusableEditor, runCursorlessAction } from "@cursorless/vscode-common"; import assert from "assert"; import * as vscode from "vscode"; import { endToEndTestSetup } from "../endToEndTestSetup"; @@ -212,7 +212,7 @@ async function testPerformanceCallback( callback: () => Promise, beforeCallback?: (editor: vscode.TextEditor) => Promise, ) { - const editor = await openNewEditor(testData, "json"); + const editor = await getReusableEditor(testData, "json"); // This is the position of the last json key in the document const position = new vscode.Position(editor.document.lineCount - 3, 5); const selection = new vscode.Selection(position, position); diff --git a/packages/cursorless-vscode-e2e/src/suite/prePhraseSnapshot.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/prePhraseSnapshot.vscode.test.ts index e62ff7990e..3f39e58039 100644 --- a/packages/cursorless-vscode-e2e/src/suite/prePhraseSnapshot.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/prePhraseSnapshot.vscode.test.ts @@ -6,7 +6,7 @@ import { import { fromVscodeSelection, getCursorlessApi, - openNewEditor, + getReusableEditor, runCursorlessCommand, } from "@cursorless/vscode-common"; import * as assert from "assert"; @@ -52,7 +52,7 @@ async function runTest( const { hatTokenMap, commandServerApi } = (await getCursorlessApi()) .testHelpers!; - const editor = await openNewEditor("a\n"); + const editor = await getReusableEditor("a\n"); editor.selections = [new vscode.Selection(1, 0, 1, 0)]; diff --git a/packages/cursorless-vscode-e2e/src/suite/recorded.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/recorded.vscode.test.ts index 7739a0d9dc..7bb2a45c31 100644 --- a/packages/cursorless-vscode-e2e/src/suite/recorded.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/recorded.vscode.test.ts @@ -5,7 +5,6 @@ import { asyncSafety, } from "@cursorless/common"; import { getRecordedTestPaths, runRecordedTest } from "@cursorless/node-common"; -import type { VscodeTestHelpers } from "@cursorless/vscode-common"; import { getCursorlessApi, getReusableEditor, diff --git a/packages/cursorless-vscode-e2e/src/suite/revealRange.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/revealRange.vscode.test.ts index 5e24ec075f..843c9fbea6 100644 --- a/packages/cursorless-vscode-e2e/src/suite/revealRange.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/revealRange.vscode.test.ts @@ -1,5 +1,5 @@ import { LATEST_VERSION } from "@cursorless/common"; -import { openNewEditor, runCursorlessCommand } from "@cursorless/vscode-common"; +import { getReusableEditor, runCursorlessCommand } from "@cursorless/vscode-common"; import assert from "node:assert"; import * as vscode from "vscode"; import { endToEndTestSetup } from "../endToEndTestSetup"; @@ -14,7 +14,7 @@ suite("revealRange", async function () { const content = new Array(100).fill("line").join("\n"); async function preFile() { - const editor = await openNewEditor(content); + const editor = await getReusableEditor(content); const startLine = editor.document.lineCount - 1; editor.selections = [new vscode.Selection(startLine, 0, startLine, 0)]; editor.revealRange(new vscode.Range(startLine, 0, startLine, 0)); @@ -39,7 +39,7 @@ async function preFile() { } async function postFile() { - const editor = await openNewEditor(content); + const editor = await getReusableEditor(content); await vscode.commands.executeCommand("revealLine", { lineNumber: 1, at: "top", diff --git a/packages/cursorless-vscode-e2e/src/suite/scopeProvider/runBasicScopeInfoTest.ts b/packages/cursorless-vscode-e2e/src/suite/scopeProvider/runBasicScopeInfoTest.ts index 5b78b94b5d..5989e25acd 100644 --- a/packages/cursorless-vscode-e2e/src/suite/scopeProvider/runBasicScopeInfoTest.ts +++ b/packages/cursorless-vscode-e2e/src/suite/scopeProvider/runBasicScopeInfoTest.ts @@ -1,6 +1,6 @@ import type { ScopeSupportInfo } from "@cursorless/common"; import { ScopeSupport } from "@cursorless/common"; -import { getCursorlessApi, openNewEditor } from "@cursorless/vscode-common"; +import { getCursorlessApi, getReusableEditor } from "@cursorless/vscode-common"; import * as sinon from "sinon"; import type { TextDocument } from "vscode"; import { Position, Range, commands } from "vscode"; @@ -21,7 +21,7 @@ export async function runBasicScopeInfoTest() { try { await assertCalledWithScopeInfo(fake, unsupported); - const editor = await openNewEditor("", "typescript"); + const editor = await getReusableEditor("", "typescript"); await assertCalledWithScopeInfo(fake, supported); await editor.edit((editBuilder) => { diff --git a/packages/cursorless-vscode-e2e/src/suite/scopeVisualizer/runUpdateTest.ts b/packages/cursorless-vscode-e2e/src/suite/scopeVisualizer/runUpdateTest.ts index 68532ae712..f39cdc2206 100644 --- a/packages/cursorless-vscode-e2e/src/suite/scopeVisualizer/runUpdateTest.ts +++ b/packages/cursorless-vscode-e2e/src/suite/scopeVisualizer/runUpdateTest.ts @@ -1,4 +1,4 @@ -import { openNewEditor } from "@cursorless/vscode-common"; +import { getReusableEditor } from "@cursorless/vscode-common"; import * as vscode from "vscode"; import { sleepWithBackoff } from "../../endToEndTestSetup"; import { injectFakes } from "./injectFakes"; @@ -10,7 +10,7 @@ import type { ExpectedArgs } from "./scopeVisualizerTest.types"; * edited. */ export async function runUpdateTest() { - const editor = await openNewEditor("aaa"); + const editor = await getReusableEditor("aaa"); const fakes = await injectFakes(); diff --git a/packages/cursorless-vscode-e2e/src/suite/scroll.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/scroll.vscode.test.ts index 99ee4e1e8e..b95ee720a5 100644 --- a/packages/cursorless-vscode-e2e/src/suite/scroll.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/scroll.vscode.test.ts @@ -1,5 +1,5 @@ import { LATEST_VERSION } from "@cursorless/common"; -import { openNewEditor, runCursorlessCommand } from "@cursorless/vscode-common"; +import { getReusableEditor, runCursorlessCommand } from "@cursorless/vscode-common"; import * as vscode from "vscode"; import { endToEndTestSetup } from "../endToEndTestSetup"; @@ -11,7 +11,7 @@ suite("scroll", async function () { }); async function topWhale() { - const editor = await openNewEditor("hello\nworld"); + const editor = await getReusableEditor("hello\nworld"); editor.selections = [new vscode.Selection(1, 0, 1, 0)]; await runCursorlessCommand({ @@ -34,7 +34,7 @@ async function topWhale() { } async function bottomWhale() { - const editor = await openNewEditor("hello\nworld"); + const editor = await getReusableEditor("hello\nworld"); await vscode.commands.executeCommand("revealLine", { lineNumber: 1, at: "top", diff --git a/packages/cursorless-vscode-e2e/src/suite/testCaseRecorder.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/testCaseRecorder.vscode.test.ts index 5dacfded5d..9418ef0a30 100644 --- a/packages/cursorless-vscode-e2e/src/suite/testCaseRecorder.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/testCaseRecorder.vscode.test.ts @@ -6,7 +6,7 @@ import { } from "@cursorless/node-common"; import { getCursorlessApi, - openNewEditor, + getReusableEditor, runCursorlessCommand, } from "@cursorless/vscode-common"; import { assert } from "chai"; @@ -114,7 +114,7 @@ async function runAndCheckTestCaseRecorder( } async function initalizeEditor(hatTokenMap: HatTokenMap) { - const editor = await openNewEditor("hello world"); + const editor = await getReusableEditor("hello world"); editor.selections = [new vscode.Selection(0, 11, 0, 11)]; diff --git a/packages/cursorless-vscode-e2e/src/suite/toggleDecorations.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/toggleDecorations.vscode.test.ts index 6aefe2c91e..eb9f5fe147 100644 --- a/packages/cursorless-vscode-e2e/src/suite/toggleDecorations.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/toggleDecorations.vscode.test.ts @@ -1,4 +1,4 @@ -import { getCursorlessApi, openNewEditor } from "@cursorless/vscode-common"; +import { getCursorlessApi, getReusableEditor } from "@cursorless/vscode-common"; import assert from "assert"; import * as vscode from "vscode"; import { endToEndTestSetup } from "../endToEndTestSetup"; @@ -12,7 +12,7 @@ suite("toggle decorations", async function () { async function runTest() { const { hatTokenMap } = (await getCursorlessApi()).testHelpers!; - await openNewEditor("Hello world testing whatever"); + await getReusableEditor("Hello world testing whatever"); // Check that hats appear by default await hatTokenMap.allocateHats(); diff --git a/packages/cursorless-vscode-e2e/src/suite/visible.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/visible.vscode.test.ts index 6690b1abbb..62849e74db 100644 --- a/packages/cursorless-vscode-e2e/src/suite/visible.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/visible.vscode.test.ts @@ -1,5 +1,8 @@ import { LATEST_VERSION } from "@cursorless/common"; -import { openNewEditor, runCursorlessCommand } from "@cursorless/vscode-common"; +import { + getReusableEditor, + runCursorlessCommand, +} from "@cursorless/vscode-common"; import * as assert from "node:assert"; import * as vscode from "vscode"; import { endToEndTestSetup } from "../endToEndTestSetup"; @@ -11,7 +14,7 @@ suite("visible", async function () { }); async function testMultipleRegions() { - const editor = await openEditor(); + const editor = await getReusableEditor(content, "typescript"); await foldRegion(); @@ -34,10 +37,6 @@ function myFunk() { // 3 `; -function openEditor() { - return openNewEditor(content, "typescript"); -} - function foldRegion() { return vscode.commands.executeCommand("editor.fold", { levels: 1, diff --git a/packages/cursorless-vscode/src/ide/vscode/textLine.vscode.test.ts b/packages/cursorless-vscode/src/ide/vscode/textLine.vscode.test.ts index 3aecf37ae3..d1075879a1 100644 --- a/packages/cursorless-vscode/src/ide/vscode/textLine.vscode.test.ts +++ b/packages/cursorless-vscode/src/ide/vscode/textLine.vscode.test.ts @@ -1,5 +1,5 @@ import * as assert from "assert"; -import { openNewEditor } from "@cursorless/vscode-common"; +import { getReusableEditor } from "@cursorless/vscode-common"; import VscodeTextLine from "./VscodeTextLine"; /** @@ -18,7 +18,7 @@ suite("TextLine", function () { this.retries(5); whiteSpaceTests.forEach(([text, trimmedStart, trimmedEnd]) => { test(`whitespace '${text}'`, async () => { - const editor = await openNewEditor(text); + const editor = await getReusableEditor(text); const line = new VscodeTextLine(editor.document.lineAt(0)); assert.equal(line.rangeTrimmed?.start?.character, trimmedStart); diff --git a/packages/vscode-common/src/testUtil/getReusableEditor.ts b/packages/vscode-common/src/testUtil/getReusableEditor.ts index c6e11c95a8..24b7cbc7f6 100644 --- a/packages/vscode-common/src/testUtil/getReusableEditor.ts +++ b/packages/vscode-common/src/testUtil/getReusableEditor.ts @@ -14,10 +14,15 @@ let editor: TextEditor | undefined; export async function getReusableEditor( content: string, - languageId: string = "plaintext", + languageId = "plaintext", + openBeside = false, ): Promise { await closeUiElements(); + if (openBeside) { + return await openNewEditor(content, languageId, true); + } + if (editor == null) { editor = await openNewEditor(content, languageId); } From d013766d7757081b373d3976b72250da03bba8d5 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 12 Mar 2026 19:05:36 +0100 Subject: [PATCH 4/8] More fixes --- .../src/languages/LanguageDefinitions.ts | 6 ------ .../src/suite/keyboard/basic.vscode.test.ts | 17 +++++++++++------ .../src/testUtil/getReusableEditor.ts | 5 +++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/packages/cursorless-engine/src/languages/LanguageDefinitions.ts b/packages/cursorless-engine/src/languages/LanguageDefinitions.ts index 87c864f3d6..c416eb802c 100644 --- a/packages/cursorless-engine/src/languages/LanguageDefinitions.ts +++ b/packages/cursorless-engine/src/languages/LanguageDefinitions.ts @@ -59,14 +59,8 @@ export class LanguageDefinitionsImpl implements LanguageDefinitions { private treeSitter: TreeSitter, private treeSitterQueryProvider: RawTreeSitterQueryProvider, ) { - const isTesting = ide.runMode === "test"; - this.disposables.push( ide.onDidOpenTextDocument((document) => { - // During testing we open untitled documents that all have the same uri and version which breaks our cache - if (isTesting) { - treeSitterQueryCache.clear(); - } this.loadLanguage(document.languageId).catch((err) => { void showError( this.ide.messages, diff --git a/packages/cursorless-vscode-e2e/src/suite/keyboard/basic.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/keyboard/basic.vscode.test.ts index b22c086629..531bf4ce1a 100644 --- a/packages/cursorless-vscode-e2e/src/suite/keyboard/basic.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/keyboard/basic.vscode.test.ts @@ -1,4 +1,8 @@ -import { getCursorlessApi, openNewEditor } from "@cursorless/vscode-common"; +import { + getCursorlessApi, + getReusableEditor, + openNewEditor, +} from "@cursorless/vscode-common"; import { assert } from "chai"; import * as vscode from "vscode"; import { endToEndTestSetup, sleepWithBackoff } from "../../endToEndTestSetup"; @@ -191,7 +195,7 @@ suite("Basic keyboard test", async function () { async function checkKeyboardStartup() { await getCursorlessApi(); - const editor = await openNewEditor(""); + const editor = await getReusableEditor(""); // Type the letter await typeText("a"); @@ -202,7 +206,7 @@ async function checkKeyboardStartup() { async function basic() { const { hatTokenMap } = (await getCursorlessApi()).testHelpers!; - const editor = await openNewEditor("function foo() {}\n", "typescript"); + const editor = await getReusableEditor("function foo() {}\n", "typescript"); await hatTokenMap.allocateHats(); editor.selection = new vscode.Selection(1, 0, 1, 0); @@ -230,7 +234,7 @@ async function basic() { async function noAutomaticTokenExpansion() { const { hatTokenMap } = (await getCursorlessApi()).testHelpers!; - const editor = await openNewEditor("aaa"); + const editor = await getReusableEditor("aaa"); await hatTokenMap.allocateHats(); editor.selection = new vscode.Selection(0, 3, 0, 3); @@ -249,6 +253,7 @@ async function noAutomaticTokenExpansion() { async function sequence(t: TestCase) { const { hatTokenMap } = (await getCursorlessApi()).testHelpers!; + // This test fails if we use getReusableEditor() const editor = await openNewEditor(t.initialContent, "typescript"); await hatTokenMap.allocateHats(); editor.selection = new vscode.Selection(1, 0, 1, 0); @@ -260,7 +265,7 @@ async function sequence(t: TestCase) { async function vscodeCommand() { const { hatTokenMap } = (await getCursorlessApi()).testHelpers!; - const editor = await openNewEditor("aaa;\nbbb;\nccc;\n", "typescript"); + const editor = await getReusableEditor("aaa;\nbbb;\nccc;\n", "typescript"); await hatTokenMap.allocateHats(); editor.selection = new vscode.Selection(0, 0, 0, 0); @@ -287,7 +292,7 @@ async function vscodeCommand() { } async function enterAndLeaveIsNoOp() { - const editor = await openNewEditor("hello"); + const editor = await getReusableEditor("hello"); const originalSelection = new vscode.Selection(0, 0, 0, 0); editor.selection = originalSelection; diff --git a/packages/vscode-common/src/testUtil/getReusableEditor.ts b/packages/vscode-common/src/testUtil/getReusableEditor.ts index 24b7cbc7f6..5ce824ad7f 100644 --- a/packages/vscode-common/src/testUtil/getReusableEditor.ts +++ b/packages/vscode-common/src/testUtil/getReusableEditor.ts @@ -42,8 +42,6 @@ export async function getReusableEditor( await (await getParseTreeApi()).loadLanguage(languageId); } - (await getCursorlessApi()).testHelpers!.clearCache(); - // Replace the entire contents of the editor with the new content await editor.edit((editBuilder) => { editBuilder.replace( @@ -60,5 +58,8 @@ export async function getReusableEditor( } }); + const { clearCache } = (await getCursorlessApi()).testHelpers!; + clearCache(); + return editor; } From c8b4579b91064c78496fcce392191a64b6ec7b09 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 12 Mar 2026 19:07:45 +0100 Subject: [PATCH 5/8] clean up --- packages/vscode-common/src/testUtil/getReusableEditor.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/vscode-common/src/testUtil/getReusableEditor.ts b/packages/vscode-common/src/testUtil/getReusableEditor.ts index 5ce824ad7f..d58c1f9c36 100644 --- a/packages/vscode-common/src/testUtil/getReusableEditor.ts +++ b/packages/vscode-common/src/testUtil/getReusableEditor.ts @@ -25,6 +25,8 @@ export async function getReusableEditor( if (editor == null) { editor = await openNewEditor(content, languageId); + } else { + (await getCursorlessApi()).testHelpers!.clearCache(); } // If the editor is not already active, make it active and close all other editors @@ -58,8 +60,5 @@ export async function getReusableEditor( } }); - const { clearCache } = (await getCursorlessApi()).testHelpers!; - clearCache(); - return editor; } From 6951fdfa5501e36de7a871bcf7b893c18c68dfb8 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 12 Mar 2026 19:09:08 +0100 Subject: [PATCH 6/8] fix --- packages/vscode-common/src/testUtil/getReusableEditor.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/vscode-common/src/testUtil/getReusableEditor.ts b/packages/vscode-common/src/testUtil/getReusableEditor.ts index d58c1f9c36..25881425c7 100644 --- a/packages/vscode-common/src/testUtil/getReusableEditor.ts +++ b/packages/vscode-common/src/testUtil/getReusableEditor.ts @@ -25,10 +25,11 @@ export async function getReusableEditor( if (editor == null) { editor = await openNewEditor(content, languageId); - } else { - (await getCursorlessApi()).testHelpers!.clearCache(); + return editor; } + (await getCursorlessApi()).testHelpers!.clearCache(); + // If the editor is not already active, make it active and close all other editors if (editor !== window.activeTextEditor) { editor = await window.showTextDocument(editor.document); From d3147d3b1b4812bc892f592aa9fb5b4bbff5ee53 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 12 Mar 2026 19:16:43 +0100 Subject: [PATCH 7/8] Format --- .../src/suite/fold.vscode.test.ts | 15 ++++++++++++--- .../src/suite/followLink.vscode.test.ts | 7 +++++-- .../src/suite/performance.vscode.test.ts | 5 ++++- .../src/suite/revealRange.vscode.test.ts | 5 ++++- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/packages/cursorless-vscode-e2e/src/suite/fold.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/fold.vscode.test.ts index de039ef918..46abe5fdc1 100644 --- a/packages/cursorless-vscode-e2e/src/suite/fold.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/fold.vscode.test.ts @@ -1,5 +1,8 @@ import { LATEST_VERSION } from "@cursorless/common"; -import { getReusableEditor, runCursorlessCommand } from "@cursorless/vscode-common"; +import { + getReusableEditor, + runCursorlessCommand, +} from "@cursorless/vscode-common"; import * as assert from "node:assert"; import * as vscode from "vscode"; import { endToEndTestSetup } from "../endToEndTestSetup"; @@ -12,7 +15,10 @@ suite("fold", async function () { }); async function foldMade() { - const editor = await getReusableEditor("function myFunk() {\n\n}", "typescript"); + const editor = await getReusableEditor( + "function myFunk() {\n\n}", + "typescript", + ); await runCursorlessCommand({ version: LATEST_VERSION, @@ -36,7 +42,10 @@ async function foldMade() { } async function unfoldMade() { - const editor = await getReusableEditor("function myFunk() {\n\n}", "typescript"); + const editor = await getReusableEditor( + "function myFunk() {\n\n}", + "typescript", + ); await vscode.commands.executeCommand("editor.fold", { selectionLines: [0], }); diff --git a/packages/cursorless-vscode-e2e/src/suite/followLink.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/followLink.vscode.test.ts index eacddee35a..1a1007f3d2 100644 --- a/packages/cursorless-vscode-e2e/src/suite/followLink.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/followLink.vscode.test.ts @@ -1,9 +1,12 @@ +import { LATEST_VERSION } from "@cursorless/common"; import { getFixturePath, isWindows } from "@cursorless/node-common"; -import { getReusableEditor, runCursorlessCommand } from "@cursorless/vscode-common"; +import { + getReusableEditor, + runCursorlessCommand, +} from "@cursorless/vscode-common"; import * as assert from "assert"; import * as vscode from "vscode"; import { endToEndTestSetup } from "../endToEndTestSetup"; -import { LATEST_VERSION } from "@cursorless/common"; suite("followLink", async function () { endToEndTestSetup(this); diff --git a/packages/cursorless-vscode-e2e/src/suite/performance.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/performance.vscode.test.ts index f4c55ca8d0..e073e4123e 100644 --- a/packages/cursorless-vscode-e2e/src/suite/performance.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/performance.vscode.test.ts @@ -5,7 +5,10 @@ import type { SimpleScopeTypeType, } from "@cursorless/common"; import { asyncSafety } from "@cursorless/common"; -import { getReusableEditor, runCursorlessAction } from "@cursorless/vscode-common"; +import { + getReusableEditor, + runCursorlessAction, +} from "@cursorless/vscode-common"; import assert from "assert"; import * as vscode from "vscode"; import { endToEndTestSetup } from "../endToEndTestSetup"; diff --git a/packages/cursorless-vscode-e2e/src/suite/revealRange.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/revealRange.vscode.test.ts index 843c9fbea6..637ef4cbec 100644 --- a/packages/cursorless-vscode-e2e/src/suite/revealRange.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/revealRange.vscode.test.ts @@ -1,5 +1,8 @@ import { LATEST_VERSION } from "@cursorless/common"; -import { getReusableEditor, runCursorlessCommand } from "@cursorless/vscode-common"; +import { + getReusableEditor, + runCursorlessCommand, +} from "@cursorless/vscode-common"; import assert from "node:assert"; import * as vscode from "vscode"; import { endToEndTestSetup } from "../endToEndTestSetup"; From d5e142dd5e34bef8a74b0ae6f18364dc2b0d6e12 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Thu, 12 Mar 2026 19:17:05 +0100 Subject: [PATCH 8/8] Format --- .../cursorless-vscode-e2e/src/suite/scroll.vscode.test.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/cursorless-vscode-e2e/src/suite/scroll.vscode.test.ts b/packages/cursorless-vscode-e2e/src/suite/scroll.vscode.test.ts index b95ee720a5..00a89a27c8 100644 --- a/packages/cursorless-vscode-e2e/src/suite/scroll.vscode.test.ts +++ b/packages/cursorless-vscode-e2e/src/suite/scroll.vscode.test.ts @@ -1,5 +1,8 @@ import { LATEST_VERSION } from "@cursorless/common"; -import { getReusableEditor, runCursorlessCommand } from "@cursorless/vscode-common"; +import { + getReusableEditor, + runCursorlessCommand, +} from "@cursorless/vscode-common"; import * as vscode from "vscode"; import { endToEndTestSetup } from "../endToEndTestSetup";