mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
chore: ui mode ui improvements (#21325)
This commit is contained in:
parent
2cbde9b8ef
commit
57624bc01b
@ -85,8 +85,13 @@ class Controller {
|
||||
this._page.exposeBinding('binding', false, (source, data) => {
|
||||
const { method, params } = data;
|
||||
if (method === 'run') {
|
||||
const { location } = params;
|
||||
config._internal.cliArgs = [location];
|
||||
const { location, testIds } = params;
|
||||
if (location)
|
||||
config._internal.cliArgs = [location];
|
||||
if (testIds) {
|
||||
const testIdSet = testIds ? new Set<string>(testIds) : null;
|
||||
config._internal.testIdMatcher = id => !testIdSet || testIdSet.has(id);
|
||||
}
|
||||
this._queue = this._queue.then(() => runTests(config, this._runReporter));
|
||||
return this._queue;
|
||||
}
|
||||
|
||||
@ -21,3 +21,21 @@
|
||||
.watch-mode-sidebar input {
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.watch-mode-sidebar .toolbar-button:not([disabled]) .codicon-play {
|
||||
color: var(--vscode-testing-runAction);
|
||||
}
|
||||
|
||||
.watch-mode-list-item {
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.watch-mode-list-item-title {
|
||||
flex: auto;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden
|
||||
}
|
||||
|
||||
.watch-mode-sidebar .toolbar-button {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@ -24,6 +24,7 @@ import type { FullConfig, Suite, TestCase, TestStep } from '../../../playwright-
|
||||
import { SplitView } from '@web/components/splitView';
|
||||
import type { MultiTraceModel } from './modelUtil';
|
||||
import './watchMode.css';
|
||||
import { ToolbarButton } from '@web/components/toolbarButton';
|
||||
|
||||
let rootSuite: Suite | undefined;
|
||||
|
||||
@ -63,10 +64,10 @@ export const WatchModeView: React.FC<{}> = ({
|
||||
const explicitlyOrAutoExpandedFiles = new Set<Suite>();
|
||||
const entries = new Map<TestCase | Suite, Entry>();
|
||||
const trimmedFilterText = filterText.trim();
|
||||
const filterTokens = trimmedFilterText.split(' ');
|
||||
const filterTokens = trimmedFilterText.toLowerCase().split(' ');
|
||||
for (const fileSuite of fileSuites) {
|
||||
const hasMatch = !trimmedFilterText || fileSuite.allTests().some(test => {
|
||||
const fullTitle = test.titlePath().join(' ');
|
||||
const fullTitle = test.titlePath().join(' ').toLowerCase();
|
||||
return !filterTokens.some(token => !fullTitle.includes(token));
|
||||
});
|
||||
if (hasMatch)
|
||||
@ -76,13 +77,28 @@ export const WatchModeView: React.FC<{}> = ({
|
||||
if (expandState === true || autoExpandMatches) {
|
||||
explicitlyOrAutoExpandedFiles.add(fileSuite);
|
||||
for (const test of fileSuite.allTests()) {
|
||||
const fullTitle = test.titlePath().join(' ');
|
||||
const fullTitle = test.titlePath().join(' ').toLowerCase();
|
||||
if (!filterTokens.some(token => !fullTitle.includes(token)))
|
||||
entries.set(test, { test, fileSuite });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const visibleTestIds = new Set<string>();
|
||||
for (const { test } of entries.values()) {
|
||||
if (test)
|
||||
visibleTestIds.add(test.id);
|
||||
}
|
||||
|
||||
const runEntry = (entry: Entry) => {
|
||||
expandedFiles.set(entry.fileSuite, true);
|
||||
setSelectedTest(entry.test);
|
||||
setIsRunningTest(true);
|
||||
runTests(entry.test ? entry.test.location.file + ':' + entry.test.location.line : entry.fileSuite.title, undefined).then(() => {
|
||||
setIsRunningTest(false);
|
||||
});
|
||||
};
|
||||
|
||||
const selectedEntry = selectedTest ? entries.get(selectedTest) : selectedOrDefaultFileSuite ? entries.get(selectedOrDefaultFileSuite) : undefined;
|
||||
return <SplitView sidebarSize={300} orientation='horizontal' sidebarIsFirst={true}>
|
||||
<TraceView test={selectedTest} isRunningTest={isRunningTest}></TraceView>
|
||||
@ -93,12 +109,23 @@ export const WatchModeView: React.FC<{}> = ({
|
||||
setFilterText(e.target.value);
|
||||
}}
|
||||
onKeyDown={e => {
|
||||
if (e.key === 'Enter') {
|
||||
setIsRunningTest(true);
|
||||
runTests(undefined, [...visibleTestIds]).then(() => {
|
||||
setIsRunningTest(false);
|
||||
});
|
||||
}
|
||||
}}></input>
|
||||
</div>
|
||||
<ListView
|
||||
items={[...entries.values()]}
|
||||
itemKey={(entry: Entry) => entry.test ? entry.test!.id : entry.fileSuite.title }
|
||||
itemRender={(entry: Entry) => entry.test ? entry.test!.titlePath().slice(3).join(' › ') : entry.fileSuite.title }
|
||||
itemRender={(entry: Entry) => {
|
||||
return <div className='hbox watch-mode-list-item'>
|
||||
<div className='watch-mode-list-item-title'>{entry.test ? entry.test!.titlePath().slice(3).join(' › ') : entry.fileSuite.title}</div>
|
||||
<ToolbarButton icon='play' title='Run' onClick={() => runEntry(entry)} disabled={isRunningTest}></ToolbarButton>
|
||||
</div>;
|
||||
}}
|
||||
itemIcon={(entry: Entry) => {
|
||||
if (entry.test) {
|
||||
if (entry.test.results.length && entry.test.results[0].duration)
|
||||
@ -113,15 +140,7 @@ export const WatchModeView: React.FC<{}> = ({
|
||||
}}
|
||||
itemIndent={(entry: Entry) => entry.test ? 1 : 0}
|
||||
selectedItem={selectedEntry}
|
||||
onAccepted={(entry: Entry) => {
|
||||
if (entry.test) {
|
||||
setSelectedTest(entry.test);
|
||||
setIsRunningTest(true);
|
||||
runTests(entry.test ? entry.test.location.file + ':' + entry.test.location.line : entry.fileSuite.title).then(() => {
|
||||
setIsRunningTest(false);
|
||||
});
|
||||
}
|
||||
}}
|
||||
onAccepted={runEntry}
|
||||
onLeftArrow={(entry: Entry) => {
|
||||
expandedFiles.set(entry.fileSuite, false);
|
||||
setSelectedTest(undefined);
|
||||
@ -248,9 +267,9 @@ const receiver = new TeleReporterReceiver({
|
||||
receiver.dispatch(message);
|
||||
};
|
||||
|
||||
async function runTests(location: string): Promise<void> {
|
||||
async function runTests(location: string | undefined, testIds: string[] | undefined): Promise<void> {
|
||||
await (window as any).binding({
|
||||
method: 'run',
|
||||
params: { location }
|
||||
params: { location, testIds }
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user