Skip to content

Commit 258fbef

Browse files
authored
feat: Select all projects iconbutton (#574)
1 parent 790adc3 commit 258fbef

10 files changed

+114
-3
lines changed

Diff for: l10n/bundle.l10n.de.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,7 @@
3030
"SETTINGS": "EINSTELLUNGEN",
3131
"PROJECTS": "PROJEKTE",
3232
"TOOLS": "WERKZEUGE",
33-
"SETUP": "KONFIGURATION"
33+
"SETUP": "KONFIGURATION",
34+
"Select All": "Alle auswählen",
35+
"Unselect All": "Alle abwählen"
3436
}

Diff for: l10n/bundle.l10n.fr.json

+2
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,7 @@
2626
"Toggle Playwright Configs": "Basculer les configurations Playwright",
2727
"Update snapshots": "Mettre à jour les captures",
2828
"Update method" : "Mettre à jour la méthode",
29+
"Select All": "Tout sélectionner",
30+
"Unselect All": "Tout désélectionner",
2931
"When enabled, Playwright will reuse the browser instance between tests. This will disable parallel execution.": "Si cette option est activée, Playwright réutilisera l'instance du navigateur entre les tests. Cela désactivera l'exécution parallèle."
3032
}

Diff for: l10n/bundle.l10n.it.json

+2
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,7 @@
2626
"Toggle Playwright Configs": "Attiva/disattiva Playwright Configs",
2727
"Update snapshots": "Aggiorna snapshots",
2828
"Update method" : "Aggiorna metodo",
29+
"Select All": "Seleziona tutto",
30+
"Unselect All": "Deseleziona tutto",
2931
"When enabled, Playwright will reuse the browser instance between tests. This will disable parallel execution.": "Quando attivata, Playwright riusa l'instanza browser tra i test. Questo disattiva l'esecuzione parallela."
3032
}

Diff for: l10n/bundle.l10n.json

+2
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,7 @@
2626
"Toggle Playwright Configs": "Toggle Playwright Configs",
2727
"Update snapshots": "Update snapshots",
2828
"Update method" : "Update method",
29+
"Select All": "Select All",
30+
"Unselect All": "Unselect All",
2931
"When enabled, Playwright will reuse the browser instance between tests. This will disable parallel execution.": "When enabled, Playwright will reuse the browser instance between tests. This will disable parallel execution."
3032
}

Diff for: l10n/bundle.l10n.zh-CN.json

+2
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,7 @@
2626
"Toggle Playwright Configs": "切换 Playwright 配置",
2727
"Update snapshots": "更新快照",
2828
"Update method" : "更新方法",
29+
"Select All": "全选",
30+
"Unselect All": "取消全选",
2931
"When enabled, Playwright will reuse the browser instance between tests. This will disable parallel execution.": "启用后,Playwright 将在测试之间重复使用浏览器实例。这将禁用并行执行。"
3032
}

Diff for: media/common.css

+14-1
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,22 @@ textarea {
8181

8282
.section-header {
8383
font-size: 11px;
84-
margin: 0 8px;
84+
margin: 10px 8px 3px 8px;
8585
font-weight: 700;
8686
color: var(--vscode-editor-inlineValuesForeground);
87+
88+
display: flex;
89+
justify-content: space-between;
90+
align-items: baseline;
91+
}
92+
93+
.section-toolbar > a {
94+
border-radius: 5px;
95+
font-size: 16px;
96+
}
97+
98+
.section-toolbar > a:hover {
99+
background-color: var(--vscode-toolbar-hoverBackground);
87100
}
88101

89102
.action, .combobox {

Diff for: media/settingsView.js

+16
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
/** @type {Config} */
2020
let selectConfig;
2121

22+
const selectAllButton = /** @type {HTMLAnchorElement} */ (document.getElementById('selectAll'));
23+
const unselectAllButton = /** @type {HTMLAnchorElement} */ (document.getElementById('unselectAll'));
24+
2225
/**
2326
* @param {Array<ProjectEntry>} projects
2427
*/
@@ -41,7 +44,20 @@ function updateProjects(projects) {
4144
div.appendChild(label);
4245
projectsElement.appendChild(div);
4346
}
47+
48+
const allEnabled = projects.every(p => p.enabled);
49+
selectAllButton.hidden = allEnabled;
50+
unselectAllButton.hidden = !allEnabled;
51+
}
52+
53+
/**
54+
* @param {boolean} enabled
55+
*/
56+
function setAllProjectsEnabled(enabled) {
57+
vscode.postMessage({ method: 'setAllProjectsEnabled', params: { configFile: selectConfig.configFile, enabled } });
4458
}
59+
selectAllButton.addEventListener('click', () => setAllProjectsEnabled(true));
60+
unselectAllButton.addEventListener('click', () => setAllProjectsEnabled(false));
4561

4662
for (const input of Array.from(document.querySelectorAll('input[type=checkbox]'))) {
4763
input.addEventListener('change', event => {

Diff for: src/settingsView.ts

+14-1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ export class SettingsView extends DisposableBase implements vscodeTypes.WebviewV
8080
} else if (data.method === 'setProjectEnabled') {
8181
const { configFile, projectName, enabled } = data.params;
8282
this._models.setProjectEnabled(configFile, projectName, enabled);
83+
} else if (data.method === 'setAllProjectsEnabled') {
84+
const { configFile, enabled } = data.params;
85+
this._models.setAllProjectsEnabled(configFile, enabled);
8386
} else if (data.method === 'selectModel') {
8487
this._models.selectModel(data.params.configFile);
8588
}
@@ -221,7 +224,17 @@ function htmlForWebview(vscode: vscodeTypes.VSCode, extensionUri: vscodeTypes.Ur
221224
<span id="configToolbar"></span>
222225
</div>
223226
</div>
224-
<div class="section-header">${vscode.l10n.t('PROJECTS')}</div>
227+
<div class="section-header">
228+
${vscode.l10n.t('PROJECTS')}
229+
<div class="section-toolbar">
230+
<a id="selectAll" role="button" title="${vscode.l10n.t('Select All')}">
231+
<svg width="48" height="48" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path d="M9 9H4v1h5V9z"/><path d="M7 12V7H6v5h1z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M5 3l1-1h7l1 1v7l-1 1h-2v2l-1 1H3l-1-1V6l1-1h2V3zm1 2h4l1 1v4h2V3H6v2zm4 1H3v7h7V6z"/></svg>
232+
</a>
233+
<a id="unselectAll" role="button" title="${vscode.l10n.t('Unselect All')}" hidden>
234+
<svg width="48" height="48" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="currentColor"><path d="M9 9H4v1h5V9z"/><path fill-rule="evenodd" clip-rule="evenodd" d="M5 3l1-1h7l1 1v7l-1 1h-2v2l-1 1H3l-1-1V6l1-1h2V3zm1 2h4l1 1v4h2V3H6v2zm4 1H3v7h7V6z"/></svg>
235+
</a>
236+
</div>
237+
</div>
225238
<div data-testid="projects" id="projects" class="vbox"></div>
226239
<div class="section-header">${vscode.l10n.t('SETUP')}</div>
227240
<div id="rareActions" class="vbox"></div>

Diff for: src/testModel.ts

+13
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,19 @@ export class TestModelCollection extends DisposableBase {
740740
this._didUpdate.fire();
741741
}
742742

743+
setAllProjectsEnabled(configFile: string, enabled: boolean) {
744+
const model = this._models.find(m => m.config.configFile === configFile);
745+
if (!model)
746+
return;
747+
const projectsToUpdate = model.projects().filter(p => p.isEnabled !== enabled);
748+
if (projectsToUpdate.length === 0)
749+
return;
750+
for (const project of projectsToUpdate)
751+
project.isEnabled = enabled;
752+
this._saveSettings();
753+
this._didUpdate.fire();
754+
}
755+
743756
testDirs(): Set<string> {
744757
const result = new Set<string>();
745758
for (const model of this._models) {

Diff for: tests/settings.spec.ts

+46
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,52 @@ test('should toggle setting from webview', async ({ activate }) => {
4646
expect(configuration.get('reuseBrowser')).toBe(true);
4747
});
4848

49+
test('should select-all/unselect-all', async ({ activate }) => {
50+
const { vscode } = await activate({
51+
'playwright.config.ts': `
52+
import { defineConfig } from '@playwright/test';
53+
export default defineConfig({
54+
projects: [
55+
{ name: 'foo', testMatch: 'foo.ts' },
56+
{ name: 'bar', testMatch: 'bar.ts' },
57+
]
58+
});
59+
`,
60+
});
61+
62+
const webView = vscode.webViews.get('pw.extension.settingsView')!;
63+
64+
await expect(webView.locator('body')).toMatchAriaSnapshot(`
65+
- text: PROJECTS
66+
- button "Select All"
67+
- checkbox "foo" [checked]
68+
- checkbox "bar" [checked=false]
69+
`);
70+
71+
await webView.getByRole('checkbox', { name: 'bar' }).check();
72+
73+
await expect(webView.locator('body')).toMatchAriaSnapshot(`
74+
- button "Unselect All"
75+
- checkbox "foo" [checked]
76+
- checkbox "bar" [checked]
77+
`);
78+
79+
await webView.getByRole('button', { name: 'Unselect All' }).click();
80+
81+
await expect(webView.locator('body')).toMatchAriaSnapshot(`
82+
- button "Select All"
83+
- checkbox "foo" [checked=false]
84+
- checkbox "bar" [checked=false]
85+
`);
86+
87+
await webView.getByRole('button', { name: 'Select All' }).click();
88+
await expect(webView.locator('body')).toMatchAriaSnapshot(`
89+
- button "Unselect All"
90+
- checkbox "foo" [checked]
91+
- checkbox "bar" [checked]
92+
`);
93+
});
94+
4995
test('should reflect changes to setting', async ({ activate }) => {
5096
const { vscode } = await activate({
5197
'playwright.config.js': `module.exports = {}`,

0 commit comments

Comments
 (0)