From e84dd4d7088e316411e708034bff57a3b245081e Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Thu, 2 Nov 2023 20:50:08 -0700 Subject: [PATCH] fix(ui): do not fail on clashing groups (#27943) Fixes https://github.com/microsoft/playwright/issues/27929 --- packages/trace-viewer/src/ui/uiModeView.tsx | 10 +++---- .../playwright-test/ui-mode-test-tree.spec.ts | 28 +++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/packages/trace-viewer/src/ui/uiModeView.tsx b/packages/trace-viewer/src/ui/uiModeView.tsx index cd9754ee51..ca5a911a2a 100644 --- a/packages/trace-viewer/src/ui/uiModeView.tsx +++ b/packages/trace-viewer/src/ui/uiModeView.tsx @@ -856,12 +856,12 @@ function createTree(rootSuite: Suite | undefined, loadErrors: TestError[], proje const visitSuite = (projectName: string, parentSuite: Suite, parentGroup: GroupItem) => { for (const suite of parentSuite.suites) { const title = suite.title || ''; - let group = parentGroup.children.find(item => item.title === title) as GroupItem | undefined; + let group = parentGroup.children.find(item => item.kind === 'group' && item.title === title) as GroupItem | undefined; if (!group) { group = { kind: 'group', subKind: 'describe', - id: parentGroup.id + '\x1e' + title, + id: 'suite:' + parentSuite.titlePath().join('\x1e') + '\x1e' + title, // account for anonymous suites title, location: suite.location!, duration: 0, @@ -877,11 +877,11 @@ function createTree(rootSuite: Suite | undefined, loadErrors: TestError[], proje for (const test of parentSuite.tests) { const title = test.title; - let testCaseItem = parentGroup.children.find(t => t.title === title) as TestCaseItem; + let testCaseItem = parentGroup.children.find(t => t.kind !== 'group' && t.title === title) as TestCaseItem; if (!testCaseItem) { testCaseItem = { kind: 'case', - id: parentGroup.id + '\x1e' + title, + id: 'test:' + test.titlePath().join('\x1e'), title, parent: parentGroup, children: [], @@ -953,7 +953,7 @@ function filterTree(rootItem: GroupItem, filterText: string, statusFilters: Map< if (!tokens.every(token => title.includes(token)) && !testCase.tests.some(t => runningTestIds?.has(t.id))) return false; testCase.children = (testCase.children as TestItem[]).filter(test => { - return !filtersStatuses || runningTestIds?.has(test.id) || statusFilters.get(test.status); + return !filtersStatuses || runningTestIds?.has(test.test.id) || statusFilters.get(test.status); }); testCase.tests = (testCase.children as TestItem[]).map(c => c.test); return !!testCase.children.length; diff --git a/tests/playwright-test/ui-mode-test-tree.spec.ts b/tests/playwright-test/ui-mode-test-tree.spec.ts index db511bd96b..0e0bc01f28 100644 --- a/tests/playwright-test/ui-mode-test-tree.spec.ts +++ b/tests/playwright-test/ui-mode-test-tree.spec.ts @@ -242,3 +242,31 @@ test('should collapse all', async ({ runUITest }) => { ► ◯ a.test.ts `); }); + +test('should resolve title conflicts', async ({ runUITest }) => { + const { page } = await runUITest({ + 'a.test.ts': ` + import { test } from '@playwright/test'; + + test("foo", () => {}); + + test.describe("foo", () => { + test("bar", () => {}); + }); + + test.describe("foo", () => { + test("bar 2", () => {}); + }); + ` + }); + + await page.getByTestId('test-tree').getByText('foo').last().click(); + await page.keyboard.press('ArrowRight'); + await expect.poll(dumpTestTree(page)).toContain(` + ▼ ◯ a.test.ts + ◯ foo + ▼ ◯ foo <= + ◯ bar + ◯ bar 2 + `); +});