Skip to content

Commit e9f4273

Browse files
authored
Fix "Run Tests Multiple Times" on Linux (#1824)
* Fix "Run Tests Multiple Times" on Linux When we process the `...args` passed to the 'run multiple' commands we're only checking if the argument is an object before deeming it a TestItem. On linux VS Code is passing an event object like `{ preserveFocus: true }`, which is being treated as a TestItem and causing the command to error out.
1 parent d8b9ff7 commit e9f4273

File tree

4 files changed

+22
-6
lines changed

4 files changed

+22
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
- Don't start debugging XCTest cases if the swift-testing debug session was stopped ([#1797](https://github.com/swiftlang/vscode-swift/pull/1797))
1515
- Improve error handling when the swift path is misconfigured ([#1801](https://github.com/swiftlang/vscode-swift/pull/1801))
16+
- Fix an error when performing "Run/Debug Tests Multiple Times" on Linux ([#1824](https://github.com/swiftlang/vscode-swift/pull/1824))
1617

1718
## 2.11.20250806 - 2025-08-06
1819

src/commands/testMultipleTimes.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,10 @@ export async function runTestMultipleTimes(
5151
}
5252
const token = new vscode.CancellationTokenSource();
5353
const testExplorer = currentFolder.testExplorer;
54+
const request = new vscode.TestRunRequest(tests);
5455
const runner = new TestRunner(
5556
kind,
56-
new vscode.TestRunRequest(tests),
57+
request,
5758
currentFolder,
5859
testExplorer.controller,
5960
token.token
@@ -110,9 +111,7 @@ export async function runTestMultipleTimes(
110111
* also accept a final count parameter. We have to find the count parameter ourselves since JavaScript
111112
* only supports varargs at the end of an argument list.
112113
*/
113-
export function extractTestItemsAndCount(
114-
...args: (vscode.TestItem | number | undefined | null)[]
115-
): {
114+
export function extractTestItemsAndCount(...args: unknown[]): {
116115
testItems: vscode.TestItem[];
117116
count?: number;
118117
} {
@@ -126,9 +125,12 @@ export function extractTestItemsAndCount(
126125
} else if (typeof arg === "number" && index === args.length - 1) {
127126
result.count = arg ?? undefined;
128127
return result;
129-
} else if (typeof arg === "object") {
128+
} else if (isVSCodeTestItem(arg)) {
130129
result.testItems.push(arg);
131130
return result;
131+
} else if (typeof arg === "object") {
132+
// Object but not a TestItem, just skip it
133+
return result;
132134
} else {
133135
throw new Error(`Unexpected argument ${arg} at index ${index}`);
134136
}
@@ -137,3 +139,15 @@ export function extractTestItemsAndCount(
137139
);
138140
return result;
139141
}
142+
143+
/**
144+
* Checks if an object is a vscode.TestItem via duck typing.
145+
*/
146+
function isVSCodeTestItem(obj: unknown): obj is vscode.TestItem {
147+
return (
148+
typeof obj === "object" &&
149+
obj !== null &&
150+
Object.prototype.hasOwnProperty.call(obj, "id") &&
151+
Object.prototype.hasOwnProperty.call(obj, "uri")
152+
);
153+
}

test/integration-tests/testexplorer/TestExplorerIntegration.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,7 @@ tag("large").suite("Test Explorer Suite", function () {
597597
await vscode.commands.executeCommand(
598598
Commands.RUN_TESTS_MULTIPLE_TIMES,
599599
testItems[0],
600+
{ preserveFocus: true }, // a trailing argument included on Linux
600601
numIterations
601602
);
602603

test/unit-tests/commands/runTestMultipleTimes.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { extractTestItemsAndCount } from "@src/commands/testMultipleTimes";
1919
suite("Run Tests Multiple Times", () => {
2020
suite("extractTestItemsAndCount()", () => {
2121
function createDummyTestItem(label: string): vscode.TestItem {
22-
return { label } as vscode.TestItem;
22+
return { id: label, uri: vscode.Uri.file(`/dummy/path/${label}`) } as vscode.TestItem;
2323
}
2424

2525
test("handles empty arguments", () => {

0 commit comments

Comments
 (0)