cherry-pick(#21792): chore(ui): follow up to watch, fix win
This commit is contained in:
parent
f4f2bdd2ac
commit
940078e06c
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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') ? '\\' : '/';
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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'),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue