mirror of
				https://github.com/microsoft/playwright.git
				synced 2025-06-26 21:40:17 +00:00 
			
		
		
		
	chore: allow sibling describes with the same name (#21967)
Fixes https://github.com/microsoft/playwright/issues/21953
This commit is contained in:
		
							parent
							
								
									79d55b959b
								
							
						
					
					
						commit
						add948cdd0
					
				| @ -154,7 +154,6 @@ export class TeleReporterReceiver { | |||||||
| 
 | 
 | ||||||
|   private _onBegin(config: JsonConfig, projects: JsonProject[]) { |   private _onBegin(config: JsonConfig, projects: JsonProject[]) { | ||||||
|     this._rootDir = config.rootDir; |     this._rootDir = config.rootDir; | ||||||
|     const removeMissing = config.listOnly; |  | ||||||
|     for (const project of projects) { |     for (const project of projects) { | ||||||
|       let projectSuite = this._rootSuite.suites.find(suite => suite.project()!.id === project.id); |       let projectSuite = this._rootSuite.suites.find(suite => suite.project()!.id === project.id); | ||||||
|       if (!projectSuite) { |       if (!projectSuite) { | ||||||
| @ -164,7 +163,24 @@ export class TeleReporterReceiver { | |||||||
|       } |       } | ||||||
|       const p = this._parseProject(project); |       const p = this._parseProject(project); | ||||||
|       projectSuite.project = () => p; |       projectSuite.project = () => p; | ||||||
|       this._mergeSuitesInto(project.suites, projectSuite, removeMissing); |       this._mergeSuitesInto(project.suites, projectSuite); | ||||||
|  | 
 | ||||||
|  |       // Remove deleted tests when listing. Empty suites will be auto-filtered
 | ||||||
|  |       // in the UI layer.
 | ||||||
|  |       if (config.listOnly) { | ||||||
|  |         const testIds = new Set<string>(); | ||||||
|  |         const collectIds = (suite: JsonSuite) => { | ||||||
|  |           suite.tests.map(t => t.testId).forEach(testId => testIds.add(testId)); | ||||||
|  |           suite.suites.forEach(collectIds); | ||||||
|  |         }; | ||||||
|  |         project.suites.forEach(collectIds); | ||||||
|  | 
 | ||||||
|  |         const filterTests = (suite: TeleSuite) => { | ||||||
|  |           suite.tests = suite.tests.filter(t => testIds.has(t.id)); | ||||||
|  |           suite.suites.forEach(filterTests); | ||||||
|  |         }; | ||||||
|  |         filterTests(projectSuite); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|     this._reporter.onBegin?.(this._parseConfig(config), this._rootSuite); |     this._reporter.onBegin?.(this._parseConfig(config), this._rootSuite); | ||||||
|   } |   } | ||||||
| @ -266,7 +282,7 @@ export class TeleReporterReceiver { | |||||||
|     }; |     }; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   private _mergeSuitesInto(jsonSuites: JsonSuite[], parent: TeleSuite, removeMissing: boolean) { |   private _mergeSuitesInto(jsonSuites: JsonSuite[], parent: TeleSuite) { | ||||||
|     for (const jsonSuite of jsonSuites) { |     for (const jsonSuite of jsonSuites) { | ||||||
|       let targetSuite = parent.suites.find(s => s.title === jsonSuite.title); |       let targetSuite = parent.suites.find(s => s.title === jsonSuite.title); | ||||||
|       if (!targetSuite) { |       if (!targetSuite) { | ||||||
| @ -277,16 +293,12 @@ export class TeleReporterReceiver { | |||||||
|       targetSuite.location = this._absoluteLocation(jsonSuite.location); |       targetSuite.location = this._absoluteLocation(jsonSuite.location); | ||||||
|       targetSuite._fileId = jsonSuite.fileId; |       targetSuite._fileId = jsonSuite.fileId; | ||||||
|       targetSuite._parallelMode = jsonSuite.parallelMode; |       targetSuite._parallelMode = jsonSuite.parallelMode; | ||||||
|       this._mergeSuitesInto(jsonSuite.suites, targetSuite, removeMissing); |       this._mergeSuitesInto(jsonSuite.suites, targetSuite); | ||||||
|       this._mergeTestsInto(jsonSuite.tests, targetSuite, removeMissing); |       this._mergeTestsInto(jsonSuite.tests, targetSuite); | ||||||
|     } |  | ||||||
|     if (removeMissing) { |  | ||||||
|       const suiteMap = new Map(parent.suites.map(p => [p.title, p])); |  | ||||||
|       parent.suites = jsonSuites.map(s => suiteMap.get(s.title)).filter(Boolean) as TeleSuite[]; |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   private _mergeTestsInto(jsonTests: JsonTestCase[], parent: TeleSuite, removeMissing: boolean) { |   private _mergeTestsInto(jsonTests: JsonTestCase[], parent: TeleSuite) { | ||||||
|     for (const jsonTest of jsonTests) { |     for (const jsonTest of jsonTests) { | ||||||
|       let targetTest = parent.tests.find(s => s.title === jsonTest.title); |       let targetTest = parent.tests.find(s => s.title === jsonTest.title); | ||||||
|       if (!targetTest) { |       if (!targetTest) { | ||||||
| @ -297,10 +309,6 @@ export class TeleReporterReceiver { | |||||||
|       } |       } | ||||||
|       this._updateTest(jsonTest, targetTest); |       this._updateTest(jsonTest, targetTest); | ||||||
|     } |     } | ||||||
|     if (removeMissing) { |  | ||||||
|       const testMap = new Map(parent.tests.map(p => [p.title, p])); |  | ||||||
|       parent.tests = jsonTests.map(s => testMap.get(s.title)).filter(Boolean) as TeleTestCase[]; |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   private _updateTest(payload: JsonTestCase, test: TeleTestCase): TeleTestCase { |   private _updateTest(payload: JsonTestCase, test: TeleTestCase): TeleTestCase { | ||||||
|  | |||||||
| @ -735,7 +735,7 @@ function createTree(rootSuite: Suite | undefined, projectFilters: Map<string, bo | |||||||
| 
 | 
 | ||||||
|   const visitSuite = (projectName: string, parentSuite: Suite, parentGroup: GroupItem) => { |   const visitSuite = (projectName: string, parentSuite: Suite, parentGroup: GroupItem) => { | ||||||
|     for (const suite of parentSuite.suites) { |     for (const suite of parentSuite.suites) { | ||||||
|       const title = suite.title; |       const title = suite.title || '<anonymous>'; | ||||||
|       let group = parentGroup.children.find(item => item.title === title) as GroupItem | undefined; |       let group = parentGroup.children.find(item => item.title === title) as GroupItem | undefined; | ||||||
|       if (!group) { |       if (!group) { | ||||||
|         group = { |         group = { | ||||||
|  | |||||||
| @ -142,3 +142,83 @@ test('should merge folder trees', async ({ runUITest }) => { | |||||||
|         ◯ passes |         ◯ passes | ||||||
|   `);
 |   `);
 | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | test('should list parametrized tests', async ({ runUITest }) => { | ||||||
|  |   const page = await runUITest({ | ||||||
|  |     'a.test.ts': ` | ||||||
|  |       import { test } from '@playwright/test'; | ||||||
|  |       test.describe('cookies', () => { | ||||||
|  |         for (const country of ['FR', 'DE', 'LT']) { | ||||||
|  |           test.describe(() => { | ||||||
|  |             test('test ' + country, async ({}) => {}); | ||||||
|  |           }); | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     ` | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   await page.getByText('cookies').click(); | ||||||
|  |   await page.keyboard.press('ArrowRight'); | ||||||
|  |   await page.getByText('<anonymous>').click(); | ||||||
|  |   await page.keyboard.press('ArrowRight'); | ||||||
|  | 
 | ||||||
|  |   await expect.poll(dumpTestTree(page), { timeout: 15000 }).toBe(` | ||||||
|  |     ▼ ◯ a.test.ts | ||||||
|  |       ▼ ◯ cookies | ||||||
|  |         ▼ ◯ <anonymous> <= | ||||||
|  |             ◯ test FR | ||||||
|  |             ◯ test DE | ||||||
|  |             ◯ test LT | ||||||
|  |   `);
 | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test('should update parametrized tests', async ({ runUITest, writeFiles }) => { | ||||||
|  |   const page = await runUITest({ | ||||||
|  |     'a.test.ts': ` | ||||||
|  |       import { test } from '@playwright/test'; | ||||||
|  |       test.describe('cookies', () => { | ||||||
|  |         for (const country of ['FR', 'DE', 'LT']) { | ||||||
|  |           test.describe(() => { | ||||||
|  |             test('test ' + country, async ({}) => {}); | ||||||
|  |           }); | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     ` | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   await page.getByText('cookies').click(); | ||||||
|  |   await page.keyboard.press('ArrowRight'); | ||||||
|  |   await page.getByText('<anonymous>').click(); | ||||||
|  |   await page.keyboard.press('ArrowRight'); | ||||||
|  | 
 | ||||||
|  |   await expect.poll(dumpTestTree(page), { timeout: 15000 }).toBe(` | ||||||
|  |     ▼ ◯ a.test.ts | ||||||
|  |       ▼ ◯ cookies | ||||||
|  |         ▼ ◯ <anonymous> <= | ||||||
|  |             ◯ test FR | ||||||
|  |             ◯ test DE | ||||||
|  |             ◯ test LT | ||||||
|  |   `);
 | ||||||
|  | 
 | ||||||
|  |   writeFiles({ | ||||||
|  |     'a.test.ts': ` | ||||||
|  |       import { test } from '@playwright/test'; | ||||||
|  |       test.describe('cookies', () => { | ||||||
|  |         for (const country of ['FR', 'LT']) { | ||||||
|  |           test.describe(() => { | ||||||
|  |             test('test ' + country, async ({}) => {}); | ||||||
|  |           }); | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     ` | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |   await expect.poll(dumpTestTree(page), { timeout: 15000 }).toBe(` | ||||||
|  |     ▼ ◯ a.test.ts | ||||||
|  |       ▼ ◯ cookies | ||||||
|  |         ▼ ◯ <anonymous> <= | ||||||
|  |             ◯ test FR | ||||||
|  |             ◯ test LT | ||||||
|  |   `);
 | ||||||
|  | }); | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Pavel Feldman
						Pavel Feldman