From f5894ed08982dab296f9e53bf1a70bc39aaaca87 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Tue, 7 Mar 2023 17:20:41 -0800 Subject: [PATCH] chore: open location in vscode (#21472) --- packages/playwright-test/src/runner/uiMode.ts | 3 + packages/trace-viewer/src/ui/watchMode.tsx | 88 ++++++++++++------- 2 files changed, 60 insertions(+), 31 deletions(-) diff --git a/packages/playwright-test/src/runner/uiMode.ts b/packages/playwright-test/src/runner/uiMode.ts index 2395eb58be..314f17a87b 100644 --- a/packages/playwright-test/src/runner/uiMode.ts +++ b/packages/playwright-test/src/runner/uiMode.ts @@ -28,6 +28,7 @@ import type { TaskRunnerState } from './tasks'; import { createTaskRunnerForList, createTaskRunnerForWatch, createTaskRunnerForWatchSetup } from './tasks'; import { chokidar } from '../utilsBundle'; import type { FSWatcher } from 'chokidar'; +import { open } from '../utilsBundle'; class UIMode { private _config: FullConfigInternal; @@ -88,6 +89,8 @@ class UIMode { this._stopTests(); if (method === 'watch') this._watchFile(params.fileName); + if (method === 'open' && params.location) + open.openApp('code', { arguments: ['--goto', params.location] }).catch(() => {}); if (method === 'resizeTerminal') { process.stdout.columns = params.cols; process.stdout.rows = params.rows; diff --git a/packages/trace-viewer/src/ui/watchMode.tsx b/packages/trace-viewer/src/ui/watchMode.tsx index 37a0776014..4f9c9948dd 100644 --- a/packages/trace-viewer/src/ui/watchMode.tsx +++ b/packages/trace-viewer/src/ui/watchMode.tsx @@ -20,7 +20,7 @@ import '@web/common.css'; import React from 'react'; import { ListView } from '@web/components/listView'; import { TeleReporterReceiver } from '../../../playwright-test/src/isomorphic/teleReceiver'; -import type { FullConfig, Suite, TestCase, TestResult, TestStep } from '../../../playwright-test/types/testReporter'; +import type { FullConfig, Suite, TestCase, TestResult, TestStep, Location } from '../../../playwright-test/types/testReporter'; import { SplitView } from '@web/components/splitView'; import { MultiTraceModel } from './modelUtil'; import './watchMode.css'; @@ -46,7 +46,7 @@ const xtermDataSource: XtermDataSource = { export const WatchModeView: React.FC<{}> = ({ }) => { - const [projectNames, setProjectNames] = React.useState([]); + const [projects, setProjects] = React.useState>(new Map()); const [rootSuite, setRootSuite] = React.useState<{ value: Suite | undefined }>({ value: undefined }); const [isRunningTest, setIsRunningTest] = React.useState(false); const [progress, setProgress] = React.useState({ total: 0, passed: 0, failed: 0 }); @@ -55,9 +55,22 @@ export const WatchModeView: React.FC<{}> = ({ const [isWatchingFiles, setIsWatchingFiles] = React.useState(true); updateRootSuite = (rootSuite: Suite, { passed, failed }: Progress) => { - setRootSuite({ value: rootSuite }); + for (const projectName of projects.keys()) { + if (!rootSuite.suites.find(s => s.title === projectName)) + projects.delete(projectName); + } + for (const projectSuite of rootSuite.suites) { + if (!projects.has(projectSuite.title)) + projects.set(projectSuite.title, false); + } + if (![...projects.values()].includes(true)) + projects.set(projects.entries().next().value[0], true); + progress.passed = passed; progress.failed = failed; + + setRootSuite({ value: rootSuite }); + setProjects(new Map(projects)); setProgress({ ...progress }); }; @@ -69,11 +82,6 @@ export const WatchModeView: React.FC<{}> = ({ }); }; - React.useEffect(() => { - if (projectNames.length === 0 && rootSuite.value?.suites.length) - setProjectNames([rootSuite.value?.suites[0].title]); - }, [projectNames, rootSuite]); - return
@@ -87,14 +95,15 @@ export const WatchModeView: React.FC<{}> = ({
{ setSettingsVisible(!settingsVisible); }}> - { !settingsVisible && } - {settingsVisible && setSettingsVisible(false)}>} + onTestItemSelected={setSelectedTestItem} + isVisible={!settingsVisible} /> + {settingsVisible && setSettingsVisible(false)}>}
@@ -104,13 +113,14 @@ export const WatchModeView: React.FC<{}> = ({ }; export const TestList: React.FC<{ - projectNames: string[], + projects: Map, rootSuite: { value: Suite | undefined }, runTests: (testIds: string[]) => void, isRunningTest: boolean, isWatchingFiles: boolean, + isVisible: boolean onTestItemSelected: (test: TestItem | undefined) => void, -}> = ({ projectNames, rootSuite, runTests, isRunningTest, isWatchingFiles, onTestItemSelected }) => { +}> = ({ projects, rootSuite, runTests, isRunningTest, isWatchingFiles, isVisible, onTestItemSelected }) => { const [filterText, setFilterText] = React.useState(''); const [selectedTreeItemId, setSelectedTreeItemId] = React.useState(); const [expandedItems, setExpandedItems] = React.useState>(new Map()); @@ -122,7 +132,7 @@ export const TestList: React.FC<{ }, []); const { filteredItems, treeItemMap, visibleTestIds } = React.useMemo(() => { - const treeItems = createTree(rootSuite.value, projectNames); + const treeItems = createTree(rootSuite.value, projects); const filteredItems = filterTree(treeItems, filterText); const treeItemMap = new Map(); @@ -135,7 +145,7 @@ export const TestList: React.FC<{ }; filteredItems.forEach(visit); return { treeItemMap, visibleTestIds, filteredItems }; - }, [filterText, rootSuite, projectNames]); + }, [filterText, rootSuite, projects]); runVisibleTests = () => runTests([...visibleTestIds]); @@ -170,6 +180,9 @@ export const TestList: React.FC<{ runTests(collectTestIds(selectedTreeItem)); }; + if (!isVisible) + return <>; + return
{treeItem.title}
runTreeItem(treeItem)} disabled={isRunningTest}> + sendMessageNoReply('open', { location: locationToOpen(treeItem) })}>
; }} itemIcon={(treeItem: TreeItem) => { @@ -241,25 +255,24 @@ export const TestList: React.FC<{ }; export const SettingsView: React.FC<{ - projectNames: string[], - setProjectNames: (projectNames: string[]) => void, + projects: Map, + setProjects: (projectNames: Map) => void, onClose: () => void, -}> = ({ projectNames, setProjectNames, onClose }) => { +}> = ({ projects, setProjects, onClose }) => { return
Projects
- {projectNames.map(projectName => { - return
- { - const copy = [...projectNames]; - if (copy.includes(projectName)) - copy.splice(copy.indexOf(projectName), 1); - else - copy.push(projectName); - setProjectNames(copy); + {[...projects.entries()].map(([projectName, value]) => { + return
+ { + const copy = new Map(projects); + copy.set(projectName, !copy.get(projectName)); + if (![...copy.values()].includes(true)) + copy.set(projectName, true); + setProjects(copy); }} style={{ margin: '0 5px 0 10px' }} />