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.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.actions = dedupeActions(this.actions);
this.sources = collectSources(this.actions);

View file

@ -192,7 +192,8 @@ export const WatchModeView: React.FC<{}> = ({
runTests={runTests}
onItemSelected={setSelectedItem}
setVisibleTestIds={setVisibleTestIds}
watchAll={watchAll} />
watchAll={watchAll}
isLoading={isLoading} />
</div>
</SplitView>
</div>;
@ -276,9 +277,10 @@ const TestList: React.FC<{
runTests: (testIds: string[]) => void,
runningState?: { testIds: Set<string>, itemSelectedByUser?: boolean },
watchAll?: boolean,
isLoading?: boolean,
setVisibleTestIds: (testIds: string[]) => 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 [selectedTreeItemId, setSelectedTreeItemId] = React.useState<string | undefined>();
const [watchedTreeIds, setWatchedTreeIds] = React.useState<{ value: Set<string> }>({ value: new Set() });
@ -420,7 +422,7 @@ const TestList: React.FC<{
setSelectedTreeItemId(treeItem.id);
}}
autoExpandDeep={!!filterText}
noItemsMessage='No tests' />;
noItemsMessage={isLoading ? 'Loading\u2026' : 'No tests'} />;
};
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 {
if (filePath.length === 0)
return rootItem;
const fileName = filePath.join('/');
const fileName = filePath.join(pathSeparator);
const existingFileItem = fileItems.get(fileName);
if (existingFileItem)
return existingFileItem;
@ -763,7 +765,7 @@ function createTree(rootSuite: Suite | undefined, projectFilters: Map<string, bo
if (filterProjects && !projectFilters.get(projectSuite.title))
continue;
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);
}
}
@ -805,6 +807,7 @@ function createTree(rootSuite: Suite | undefined, projectFilters: Map<string, bo
let shortRoot = rootItem;
while (shortRoot.children.length === 1 && shortRoot.children[0].kind === 'group' && shortRoot.children[0].subKind === 'folder')
shortRoot = shortRoot.children[0];
shortRoot.location = rootItem.location;
return shortRoot;
}
@ -855,3 +858,5 @@ async function loadSingleTraceFile(url: string): Promise<MultiTraceModel> {
const contextEntries = await response.json() as ContextEntry[];
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 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 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 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', () => {});`,
});
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(`
a.test.ts 👁
@ -167,7 +167,7 @@ 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%)');
await expect(page.getByTestId('status-line')).toHaveText('2/2 passed (100%)', { timeout: 15000 });
await expect.poll(dumpTestTree(page), { timeout: 15000 }).toBe(`
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', () => {});`,
});
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(`
a.test.ts

View file

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