From b929c0d8f7dd6a6577dce249a931b10652602651 Mon Sep 17 00:00:00 2001 From: jonghoonpark Date: Tue, 19 Mar 2024 20:36:42 +0900 Subject: [PATCH] feat(ui-mode): add key shortcuts for playwright uI test runner (#29868) --- packages/trace-viewer/src/ui/uiModeView.tsx | 18 +++++ .../ui-mode-test-shortcut.spec.ts | 69 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 tests/playwright-test/ui-mode-test-shortcut.spec.ts diff --git a/packages/trace-viewer/src/ui/uiModeView.tsx b/packages/trace-viewer/src/ui/uiModeView.tsx index 74e85c07d4..50d5551664 100644 --- a/packages/trace-viewer/src/ui/uiModeView.tsx +++ b/packages/trace-viewer/src/ui/uiModeView.tsx @@ -177,6 +177,24 @@ export const UIModeView: React.FC<{}> = ({ }); }, [projectFilters, runningState, testModel]); + React.useEffect(() => { + const onShortcutEvent = (e: KeyboardEvent) => { + if (e.code === 'F6') { + e.preventDefault(); + sendMessageNoReply('stop'); + } else if (e.code === 'F5') { + e.preventDefault(); + reloadTests(); + } + }; + + addEventListener('keydown', onShortcutEvent); + + return () => { + removeEventListener('keydown', onShortcutEvent); + }; + }, [runTests, reloadTests]); + const isRunningTest = !!runningState; const dialogRef = React.useRef(null); const openInstallDialog = React.useCallback((e: React.MouseEvent) => { diff --git a/tests/playwright-test/ui-mode-test-shortcut.spec.ts b/tests/playwright-test/ui-mode-test-shortcut.spec.ts new file mode 100644 index 0000000000..8768ccbca0 --- /dev/null +++ b/tests/playwright-test/ui-mode-test-shortcut.spec.ts @@ -0,0 +1,69 @@ +/** + * 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 { test, expect, retries, dumpTestTree } from './ui-mode-fixtures'; + +test.describe.configure({ mode: 'parallel', retries }); + +const basicTestTree = { + 'a.test.ts': ` + import { test, expect } from '@playwright/test'; + test('test 0', () => { test.skip(); }); + test('test 1', () => {}); + test('test 2', async () => { await new Promise(() => {}); }); + test('test 3', async () => {}); + ` +}; + +test('should stop on F6', async ({ runUITest }) => { + const { page } = await runUITest(basicTestTree); + + await expect(page.getByTitle('Run all')).toBeEnabled(); + await expect(page.getByTitle('Stop')).toBeDisabled(); + + await page.getByTitle('Run all').click(); + + await expect.poll(dumpTestTree(page)).toBe(` + ▼ ↻ a.test.ts + ⊘ test 0 + ✅ test 1 + ↻ test 2 + 🕦 test 3 + `); + + await expect(page.getByTitle('Run all')).toBeDisabled(); + await expect(page.getByTitle('Stop')).toBeEnabled(); + + await page.keyboard.press('F6'); + + await expect.poll(dumpTestTree(page)).toBe(` + ▼ ◯ a.test.ts + ⊘ test 0 + ✅ test 1 + ◯ test 2 + ◯ test 3 + `); +}); + +test('should reload on F5', async ({ runUITest }) => { + const { page } = await runUITest(basicTestTree); + + await page.getByTitle('Run all').click(); + await expect(page.getByTestId('status-line')).toHaveText('Running 1/4 passed (25%)'); + + await page.keyboard.press('F5'); + await expect(page.getByTestId('status-line')).toBeHidden(); +}); \ No newline at end of file