cherry-pick(#21792): chore(ui): follow up to watch, fix win

This commit is contained in:
Pavel Feldman 2023-03-19 22:52:48 -07:00 committed by Pavel
parent f4f2bdd2ac
commit 940078e06c
5 changed files with 17 additions and 12 deletions

View file

@ -66,7 +66,7 @@ export class MultiTraceModel {
this.events = ([] as EventTraceEvent[]).concat(...contexts.map(c => c.events)); this.events = ([] as EventTraceEvent[]).concat(...contexts.map(c => c.events));
this.hasSource = contexts.some(c => c.hasSource); this.hasSource = contexts.some(c => c.hasSource);
this.actions.sort((a1, a2) => a1.startTime - a2.startTime); this.actions.sort((a1, a2) => (a1.startTime - a2.startTime) || (a1.endTime - a2.endTime));
this.events.sort((a1, a2) => a1.time - a2.time); this.events.sort((a1, a2) => a1.time - a2.time);
this.actions = dedupeActions(this.actions); this.actions = dedupeActions(this.actions);
this.sources = collectSources(this.actions); this.sources = collectSources(this.actions);

View file

@ -192,7 +192,8 @@ export const WatchModeView: React.FC<{}> = ({
runTests={runTests} runTests={runTests}
onItemSelected={setSelectedItem} onItemSelected={setSelectedItem}
setVisibleTestIds={setVisibleTestIds} setVisibleTestIds={setVisibleTestIds}
watchAll={watchAll} /> watchAll={watchAll}
isLoading={isLoading} />
</div> </div>
</SplitView> </SplitView>
</div>; </div>;
@ -276,9 +277,10 @@ const TestList: React.FC<{
runTests: (testIds: string[]) => void, runTests: (testIds: string[]) => void,
runningState?: { testIds: Set<string>, itemSelectedByUser?: boolean }, runningState?: { testIds: Set<string>, itemSelectedByUser?: boolean },
watchAll?: boolean, watchAll?: boolean,
isLoading?: boolean,
setVisibleTestIds: (testIds: string[]) => void, setVisibleTestIds: (testIds: string[]) => void,
onItemSelected: (item: { testCase?: TestCase, location?: Location }) => void, onItemSelected: (item: { testCase?: TestCase, location?: Location }) => void,
}> = ({ statusFilters, projectFilters, filterText, testModel, runTests, runningState, watchAll, onItemSelected, setVisibleTestIds }) => { }> = ({ statusFilters, projectFilters, filterText, testModel, runTests, runningState, watchAll, isLoading, onItemSelected, setVisibleTestIds }) => {
const [treeState, setTreeState] = React.useState<TreeState>({ expandedItems: new Map() }); const [treeState, setTreeState] = React.useState<TreeState>({ expandedItems: new Map() });
const [selectedTreeItemId, setSelectedTreeItemId] = React.useState<string | undefined>(); const [selectedTreeItemId, setSelectedTreeItemId] = React.useState<string | undefined>();
const [watchedTreeIds, setWatchedTreeIds] = React.useState<{ value: Set<string> }>({ value: new Set() }); const [watchedTreeIds, setWatchedTreeIds] = React.useState<{ value: Set<string> }>({ value: new Set() });
@ -420,7 +422,7 @@ const TestList: React.FC<{
setSelectedTreeItemId(treeItem.id); setSelectedTreeItemId(treeItem.id);
}} }}
autoExpandDeep={!!filterText} autoExpandDeep={!!filterText}
noItemsMessage='No tests' />; noItemsMessage={isLoading ? 'Loading\u2026' : 'No tests'} />;
}; };
const TraceView: React.FC<{ const TraceView: React.FC<{
@ -661,7 +663,7 @@ type TreeItem = GroupItem | TestCaseItem | TestItem;
function getFileItem(rootItem: GroupItem, filePath: string[], isFile: boolean, fileItems: Map<string, GroupItem>): GroupItem { function getFileItem(rootItem: GroupItem, filePath: string[], isFile: boolean, fileItems: Map<string, GroupItem>): GroupItem {
if (filePath.length === 0) if (filePath.length === 0)
return rootItem; return rootItem;
const fileName = filePath.join('/'); const fileName = filePath.join(pathSeparator);
const existingFileItem = fileItems.get(fileName); const existingFileItem = fileItems.get(fileName);
if (existingFileItem) if (existingFileItem)
return existingFileItem; return existingFileItem;
@ -763,7 +765,7 @@ function createTree(rootSuite: Suite | undefined, projectFilters: Map<string, bo
if (filterProjects && !projectFilters.get(projectSuite.title)) if (filterProjects && !projectFilters.get(projectSuite.title))
continue; continue;
for (const fileSuite of projectSuite.suites) { for (const fileSuite of projectSuite.suites) {
const fileItem = getFileItem(rootItem, fileSuite.location!.file.split(/[\\\/]/), true, fileMap); const fileItem = getFileItem(rootItem, fileSuite.location!.file.split(pathSeparator), true, fileMap);
visitSuite(projectSuite.title, fileSuite, fileItem); visitSuite(projectSuite.title, fileSuite, fileItem);
} }
} }
@ -805,6 +807,7 @@ function createTree(rootSuite: Suite | undefined, projectFilters: Map<string, bo
let shortRoot = rootItem; let shortRoot = rootItem;
while (shortRoot.children.length === 1 && shortRoot.children[0].kind === 'group' && shortRoot.children[0].subKind === 'folder') while (shortRoot.children.length === 1 && shortRoot.children[0].kind === 'group' && shortRoot.children[0].subKind === 'folder')
shortRoot = shortRoot.children[0]; shortRoot = shortRoot.children[0];
shortRoot.location = rootItem.location;
return shortRoot; return shortRoot;
} }
@ -855,3 +858,5 @@ async function loadSingleTraceFile(url: string): Promise<MultiTraceModel> {
const contextEntries = await response.json() as ContextEntry[]; const contextEntries = await response.json() as ContextEntry[];
return new MultiTraceModel(contextEntries); return new MultiTraceModel(contextEntries);
} }
const pathSeparator = navigator.userAgent.toLowerCase().includes('windows') ? '\\' : '/';

View file

@ -75,9 +75,9 @@ test('should show running progress', async ({ runUITest }) => {
}); });
await page.getByTitle('Run all').click(); await page.getByTitle('Run all').click();
await expect(page.getByTestId('status-line')).toHaveText('Running 1/4 passed (25%)'); await expect(page.getByTestId('status-line')).toHaveText('Running 1/4 passed (25%)', { timeout: 15000 });
await page.getByTitle('Stop').click(); await page.getByTitle('Stop').click();
await expect(page.getByTestId('status-line')).toHaveText('1/4 passed (25%)'); await expect(page.getByTestId('status-line')).toHaveText('1/4 passed (25%)', { timeout: 15000 });
await page.getByTitle('Reload').click(); await page.getByTitle('Reload').click();
await expect(page.getByTestId('status-line')).toBeHidden(); await expect(page.getByTestId('status-line')).toBeHidden();
}); });

View file

@ -128,7 +128,7 @@ test('should batch watch updates', async ({ runUITest, writeFiles }) => {
'd.test.ts': `import { test } from '@playwright/test'; test('test', () => {});`, 'd.test.ts': `import { test } from '@playwright/test'; test('test', () => {});`,
}); });
await expect(page.getByTestId('status-line')).toHaveText('4/4 passed (100%)'); await expect(page.getByTestId('status-line')).toHaveText('4/4 passed (100%)', { timeout: 15000 });
await expect.poll(dumpTestTree(page), { timeout: 15000 }).toBe(` await expect.poll(dumpTestTree(page), { timeout: 15000 }).toBe(`
a.test.ts 👁 a.test.ts 👁
@ -167,7 +167,7 @@ test('should watch all', async ({ runUITest, writeFiles }) => {
'd.test.ts': `import { test } from '@playwright/test'; test('test', () => {});`, 'd.test.ts': `import { test } from '@playwright/test'; test('test', () => {});`,
}); });
await expect(page.getByTestId('status-line')).toHaveText('2/2 passed (100%)'); await expect(page.getByTestId('status-line')).toHaveText('2/2 passed (100%)', { timeout: 15000 });
await expect.poll(dumpTestTree(page), { timeout: 15000 }).toBe(` await expect.poll(dumpTestTree(page), { timeout: 15000 }).toBe(`
a.test.ts a.test.ts
@ -210,7 +210,7 @@ test('should watch new file', async ({ runUITest, writeFiles }) => {
'b.test.ts': ` import { test } from '@playwright/test'; test('test', () => {});`, 'b.test.ts': ` import { test } from '@playwright/test'; test('test', () => {});`,
}); });
await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)', { timeout: 15000 });
await expect.poll(dumpTestTree(page), { timeout: 15000 }).toBe(` await expect.poll(dumpTestTree(page), { timeout: 15000 }).toBe(`
a.test.ts a.test.ts

View file

@ -86,7 +86,7 @@ test('should show snapshots for sync assertions', async ({ runUITest, server })
/page\.setContent[\d.]+m?s/, /page\.setContent[\d.]+m?s/,
/locator\.clickgetByRole\('button'\)[\d.]+m?s/, /locator\.clickgetByRole\('button'\)[\d.]+m?s/,
/expect\.toBe[\d.]+m?s/, /expect\.toBe[\d.]+m?s/,
]); ], { timeout: 15000 });
await expect( await expect(
page.frameLocator('id=snapshot').locator('button'), page.frameLocator('id=snapshot').locator('button'),