diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index aa3549be39d..e62ec2826b2 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1661,6 +1661,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I LinkedEditingRanges: extHostTypes.LinkedEditingRanges, TestResultState: extHostTypes.TestResultState, TestRunRequest: extHostTypes.TestRunRequest, + TestRunRequest2: extHostTypes.TestRunRequest, TestMessage: extHostTypes.TestMessage, TestTag: extHostTypes.TestTag, TestRunProfileKind: extHostTypes.TestRunProfileKind, diff --git a/src/vs/workbench/api/common/extHostTesting.ts b/src/vs/workbench/api/common/extHostTesting.ts index 0aaec347ee6..27d76030c61 100644 --- a/src/vs/workbench/api/common/extHostTesting.ts +++ b/src/vs/workbench/api/common/extHostTesting.ts @@ -210,7 +210,7 @@ export class ExtHostTesting extends Disposable implements ExtHostTestingShape { } await this.proxy.$runTests({ - isUiTriggered: false, + preserveFocus: (req as vscode.TestRunRequest2).preserveFocus ?? true, targets: [{ testIds: req.include?.map(t => TestId.fromExtHostTestItem(t, controller.collection.root.id).toString()) ?? [controller.collection.root.id], profileGroup: profileGroupToBitset[profile.kind], @@ -746,6 +746,7 @@ export class TestRunCoordinator { exclude: request.exclude?.map(t => TestId.fromExtHostTestItem(t, collection.root.id).toString()) ?? [], id: dto.id, include: request.include?.map(t => TestId.fromExtHostTestItem(t, collection.root.id).toString()) ?? [collection.root.id], + preserveFocus: (request as vscode.TestRunRequest2).preserveFocus ?? true, persist }); diff --git a/src/vs/workbench/api/common/extHostTypes.ts b/src/vs/workbench/api/common/extHostTypes.ts index 71cd622ed18..fbc756b5f64 100644 --- a/src/vs/workbench/api/common/extHostTypes.ts +++ b/src/vs/workbench/api/common/extHostTypes.ts @@ -4018,12 +4018,13 @@ export enum TestRunProfileKind { } @es5ClassCompat -export class TestRunRequest implements vscode.TestRunRequest { +export class TestRunRequest implements vscode.TestRunRequest2 { constructor( public readonly include: vscode.TestItem[] | undefined = undefined, public readonly exclude: vscode.TestItem[] | undefined = undefined, public readonly profile: vscode.TestRunProfile | undefined = undefined, public readonly continuous = false, + public readonly preserveFocus = true, ) { } } diff --git a/src/vs/workbench/api/test/browser/extHostTesting.test.ts b/src/vs/workbench/api/test/browser/extHostTesting.test.ts index 9a3e9ad4980..adcd787f160 100644 --- a/src/vs/workbench/api/test/browser/extHostTesting.test.ts +++ b/src/vs/workbench/api/test/browser/extHostTesting.test.ts @@ -752,6 +752,7 @@ suite('ExtHost Testing', () => { exclude: [new TestId(['ctrlId', 'id-b']).toString()], persist: false, continuous: false, + preserveFocus: true, }] ]); diff --git a/src/vs/workbench/contrib/testing/browser/testingProgressUiService.ts b/src/vs/workbench/contrib/testing/browser/testingProgressUiService.ts index fbabc8903f8..57de4712ef1 100644 --- a/src/vs/workbench/contrib/testing/browser/testingProgressUiService.ts +++ b/src/vs/workbench/contrib/testing/browser/testingProgressUiService.ts @@ -31,7 +31,7 @@ export class TestingProgressTrigger extends Disposable { } private attachAutoOpenForNewResults(result: LiveTestResult) { - if (result.request.isUiTriggered === false) { + if (result.request.preserveFocus === true) { return; } diff --git a/src/vs/workbench/contrib/testing/common/testResultService.ts b/src/vs/workbench/contrib/testing/common/testResultService.ts index 98dbec77cca..3035be654df 100644 --- a/src/vs/workbench/contrib/testing/common/testResultService.ts +++ b/src/vs/workbench/contrib/testing/common/testResultService.ts @@ -149,7 +149,7 @@ export class TestResultService extends Disposable implements ITestResultService } const resolved: ResolvedTestRunRequest = { - isUiTriggered: false, + preserveFocus: req.preserveFocus, targets: [], exclude: req.exclude, continuous: req.continuous, diff --git a/src/vs/workbench/contrib/testing/common/testServiceImpl.ts b/src/vs/workbench/contrib/testing/common/testServiceImpl.ts index fa0d439e186..04692c5dc81 100644 --- a/src/vs/workbench/contrib/testing/common/testServiceImpl.ts +++ b/src/vs/workbench/contrib/testing/common/testServiceImpl.ts @@ -366,7 +366,7 @@ export class TestService extends Disposable implements ITestService { } private async saveAllBeforeTest(req: ResolvedTestRunRequest, configurationService: IConfigurationService = this.configurationService, editorService: IEditorService = this.editorService): Promise { - if (req.isUiTriggered === false) { + if (req.preserveFocus === true) { return; } const saveBeforeTest = getTestingConfiguration(this.configurationService, TestingConfigKeys.SaveBeforeTest); diff --git a/src/vs/workbench/contrib/testing/common/testTypes.ts b/src/vs/workbench/contrib/testing/common/testTypes.ts index 9aa9db27bcb..cd14796eb0a 100644 --- a/src/vs/workbench/contrib/testing/common/testTypes.ts +++ b/src/vs/workbench/contrib/testing/common/testTypes.ts @@ -88,7 +88,7 @@ export interface ResolvedTestRunRequest { /** Whether this is a continuous test run */ continuous?: boolean; /** Whether this was trigged by a user action in UI. Default=true */ - isUiTriggered?: boolean; + preserveFocus?: boolean; } /** @@ -101,6 +101,7 @@ export interface ExtensionRunTestsRequest { controllerId: string; profile?: { group: TestRunProfileBitset; id: number }; persist: boolean; + preserveFocus: boolean; /** Whether this is a result of a continuous test run request */ continuous: boolean; } diff --git a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts index 93fffb8efbc..402560ad1bd 100644 --- a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts +++ b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts @@ -115,6 +115,7 @@ export const allApiProposals = Object.freeze({ terminalSelection: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalSelection.d.ts', terminalShellIntegration: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.terminalShellIntegration.d.ts', testObserver: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.testObserver.d.ts', + testPreserveFocus: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.testPreserveFocus.d.ts', textSearchProvider: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.textSearchProvider.d.ts', timeline: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.timeline.d.ts', tokenInformation: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.tokenInformation.d.ts', diff --git a/src/vscode-dts/vscode.proposed.testPreserveFocus.d.ts b/src/vscode-dts/vscode.proposed.testPreserveFocus.d.ts new file mode 100644 index 00000000000..1404b4de096 --- /dev/null +++ b/src/vscode-dts/vscode.proposed.testPreserveFocus.d.ts @@ -0,0 +1,28 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +declare module 'vscode' { + + // See https://github.com/microsoft/vscode/issues/209491 + + export class TestRunRequest2 extends TestRunRequest { + /** + * Controls how test Test Results view is focused. If true, the editor + * will keep the maintain the user's focus. If false, the editor will + * prefer to move focus into the Test Results view, although + * this may be configured by users. + */ + readonly preserveFocus: boolean; + + /** + * @param include Array of specific tests to run, or undefined to run all tests + * @param exclude An array of tests to exclude from the run. + * @param profile The run profile used for this request. + * @param continuous Whether to run tests continuously as source changes. + * @param preserveFocus Whether to preserve the user's focus when the run is started + */ + constructor(include?: readonly TestItem[], exclude?: readonly TestItem[], profile?: TestRunProfile, continuous?: boolean); + } +}