Skip to content

Commit

Permalink
improve default outputConfig user experience
Browse files Browse the repository at this point in the history
  • Loading branch information
connectdotz committed Mar 15, 2024
1 parent 0c57873 commit 8d2cdec
Show file tree
Hide file tree
Showing 10 changed files with 480 additions and 267 deletions.
3 changes: 1 addition & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
},
"typescript.tsdk": "./node_modules/typescript/lib",
// jest
"jest.runMode":"on-demand",
// "testing.openTesting": "neverOpen",

// eslint
"tslint.enable": false,
"eslint.enable": true,
Expand Down
33 changes: 22 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -387,14 +387,15 @@ This setting can be one of the predefined types or a custom object.
4. "none": Do not clear any panel. (default)
(_**Note**: As of the current version, the testing framework does not support the clearing of the "TEST RESULTS" panel without side effects. The closest available command also clears all test item statuses, which may not be desirable. We are aware of this limitation and will raise the issue with the VS Code team._)


<a id="outputconfig-conflict"></a>
**Handling Conflicts with "TEST RESULTS" panel**

_The Problem_

The behavior of the "TEST RESULTS" panel is influenced by VSCode's native `"testing.openTesting"` setting. This can cause inconsistencies with your `"jest.outputConfig"` settings.

For instance, if you set `"jest.outputConfig": {"revealWithFocus": "none"}` to prevent automatic focus changes, but leave `"testing.openTesting"` at its default value of `"openOnTestStart"`, the "TEST RESULTS" panel will still automatically switch focus whenever tests run.
For instance, if you set `"jest.outputConfig": {"revealWithFocus": "none"}` to prevent automatic focus changes, but leave `"testing.openTesting"` at its default value of `"openOnTestStart"`, the "TEST RESULTS" panel will still automatically switch focus when the tests are run via UI.

_The Universal Solution_

Expand All @@ -415,12 +416,26 @@ The extension features output config diagnosis information in the jest terminal,

Upon upgrading to v6.2, some users, frequently with auto run modes (e.g., 'watch', 'on-save'), might experience frequent "TEST RESULTS" panel automatically grabbing focus whenever files are saved or tests are run.

> [!NOTE]
>
> **update**
> In version 6.2.3, we've resolved this issue by modifying the default auto-focus behavior so the 'TEST RESULTS' panel will not automatically grab focus in auto-run modes, particularly when `"testing.openTesting"` or `"jest.outputConfig"` settings are not specified. This change should completely eliminate this issue.
>
>
<details>

<summary>Previous Workaround</summary>

This is due to the extension generates a default `jest.outputConfig`, if none is existing in your settings, to match the existing `testing.openTesting` setting, which defaults to `"openOnTestStart"`. If this is not your desired output experience, you can easily disable `testing.openTesting` in your settings.json:
```json
"testing.openTesting": "neverOpen"
```
Then use the `jest.outputConfig` to find-tune the output experience you prefer.

</details>


**Examples**
- Choose a passive output experience that is identical to the previous version: no automatic focus switch, no automatic clear.
```json
Expand All @@ -432,11 +447,6 @@ Then use the `jest.outputConfig` to find-tune the output experience you prefer.
"testing.openTesting": "neverOpen",
"jest.outputConfig": "terminal-based"
```
- Choose a test-results-based experience and switch focus to it when test run starts.
```json
"testing.openTesting": "neverOpen",
"jest.outputConfig": "test-results-based"
```
- Choose a test-results-based experience and switch focus to it when test fails.
```json
"testing.openTesting": "neverOpen",
Expand All @@ -457,16 +467,17 @@ Then use the `jest.outputConfig` to find-tune the output experience you prefer.
> <a id="outputconfig-migration"></a>
> **Migration Guide**
>
> Migrating to the new `"jest.outputConfig"` can require some manual adjustments, especially if you're working in a multi-root workspace. Here are some guidelines to help with the transition:
> Migrating to the new `"jest.outputConfig"` might require some manual adjustments, especially if you're working in a multi-root workspace. Here are some guidelines to help with the transition:
>
> 1. **Workspace Level vs Workspace-Folder Level**: The new `"jest.outputConfig"` is a workspace-level setting, unlike legacy settings like `"jest.autoClearTerminal"` and `"jest.autoRevealOutput"`, which are workspace-folder level settings.
>
> 2. **Backward Compatibility**: If no `"jest.outputConfig"` is defined in your settings.json, the extension will attempt to generate a backward-compatible outputConfig in memory. This uses the `"testing.openTesting"` setting and any legacy settings (`"jest.autoClearTerminal"`, `"jest.autoRevealOutput"`) you might have. Note that this might only work for single-root workspaces.
>
> 3. **Migration Steps**:
> - Use the `"Jest: Save Current Output Config"` command from the command palette to update your settings.json.
> - (optional) Fix warning: The save does not include `"testing.openTesting"`, so you might see the conflict warning message. You can either use the "Quick Fix" action or adjust the `settings.json` manually (see [handling conflict](#outputconfig-conflict)).
> - Finally, remove any deprecated settings.
> 3. **Customization Steps**:
In general it should work out of the box, but if you encounter any issues, here are some steps to help adjusting the output behavior:
> - Use the `"Jest: Save Current Output Config"` command from the command palette to update your settings.json. Then adjust it to fit your needs.
> - Fix warning if any: The save does not include `"testing.openTesting"`, so you might see the conflict warning message. You can either use the "Quick Fix" action or adjust the `settings.json` manually (see [handling conflict](#outputconfig-conflict)).
> - Finally, remove any deprecated settings.
>
> By following these guidelines, you should be able to smoothly transition to using `"jest.outputConfig"`.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "vscode-jest",
"displayName": "Jest",
"description": "Use Facebook's Jest With Pleasure.",
"version": "6.2.2",
"version": "6.2.3",
"publisher": "Orta",
"engines": {
"vscode": "^1.68.1"
Expand Down
31 changes: 5 additions & 26 deletions src/JestExt/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { CoverageMapData } from 'istanbul-lib-coverage';
import { Logging } from '../logging';
import { createProcessSession, ProcessSession } from './process-session';
import { JestExtContext, JestSessionEvents, JestExtSessionContext, JestRunEvent } from './types';
import { extensionName, OUTPUT_CONFIG_HELP_URL, SupportedLanguageIds } from '../appGlobals';
import { extensionName, SupportedLanguageIds } from '../appGlobals';
import { createJestExtContext, getExtensionResourceSettings, prefixWorkspace } from './helper';
import { PluginResourceSettings } from '../Settings';
import { WizardTaskId } from '../setup-wizard';
Expand All @@ -38,8 +38,6 @@ interface JestCommandSettings {
jestCommandLine: string;
}

const AUTO_FOCUS_WARNING = `The TEST RESULTS panel has auto-focus enabled, which may cause frequent focus shifts during the current run mode. If this becomes a problem, you can disable the auto-focus using the command "Jest: Disable Auto Focus Test Output". Alternatively, click on the action link below. For more details, see ${OUTPUT_CONFIG_HELP_URL}`;

/** extract lines starts and end with [] */
export class JestExt {
coverageMapProvider: CoverageMapProvider;
Expand Down Expand Up @@ -145,8 +143,8 @@ export class JestExt {
this.output.write(
'Critical Settings:\r\n' +
`jest.runMode: ${JSON.stringify(pluginSettings.runMode.config, undefined, 4)}\r\n` +
`jest.outputConfig: ${JSON.stringify(outputConfig, undefined, 4)}\r\n` +
`testing.openTesting: ${JSON.stringify(openTesting, undefined, 4)}\r\n`,
`jest.outputConfig: ${JSON.stringify(outputConfig.value, undefined, 4)}\r\n` +
`testing.openTesting: ${JSON.stringify(openTesting.value, undefined, 4)}\r\n`,
'info'
);
return pluginSettings;
Expand Down Expand Up @@ -186,7 +184,7 @@ export class JestExt {
}

private enableOutputOnRun(): void {
outputManager.showOutputOn('run', this.output);
outputManager.showOutputOn('run', this.output, this.extContext.settings.runMode);
}
private setupRunEvents(events: JestSessionEvents): void {
events.onRunEvent.event((event: JestRunEvent) => {
Expand Down Expand Up @@ -236,7 +234,7 @@ export class JestExt {
}
case 'test-error': {
if (!event.process.userData?.testError) {
outputManager.showOutputOn('test-error', this.output);
outputManager.showOutputOn('test-error', this.output, this.extContext.settings.runMode);
event.process.userData = { ...(event.process.userData ?? {}), testError: true };
}
break;
Expand Down Expand Up @@ -321,7 +319,6 @@ export class JestExt {

// update visible editors that belong to this folder
this.updateVisibleTextEditors();
this.warnAutoRunAutoFocus();
} catch (e) {
this.outputActionMessages(
`Failed to start jest session: ${e}`,
Expand Down Expand Up @@ -354,24 +351,6 @@ export class JestExt {
}
}

// check if output config has conflict, especially for auto-run modes
private async warnAutoRunAutoFocus(): Promise<void> {
if (
this.extContext.settings.runMode.config.deferred ||
this.extContext.settings.runMode.config.type === 'on-demand' ||
outputManager.isAutoFocus() === false
) {
return;
}
const cmdLink = executableTerminalLinkProvider.executableLink(
this.extContext.workspace.name,
`${extensionName}.disable-auto-focus`
);

this.output.write(AUTO_FOCUS_WARNING, 'warn');
this.output.write(`Disable Auto Focus: \u2192 ${cmdLink}\r\n`, 'info');
}

private updateTestFileEditor(editor: vscode.TextEditor): void {
if (!this.isTestFileEditor(editor)) {
return;
Expand Down
27 changes: 26 additions & 1 deletion src/Settings/helper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import * as vscode from 'vscode';
import { GetConfigFunction, VirtualFolderSettings, VirtualFolderSettingKey } from './types';
import {
GetConfigFunction,
VirtualFolderSettings,
VirtualFolderSettingKey,
SettingDetail,
} from './types';
import { isVirtualWorkspaceFolder } from '../virtual-workspace-folder';

/**
Expand Down Expand Up @@ -55,3 +60,23 @@ export const updateSetting = async (
(vFolder as any)[key] = value;
await config.update('virtualFolders', virtualFolders);
};

export const getSettingDetail = <T>(configName: string, section: string): SettingDetail<T> => {
// Use the `inspect` method to get detailed information about the setting
const config = vscode.workspace.getConfiguration(configName);
const value = config.get<T>(section);
const settingInspection = config.inspect<T>(section);

if (settingInspection) {
const isExplicitlySet =
settingInspection.globalValue !== undefined ||
settingInspection.workspaceValue !== undefined ||
settingInspection.workspaceFolderValue !== undefined ||
settingInspection.globalLanguageValue !== undefined ||
settingInspection.workspaceLanguageValue !== undefined ||
settingInspection.workspaceFolderLanguageValue !== undefined;

return { value, isExplicitlySet };
}
return { value: undefined, isExplicitlySet: false };
};
6 changes: 6 additions & 0 deletions src/Settings/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,9 @@ export interface VirtualFolderSettings extends AllPluginResourceSettings {
}

export type GetConfigFunction = <T>(key: VirtualFolderSettingKey) => T | undefined;

export interface SettingDetail<T> {
value: T | undefined;
/** true if the setting is explicitly defined in a settings file, i.e., not from default value */
isExplicitlySet: boolean;
}
Loading

0 comments on commit 8d2cdec

Please sign in to comment.