Change:
It's common that extensions trigger tests in various ways. Some of those may be user-initiated through UI actions outside of the built-in ones where focus should be transferred, some of them may be triggered in the background where focus should not be transferred. There have been a bunch of issues around this, on as well as those of community extensions. I suggest adding an additional option to the to allow extensions to hint whether focus should be preserved: Note this is on the TestRunRequest, not the individual TestRun. TestRunRequests can be created both by the the editor and extensions (if they initiate a test run), and this provides control for the latter case.
I presume is treated like , but I think it's worth tweaking the text to make this explicit. It's also not quite clear to me how the user overrides this - is this some tri-state setting like: let extension decide whether to show results (default) always show results never show results ?
Yea would be the current behavior, which is (most of the time.) In the false case this is a 'hint': whether focus is actually moved is controlled by the user's setting. I'm not planning on having a mechanism to force focus to move, although if an extension really wanted that they could run a command to that effect.
I think I'm still confused. From the above, it sounds like: - don't open testing view, always keep focus in the editor - do what happens today - don't open testing view for programmatic test runs triggered by extensions - does this differ from ? But I'm not sure how I handle Maybe the interaction with the user settings needs to be clearer - which different user settings influence the behaviour for each of these values?
Ah, yea, sorry. It has been a while since I touched that area I thought there we cases where that was for extension-triggered runs -- so there's no need for , it'll be true/fase (defaulting to true for backwards compatibility.) I updated my initial proposal. Maybe the interaction with the user settings needs to be clearer - which different user settings influence the behaviour for each of these values? Whether focus actually moves when will be controlled by : the same way as ui-triggered runs do today.
For my particular use case, I would need slightly different behavior. Essentially, I am offering a "Measure Code Coverage" command. This command is explicitly triggered by the user, i.e. I know the user wants to see the coverage results. I think the most intuitive behavior would be the following: If the user already has a file open, and the coverage run actually provided coverage for that file: Don't switch to the test results view. The user is probably interested in seeing the coverage for the file which he has already open, and the in-editor rendering of the coverage results will allow him to do exactly that. If the user has no file open, or if the coverage run did not provide any coverage data for that file, switch focus to the test results / test coverage view Not sure if my use case could be accommodated somehow by expanding on your proposed design. Maybe my use case is too much of a special case... How would I do that? I couldn't find an API or a command which would allow me to do so
You could run Your use case does seem like it's kind of special, I would say you can use the command for now, unless I get feedback from others asking for something similar for that.
This is available in the latest Insiders, please try it out and let me know if it works for you
thanks, this seems to work for me :) I'm currently setting it like this so I don't have to crank the min VS Code version to get the updated type though

Discussion:
LinkedEditingRanges: extHostTypes.LinkedEditingRanges, TestResultState: extHostTypes.TestResultState, TestRunRequest: extHostTypes.TestRunRequest, <del> TestRunRequest2: extHostTypes.TestRunRequest, </del> TestMessage: extHostTypes.TestMessage, TestTag: extHostTypes.TestTag, TestRunProfileKind: extHostTypes.TestRunProfileKind,

} await this.proxy.$runTests({ <del> preserveFocus: (req as vscode.TestRunRequest2).preserveFocus ?? true, </del> <ins> preserveFocus: req.preserveFocus ?? true, </ins> targets: [{ testIds: req.include?.map(t => TestId.fromExtHostTestItem(t, controller.collection.root.id).toString()) ?? [controller.collection.root.id], profileGroup: profileGroupToBitset[profile.kind],

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], <del> preserveFocus: (request as vscode.TestRunRequest2).preserveFocus ?? true, </del> <ins> preserveFocus: request.preserveFocus ?? true, </ins> persist });

} @es5ClassCompat <del> export class TestRunRequest implements vscode.TestRunRequest2 { </del> <ins> export class TestRunRequest implements vscode.TestRunRequest { </ins> constructor( public readonly include: vscode.TestItem[] | undefined = undefined, public readonly exclude: vscode.TestItem[] | undefined = undefined,

include: undefined, exclude: [single.root.children.get('id-b')!], profile: configuration, <ins> preserveFocus: false, </ins> }; dto = TestRunDto.fromInternal({

exclude: [new TestId(['ctrlId', 'id-b']).toString()], persist: false, continuous: false, <del> preserveFocus: true, </del> <ins> preserveFocus: false, </ins> }] ]);

profile: configuration, include: [single.root.children.get('id-a')!], exclude: [single.root.children.get('id-a')!.children.get('id-aa')!], <ins> preserveFocus: false, </ins> }, 'hello world', false); task.passed(single.root.children.get('id-a')!.children.get('id-aa')!);

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', <del> testPreserveFocus: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.testPreserveFocus.d.ts', </del> 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',

readonly continuous?: boolean; /** <ins> * 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; /** </ins> * @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. <ins> * @param preserveFocus Whether to preserve the user's focus when the run is started </ins> */ <del> constructor(include?: readonly TestItem[], exclude?: readonly TestItem[], profile?: TestRunProfile, continuous?: boolean); </del> <ins> constructor(include?: readonly TestItem[], exclude?: readonly TestItem[], profile?: TestRunProfile, continuous?: boolean, preserveFocus?: boolean); </ins> } /**

<del> /*--------------------------------------------------------------------------------------------- *  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); } } </del>