@codingame/monaco-vscode-testing-service-override 3.2.3 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/package.json +8 -8
  2. package/testing.js +5 -4
  3. package/external/rollup-plugin-styles/dist/runtime/inject-css.js +0 -3
  4. package/external/tslib/tslib.es6.js +0 -11
  5. package/vscode/src/vs/workbench/contrib/testing/browser/codeCoverageDecorations.js +0 -567
  6. package/vscode/src/vs/workbench/contrib/testing/browser/explorerProjections/display.js +0 -3
  7. package/vscode/src/vs/workbench/contrib/testing/browser/explorerProjections/index.js +0 -83
  8. package/vscode/src/vs/workbench/contrib/testing/browser/explorerProjections/listProjection.js +0 -186
  9. package/vscode/src/vs/workbench/contrib/testing/browser/explorerProjections/testItemContextOverlay.js +0 -18
  10. package/vscode/src/vs/workbench/contrib/testing/browser/explorerProjections/testingObjectTree.js +0 -46
  11. package/vscode/src/vs/workbench/contrib/testing/browser/explorerProjections/testingViewState.js +0 -17
  12. package/vscode/src/vs/workbench/contrib/testing/browser/explorerProjections/treeProjection.js +0 -225
  13. package/vscode/src/vs/workbench/contrib/testing/browser/icons.js +0 -174
  14. package/vscode/src/vs/workbench/contrib/testing/browser/media/testing.css.js +0 -6
  15. package/vscode/src/vs/workbench/contrib/testing/browser/testCoverageBars.js +0 -227
  16. package/vscode/src/vs/workbench/contrib/testing/browser/testCoverageView.js +0 -545
  17. package/vscode/src/vs/workbench/contrib/testing/browser/testExplorerActions.js +0 -1662
  18. package/vscode/src/vs/workbench/contrib/testing/browser/testing.contribution.js +0 -219
  19. package/vscode/src/vs/workbench/contrib/testing/browser/testingDecorations.js +0 -970
  20. package/vscode/src/vs/workbench/contrib/testing/browser/testingExplorerFilter.js +0 -236
  21. package/vscode/src/vs/workbench/contrib/testing/browser/testingExplorerView.js +0 -1227
  22. package/vscode/src/vs/workbench/contrib/testing/browser/testingOutputPeek.css.js +0 -6
  23. package/vscode/src/vs/workbench/contrib/testing/browser/testingOutputPeek.js +0 -2091
  24. package/vscode/src/vs/workbench/contrib/testing/browser/testingProgressUiService.js +0 -142
  25. package/vscode/src/vs/workbench/contrib/testing/browser/testingViewPaneContainer.js +0 -47
  26. package/vscode/src/vs/workbench/contrib/testing/browser/theme.js +0 -259
  27. package/vscode/src/vs/workbench/contrib/testing/common/configuration.js +0 -273
  28. package/vscode/src/vs/workbench/contrib/testing/common/constants.js +0 -59
  29. package/vscode/src/vs/workbench/contrib/testing/common/mainThreadTestCollection.js +0 -129
  30. package/vscode/src/vs/workbench/contrib/testing/common/testExclusions.js +0 -48
  31. package/vscode/src/vs/workbench/contrib/testing/common/testServiceImpl.js +0 -296
  32. package/vscode/src/vs/workbench/contrib/testing/common/testingContentProvider.js +0 -125
  33. package/vscode/src/vs/workbench/contrib/testing/common/testingUri.js +0 -67
@@ -1,1227 +0,0 @@
1
- import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
2
- import { append, $, clearNode, reset, h, addStandardDisposableListener, isMouseEvent } from 'vscode/vscode/vs/base/browser/dom';
3
- import { ActionBar } from 'vscode/vscode/vs/base/browser/ui/actionbar/actionbar';
4
- import { Button } from 'vscode/vscode/vs/base/browser/ui/button/button';
5
- import { renderLabelWithIcons } from 'vscode/vscode/vs/base/browser/ui/iconLabel/iconLabels';
6
- import { DefaultKeyboardNavigationDelegate } from 'vscode/vscode/vs/base/browser/ui/list/listWidget';
7
- import { Action, Separator, ActionRunner } from 'vscode/vscode/vs/base/common/actions';
8
- import { mapFindFirst } from 'vscode/vscode/vs/base/common/arraysFind';
9
- import { RunOnceScheduler, disposableTimeout } from 'vscode/vscode/vs/base/common/async';
10
- import { Color, RGBA } from 'vscode/vscode/vs/base/common/color';
11
- import { Emitter, Event } from 'vscode/vscode/vs/base/common/event';
12
- import { Disposable, DisposableStore, MutableDisposable } from 'vscode/vscode/vs/base/common/lifecycle';
13
- import { fuzzyContains } from 'vscode/vscode/vs/base/common/strings';
14
- import { ThemeIcon } from 'vscode/vscode/vs/base/common/themables';
15
- import { isDefined } from 'vscode/vscode/vs/base/common/types';
16
- import './media/testing.css.js';
17
- import { MarkdownRenderer } from 'vscode/vscode/vs/editor/browser/widget/markdownRenderer/browser/markdownRenderer';
18
- import { localizeWithPath } from 'vscode/vscode/vs/nls';
19
- import { DropdownWithPrimaryActionViewItem } from 'vscode/vscode/vs/platform/actions/browser/dropdownWithPrimaryActionViewItem';
20
- import { MenuEntryActionViewItem, createAndFillInActionBarActions, createActionViewItem } from 'vscode/vscode/vs/platform/actions/browser/menuEntryActionViewItem';
21
- import { MenuItemAction, MenuId, IMenuService } from 'vscode/vscode/vs/platform/actions/common/actions';
22
- import { ICommandService } from 'vscode/vscode/vs/platform/commands/common/commands';
23
- import { IConfigurationService } from 'vscode/vscode/vs/platform/configuration/common/configuration';
24
- import { IContextKeyService } from 'vscode/vscode/vs/platform/contextkey/common/contextkey';
25
- import { IContextMenuService } from 'vscode/vscode/vs/platform/contextview/browser/contextView';
26
- import { IInstantiationService } from 'vscode/vscode/vs/platform/instantiation/common/instantiation';
27
- import { IKeybindingService } from 'vscode/vscode/vs/platform/keybinding/common/keybinding';
28
- import { IOpenerService } from 'vscode/vscode/vs/platform/opener/common/opener';
29
- import { UnmanagedProgress } from 'vscode/vscode/vs/platform/progress/common/progress';
30
- import { WillSaveStateReason, IStorageService } from 'vscode/vscode/vs/platform/storage/common/storage';
31
- import { ITelemetryService } from 'vscode/vscode/vs/platform/telemetry/common/telemetry';
32
- import { defaultButtonStyles } from 'vscode/vscode/vs/platform/theme/browser/defaultStyles';
33
- import { foreground } from 'vscode/vscode/vs/platform/theme/common/colorRegistry';
34
- import { spinningLoading } from 'vscode/vscode/vs/platform/theme/common/iconRegistry';
35
- import { registerThemingParticipant, IThemeService } from 'vscode/vscode/vs/platform/theme/common/themeService';
36
- import { IUriIdentityService } from 'vscode/vscode/vs/platform/uriIdentity/common/uriIdentity';
37
- import { registerNavigableContainer } from 'vscode/vscode/vs/workbench/browser/actions/widgetNavigationCommands';
38
- import { ViewPane } from 'vscode/vscode/vs/workbench/browser/parts/views/viewPane';
39
- import { DiffEditorInput } from 'vscode/vscode/vs/workbench/common/editor/diffEditorInput';
40
- import { IViewDescriptorService } from 'vscode/vscode/vs/workbench/common/views';
41
- import { TestItemTreeElement, TestTreeErrorMessage } from './explorerProjections/index.js';
42
- import { ListProjection } from './explorerProjections/listProjection.js';
43
- import { getTestItemContextOverlay } from './explorerProjections/testItemContextOverlay.js';
44
- import { TestingObjectTree } from './explorerProjections/testingObjectTree.js';
45
- import { TreeProjection } from './explorerProjections/treeProjection.js';
46
- import { testingHiddenIcon, testingStatesToIcons, testingRunAllIcon, testingDebugAllIcon, testingRerunIcon, testingDebugIcon, testingContinuousIsOn } from './icons.js';
47
- import { ReRunLastRun, DebugLastRun } from './testExplorerActions.js';
48
- import { TestingExplorerFilter } from './testingExplorerFilter.js';
49
- import { collectTestStateCounts, getTestProgressText } from './testingProgressUiService.js';
50
- import { getTestingConfiguration } from '../common/configuration.js';
51
- import { labelForTestInState } from '../common/constants.js';
52
- import { StoredValue } from 'vscode/vscode/vs/workbench/contrib/testing/common/storedValue';
53
- import { ITestExplorerFilterState } from 'vscode/vscode/vs/workbench/contrib/testing/common/testExplorerFilterState';
54
- import { TestId } from 'vscode/vscode/vs/workbench/contrib/testing/common/testId';
55
- import { canUseProfileWithTest, ITestProfileService } from 'vscode/vscode/vs/workbench/contrib/testing/common/testProfileService';
56
- import { LiveTestResult } from 'vscode/vscode/vs/workbench/contrib/testing/common/testResult';
57
- import { ITestResultService } from 'vscode/vscode/vs/workbench/contrib/testing/common/testResultService';
58
- import { testCollectionIsEmpty, ITestService } from 'vscode/vscode/vs/workbench/contrib/testing/common/testService';
59
- import { TestingContextKeys } from 'vscode/vscode/vs/workbench/contrib/testing/common/testingContextKeys';
60
- import { ITestingContinuousRunService } from 'vscode/vscode/vs/workbench/contrib/testing/common/testingContinuousRunService';
61
- import { ITestingPeekOpener } from 'vscode/vscode/vs/workbench/contrib/testing/common/testingPeekOpener';
62
- import { statesInOrder, isStateWithResult, isFailedState, cmpPriority } from 'vscode/vscode/vs/workbench/contrib/testing/common/testingStates';
63
- import { NumberBadge, IconBadge, IActivityService } from 'vscode/vscode/vs/workbench/services/activity/common/activity';
64
- import { IEditorService } from 'vscode/vscode/vs/workbench/services/editor/common/editorService';
65
-
66
- var ErrorRenderer_1, TestItemRenderer_1;
67
- let TestingExplorerView = class TestingExplorerView extends ViewPane {
68
- get focusedTreeElements() {
69
- return this.viewModel.tree.getFocus().filter(isDefined);
70
- }
71
- constructor(options, contextMenuService, keybindingService, configurationService, instantiationService, viewDescriptorService, contextKeyService, openerService, themeService, testService, telemetryService, testProfileService, commandService) {
72
- super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService);
73
- this.testService = testService;
74
- this.testProfileService = testProfileService;
75
- this.commandService = commandService;
76
- this.filterActionBar = this._register(( new MutableDisposable()));
77
- this.discoveryProgress = this._register(( new MutableDisposable()));
78
- this.filter = this._register(( new MutableDisposable()));
79
- this.filterFocusListener = this._register(( new MutableDisposable()));
80
- this.dimensions = { width: 0, height: 0 };
81
- this.lastFocusState = 0 ;
82
- const relayout = this._register(( new RunOnceScheduler(() => this.layoutBody(), 1)));
83
- this._register(this.onDidChangeViewWelcomeState(() => {
84
- if (!this.shouldShowWelcome()) {
85
- relayout.schedule();
86
- }
87
- }));
88
- this._register(testService.collection.onBusyProvidersChange(busy => {
89
- this.updateDiscoveryProgress(busy);
90
- }));
91
- this._register(testProfileService.onDidChange(() => this.updateActions()));
92
- }
93
- shouldShowWelcome() {
94
- return this.viewModel?.welcomeExperience === 1 ?? true;
95
- }
96
- focus() {
97
- super.focus();
98
- if (this.lastFocusState === 1 ) {
99
- this.viewModel.tree.domFocus();
100
- }
101
- else {
102
- this.filter.value?.focus();
103
- }
104
- }
105
- getTreeIncludeExclude(withinItems, profile, filterToType = 'visible') {
106
- const projection = this.viewModel.projection.value;
107
- if (!projection) {
108
- return { include: [], exclude: [] };
109
- }
110
- const include = ( new Set());
111
- const exclude = [];
112
- const attempt = (element, alreadyIncluded) => {
113
- if (!(element instanceof TestItemTreeElement) || !this.viewModel.tree.hasElement(element)) {
114
- return;
115
- }
116
- const inTree = this.viewModel.tree.getNode(element);
117
- if (!inTree.visible) {
118
- if (alreadyIncluded) {
119
- exclude.push(element.test);
120
- }
121
- return;
122
- }
123
- if (
124
- !alreadyIncluded
125
- && (!profile || canUseProfileWithTest(profile, element.test))
126
- && (inTree.children.length === 0 || inTree.visibleChildrenCount * 2 >= inTree.children.length)
127
- && inTree.visibleChildrenCount !== 1) {
128
- include.add(element.test);
129
- alreadyIncluded = true;
130
- }
131
- for (const child of element.children) {
132
- attempt(child, alreadyIncluded);
133
- }
134
- };
135
- if (filterToType === 'selected') {
136
- const sel = this.viewModel.tree.getSelection().filter(isDefined);
137
- if (sel.length) {
138
- L: for (const node of sel) {
139
- if (node instanceof TestItemTreeElement) {
140
- for (let i = node; i; i = i.parent) {
141
- if (( include.has(i.test))) {
142
- continue L;
143
- }
144
- }
145
- include.add(node.test);
146
- node.children.forEach(c => attempt(c, true));
147
- }
148
- }
149
- return { include: [...include], exclude };
150
- }
151
- }
152
- for (const root of withinItems || this.testService.collection.rootItems) {
153
- const element = projection.getElementByTestId(root.item.extId);
154
- if (!element) {
155
- continue;
156
- }
157
- if (profile && !canUseProfileWithTest(profile, root)) {
158
- continue;
159
- }
160
- if (!this.viewModel.tree.hasElement(element)) {
161
- const visibleChildren = [...element.children].reduce((acc, c) => this.viewModel.tree.hasElement(c) && this.viewModel.tree.getNode(c).visible ? acc + 1 : acc, 0);
162
- if (element.children.size > 0 && visibleChildren * 2 >= element.children.size) {
163
- include.add(element.test);
164
- element.children.forEach(c => attempt(c, true));
165
- }
166
- else {
167
- element.children.forEach(c => attempt(c, false));
168
- }
169
- }
170
- else {
171
- attempt(element, false);
172
- }
173
- }
174
- return { include: [...include], exclude };
175
- }
176
- render() {
177
- super.render();
178
- this._register(registerNavigableContainer({
179
- focusNotifiers: [this],
180
- focusNextWidget: () => {
181
- if (!this.viewModel.tree.isDOMFocused()) {
182
- this.viewModel.tree.domFocus();
183
- }
184
- },
185
- focusPreviousWidget: () => {
186
- if (this.viewModel.tree.isDOMFocused()) {
187
- this.filter.value?.focus();
188
- }
189
- }
190
- }));
191
- }
192
- renderBody(container) {
193
- super.renderBody(container);
194
- this.container = append(container, $('.test-explorer'));
195
- this.treeHeader = append(this.container, $('.test-explorer-header'));
196
- this.filterActionBar.value = this.createFilterActionBar();
197
- const messagesContainer = append(this.treeHeader, $('.result-summary-container'));
198
- this._register(this.instantiationService.createInstance(ResultSummaryView, messagesContainer));
199
- const listContainer = append(this.container, $('.test-explorer-tree'));
200
- this.viewModel = this.instantiationService.createInstance(TestingExplorerViewModel, listContainer, this.onDidChangeBodyVisibility);
201
- this._register(this.viewModel.tree.onDidFocus(() => this.lastFocusState = 1 ));
202
- this._register(this.viewModel.onChangeWelcomeVisibility(() => this._onDidChangeViewWelcomeState.fire()));
203
- this._register(this.viewModel);
204
- this._onDidChangeViewWelcomeState.fire();
205
- }
206
- getActionViewItem(action) {
207
- switch (action.id) {
208
- case "workbench.actions.treeView.testExplorer.filter" :
209
- this.filter.value = this.instantiationService.createInstance(TestingExplorerFilter, action);
210
- this.filterFocusListener.value = this.filter.value.onDidFocus(() => this.lastFocusState = 0 );
211
- return this.filter.value;
212
- case "testing.runSelected" :
213
- return this.getRunGroupDropdown(2 , action);
214
- case "testing.debugSelected" :
215
- return this.getRunGroupDropdown(4 , action);
216
- default:
217
- return super.getActionViewItem(action);
218
- }
219
- }
220
- getTestConfigGroupActions(group) {
221
- const profileActions = [];
222
- let participatingGroups = 0;
223
- let hasConfigurable = false;
224
- const defaults = this.testProfileService.getGroupDefaultProfiles(group);
225
- for (const { profiles, controller } of this.testProfileService.all()) {
226
- let hasAdded = false;
227
- for (const profile of profiles) {
228
- if (profile.group !== group) {
229
- continue;
230
- }
231
- if (!hasAdded) {
232
- hasAdded = true;
233
- participatingGroups++;
234
- profileActions.push(( new Action(`${controller.id}.$root`, controller.label.value, undefined, false)));
235
- }
236
- hasConfigurable = hasConfigurable || profile.hasConfigurationHandler;
237
- profileActions.push(( new Action(
238
- `${controller.id}.${profile.profileId}`,
239
- defaults.includes(profile) ? ( localizeWithPath(
240
- 'vs/workbench/contrib/testing/browser/testingExplorerView',
241
- 'defaultTestProfile',
242
- '{0} (Default)',
243
- profile.label
244
- )) : profile.label,
245
- undefined,
246
- undefined,
247
- () => {
248
- const { include, exclude } = this.getTreeIncludeExclude(undefined, profile);
249
- this.testService.runResolvedTests({
250
- exclude: ( exclude.map(e => e.item.extId)),
251
- targets: [{
252
- profileGroup: profile.group,
253
- profileId: profile.profileId,
254
- controllerId: profile.controllerId,
255
- testIds: ( include.map(i => i.item.extId)),
256
- }]
257
- });
258
- }
259
- )));
260
- }
261
- }
262
- if (participatingGroups === 1) {
263
- profileActions.shift();
264
- }
265
- const postActions = [];
266
- if (profileActions.length > 1) {
267
- postActions.push(( new Action('selectDefaultTestConfigurations', ( localizeWithPath(
268
- 'vs/workbench/contrib/testing/browser/testingExplorerView',
269
- 'selectDefaultConfigs',
270
- 'Select Default Profile'
271
- )), undefined, undefined, () => this.commandService.executeCommand("testing.selectDefaultTestProfiles" , group))));
272
- }
273
- if (hasConfigurable) {
274
- postActions.push(( new Action('configureTestProfiles', ( localizeWithPath(
275
- 'vs/workbench/contrib/testing/browser/testingExplorerView',
276
- 'configureTestProfiles',
277
- 'Configure Test Profiles'
278
- )), undefined, undefined, () => this.commandService.executeCommand("testing.configureProfile" , group))));
279
- }
280
- return Separator.join(profileActions, postActions);
281
- }
282
- saveState() {
283
- this.filter.value?.saveState();
284
- super.saveState();
285
- }
286
- getRunGroupDropdown(group, defaultAction) {
287
- const dropdownActions = this.getTestConfigGroupActions(group);
288
- if (dropdownActions.length < 2) {
289
- return super.getActionViewItem(defaultAction);
290
- }
291
- const primaryAction = this.instantiationService.createInstance(MenuItemAction, {
292
- id: defaultAction.id,
293
- title: defaultAction.label,
294
- icon: group === 2
295
- ? testingRunAllIcon
296
- : testingDebugAllIcon,
297
- }, undefined, undefined, undefined);
298
- const dropdownAction = ( new Action('selectRunConfig', 'Select Configuration...', 'codicon-chevron-down', true));
299
- return this.instantiationService.createInstance(DropdownWithPrimaryActionViewItem, primaryAction, dropdownAction, dropdownActions, '', this.contextMenuService, {});
300
- }
301
- createFilterActionBar() {
302
- const bar = ( new ActionBar(this.treeHeader, {
303
- actionViewItemProvider: action => this.getActionViewItem(action),
304
- triggerKeys: { keyDown: false, keys: [] },
305
- }));
306
- bar.push(( new Action(
307
- "workbench.actions.treeView.testExplorer.filter"
308
- )));
309
- bar.getContainer().classList.add('testing-filter-action-bar');
310
- return bar;
311
- }
312
- updateDiscoveryProgress(busy) {
313
- if (!busy && this.discoveryProgress) {
314
- this.discoveryProgress.clear();
315
- }
316
- else if (busy && !this.discoveryProgress.value) {
317
- this.discoveryProgress.value = this.instantiationService.createInstance(UnmanagedProgress, { location: this.getProgressLocation() });
318
- }
319
- }
320
- layoutBody(height = this.dimensions.height, width = this.dimensions.width) {
321
- super.layoutBody(height, width);
322
- this.dimensions.height = height;
323
- this.dimensions.width = width;
324
- this.container.style.height = `${height}px`;
325
- this.viewModel?.layout(height - this.treeHeader.clientHeight, width);
326
- this.filter.value?.layout(width);
327
- }
328
- };
329
- TestingExplorerView = ( __decorate([
330
- ( __param(1, IContextMenuService)),
331
- ( __param(2, IKeybindingService)),
332
- ( __param(3, IConfigurationService)),
333
- ( __param(4, IInstantiationService)),
334
- ( __param(5, IViewDescriptorService)),
335
- ( __param(6, IContextKeyService)),
336
- ( __param(7, IOpenerService)),
337
- ( __param(8, IThemeService)),
338
- ( __param(9, ITestService)),
339
- ( __param(10, ITelemetryService)),
340
- ( __param(11, ITestProfileService)),
341
- ( __param(12, ICommandService))
342
- ], TestingExplorerView));
343
- const SUMMARY_RENDER_INTERVAL = 200;
344
- let ResultSummaryView = class ResultSummaryView extends Disposable {
345
- constructor(container, resultService, activityService, crService, configurationService, instantiationService) {
346
- super();
347
- this.container = container;
348
- this.resultService = resultService;
349
- this.activityService = activityService;
350
- this.crService = crService;
351
- this.elementsWereAttached = false;
352
- this.badgeDisposable = this._register(( new MutableDisposable()));
353
- this.renderLoop = this._register(( new RunOnceScheduler(() => this.render(), SUMMARY_RENDER_INTERVAL)));
354
- this.elements = h('div.result-summary', [
355
- h('div@status'),
356
- h('div@count'),
357
- h('div@count'),
358
- h('span'),
359
- h('duration@duration'),
360
- h('a@rerun'),
361
- ]);
362
- this.badgeType = configurationService.getValue("testing.countBadge" );
363
- this._register(resultService.onResultsChanged(this.render, this));
364
- this._register(configurationService.onDidChangeConfiguration(e => {
365
- if (e.affectsConfiguration("testing.countBadge" )) {
366
- this.badgeType = configurationService.getValue("testing.countBadge" );
367
- this.render();
368
- }
369
- }));
370
- const ab = this._register(( new ActionBar(this.elements.rerun, {
371
- actionViewItemProvider: (action, options) => createActionViewItem(instantiationService, action, options),
372
- })));
373
- ab.push(instantiationService.createInstance(MenuItemAction, { ...( new ReRunLastRun()).desc, icon: testingRerunIcon }, { ...( new DebugLastRun()).desc, icon: testingDebugIcon }, {}, undefined), { icon: true, label: false });
374
- this.render();
375
- }
376
- render() {
377
- const { results } = this.resultService;
378
- const { count, root, status, duration, rerun } = this.elements;
379
- if (!results.length) {
380
- if (this.elementsWereAttached) {
381
- this.container.removeChild(root);
382
- this.elementsWereAttached = false;
383
- }
384
- this.container.innerText = ( localizeWithPath(
385
- 'vs/workbench/contrib/testing/browser/testingExplorerView',
386
- 'noResults',
387
- 'No test results yet.'
388
- ));
389
- this.badgeDisposable.clear();
390
- return;
391
- }
392
- const live = results.filter(r => !r.completedAt);
393
- let counts;
394
- if (live.length) {
395
- status.className = ThemeIcon.asClassName(spinningLoading);
396
- counts = collectTestStateCounts(true, live);
397
- this.renderLoop.schedule();
398
- const last = live[live.length - 1];
399
- duration.textContent = formatDuration(Date.now() - last.startedAt);
400
- rerun.style.display = 'none';
401
- }
402
- else {
403
- const last = results[0];
404
- const dominantState = mapFindFirst(statesInOrder, s => last.counts[s] > 0 ? s : undefined);
405
- status.className = ThemeIcon.asClassName(testingStatesToIcons.get(dominantState ?? 0 ));
406
- counts = collectTestStateCounts(false, [last]);
407
- duration.textContent = last instanceof LiveTestResult ? formatDuration(last.completedAt - last.startedAt) : '';
408
- rerun.style.display = 'block';
409
- }
410
- count.textContent = `${counts.passed}/${counts.totalWillBeRun}`;
411
- count.title = getTestProgressText(counts);
412
- this.renderActivityBadge(counts);
413
- if (!this.elementsWereAttached) {
414
- clearNode(this.container);
415
- this.container.appendChild(root);
416
- this.elementsWereAttached = true;
417
- }
418
- }
419
- renderActivityBadge(countSummary) {
420
- if (countSummary && this.badgeType !== "off" && countSummary[this.badgeType] !== 0) {
421
- if (this.lastBadge instanceof NumberBadge && this.lastBadge.number === countSummary[this.badgeType]) {
422
- return;
423
- }
424
- this.lastBadge = ( new NumberBadge(
425
- countSummary[this.badgeType],
426
- num => this.getLocalizedBadgeString(this.badgeType, num)
427
- ));
428
- }
429
- else if (this.crService.isEnabled()) {
430
- if (this.lastBadge instanceof IconBadge && this.lastBadge.icon === testingContinuousIsOn) {
431
- return;
432
- }
433
- this.lastBadge = ( new IconBadge(testingContinuousIsOn, () => ( localizeWithPath(
434
- 'vs/workbench/contrib/testing/browser/testingExplorerView',
435
- 'testingContinuousBadge',
436
- 'Tests are being watched for changes'
437
- ))));
438
- }
439
- else {
440
- if (!this.lastBadge) {
441
- return;
442
- }
443
- this.lastBadge = undefined;
444
- }
445
- this.badgeDisposable.value = this.lastBadge && this.activityService.showViewActivity("workbench.view.testing" , { badge: this.lastBadge });
446
- }
447
- getLocalizedBadgeString(countBadgeType, count) {
448
- switch (countBadgeType) {
449
- case "passed" :
450
- return ( localizeWithPath(
451
- 'vs/workbench/contrib/testing/browser/testingExplorerView',
452
- 'testingCountBadgePassed',
453
- '{0} passed tests',
454
- count
455
- ));
456
- case "skipped" :
457
- return ( localizeWithPath(
458
- 'vs/workbench/contrib/testing/browser/testingExplorerView',
459
- 'testingCountBadgeSkipped',
460
- '{0} skipped tests',
461
- count
462
- ));
463
- default:
464
- return ( localizeWithPath(
465
- 'vs/workbench/contrib/testing/browser/testingExplorerView',
466
- 'testingCountBadgeFailed',
467
- '{0} failed tests',
468
- count
469
- ));
470
- }
471
- }
472
- };
473
- ResultSummaryView = ( __decorate([
474
- ( __param(1, ITestResultService)),
475
- ( __param(2, IActivityService)),
476
- ( __param(3, ITestingContinuousRunService)),
477
- ( __param(4, IConfigurationService)),
478
- ( __param(5, IInstantiationService))
479
- ], ResultSummaryView));
480
- let TestingExplorerViewModel = class TestingExplorerViewModel extends Disposable {
481
- get viewMode() {
482
- return this._viewMode.get() ?? "true" ;
483
- }
484
- set viewMode(newMode) {
485
- if (newMode === this._viewMode.get()) {
486
- return;
487
- }
488
- this._viewMode.set(newMode);
489
- this.updatePreferredProjection();
490
- this.storageService.store('testing.viewMode', newMode, 1 , 1 );
491
- }
492
- get viewSorting() {
493
- return this._viewSorting.get() ?? "status" ;
494
- }
495
- set viewSorting(newSorting) {
496
- if (newSorting === this._viewSorting.get()) {
497
- return;
498
- }
499
- this._viewSorting.set(newSorting);
500
- this.tree.resort(null);
501
- this.storageService.store('testing.viewSorting', newSorting, 1 , 1 );
502
- }
503
- constructor(listContainer, onDidChangeVisibility, configurationService, editorService, menuService, contextMenuService, testService, filterState, instantiationService, storageService, contextKeyService, testResults, peekOpener, testProfileService, crService, commandService) {
504
- super();
505
- this.menuService = menuService;
506
- this.contextMenuService = contextMenuService;
507
- this.testService = testService;
508
- this.filterState = filterState;
509
- this.instantiationService = instantiationService;
510
- this.storageService = storageService;
511
- this.contextKeyService = contextKeyService;
512
- this.testResults = testResults;
513
- this.peekOpener = peekOpener;
514
- this.testProfileService = testProfileService;
515
- this.crService = crService;
516
- this.projection = this._register(( new MutableDisposable()));
517
- this.revealTimeout = ( new MutableDisposable());
518
- this._viewMode = TestingContextKeys.viewMode.bindTo(this.contextKeyService);
519
- this._viewSorting = TestingContextKeys.viewSorting.bindTo(this.contextKeyService);
520
- this.welcomeVisibilityEmitter = ( new Emitter());
521
- this.actionRunner = ( new TestExplorerActionRunner(() => this.tree.getSelection().filter(isDefined)));
522
- this.lastViewState = this._register(( new StoredValue({
523
- key: 'testing.treeState',
524
- scope: 1 ,
525
- target: 1 ,
526
- }, this.storageService)));
527
- this.hasPendingReveal = false;
528
- this.onChangeWelcomeVisibility = this.welcomeVisibilityEmitter.event;
529
- this.welcomeExperience = 0 ;
530
- this.hasPendingReveal = !!filterState.reveal.value;
531
- this.noTestForDocumentWidget = this._register(instantiationService.createInstance(NoTestsForDocumentWidget, listContainer));
532
- this._viewMode.set(this.storageService.get('testing.viewMode', 1 , "true" ));
533
- this._viewSorting.set(this.storageService.get('testing.viewSorting', 1 , "location" ));
534
- this.reevaluateWelcomeState();
535
- this.filter = this.instantiationService.createInstance(TestsFilter, testService.collection);
536
- this.tree = instantiationService.createInstance(TestingObjectTree, 'Test Explorer List', listContainer, ( new ListDelegate()), [
537
- instantiationService.createInstance(TestItemRenderer, this.actionRunner),
538
- instantiationService.createInstance(ErrorRenderer),
539
- ], {
540
- identityProvider: instantiationService.createInstance(IdentityProvider),
541
- hideTwistiesOfChildlessElements: false,
542
- sorter: instantiationService.createInstance(TreeSorter, this),
543
- keyboardNavigationLabelProvider: instantiationService.createInstance(TreeKeyboardNavigationLabelProvider),
544
- accessibilityProvider: instantiationService.createInstance(ListAccessibilityProvider),
545
- filter: this.filter,
546
- findWidgetEnabled: false,
547
- openOnSingleClick: false,
548
- });
549
- const collapseStateSaver = this._register(( new RunOnceScheduler(() => {
550
- const state = this.tree.getOptimizedViewState(this.lastViewState.get({}));
551
- const projection = this.projection.value;
552
- if (projection) {
553
- projection.lastState = state;
554
- }
555
- }, 3000)));
556
- this._register(this.tree.onDidChangeCollapseState(evt => {
557
- if (evt.node.element instanceof TestItemTreeElement) {
558
- if (!evt.node.collapsed) {
559
- this.projection.value?.expandElement(evt.node.element, evt.deep ? Infinity : 0);
560
- }
561
- collapseStateSaver.schedule();
562
- }
563
- }));
564
- this._register(this.crService.onDidChange(testId => {
565
- if (testId) {
566
- const elem = this.projection.value?.getElementByTestId(testId);
567
- this.tree.resort(elem?.parent && this.tree.hasElement(elem.parent) ? elem.parent : null, false);
568
- }
569
- }));
570
- this._register(onDidChangeVisibility(visible => {
571
- if (visible) {
572
- this.ensureProjection();
573
- }
574
- }));
575
- this._register(this.tree.onContextMenu(e => this.onContextMenu(e)));
576
- this._register(Event.any(filterState.text.onDidChange, filterState.fuzzy.onDidChange, testService.excluded.onTestExclusionsChanged)(this.tree.refilter, this.tree));
577
- this._register(this.tree.onDidOpen(e => {
578
- if (e.element instanceof TestItemTreeElement && !e.element.children.size && e.element.test.item.uri) {
579
- commandService.executeCommand('vscode.revealTest', e.element.test.item.extId);
580
- }
581
- }));
582
- this._register(this.tree);
583
- this._register(this.onChangeWelcomeVisibility(e => {
584
- this.noTestForDocumentWidget.setVisible(e === 2 );
585
- }));
586
- this._register(addStandardDisposableListener(this.tree.getHTMLElement(), 'keydown', evt => {
587
- if (evt.equals(3 )) {
588
- this.handleExecuteKeypress(evt);
589
- }
590
- else if (DefaultKeyboardNavigationDelegate.mightProducePrintableCharacter(evt)) {
591
- filterState.text.value = evt.browserEvent.key;
592
- filterState.focusInput();
593
- }
594
- }));
595
- this._register(filterState.reveal.onDidChange(id => this.revealById(id, undefined, false)));
596
- this._register(onDidChangeVisibility(visible => {
597
- if (visible) {
598
- filterState.focusInput();
599
- }
600
- }));
601
- this._register(this.tree.onDidChangeSelection(evt => {
602
- if (isMouseEvent(evt.browserEvent) && (evt.browserEvent.altKey || evt.browserEvent.shiftKey)) {
603
- return;
604
- }
605
- const selected = evt.elements[0];
606
- if (selected && evt.browserEvent && selected instanceof TestItemTreeElement
607
- && selected.children.size === 0 && selected.test.expand === 0 ) {
608
- this.tryPeekError(selected);
609
- }
610
- }));
611
- let followRunningTests = getTestingConfiguration(configurationService, "testing.followRunningTest" );
612
- this._register(configurationService.onDidChangeConfiguration(e => {
613
- if (e.affectsConfiguration("testing.followRunningTest" )) {
614
- followRunningTests = getTestingConfiguration(configurationService, "testing.followRunningTest" );
615
- }
616
- }));
617
- let alwaysRevealTestAfterStateChange = getTestingConfiguration(configurationService, "testing.alwaysRevealTestOnStateChange" );
618
- this._register(configurationService.onDidChangeConfiguration(e => {
619
- if (e.affectsConfiguration("testing.alwaysRevealTestOnStateChange" )) {
620
- alwaysRevealTestAfterStateChange = getTestingConfiguration(configurationService, "testing.alwaysRevealTestOnStateChange" );
621
- }
622
- }));
623
- this._register(testResults.onTestChanged(evt => {
624
- if (!followRunningTests) {
625
- return;
626
- }
627
- if (evt.reason !== 1 ) {
628
- return;
629
- }
630
- if (this.tree.selectionSize > 1) {
631
- return;
632
- }
633
- if (evt.item.ownComputedState !== 2 && !(evt.previousState === 1 && isStateWithResult(evt.item.ownComputedState))) {
634
- return;
635
- }
636
- this.revealById(evt.item.item.extId, alwaysRevealTestAfterStateChange, false);
637
- }));
638
- this._register(testResults.onResultsChanged(() => {
639
- this.tree.resort(null);
640
- }));
641
- this._register(this.testProfileService.onDidChange(() => {
642
- this.tree.rerender();
643
- }));
644
- const onEditorChange = () => {
645
- if (editorService.activeEditor instanceof DiffEditorInput) {
646
- this.filter.filterToDocumentUri(editorService.activeEditor.primary.resource);
647
- }
648
- else {
649
- this.filter.filterToDocumentUri(editorService.activeEditor?.resource);
650
- }
651
- if (this.filterState.isFilteringFor("@doc" )) {
652
- this.tree.refilter();
653
- }
654
- };
655
- this._register(editorService.onDidActiveEditorChange(onEditorChange));
656
- this._register(this.storageService.onWillSaveState(({ reason, }) => {
657
- if (reason === WillSaveStateReason.SHUTDOWN) {
658
- this.lastViewState.store(this.tree.getOptimizedViewState());
659
- }
660
- }));
661
- onEditorChange();
662
- }
663
- layout(height, width) {
664
- this.tree.layout(height, width);
665
- }
666
- revealById(id, expand = true, focus = true) {
667
- if (!id) {
668
- this.hasPendingReveal = false;
669
- return;
670
- }
671
- const projection = this.ensureProjection();
672
- let expandToLevel = 0;
673
- const idPath = [...TestId.fromString(id).idsFromRoot()];
674
- for (let i = idPath.length - 1; i >= expandToLevel; i--) {
675
- const element = projection.getElementByTestId(( idPath[i].toString()));
676
- if (!element || !this.tree.hasElement(element)) {
677
- continue;
678
- }
679
- if (i < idPath.length - 1) {
680
- if (expand) {
681
- this.tree.expand(element);
682
- expandToLevel = i + 1;
683
- i = idPath.length - 1;
684
- continue;
685
- }
686
- }
687
- let focusTarget = element;
688
- for (let n = element; n instanceof TestItemTreeElement; n = n.parent) {
689
- if (n.test && this.testService.excluded.contains(n.test)) {
690
- this.filterState.toggleFilteringFor("@hidden" , true);
691
- break;
692
- }
693
- if (!expand && (this.tree.hasElement(n) && this.tree.isCollapsed(n))) {
694
- focusTarget = n;
695
- }
696
- }
697
- this.filterState.reveal.value = undefined;
698
- this.hasPendingReveal = false;
699
- if (focus) {
700
- this.tree.domFocus();
701
- }
702
- if (this.tree.getRelativeTop(focusTarget) === null) {
703
- this.tree.reveal(focusTarget, 0.5);
704
- }
705
- this.revealTimeout.value = disposableTimeout(() => {
706
- this.tree.setFocus([focusTarget]);
707
- this.tree.setSelection([focusTarget]);
708
- }, 1);
709
- return;
710
- }
711
- this.hasPendingReveal = true;
712
- }
713
- async collapseAll() {
714
- this.tree.collapseAll();
715
- }
716
- tryPeekError(item) {
717
- const lookup = item.test && this.testResults.getStateById(item.test.item.extId);
718
- return lookup && ( lookup[1].tasks.some(s => isFailedState(s.state)))
719
- ? this.peekOpener.tryPeekFirstError(lookup[0], lookup[1], { preserveFocus: true })
720
- : false;
721
- }
722
- onContextMenu(evt) {
723
- const element = evt.element;
724
- if (!(element instanceof TestItemTreeElement)) {
725
- return;
726
- }
727
- const { actions } = getActionableElementActions(this.contextKeyService, this.menuService, this.testService, this.crService, this.testProfileService, element);
728
- this.contextMenuService.showContextMenu({
729
- getAnchor: () => evt.anchor,
730
- getActions: () => actions.secondary,
731
- getActionsContext: () => element,
732
- actionRunner: this.actionRunner,
733
- });
734
- }
735
- handleExecuteKeypress(evt) {
736
- const focused = this.tree.getFocus();
737
- const selected = this.tree.getSelection();
738
- let targeted;
739
- if (focused.length === 1 && selected.includes(focused[0])) {
740
- evt.browserEvent?.preventDefault();
741
- targeted = selected;
742
- }
743
- else {
744
- targeted = focused;
745
- }
746
- const toRun = targeted
747
- .filter((e) => e instanceof TestItemTreeElement);
748
- if (toRun.length) {
749
- this.testService.runTests({
750
- group: 2 ,
751
- tests: ( toRun.map(t => t.test)),
752
- });
753
- }
754
- }
755
- reevaluateWelcomeState() {
756
- const shouldShowWelcome = this.testService.collection.busyProviders === 0 && testCollectionIsEmpty(this.testService.collection);
757
- const welcomeExperience = shouldShowWelcome
758
- ? ((this.filterState.isFilteringFor("@doc" ) ? 2 : 1) )
759
- : 0 ;
760
- if (welcomeExperience !== this.welcomeExperience) {
761
- this.welcomeExperience = welcomeExperience;
762
- this.welcomeVisibilityEmitter.fire(welcomeExperience);
763
- }
764
- }
765
- ensureProjection() {
766
- return this.projection.value ?? this.updatePreferredProjection();
767
- }
768
- updatePreferredProjection() {
769
- this.projection.clear();
770
- const lastState = this.lastViewState.get({});
771
- if (this._viewMode.get() === "list" ) {
772
- this.projection.value = this.instantiationService.createInstance(ListProjection, lastState);
773
- }
774
- else {
775
- this.projection.value = this.instantiationService.createInstance(TreeProjection, lastState);
776
- }
777
- const scheduler = this._register(( new RunOnceScheduler(() => this.applyProjectionChanges(), 200)));
778
- this.projection.value.onUpdate(() => {
779
- if (!scheduler.isScheduled()) {
780
- scheduler.schedule();
781
- }
782
- });
783
- this.applyProjectionChanges();
784
- return this.projection.value;
785
- }
786
- applyProjectionChanges() {
787
- this.reevaluateWelcomeState();
788
- this.projection.value?.applyTo(this.tree);
789
- this.tree.refilter();
790
- if (this.hasPendingReveal) {
791
- this.revealById(this.filterState.reveal.value);
792
- }
793
- }
794
- getSelectedTests() {
795
- return this.tree.getSelection();
796
- }
797
- };
798
- TestingExplorerViewModel = ( __decorate([
799
- ( __param(2, IConfigurationService)),
800
- ( __param(3, IEditorService)),
801
- ( __param(4, IMenuService)),
802
- ( __param(5, IContextMenuService)),
803
- ( __param(6, ITestService)),
804
- ( __param(7, ITestExplorerFilterState)),
805
- ( __param(8, IInstantiationService)),
806
- ( __param(9, IStorageService)),
807
- ( __param(10, IContextKeyService)),
808
- ( __param(11, ITestResultService)),
809
- ( __param(12, ITestingPeekOpener)),
810
- ( __param(13, ITestProfileService)),
811
- ( __param(14, ITestingContinuousRunService)),
812
- ( __param(15, ICommandService))
813
- ], TestingExplorerViewModel));
814
- const hasNodeInOrParentOfUri = (collection, ident, testUri, fromNode) => {
815
- const queue = [fromNode ? [fromNode] : collection.rootIds];
816
- while (queue.length) {
817
- for (const id of queue.pop()) {
818
- const node = collection.getNodeById(id);
819
- if (!node) {
820
- continue;
821
- }
822
- if (!node.item.uri || !ident.extUri.isEqualOrParent(testUri, node.item.uri)) {
823
- continue;
824
- }
825
- if (node.item.range || node.expand === 1 ) {
826
- return true;
827
- }
828
- queue.push(node.children);
829
- }
830
- }
831
- return false;
832
- };
833
- let TestsFilter = class TestsFilter {
834
- constructor(collection, state, testService, uriIdentityService) {
835
- this.collection = collection;
836
- this.state = state;
837
- this.testService = testService;
838
- this.uriIdentityService = uriIdentityService;
839
- }
840
- filter(element) {
841
- if (element instanceof TestTreeErrorMessage) {
842
- return 1 ;
843
- }
844
- if (element.test
845
- && !this.state.isFilteringFor("@hidden" )
846
- && this.testService.excluded.contains(element.test)) {
847
- return 0 ;
848
- }
849
- switch (Math.min(this.testFilterText(element), this.testLocation(element), this.testState(element), this.testTags(element))) {
850
- case 0 :
851
- return 0 ;
852
- case 2 :
853
- return 1 ;
854
- default:
855
- return 2 ;
856
- }
857
- }
858
- filterToDocumentUri(uri) {
859
- this.documentUri = uri;
860
- }
861
- testTags(element) {
862
- if (!this.state.includeTags.size && !this.state.excludeTags.size) {
863
- return 2 ;
864
- }
865
- return (this.state.includeTags.size ?
866
- ( element.test.item.tags.some(t => ( this.state.includeTags.has(t)))) :
867
- true) && element.test.item.tags.every(t => !( this.state.excludeTags.has(t)))
868
- ? 2
869
- : 1 ;
870
- }
871
- testState(element) {
872
- if (this.state.isFilteringFor("@failed" )) {
873
- return isFailedState(element.state) ? 2 : 1 ;
874
- }
875
- if (this.state.isFilteringFor("@executed" )) {
876
- return element.state !== 0 ? 2 : 1 ;
877
- }
878
- return 2 ;
879
- }
880
- testLocation(element) {
881
- if (!this.documentUri) {
882
- return 2 ;
883
- }
884
- if (!this.state.isFilteringFor("@doc" ) || !(element instanceof TestItemTreeElement)) {
885
- return 2 ;
886
- }
887
- if (hasNodeInOrParentOfUri(this.collection, this.uriIdentityService, this.documentUri, element.test.item.extId)) {
888
- return 2 ;
889
- }
890
- return 1 ;
891
- }
892
- testFilterText(element) {
893
- if (this.state.globList.length === 0) {
894
- return 2 ;
895
- }
896
- const fuzzy = this.state.fuzzy.value;
897
- for (let e = element; e; e = e.parent) {
898
- let included = this.state.globList[0].include === false ? 2 : 1 ;
899
- const data = e.test.item.label.toLowerCase();
900
- for (const { include, text } of this.state.globList) {
901
- if (fuzzy ? fuzzyContains(data, text) : data.includes(text)) {
902
- included = include ? 2 : 0 ;
903
- }
904
- }
905
- if (included !== 1 ) {
906
- return included;
907
- }
908
- }
909
- return 1 ;
910
- }
911
- };
912
- TestsFilter = ( __decorate([
913
- ( __param(1, ITestExplorerFilterState)),
914
- ( __param(2, ITestService)),
915
- ( __param(3, IUriIdentityService))
916
- ], TestsFilter));
917
- class TreeSorter {
918
- constructor(viewModel) {
919
- this.viewModel = viewModel;
920
- }
921
- compare(a, b) {
922
- if (a instanceof TestTreeErrorMessage || b instanceof TestTreeErrorMessage) {
923
- return (a instanceof TestTreeErrorMessage ? -1 : 0) + (b instanceof TestTreeErrorMessage ? 1 : 0);
924
- }
925
- const durationDelta = (b.duration || 0) - (a.duration || 0);
926
- if (this.viewModel.viewSorting === "duration" && durationDelta !== 0) {
927
- return durationDelta;
928
- }
929
- const stateDelta = cmpPriority(a.state, b.state);
930
- if (this.viewModel.viewSorting === "status" && stateDelta !== 0) {
931
- return stateDelta;
932
- }
933
- let inSameLocation = false;
934
- if (a instanceof TestItemTreeElement && b instanceof TestItemTreeElement && a.test.item.uri && b.test.item.uri && ( a.test.item.uri.toString()) === ( b.test.item.uri.toString()) && a.test.item.range && b.test.item.range) {
935
- inSameLocation = true;
936
- const delta = a.test.item.range.startLineNumber - b.test.item.range.startLineNumber;
937
- if (delta !== 0) {
938
- return delta;
939
- }
940
- }
941
- const sa = a.test.item.sortText;
942
- const sb = b.test.item.sortText;
943
- return inSameLocation && !sa && !sb ? 0 : (sa || a.test.item.label).localeCompare(sb || b.test.item.label);
944
- }
945
- }
946
- let NoTestsForDocumentWidget = class NoTestsForDocumentWidget extends Disposable {
947
- constructor(container, filterState) {
948
- super();
949
- const el = this.el = append(container, $('.testing-no-test-placeholder'));
950
- const emptyParagraph = append(el, $('p'));
951
- emptyParagraph.innerText = ( localizeWithPath(
952
- 'vs/workbench/contrib/testing/browser/testingExplorerView',
953
- 'testingNoTest',
954
- 'No tests were found in this file.'
955
- ));
956
- const buttonLabel = ( localizeWithPath(
957
- 'vs/workbench/contrib/testing/browser/testingExplorerView',
958
- 'testingFindExtension',
959
- 'Show Workspace Tests'
960
- ));
961
- const button = this._register(( new Button(el, { title: buttonLabel, ...defaultButtonStyles })));
962
- button.label = buttonLabel;
963
- this._register(button.onDidClick(() => filterState.toggleFilteringFor("@doc" , false)));
964
- }
965
- setVisible(isVisible) {
966
- this.el.classList.toggle('visible', isVisible);
967
- }
968
- };
969
- NoTestsForDocumentWidget = ( __decorate([
970
- ( __param(1, ITestExplorerFilterState))
971
- ], NoTestsForDocumentWidget));
972
- class TestExplorerActionRunner extends ActionRunner {
973
- constructor(getSelectedTests) {
974
- super();
975
- this.getSelectedTests = getSelectedTests;
976
- }
977
- async runAction(action, context) {
978
- if (!(action instanceof MenuItemAction)) {
979
- return super.runAction(action, context);
980
- }
981
- const selection = this.getSelectedTests();
982
- const contextIsSelected = ( selection.some(s => s === context));
983
- const actualContext = contextIsSelected ? selection : [context];
984
- const actionable = actualContext.filter((t) => t instanceof TestItemTreeElement);
985
- await action.run(...actionable);
986
- }
987
- }
988
- const getLabelForTestTreeElement = (element) => {
989
- let label = labelForTestInState(element.description || element.test.item.label, element.state);
990
- if (element instanceof TestItemTreeElement) {
991
- if (element.duration !== undefined) {
992
- label = ( localizeWithPath('vs/workbench/contrib/testing/browser/testingExplorerView', {
993
- key: 'testing.treeElementLabelDuration',
994
- comment: ['{0} is the original label in testing.treeElementLabel, {1} is a duration'],
995
- }, '{0}, in {1}', label, formatDuration(element.duration)));
996
- }
997
- if (element.retired) {
998
- label = ( localizeWithPath('vs/workbench/contrib/testing/browser/testingExplorerView', {
999
- key: 'testing.treeElementLabelOutdated',
1000
- comment: ['{0} is the original label in testing.treeElementLabel'],
1001
- }, '{0}, outdated result', label));
1002
- }
1003
- }
1004
- return label;
1005
- };
1006
- class ListAccessibilityProvider {
1007
- getWidgetAriaLabel() {
1008
- return ( localizeWithPath(
1009
- 'vs/workbench/contrib/testing/browser/testingExplorerView',
1010
- 'testExplorer',
1011
- "Test Explorer"
1012
- ));
1013
- }
1014
- getAriaLabel(element) {
1015
- return element instanceof TestTreeErrorMessage
1016
- ? element.description
1017
- : getLabelForTestTreeElement(element);
1018
- }
1019
- }
1020
- class TreeKeyboardNavigationLabelProvider {
1021
- getKeyboardNavigationLabel(element) {
1022
- return element instanceof TestTreeErrorMessage ? element.message : element.test.item.label;
1023
- }
1024
- }
1025
- class ListDelegate {
1026
- getHeight(element) {
1027
- return element instanceof TestTreeErrorMessage ? 17 + 10 : 22;
1028
- }
1029
- getTemplateId(element) {
1030
- if (element instanceof TestTreeErrorMessage) {
1031
- return ErrorRenderer.ID;
1032
- }
1033
- return TestItemRenderer.ID;
1034
- }
1035
- }
1036
- class IdentityProvider {
1037
- getId(element) {
1038
- return element.treeId;
1039
- }
1040
- }
1041
- let ErrorRenderer = class ErrorRenderer {
1042
- static { ErrorRenderer_1 = this; }
1043
- static { this.ID = 'error'; }
1044
- constructor(instantionService) {
1045
- this.renderer = instantionService.createInstance(MarkdownRenderer, {});
1046
- }
1047
- get templateId() {
1048
- return ErrorRenderer_1.ID;
1049
- }
1050
- renderTemplate(container) {
1051
- const label = append(container, $('.error'));
1052
- return { label };
1053
- }
1054
- renderElement({ element }, _, data) {
1055
- clearNode(data.label);
1056
- if (typeof element.message === 'string') {
1057
- data.label.innerText = element.message;
1058
- }
1059
- else {
1060
- const result = this.renderer.render(element.message, { inline: true });
1061
- data.label.appendChild(result.element);
1062
- }
1063
- data.label.title = element.description;
1064
- }
1065
- disposeTemplate() {
1066
- }
1067
- };
1068
- ErrorRenderer = ErrorRenderer_1 = ( __decorate([
1069
- ( __param(0, IInstantiationService))
1070
- ], ErrorRenderer));
1071
- let TestItemRenderer = class TestItemRenderer extends Disposable {
1072
- static { TestItemRenderer_1 = this; }
1073
- static { this.ID = 'testItem'; }
1074
- constructor(actionRunner, menuService, testService, profiles, contextKeyService, instantiationService, crService) {
1075
- super();
1076
- this.actionRunner = actionRunner;
1077
- this.menuService = menuService;
1078
- this.testService = testService;
1079
- this.profiles = profiles;
1080
- this.contextKeyService = contextKeyService;
1081
- this.instantiationService = instantiationService;
1082
- this.crService = crService;
1083
- this.templateId = TestItemRenderer_1.ID;
1084
- }
1085
- renderTemplate(container) {
1086
- const wrapper = append(container, $('.test-item'));
1087
- const icon = append(wrapper, $('.computed-state'));
1088
- const label = append(wrapper, $('.label'));
1089
- const disposable = ( new DisposableStore());
1090
- append(wrapper, $(ThemeIcon.asCSSSelector(testingHiddenIcon)));
1091
- const actionBar = disposable.add(( new ActionBar(wrapper, {
1092
- actionRunner: this.actionRunner,
1093
- actionViewItemProvider: action => action instanceof MenuItemAction
1094
- ? this.instantiationService.createInstance(MenuEntryActionViewItem, action, undefined)
1095
- : undefined
1096
- })));
1097
- disposable.add(this.crService.onDidChange(changed => {
1098
- const id = templateData.current?.test.item.extId;
1099
- if (id && (!changed || changed === id || TestId.isChild(id, changed))) {
1100
- this.fillActionBar(templateData.current, templateData);
1101
- }
1102
- }));
1103
- const templateData = { wrapper, label, actionBar, icon, elementDisposable: ( new DisposableStore()), templateDisposable: disposable };
1104
- return templateData;
1105
- }
1106
- disposeTemplate(templateData) {
1107
- templateData.templateDisposable.clear();
1108
- }
1109
- disposeElement(_element, _, templateData) {
1110
- templateData.elementDisposable.clear();
1111
- }
1112
- fillActionBar(element, data) {
1113
- const { actions, contextOverlay } = getActionableElementActions(this.contextKeyService, this.menuService, this.testService, this.crService, this.profiles, element);
1114
- const crSelf = !!contextOverlay.getContextKeyValue(TestingContextKeys.isContinuousModeOn.key);
1115
- const crChild = !crSelf && this.crService.isEnabledForAChildOf(element.test.item.extId);
1116
- data.actionBar.domNode.classList.toggle('testing-is-continuous-run', crSelf || crChild);
1117
- data.actionBar.clear();
1118
- data.actionBar.context = element;
1119
- data.actionBar.push(actions.primary, { icon: true, label: false });
1120
- }
1121
- renderElement(node, _depth, data) {
1122
- data.elementDisposable.clear();
1123
- data.current = node.element;
1124
- this.fillActionBar(node.element, data);
1125
- data.elementDisposable.add(node.element.onChange(() => this._renderElement(node, data)));
1126
- this._renderElement(node, data);
1127
- }
1128
- _renderElement(node, data) {
1129
- const testHidden = this.testService.excluded.contains(node.element.test);
1130
- data.wrapper.classList.toggle('test-is-hidden', testHidden);
1131
- const icon = testingStatesToIcons.get(node.element.test.expand === 2 || node.element.test.item.busy
1132
- ? 2
1133
- : node.element.state);
1134
- data.icon.className = 'computed-state ' + (icon ? ThemeIcon.asClassName(icon) : '');
1135
- if (node.element.retired) {
1136
- data.icon.className += ' retired';
1137
- }
1138
- data.label.title = getLabelForTestTreeElement(node.element);
1139
- if (node.element.test.item.label.trim()) {
1140
- reset(data.label, ...renderLabelWithIcons(node.element.test.item.label));
1141
- }
1142
- else {
1143
- data.label.textContent = String.fromCharCode(0xA0);
1144
- }
1145
- let description = node.element.description;
1146
- if (node.element.duration !== undefined) {
1147
- description = description
1148
- ? `${description}: ${formatDuration(node.element.duration)}`
1149
- : formatDuration(node.element.duration);
1150
- }
1151
- if (description) {
1152
- append(data.label, $('span.test-label-description', {}, description));
1153
- }
1154
- }
1155
- };
1156
- TestItemRenderer = TestItemRenderer_1 = ( __decorate([
1157
- ( __param(1, IMenuService)),
1158
- ( __param(2, ITestService)),
1159
- ( __param(3, ITestProfileService)),
1160
- ( __param(4, IContextKeyService)),
1161
- ( __param(5, IInstantiationService)),
1162
- ( __param(6, ITestingContinuousRunService))
1163
- ], TestItemRenderer));
1164
- const formatDuration = (ms) => {
1165
- if (ms < 10) {
1166
- return `${ms.toFixed(1)}ms`;
1167
- }
1168
- if (ms < 1000) {
1169
- return `${ms.toFixed(0)}ms`;
1170
- }
1171
- return `${(ms / 1000).toFixed(1)}s`;
1172
- };
1173
- const getActionableElementActions = (contextKeyService, menuService, testService, crService, profiles, element) => {
1174
- const test = element instanceof TestItemTreeElement ? element.test : undefined;
1175
- const contextKeys = getTestItemContextOverlay(test, test ? profiles.capabilitiesForTest(test) : 0);
1176
- contextKeys.push(['view', "workbench.view.testing" ]);
1177
- if (test) {
1178
- const ctrl = testService.getTestController(test.controllerId);
1179
- const supportsCr = !!ctrl && ( profiles.getControllerProfiles(ctrl.id).some(p => p.supportsContinuousRun));
1180
- contextKeys.push([
1181
- TestingContextKeys.canRefreshTests.key,
1182
- !!ctrl?.canRefresh.value && TestId.isRoot(test.item.extId),
1183
- ], [
1184
- TestingContextKeys.testItemIsHidden.key,
1185
- testService.excluded.contains(test)
1186
- ], [
1187
- TestingContextKeys.isContinuousModeOn.key,
1188
- supportsCr && crService.isSpecificallyEnabledFor(test.item.extId)
1189
- ], [
1190
- TestingContextKeys.isParentRunningContinuously.key,
1191
- supportsCr && crService.isEnabledForAParentOf(test.item.extId)
1192
- ], [
1193
- TestingContextKeys.supportsContinuousRun.key,
1194
- supportsCr,
1195
- ]);
1196
- }
1197
- const contextOverlay = contextKeyService.createOverlay(contextKeys);
1198
- const menu = menuService.createMenu(MenuId.TestItem, contextOverlay);
1199
- try {
1200
- const primary = [];
1201
- const secondary = [];
1202
- const result = { primary, secondary };
1203
- createAndFillInActionBarActions(menu, {
1204
- shouldForwardArgs: true,
1205
- }, result, 'inline');
1206
- return { actions: result, contextOverlay };
1207
- }
1208
- finally {
1209
- menu.dispose();
1210
- }
1211
- };
1212
- registerThemingParticipant((theme, collector) => {
1213
- if (theme.type === 'dark') {
1214
- const foregroundColor = theme.getColor(foreground);
1215
- if (foregroundColor) {
1216
- const fgWithOpacity = ( new Color(( new RGBA(
1217
- foregroundColor.rgba.r,
1218
- foregroundColor.rgba.g,
1219
- foregroundColor.rgba.b,
1220
- 0.65
1221
- ))));
1222
- collector.addRule(`.test-explorer .test-explorer-messages { color: ${fgWithOpacity}; }`);
1223
- }
1224
- }
1225
- });
1226
-
1227
- export { TestingExplorerView };