Skip to content

Commit

Permalink
chore: show disabled projects in the tree (#595)
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelfeldman authored Jan 15, 2025
1 parent 3b8bbe6 commit a95208d
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 42 deletions.
9 changes: 5 additions & 4 deletions media/common.css
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ input {
letter-spacing: 0px;
}

.combobox {
margin: 0 8px;
.combobox select {
margin: 0 6px;
flex: auto;
}

input:focus, textarea:focus {
Expand All @@ -87,12 +88,13 @@ textarea {

display: flex;
justify-content: space-between;
align-items: baseline;
align-items: center;
}

.section-toolbar > a {
border-radius: 5px;
font-size: 16px;
cursor: pointer;
}

.section-toolbar > a:hover {
Expand Down Expand Up @@ -124,7 +126,6 @@ select {
height: 22px;
padding: 2px 0;
cursor: pointer;
background: var(--vscode-sideBar-background);
}

label {
Expand Down
10 changes: 4 additions & 6 deletions src/settingsView.script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ let selectConfig: Config;

const selectAllButton = document.getElementById('selectAll') as HTMLAnchorElement;
const unselectAllButton = document.getElementById('unselectAll') as HTMLAnchorElement;
const toggleModels = document.getElementById('toggleModels') as HTMLAnchorElement;

function updateProjects(projects: ProjectEntry[]) {
const projectsElement = document.getElementById('projects') as HTMLElement;
Expand Down Expand Up @@ -51,6 +52,7 @@ function setAllProjectsEnabled(enabled: boolean) {
}
selectAllButton.addEventListener('click', () => setAllProjectsEnabled(true));
unselectAllButton.addEventListener('click', () => setAllProjectsEnabled(false));
toggleModels.addEventListener('click', () => (vscode.postMessage({ method: 'execute', params: { command: 'pw.extension.command.toggleModels' } })));

for (const input of Array.from(document.querySelectorAll('input[type=checkbox]'))) {
input.addEventListener('change', event => {
Expand All @@ -65,7 +67,6 @@ for (const select of Array.from(document.querySelectorAll<HTMLSelectElement>('se

window.addEventListener('message', event => {
const actionsElement = document.getElementById('actions')!;
const configToolbarElement = document.getElementById('configToolbar')!;
const rareActionsElement = document.getElementById('rareActions')!;
const modelSelector = document.getElementById('model-selector')!;

Expand All @@ -85,15 +86,12 @@ window.addEventListener('message', event => {
}
} else if (method === 'actions') {
actionsElement.textContent = '';
configToolbarElement.textContent = '';
rareActionsElement.textContent = '';
for (const action of params.actions) {
const actionElement = createAction(action);
if (!actionElement)
continue;
if (action.location === 'configToolbar')
configToolbarElement.appendChild(actionElement);
else if (action.location === 'rareActions')
if (action.location === 'rareActions')
rareActionsElement.appendChild(actionElement);
else
actionsElement.appendChild(actionElement);
Expand All @@ -119,6 +117,6 @@ window.addEventListener('message', event => {
vscode.postMessage({ method: 'selectModel', params: { configFile: select.value } });
updateProjects(configsMap.get(select.value).projects);
});
modelSelector.style.display = showModelSelector ? 'block' : 'none';
modelSelector.style.display = showModelSelector ? 'flex' : 'none';
}
});
37 changes: 15 additions & 22 deletions src/settingsView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,6 @@ export class SettingsView extends DisposableBase implements vscodeTypes.WebviewV
...clearCacheAction(this._vscode, this._models),
location: 'rareActions',
},
{
...toggleModelsAction(this._vscode),
location: 'configToolbar',
},
];
if (this._view)
this._view.webview.postMessage({ method: 'actions', params: { actions } });
Expand Down Expand Up @@ -214,12 +210,17 @@ function htmlForWebview(vscode: vscodeTypes.VSCode, extensionUri: vscodeTypes.Ur
<body class="settings-view">
<div class="section-header">${vscode.l10n.t('TOOLS')}</div>
<div id="actions" class="vbox"></div>
<div class="vbox" id="model-selector">
<div>
<label title="${vscode.l10n.t('Select Playwright Config')}">
<select data-testid="models" id="models"></select>
</label>
<span id="configToolbar"></span>
<div id="model-selector" class="vbox" style="display: none">
<div class="section-header">
${vscode.l10n.t('CONFIGS')}
<div class="section-toolbar">
<a id="toggleModels" role="button" title="${vscode.l10n.t('Toggle Playwright Configs')}">
<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="m388-80-20-126q-19-7-40-19t-37-25l-118 54-93-164 108-79q-2-9-2.5-20.5T185-480q0-9 .5-20.5T188-521L80-600l93-164 118 54q16-13 37-25t40-18l20-127h184l20 126q19 7 40.5 18.5T669-710l118-54 93 164-108 77q2 10 2.5 21.5t.5 21.5q0 10-.5 21t-2.5 21l108 78-93 164-118-54q-16 13-36.5 25.5T592-206L572-80H388Zm48-60h88l14-112q33-8 62.5-25t53.5-41l106 46 40-72-94-69q4-17 6.5-33.5T715-480q0-17-2-33.5t-7-33.5l94-69-40-72-106 46q-23-26-52-43.5T538-708l-14-112h-88l-14 112q-34 7-63.5 24T306-642l-106-46-40 72 94 69q-4 17-6.5 33.5T245-480q0 17 2.5 33.5T254-413l-94 69 40 72 106-46q24 24 53.5 41t62.5 25l14 112Zm44-210q54 0 92-38t38-92q0-54-38-92t-92-38q-54 0-92 38t-38 92q0 54 38 92t92 38Zm0-130Z"/></svg>
</a>
</div>
</div>
<div class="combobox">
<select data-testid="models" id="models" title="${vscode.l10n.t('Select Playwright Config')}" ></select>
</div>
</div>
<div class="section-header">
Expand Down Expand Up @@ -261,9 +262,9 @@ function htmlForWebview(vscode: vscodeTypes.VSCode, extensionUri: vscodeTypes.Ur
<div class="action-indent"></div>
<label id="updateSnapshotLabel">${vscode.l10n.t('Update snapshots')}</label>
</div>
<div>
<div class="combobox">
<div class="action-big-indent"></div>
<select class="combobox" setting="updateSnapshots" aria-labelledby="updateSnapshotLabel">
<select setting="updateSnapshots" aria-labelledby="updateSnapshotLabel">
<option value="all">all</option>
<option value="changed">changed</option>
<option value="missing">missing</option>
Expand All @@ -276,9 +277,9 @@ function htmlForWebview(vscode: vscodeTypes.VSCode, extensionUri: vscodeTypes.Ur
<div class="action-indent"></div>
<label id="updateSourceMethod">${vscode.l10n.t('Update method')}</label>
</div>
<div>
<div class="combobox">
<div class="action-big-indent"></div>
<select class="combobox" setting="updateSourceMethod" aria-labelledby="updateSourceMethod">
<select setting="updateSourceMethod" aria-labelledby="updateSourceMethod">
<option value="overwrite">overwrite</option>
<option value="patch">patch</option>
<option value="3way">3-way</option>
Expand Down Expand Up @@ -360,11 +361,3 @@ export const clearCacheAction = (vscode: vscodeTypes.VSCode, models: TestModelCo
disabled: !models.selectedModel(),
};
};

export const toggleModelsAction = (vscode: vscodeTypes.VSCode) => {
return {
command: 'pw.extension.command.toggleModels',
svg: `<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="m388-80-20-126q-19-7-40-19t-37-25l-118 54-93-164 108-79q-2-9-2.5-20.5T185-480q0-9 .5-20.5T188-521L80-600l93-164 118 54q16-13 37-25t40-18l20-127h184l20 126q19 7 40.5 18.5T669-710l118-54 93 164-108 77q2 10 2.5 21.5t.5 21.5q0 10-.5 21t-2.5 21l108 78-93 164-118-54q-16 13-36.5 25.5T592-206L572-80H388Zm48-60h88l14-112q33-8 62.5-25t53.5-41l106 46 40-72-94-69q4-17 6.5-33.5T715-480q0-17-2-33.5t-7-33.5l94-69-40-72-106 46q-23-26-52-43.5T538-708l-14-112h-88l-14 112q-34 7-63.5 24T306-642l-106-46-40 72 94 69q-4 17-6.5 33.5T245-480q0 17 2.5 33.5T254-413l-94 69 40 72 106-46q24 24 53.5 41t62.5 25l14 112Zm44-210q54 0 92-38t38-92q0-54-38-92t-92-38q-54 0-92 38t-38 92q0 54 38 92t92 38Zm0-130Z"/></svg>`,
title: vscode.l10n.t('Toggle Playwright Configs'),
};
};
50 changes: 42 additions & 8 deletions src/testTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@

import path from 'path';
import { TestModelCollection } from './testModel';
import { createGuid, uriToPath } from './utils';
import { createGuid, normalizePath, uriToPath } from './utils';
import * as vscodeTypes from './vscodeTypes';
import * as reporterTypes from './upstream/reporter';
import * as upstream from './upstream/testTree';
import { TeleSuite } from './upstream/teleReceiver';
import { DisposableBase } from './disposableBase';
import type { TestConfig } from './playwrightTestTypes';

/**
* This class maps a collection of TestModels into the UI terms, it merges
Expand Down Expand Up @@ -57,6 +58,7 @@ export class TestTree extends DisposableBase {
startedLoading() {
this._testGeneration = createGuid() + ':';
this._testController.items.replace([]);
this._rootItems.clear();
this._testItemByTestId.clear();
this._testItemByFile.clear();

Expand Down Expand Up @@ -90,23 +92,32 @@ export class TestTree extends DisposableBase {

private _update() {
for (const workspaceFolder of this._vscode.workspace.workspaceFolders ?? []) {
const disabledProjects = new Map<string, TestConfig>();
const workspaceFSPath = uriToPath(workspaceFolder.uri);
const rootSuite = new TeleSuite('', 'root');
for (const model of this._models.enabledModels().filter(m => m.config.workspaceFolder === workspaceFSPath)) {
for (const project of model.enabledProjects())
rootSuite.suites.push(project.suite as TeleSuite);
for (const project of model.projects()) {
if (project.isEnabled)
rootSuite.suites.push(project.suite as TeleSuite);
else
disabledProjects.set(project.name, model.config);
}
}

const upstreamTree = new upstream.TestTree(workspaceFSPath, rootSuite, [], undefined, path.sep);
upstreamTree.sortAndPropagateStatus();
upstreamTree.flattenForSingleProject();
// Create root item if there are test files.
if (upstreamTree.rootItem.children.length === 0) {

if (upstreamTree.rootItem.children.length === 0 && !disabledProjects.size) {
this._deleteRootItem(workspaceFSPath);
continue;
}

const workspaceRootItem = this._createRootItemIfNeeded(workspaceFolder.uri);
this._syncSuite(upstreamTree.rootItem, workspaceRootItem);
this._syncDisabledProjects(workspaceRootItem, disabledProjects);
}

// Remove stale root items.
for (const itemFsPath of this._rootItems.keys()) {
if (!this._vscode.workspace.workspaceFolders!.find(f => uriToPath(f.uri) === itemFsPath))
Expand Down Expand Up @@ -163,6 +174,26 @@ export class TestTree extends DisposableBase {
}
}

private _syncDisabledProjects(workspaceRootItem: vscodeTypes.TestItem, disabledProjects: Map<string, TestConfig>) {
const topLevelItems: string[] = [];
workspaceRootItem.children.forEach(item => topLevelItems.push(item.id));
const oldDisabledProjectIds = new Set(topLevelItems.filter(item => item.startsWith('[disabled] ')));
for (const [projectName, config] of disabledProjects) {
const projectId = '[disabled] ' + projectName + ' - ' + config.configFile;
if (oldDisabledProjectIds.has(projectId)) {
oldDisabledProjectIds.delete(projectId);
continue;
}

const item = this._testController.createTestItem(projectId, '');
item.description = `${path.relative(config.workspaceFolder, normalizePath(config.configFile))} [${projectName}] — disabled`;
item.sortText = 'z' + projectName;
workspaceRootItem.children.add(item);
}
for (const projectId of oldDisabledProjectIds)
workspaceRootItem.children.delete(projectId);
}

private _indexTree() {
this._testItemByTestId.clear();
this._testItemByFile.clear();
Expand Down Expand Up @@ -206,10 +237,13 @@ export class TestTree extends DisposableBase {
}

private _deleteRootItem(fsPath: string): void {
if (this._vscode.workspace.workspaceFolders!.length === 1)
this._testController.items.replace([]);
else
if (this._vscode.workspace.workspaceFolders!.length === 1) {
const items: vscodeTypes.TestItem[] = [];
this._testController.items.forEach(item => items.push(item));
this._testController.items.replace(items.filter(i => i.id === 'loading' || i.id === 'disabled'));
} else {
this._testController.items.delete(this._idWithGeneration(fsPath));
}
this._rootItems.delete(fsPath);
}

Expand Down
3 changes: 3 additions & 0 deletions tests/list-files.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ test('should support multiple projects', async ({ activate }) => {
- tests
- test1.spec.ts
- test2.spec.ts
- [playwright.config.js [project 2] — disabled]
`);

await expect(vscode).toHaveExecLog(`
Expand Down Expand Up @@ -310,6 +311,7 @@ test('should switch between multiple projects with filter', async ({ activate })
await expect(testController).toHaveTestTree(`
- tests
- test1.spec.ts
- [playwright.config.js [project 2] — disabled]
`);

await expect(vscode).toHaveExecLog(`
Expand All @@ -330,6 +332,7 @@ test('should switch between multiple projects with filter', async ({ activate })
await expect(testController).toHaveTestTree(`
- tests
- test2.spec.ts
- [playwright.config.js [project 1] — disabled]
`);

await expect(vscode).toHaveProjectTree(`
Expand Down
6 changes: 6 additions & 0 deletions tests/list-tests.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -838,12 +838,16 @@ test('should show project-specific tests', async ({ activate }, testInfo) => {

await expect(testController).toHaveTestTree(`
- test.spec.ts
- [playwright.config.ts [firefox] — disabled]
- [playwright.config.ts [webkit] — disabled]
`);

await testController.expandTestItems(/test.spec.ts/);
await expect(testController).toHaveTestTree(`
- test.spec.ts
- test [2:0]
- [playwright.config.ts [firefox] — disabled]
- [playwright.config.ts [webkit] — disabled]
`);

await enableProjects(vscode, ['chromium', 'firefox', 'webkit']);
Expand All @@ -859,6 +863,8 @@ test('should show project-specific tests', async ({ activate }, testInfo) => {
await expect(testController).toHaveTestTree(`
- test.spec.ts
- test [2:0]
- [playwright.config.ts [chromium] — disabled]
- [playwright.config.ts [firefox] — disabled]
`);
});

Expand Down
9 changes: 7 additions & 2 deletions tests/mock/vscode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ export class TestItem {
tags: readonly TestTag[] = [];
canResolveChildren = false;
status: 'none' | 'enqueued' | 'started' | 'skipped' | 'failed' | 'passed' = 'none';
description: string | undefined;
sortText: string | undefined;

constructor(
readonly testController: TestController,
Expand Down Expand Up @@ -288,7 +290,10 @@ export class TestItem {
let location = '';
if (this.range)
location = ` [${this.range.start.toString()}]`;
return `${this.label}${location}`;
let description = '';
if (this.description)
description = ` [${this.description}]`;
return `${this.label}${description}${location}`;
}

flatTitle(): string {
Expand All @@ -309,7 +314,7 @@ function itemOrder(item: TestItem) {
let result = '';
if (item.range)
result += item.range.start.line.toString().padStart(5, '0');
result += item.label;
result += item.sortText || item.label;
return result;
}

Expand Down
3 changes: 3 additions & 0 deletions tests/project-setup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ test.describe(() => {
- ✅ teardown [2:0]
- test.ts
- ✅ test [2:0]
- [playwright.config.ts [setup] — disabled]
`);

const output = testRun.renderLog({ output: true });
Expand All @@ -103,6 +104,8 @@ test.describe(() => {
await expect(testController).toHaveTestTree(`
- test.ts
- ✅ test [2:0]
- [playwright.config.ts [setup] — disabled]
- [playwright.config.ts [teardown] — disabled]
`);

const output = testRun.renderLog({ output: true });
Expand Down
6 changes: 6 additions & 0 deletions tests/project-tree.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ test('should switch between configs', async ({ activate }) => {
await expect(testController).toHaveTestTree(`
- tests1
- test.spec.ts
- [tests1/playwright.config.js [projectTwo] — disabled]
`);
await expect(vscode).toHaveProjectTree(`
config: tests1/playwright.config.js
Expand All @@ -58,6 +59,7 @@ test('should switch between configs', async ({ activate }) => {
await expect(testController).toHaveTestTree(`
- tests2
- test.spec.ts
- [tests2/playwright.config.js [projectFour] — disabled]
`);
await expect(vscode).toHaveExecLog(`
tests1> playwright list-files -c playwright.config.js
Expand Down Expand Up @@ -90,6 +92,7 @@ test('should switch between projects', async ({ activate }) => {
await expect(testController).toHaveTestTree(`
- tests1
- test.spec.ts
- [playwright.config.js [projectTwo] — disabled]
`);

await expect(vscode).toHaveProjectTree(`
Expand Down Expand Up @@ -143,6 +146,7 @@ test('should hide unchecked projects', async ({ activate }) => {
await expect(testController).toHaveTestTree(`
- tests1
- test.spec.ts
- [playwright.config.js [projectTwo] — disabled]
`);

await expect(vscode).toHaveProjectTree(`
Expand All @@ -160,5 +164,7 @@ test('should hide unchecked projects', async ({ activate }) => {
`);

await expect(testController).toHaveTestTree(`
- [playwright.config.js [projectOne] — disabled]
- [playwright.config.js [projectTwo] — disabled]
`);
});

0 comments on commit a95208d

Please sign in to comment.