diff --git a/packages/trace-viewer/src/ui/statusLine.css b/packages/trace-viewer/src/ui/statusLine.css new file mode 100644 index 0000000000000..dc427e1b8d502 --- /dev/null +++ b/packages/trace-viewer/src/ui/statusLine.css @@ -0,0 +1,55 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +.status-line { + display: block; + width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + line-height: 30px; + height: 30px; + margin-left: 5px; + cursor: default; +} + +.status-line > span:not(:first-child) { + display: inline-flex; + align-items: center; + gap: 4px; + user-select: none; + margin-left: 8px; + vertical-align: sub; +} + +.status-line-count { + display: inline-flex; + align-items: center; + gap: 8px; + vertical-align: sub; +} + +.status-passed { + color: var(--vscode-debugIcon-restartForeground); +} + +.status-failed { + color: var(--vscode-list-errorForeground); +} + +.status-skipped { + color: var(--vscode-foreground); +} diff --git a/packages/trace-viewer/src/ui/statusLine.tsx b/packages/trace-viewer/src/ui/statusLine.tsx new file mode 100644 index 0000000000000..5bcce65de4bee --- /dev/null +++ b/packages/trace-viewer/src/ui/statusLine.tsx @@ -0,0 +1,51 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import '@web/third_party/vscode/codicon.css'; +import '@web/common.css'; +import './statusLine.css'; +import React from 'react'; +import { clsx } from '@web/uiUtils'; +import { testStatusIcon } from './testUtils'; + +interface StatusLineProps { + passed: number; + failed: number; + skipped: number; + total: number; + isRunning: boolean; +} + +export const StatusLine: React.FC = ({ passed, failed, skipped, total, isRunning }) => { + const count = passed + failed + skipped; + return ( +
+ + + {count}/{total} + + + {passed || 0} + + + {failed || 0} + + + {skipped || 0} + +
+ ); +}; diff --git a/packages/trace-viewer/src/ui/uiModeView.css b/packages/trace-viewer/src/ui/uiModeView.css index de89b911c33b7..6e122753cc4b5 100644 --- a/packages/trace-viewer/src/ui/uiModeView.css +++ b/packages/trace-viewer/src/ui/uiModeView.css @@ -82,22 +82,6 @@ margin-bottom: 30px; } -.status-line { - flex: auto; - white-space: nowrap; - line-height: 22px; - padding-left: 10px; - display: flex; - flex-direction: row; - align-items: center; - height: 30px; -} - -.status-line > div { - overflow: hidden; - text-overflow: ellipsis; -} - .ui-mode-sidebar input[type=search] { flex: auto; padding: 0 5px; diff --git a/packages/trace-viewer/src/ui/uiModeView.tsx b/packages/trace-viewer/src/ui/uiModeView.tsx index 4375018765aea..c1d697f3bf99c 100644 --- a/packages/trace-viewer/src/ui/uiModeView.tsx +++ b/packages/trace-viewer/src/ui/uiModeView.tsx @@ -37,6 +37,7 @@ import { TestListView } from './uiModeTestListView'; import { TraceView } from './uiModeTraceView'; import { SettingsView } from './settingsView'; import { DefaultSettingsView } from './defaultSettingsView'; +import { StatusLine } from './statusLine'; let xtermSize = { cols: 80, rows: 24 }; const xtermDataSource: XtermDataSource = { @@ -460,13 +461,13 @@ export const UIModeView: React.FC<{}> = ({ testModel={testModel} runTests={() => runTests('bounce-if-busy', visibleTestIds)} /> - {!isRunningTest && !progress &&
Tests
} - {!isRunningTest && progress &&
-
{progress.passed}/{progress.total} passed ({(progress.passed / progress.total) * 100 | 0}%)
-
} - {isRunningTest && progress &&
-
Running {progress.passed}/{runningState.testIds.size} passed ({(progress.passed / runningState.testIds.size) * 100 | 0}%)
-
} + runTests('bounce-if-busy', visibleTestIds)} disabled={isRunningTest || isLoading}> testServerConnection?.stopTests({})} disabled={!isRunningTest || isLoading}> { diff --git a/tests/playwright-test/ui-mode-metadata.spec.ts b/tests/playwright-test/ui-mode-metadata.spec.ts index bfbbba08a54f2..e622332555b53 100644 --- a/tests/playwright-test/ui-mode-metadata.spec.ts +++ b/tests/playwright-test/ui-mode-metadata.spec.ts @@ -41,7 +41,11 @@ test('should render html report git info metadata', async ({ runUITest }) => { }); await page.getByTitle('Run all').click(); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await page.getByTitle('Toggle output').click(); await expect(page.getByTestId('output')).toContainText('ci.link: https://playwright.dev'); diff --git a/tests/playwright-test/ui-mode-test-annotations.spec.ts b/tests/playwright-test/ui-mode-test-annotations.spec.ts index cc1f0b5f04db8..377cec58c45a8 100644 --- a/tests/playwright-test/ui-mode-test-annotations.spec.ts +++ b/tests/playwright-test/ui-mode-test-annotations.spec.ts @@ -32,7 +32,11 @@ test('should display annotations', async ({ runUITest }) => { `, }); await page.getByTitle('Run all').click(); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await page.getByRole('treeitem', { name: 'suite' }).locator('.codicon-chevron-right').click(); await page.getByText('annotation test').click(); await page.getByText('Annotations', { exact: true }).click(); diff --git a/tests/playwright-test/ui-mode-test-attachments.spec.ts b/tests/playwright-test/ui-mode-test-attachments.spec.ts index 6d466acec547b..bc90a50d44dde 100644 --- a/tests/playwright-test/ui-mode-test-attachments.spec.ts +++ b/tests/playwright-test/ui-mode-test-attachments.spec.ts @@ -33,7 +33,11 @@ test('should contain text attachment', async ({ runUITest }) => { }); await page.getByText('attach test').click(); await page.getByTitle('Run all').click(); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await page.getByText('Attachments').click(); await page.locator('.tab-attachments').getByText('text attachment').click(); @@ -69,7 +73,11 @@ test('should contain binary attachment', async ({ runUITest }) => { }); await page.getByText('attach test').click(); await page.getByTitle('Run all').click(); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await page.getByText('Attachments').click(); const downloadPromise = page.waitForEvent('download'); await page.getByRole('link', { name: 'download' }).click(); @@ -89,7 +97,11 @@ test('should contain string attachment', async ({ runUITest }) => { }); await page.getByText('attach test').click(); await page.getByTitle('Run all').click(); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await page.getByText('Attachments').click(); await page.getByText('note', { exact: true }).click(); const downloadPromise = page.waitForEvent('download'); @@ -116,7 +128,11 @@ test('should linkify string attachments', async ({ runUITest, server }) => { }); await page.getByText('attach test').click(); await page.getByTitle('Run all').click(); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await page.getByText('Attachments').click(); const attachmentsPane = page.locator('.attachments-tab'); @@ -162,7 +178,11 @@ test('should link from attachment step to attachments view', async ({ runUITest await page.getByText('attach test').click(); await page.getByTitle('Run all').click(); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await page.getByRole('tab', { name: 'Attachments' }).click(); const panel = page.getByRole('tabpanel', { name: 'Attachments' }); diff --git a/tests/playwright-test/ui-mode-test-output.spec.ts b/tests/playwright-test/ui-mode-test-output.spec.ts index 75d4c545f88ed..5b58047baf4a5 100644 --- a/tests/playwright-test/ui-mode-test-output.spec.ts +++ b/tests/playwright-test/ui-mode-test-output.spec.ts @@ -250,7 +250,11 @@ test('should print beforeAll console messages once', async ({ runUITest }, testI await page.getByTitle('Run all').click(); await page.getByText('Console').click(); await page.getByText('print').click(); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await expect(page.locator('.console-tab .console-line-message')).toHaveText([ 'before all log', 'test log', diff --git a/tests/playwright-test/ui-mode-test-run.spec.ts b/tests/playwright-test/ui-mode-test-run.spec.ts index 3b2351083a8a4..1cef41a2745b5 100644 --- a/tests/playwright-test/ui-mode-test-run.spec.ts +++ b/tests/playwright-test/ui-mode-test-run.spec.ts @@ -81,7 +81,11 @@ test('should run visible', async ({ runUITest }) => { - treeitem "[icon-circle-slash] skipped" `); - await expect(page.getByTestId('status-line')).toHaveText('4/8 passed (50%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('8/8'); + await expect(statusLine.locator('.status-passed')).toHaveText('4'); + await expect(statusLine.locator('.status-failed')).toHaveText('3'); + await expect(statusLine.locator('.status-skipped')).toHaveText('1'); }); test('should show running progress', async ({ runUITest }) => { @@ -96,11 +100,21 @@ test('should show running progress', async ({ runUITest }) => { }); await page.getByTitle('Run all').click(); - await expect(page.getByTestId('status-line')).toHaveText('Running 1/4 passed (25%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/4'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await page.getByTitle('Stop').click(); - await expect(page.getByTestId('status-line')).toHaveText('1/4 passed (25%)'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/4'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await page.getByTitle('Reload').click(); - await expect(page.getByTestId('status-line')).toBeHidden(); + await expect(statusLine.getByTestId('test-count')).toHaveText('0/4'); + await expect(statusLine.locator('.status-passed')).toHaveText('0'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); }); test('should run on hover', async ({ runUITest }) => { @@ -491,7 +505,11 @@ test('should show time', async ({ runUITest }) => { - treeitem "[icon-circle-slash] skipped" `); - await expect(page.getByTestId('status-line')).toHaveText('4/8 passed (50%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('8/8'); + await expect(statusLine.locator('.status-passed')).toHaveText('4'); + await expect(statusLine.locator('.status-failed')).toHaveText('3'); + await expect(statusLine.locator('.status-skipped')).toHaveText('1'); }); test('should show test.fail as passing', async ({ runUITest }) => { @@ -522,7 +540,11 @@ test('should show test.fail as passing', async ({ runUITest }) => { - treeitem ${/\[icon-check\] should fail \d+m?s/} `); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); }); test('should ignore repeatEach', async ({ runUITest }) => { @@ -558,7 +580,11 @@ test('should ignore repeatEach', async ({ runUITest }) => { - treeitem ${/\[icon-check\] should pass/} `); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); }); test('should remove output folder before test run', async ({ runUITest }) => { @@ -593,7 +619,11 @@ test('should remove output folder before test run', async ({ runUITest }) => { - treeitem ${/\[icon-check\] should pass/} `); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await page.getByTitle('Run all').click(); await expect.poll(dumpTestTree(page)).toBe(` @@ -608,7 +638,10 @@ test('should remove output folder before test run', async ({ runUITest }) => { - treeitem ${/\[icon-check\] should pass/} `); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); }); test('should show proper total when using deps', async ({ runUITest }) => { @@ -660,7 +693,11 @@ test('should show proper total when using deps', async ({ runUITest }) => { - treeitem "[icon-circle-outline] run @chromium chromium" `); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await page.getByTitle('run @chromium').dblclick(); await expect.poll(dumpTestTree(page)).toBe(` @@ -680,7 +717,10 @@ test('should show proper total when using deps', async ({ runUITest }) => { - button "Watch" `); - await expect(page.getByTestId('status-line')).toHaveText('2/2 passed (100%)'); + await expect(statusLine.getByTestId('test-count')).toHaveText('2/2'); + await expect(statusLine.locator('.status-passed')).toHaveText('2'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); }); test('should respect --tsconfig option', { @@ -746,7 +786,11 @@ test('should respect --tsconfig option', { - treeitem ${/\[icon-check\] test/} `); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); }); test('should respect --ignore-snapshots option', { diff --git a/tests/playwright-test/ui-mode-test-screencast.spec.ts b/tests/playwright-test/ui-mode-test-screencast.spec.ts index 4affc726bc313..8242093fae22e 100644 --- a/tests/playwright-test/ui-mode-test-screencast.spec.ts +++ b/tests/playwright-test/ui-mode-test-screencast.spec.ts @@ -35,7 +35,11 @@ test('should show screenshots', async ({ runUITest }) => { `, }); await page.getByTitle('Run all').click(); - await expect(page.getByTestId('status-line')).toHaveText('2/2 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('2/2'); + await expect(statusLine.locator('.status-passed')).toHaveText('2'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await page.getByText('test 1', { exact: true }).click(); await expect(page.getByTestId('actions-tree')).toContainText('Expect'); diff --git a/tests/playwright-test/ui-mode-test-setup.spec.ts b/tests/playwright-test/ui-mode-test-setup.spec.ts index c912038571bdd..faa9d48fa2ba7 100644 --- a/tests/playwright-test/ui-mode-test-setup.spec.ts +++ b/tests/playwright-test/ui-mode-test-setup.spec.ts @@ -47,7 +47,11 @@ test('should run global setup and teardown', async ({ runUITest }, testInfo) => ` }, undefined, { additionalArgs: ['--output=foo'] }); await page.getByTitle('Run all').click(); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await page.getByTitle('Toggle output').click(); const output = page.getByTestId('output'); @@ -85,7 +89,11 @@ test('should teardown on sigint', async ({ runUITest, nodeVersion }) => { ` }); await page.getByTitle('Run all').click(); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await page.getByTitle('Toggle output').click(); await expect(page.getByTestId('output')).toContainText('from-global-setup'); @@ -335,7 +343,11 @@ for (const useWeb of [true, false]) { ` }, null, { useWeb }); await page.getByTitle('Run all').click(); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await testProcess.kill('SIGINT'); await expect.poll(() => testProcess.outputLines()).toEqual([ 'from-global-teardown0000', @@ -368,7 +380,11 @@ test('should restart webserver on reload', async ({ runUITest }) => { ` }, { DEBUG: 'pw:webserver' }); await page.getByTitle('Run all').click(); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await page.getByTitle('Toggle output').click(); await expect(page.getByTestId('output')).toContainText('[WebServer] listening'); @@ -381,5 +397,8 @@ test('should restart webserver on reload', async ({ runUITest }) => { await expect(page.getByTestId('output')).not.toContainText('set reuseExistingServer:true'); await page.getByTitle('Run all').click(); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); }); diff --git a/tests/playwright-test/ui-mode-test-shortcut.spec.ts b/tests/playwright-test/ui-mode-test-shortcut.spec.ts index 9dd73f3e902d1..8c992f1a58618 100644 --- a/tests/playwright-test/ui-mode-test-shortcut.spec.ts +++ b/tests/playwright-test/ui-mode-test-shortcut.spec.ts @@ -37,7 +37,11 @@ test('should run tests', async ({ runUITest }) => { await page.getByPlaceholder('Filter (e.g. text, @tag)').fill('test 3'); await page.keyboard.press('F5'); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await page.getByPlaceholder('Filter (e.g. text, @tag)').fill(''); // Only the filtered test was run. diff --git a/tests/playwright-test/ui-mode-test-watch.spec.ts b/tests/playwright-test/ui-mode-test-watch.spec.ts index 867da5cbf540f..3b2f95fd91196 100644 --- a/tests/playwright-test/ui-mode-test-watch.spec.ts +++ b/tests/playwright-test/ui-mode-test-watch.spec.ts @@ -128,7 +128,10 @@ test('should batch watch updates', async ({ runUITest, writeFiles }) => { 'd.test.ts': `import { test } from '@playwright/test'; test('test', () => {});`, }); - await expect(page.getByTestId('status-line')).toHaveText('4/4 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.locator('.status-passed')).toHaveText('4'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await expect.poll(dumpTestTree(page)).toBe(` ▼ ✅ a.test.ts 👁 @@ -167,7 +170,11 @@ test('should watch all', async ({ runUITest, writeFiles }) => { 'd.test.ts': `import { test } from '@playwright/test'; test('test', () => {});`, }); - await expect(page.getByTestId('status-line')).toHaveText('2/2 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('2/2'); + await expect(statusLine.locator('.status-passed')).toHaveText('2'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await expect.poll(dumpTestTree(page)).toBe(` ▼ ✅ a.test.ts @@ -210,7 +217,11 @@ test('should watch new file', async ({ runUITest, writeFiles }) => { 'b.test.ts': ` import { test } from '@playwright/test'; test('test', () => {});`, }); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await expect.poll(dumpTestTree(page)).toBe(` ▼ ◯ a.test.ts @@ -276,7 +287,11 @@ test('should queue watches', async ({ runUITest, writeFiles, createLatch }) => { await page.getByTitle('Watch all').click(); await page.getByTitle('Run all').click(); - await expect(page.getByTestId('status-line')).toHaveText('Running 1/4 passed (25%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/4'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); await writeFiles({ 'a.test.ts': `import { test } from '@playwright/test'; test('test', () => {});`, @@ -286,12 +301,18 @@ test('should queue watches', async ({ runUITest, writeFiles, createLatch }) => { // Now watches should not kick in. await new Promise(f => setTimeout(f, 1000)); - await expect(page.getByTestId('status-line')).toHaveText('Running 1/4 passed (25%)'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/4'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); // Allow test to finish and new watch to kick in. latch.open(); - await expect(page.getByTestId('status-line')).toHaveText('3/3 passed (100%)'); + await expect(statusLine.getByTestId('test-count')).toHaveText('3/3'); + await expect(statusLine.locator('.status-passed')).toHaveText('3'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); }); test('should not watch output', async ({ runUITest }) => { @@ -316,7 +337,11 @@ test('should not watch output', async ({ runUITest }) => { await page.getByTitle('Run all').click(); - await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); + const statusLine = page.getByTestId('status-line'); + await expect(statusLine.getByTestId('test-count')).toHaveText('1/1'); + await expect(statusLine.locator('.status-passed')).toHaveText('1'); + await expect(statusLine.locator('.status-failed')).toHaveText('0'); + await expect(statusLine.locator('.status-skipped')).toHaveText('0'); expect(commands).toContain('runTests'); expect(commands).not.toContain('listTests'); });