| 
									
										
										
										
											2023-03-29 13:57:19 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Copyright (c) Microsoft Corporation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-15 15:11:31 -07:00
										 |  |  | import { test, expect, retries, dumpTestTree } from './ui-mode-fixtures'; | 
					
						
							| 
									
										
										
										
											2024-08-22 05:48:31 -07:00
										 |  |  | import path from 'path'; | 
					
						
							| 
									
										
										
										
											2023-03-29 13:57:19 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-18 11:28:28 -07:00
										 |  |  | test.describe.configure({ mode: 'parallel', retries }); | 
					
						
							| 
									
										
										
										
											2023-03-29 13:57:19 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-30 08:29:49 +02:00
										 |  |  | test('should run global setup and teardown', async ({ runUITest }, testInfo) => { | 
					
						
							| 
									
										
										
										
											2023-03-29 13:57:19 -07:00
										 |  |  |   const { page, testProcess } = await runUITest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       import { defineConfig } from '@playwright/test'; | 
					
						
							|  |  |  |       export default defineConfig({ | 
					
						
							|  |  |  |         globalSetup: './globalSetup', | 
					
						
							|  |  |  |         globalTeardown: './globalTeardown.ts', | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'globalSetup.ts': `
 | 
					
						
							| 
									
										
										
										
											2024-08-30 08:29:49 +02:00
										 |  |  |       import { basename } from "node:path"; | 
					
						
							|  |  |  |       export default (config) => { | 
					
						
							|  |  |  |         console.log('\\n%%from-global-setup'); | 
					
						
							|  |  |  |         console.log("setupOutputDir: " + basename(config.projects[0].outputDir)); | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2023-03-29 13:57:19 -07:00
										 |  |  |     `,
 | 
					
						
							|  |  |  |     'globalTeardown.ts': `
 | 
					
						
							| 
									
										
										
										
											2024-08-30 08:29:49 +02:00
										 |  |  |       export default (config) => { | 
					
						
							|  |  |  |         console.log('\\n%%from-global-teardown'); | 
					
						
							|  |  |  |         console.log('%%' + JSON.stringify(config)); | 
					
						
							|  |  |  |       }; | 
					
						
							| 
									
										
										
										
											2023-03-29 13:57:19 -07:00
										 |  |  |     `,
 | 
					
						
							|  |  |  |     'a.test.js': `
 | 
					
						
							|  |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |       test('should work', async ({}) => {}); | 
					
						
							|  |  |  |     `
 | 
					
						
							| 
									
										
										
										
											2024-08-30 08:29:49 +02:00
										 |  |  |   }, undefined, { additionalArgs: ['--output=foo'] }); | 
					
						
							| 
									
										
										
										
											2023-03-29 13:57:19 -07:00
										 |  |  |   await page.getByTitle('Run all').click(); | 
					
						
							| 
									
										
										
										
											2023-04-28 14:18:46 -07:00
										 |  |  |   await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); | 
					
						
							| 
									
										
										
										
											2024-03-19 13:00:49 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   await page.getByTitle('Toggle output').click(); | 
					
						
							| 
									
										
										
										
											2024-08-30 08:29:49 +02:00
										 |  |  |   const output = page.getByTestId('output'); | 
					
						
							|  |  |  |   await expect(output).toContainText('from-global-setup'); | 
					
						
							|  |  |  |   await expect(output).toContainText('setupOutputDir: foo'); | 
					
						
							| 
									
										
										
										
											2023-03-29 13:57:19 -07:00
										 |  |  |   await page.close(); | 
					
						
							| 
									
										
										
										
											2024-03-19 13:00:49 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-30 08:29:49 +02:00
										 |  |  |   await expect.poll(() => testProcess.outputLines()).toContain('from-global-teardown'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const teardownConfig = JSON.parse(testProcess.outputLines()[1]); | 
					
						
							|  |  |  |   expect(teardownConfig.projects[0].outputDir).toEqual(testInfo.outputPath('foo')); | 
					
						
							| 
									
										
										
										
											2023-03-29 13:57:19 -07:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-22 16:04:59 -07:00
										 |  |  | test('should teardown on sigint', async ({ runUITest, nodeVersion }) => { | 
					
						
							| 
									
										
										
										
											2023-03-29 13:57:19 -07:00
										 |  |  |   test.skip(process.platform === 'win32', 'No sending SIGINT on Windows'); | 
					
						
							| 
									
										
										
										
											2024-03-22 16:04:59 -07:00
										 |  |  |   test.skip(nodeVersion.major < 18); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-29 13:57:19 -07:00
										 |  |  |   const { page, testProcess } = await runUITest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       import { defineConfig } from '@playwright/test'; | 
					
						
							|  |  |  |       export default defineConfig({ | 
					
						
							|  |  |  |         globalSetup: './globalSetup', | 
					
						
							|  |  |  |         globalTeardown: './globalTeardown.ts', | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'globalSetup.ts': `
 | 
					
						
							|  |  |  |       export default () => console.log('\\n%%from-global-setup'); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'globalTeardown.ts': `
 | 
					
						
							|  |  |  |       export default () => console.log('\\n%%from-global-teardown'); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'a.test.js': `
 | 
					
						
							|  |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |       test('should work', async ({}) => {}); | 
					
						
							|  |  |  |     `
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   await page.getByTitle('Run all').click(); | 
					
						
							| 
									
										
										
										
											2023-04-28 14:18:46 -07:00
										 |  |  |   await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); | 
					
						
							| 
									
										
										
										
											2024-03-19 13:00:49 -07:00
										 |  |  |   await page.getByTitle('Toggle output').click(); | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).toContainText('from-global-setup'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-29 13:57:19 -07:00
										 |  |  |   testProcess.process.kill('SIGINT'); | 
					
						
							| 
									
										
										
										
											2023-04-28 14:18:46 -07:00
										 |  |  |   await expect.poll(() => testProcess.outputLines()).toEqual([ | 
					
						
							| 
									
										
										
										
											2023-03-29 13:57:19 -07:00
										 |  |  |     'from-global-teardown', | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2023-07-15 15:11:31 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-24 18:54:48 -07:00
										 |  |  | test('should show errors in config', async ({ runUITest }) => { | 
					
						
							|  |  |  |   const { page } = await runUITest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       import { defineConfig, devices } from '@playwright/test'; | 
					
						
							|  |  |  |       throw new Error("URL is empty") | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   await page.getByText('playwright.config.ts').click(); | 
					
						
							|  |  |  |   await expect(page.getByText('Error: URL is empty')).toBeInViewport(); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-15 15:11:31 -07:00
										 |  |  | const testsWithSetup = { | 
					
						
							|  |  |  |   'playwright.config.ts': `
 | 
					
						
							|  |  |  |     import { defineConfig } from '@playwright/test'; | 
					
						
							|  |  |  |     export default defineConfig({ | 
					
						
							|  |  |  |       projects: [ | 
					
						
							|  |  |  |         { name: 'setup', teardown: 'teardown', testMatch: 'setup.ts' }, | 
					
						
							|  |  |  |         { name: 'test', testMatch: 'test.ts', dependencies: ['setup'] }, | 
					
						
							|  |  |  |         { name: 'teardown', testMatch: 'teardown.ts' }, | 
					
						
							|  |  |  |       ] | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   `,
 | 
					
						
							|  |  |  |   'setup.ts': `
 | 
					
						
							|  |  |  |     import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |     test('setup', async ({}) => { | 
					
						
							|  |  |  |       console.log('from-setup'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   `,
 | 
					
						
							|  |  |  |   'test.ts': `
 | 
					
						
							|  |  |  |     import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |     test('test', async ({}) => { | 
					
						
							|  |  |  |       console.log('from-test'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   `,
 | 
					
						
							|  |  |  |   'teardown.ts': `
 | 
					
						
							|  |  |  |     import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |     test('teardown', async ({}) => { | 
					
						
							|  |  |  |       console.log('from-teardown'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   `,
 | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test('should run setup and teardown projects (1)', async ({ runUITest }) => { | 
					
						
							|  |  |  |   const { page } = await runUITest(testsWithSetup); | 
					
						
							|  |  |  |   await page.getByText('Status:').click(); | 
					
						
							| 
									
										
										
										
											2024-10-18 13:50:43 -07:00
										 |  |  |   await page.getByRole('checkbox', { name: 'setup' }).setChecked(false); | 
					
						
							|  |  |  |   await page.getByRole('checkbox', { name: 'teardown' }).setChecked(false); | 
					
						
							|  |  |  |   await page.getByRole('checkbox', { name: 'test' }).setChecked(false); | 
					
						
							| 
									
										
										
										
											2023-07-15 15:11:31 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 16:13:38 -07:00
										 |  |  |   await expect(page.getByTestId('project-filters')).toMatchAriaSnapshot(`
 | 
					
						
							|  |  |  |     - list: | 
					
						
							|  |  |  |       - listitem: | 
					
						
							|  |  |  |         - checkbox "teardown" | 
					
						
							|  |  |  |       - listitem: | 
					
						
							|  |  |  |         - checkbox "setup" | 
					
						
							|  |  |  |       - listitem: | 
					
						
							|  |  |  |         - checkbox "test" | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-15 15:11:31 -07:00
										 |  |  |   await page.getByTitle('Run all').click(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await expect.poll(dumpTestTree(page)).toBe(`
 | 
					
						
							|  |  |  |     ▼ ✅ setup.ts | 
					
						
							|  |  |  |         ✅ setup | 
					
						
							|  |  |  |     ▼ ✅ teardown.ts | 
					
						
							|  |  |  |         ✅ teardown | 
					
						
							|  |  |  |     ▼ ✅ test.ts | 
					
						
							|  |  |  |         ✅ test | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 16:13:38 -07:00
										 |  |  |   await expect(page.getByTestId('test-tree')).toMatchAriaSnapshot(`
 | 
					
						
							|  |  |  |     - tree: | 
					
						
							|  |  |  |       - treeitem "[icon-check] setup.ts" [expanded]: | 
					
						
							|  |  |  |         - group: | 
					
						
							|  |  |  |           - treeitem ${/\[icon-check\] setup/} | 
					
						
							|  |  |  |       - treeitem "[icon-check] teardown.ts" [expanded]: | 
					
						
							|  |  |  |         - group: | 
					
						
							|  |  |  |           - treeitem ${/\[icon-check\] teardown/} | 
					
						
							|  |  |  |       - treeitem "[icon-check] test.ts" [expanded]: | 
					
						
							|  |  |  |         - group: | 
					
						
							|  |  |  |           - treeitem ${/\[icon-check\] test/} | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-15 15:11:31 -07:00
										 |  |  |   await page.getByTitle('Toggle output').click(); | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).toContainText(`from-setup`); | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).toContainText(`from-test`); | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).toContainText(`from-teardown`); | 
					
						
							| 
									
										
										
										
											2024-10-25 16:13:38 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).toMatchAriaSnapshot(`
 | 
					
						
							|  |  |  |     - textbox "Terminal input" | 
					
						
							|  |  |  |   `);
 | 
					
						
							| 
									
										
										
										
											2023-07-15 15:11:31 -07:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test('should run setup and teardown projects (2)', async ({ runUITest }) => { | 
					
						
							|  |  |  |   const { page } = await runUITest(testsWithSetup); | 
					
						
							|  |  |  |   await page.getByText('Status:').click(); | 
					
						
							| 
									
										
										
										
											2024-10-18 13:50:43 -07:00
										 |  |  |   await page.getByRole('checkbox', { name: 'setup' }).setChecked(false); | 
					
						
							|  |  |  |   await page.getByRole('checkbox', { name: 'teardown' }).setChecked(true); | 
					
						
							|  |  |  |   await page.getByRole('checkbox', { name: 'test' }).setChecked(true); | 
					
						
							| 
									
										
										
										
											2023-07-15 15:11:31 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 16:13:38 -07:00
										 |  |  |   await expect(page.getByTestId('project-filters')).toMatchAriaSnapshot(`
 | 
					
						
							|  |  |  |     - list: | 
					
						
							|  |  |  |       - listitem: | 
					
						
							|  |  |  |         - checkbox "teardown" [checked] | 
					
						
							|  |  |  |       - listitem: | 
					
						
							|  |  |  |         - checkbox "setup" | 
					
						
							|  |  |  |       - listitem: | 
					
						
							|  |  |  |         - checkbox "test" [checked] | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-15 15:11:31 -07:00
										 |  |  |   await page.getByTitle('Run all').click(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await expect.poll(dumpTestTree(page)).toBe(`
 | 
					
						
							|  |  |  |     ▼ ✅ teardown.ts | 
					
						
							|  |  |  |         ✅ teardown | 
					
						
							|  |  |  |     ▼ ✅ test.ts | 
					
						
							|  |  |  |         ✅ test | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 16:13:38 -07:00
										 |  |  |   await expect(page.getByTestId('test-tree')).toMatchAriaSnapshot(`
 | 
					
						
							|  |  |  |     - tree: | 
					
						
							|  |  |  |       - treeitem "[icon-check] teardown.ts" [expanded]: | 
					
						
							|  |  |  |         - group: | 
					
						
							|  |  |  |           - treeitem ${/\[icon-check\] teardown/} | 
					
						
							|  |  |  |       - treeitem "[icon-check] test.ts" [expanded]: | 
					
						
							|  |  |  |         - group: | 
					
						
							|  |  |  |           - treeitem ${/\[icon-check\] test/} | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-15 15:11:31 -07:00
										 |  |  |   await page.getByTitle('Toggle output').click(); | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).toContainText(`from-test`); | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).toContainText(`from-teardown`); | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).not.toContainText(`from-setup`); | 
					
						
							| 
									
										
										
										
											2024-10-25 16:13:38 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).toMatchAriaSnapshot(`
 | 
					
						
							|  |  |  |     - textbox "Terminal input" | 
					
						
							|  |  |  |   `);
 | 
					
						
							| 
									
										
										
										
											2023-07-15 15:11:31 -07:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test('should run setup and teardown projects (3)', async ({ runUITest }) => { | 
					
						
							|  |  |  |   const { page } = await runUITest(testsWithSetup); | 
					
						
							|  |  |  |   await page.getByText('Status:').click(); | 
					
						
							| 
									
										
										
										
											2024-10-18 13:50:43 -07:00
										 |  |  |   await page.getByRole('checkbox', { name: 'setup' }).setChecked(false); | 
					
						
							|  |  |  |   await page.getByRole('checkbox', { name: 'teardown' }).setChecked(false); | 
					
						
							|  |  |  |   await page.getByRole('checkbox', { name: 'test' }).setChecked(true); | 
					
						
							| 
									
										
										
										
											2023-07-15 15:11:31 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 16:13:38 -07:00
										 |  |  |   await expect(page.getByTestId('project-filters')).toMatchAriaSnapshot(`
 | 
					
						
							|  |  |  |     - list: | 
					
						
							|  |  |  |       - listitem: | 
					
						
							|  |  |  |         - checkbox "teardown" | 
					
						
							|  |  |  |       - listitem: | 
					
						
							|  |  |  |         - checkbox "setup" | 
					
						
							|  |  |  |       - listitem: | 
					
						
							|  |  |  |         - checkbox "test" [checked] | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-15 15:11:31 -07:00
										 |  |  |   await page.getByTitle('Run all').click(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await expect.poll(dumpTestTree(page)).toBe(`
 | 
					
						
							|  |  |  |     ▼ ✅ test.ts | 
					
						
							|  |  |  |         ✅ test | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 16:13:38 -07:00
										 |  |  |   await expect(page.getByTestId('test-tree')).toMatchAriaSnapshot(`
 | 
					
						
							|  |  |  |     - tree: | 
					
						
							|  |  |  |       - treeitem "[icon-check] test.ts" [expanded]: | 
					
						
							|  |  |  |         - group: | 
					
						
							|  |  |  |           - treeitem ${/\[icon-check\] test/} | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-15 15:11:31 -07:00
										 |  |  |   await page.getByTitle('Toggle output').click(); | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).toContainText(`from-test`); | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).not.toContainText(`from-setup`); | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).not.toContainText(`from-teardown`); | 
					
						
							| 
									
										
										
										
											2024-10-25 16:13:38 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).toMatchAriaSnapshot(`
 | 
					
						
							|  |  |  |     - textbox "Terminal input" | 
					
						
							|  |  |  |   `);
 | 
					
						
							| 
									
										
										
										
											2023-07-15 15:11:31 -07:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2023-07-17 12:29:16 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | test('should run part of the setup only', async ({ runUITest }) => { | 
					
						
							|  |  |  |   const { page } = await runUITest(testsWithSetup); | 
					
						
							|  |  |  |   await page.getByText('Status:').click(); | 
					
						
							| 
									
										
										
										
											2024-10-18 13:50:43 -07:00
										 |  |  |   await page.getByRole('checkbox', { name: 'setup' }).setChecked(true); | 
					
						
							|  |  |  |   await page.getByRole('checkbox', { name: 'teardown' }).setChecked(true); | 
					
						
							|  |  |  |   await page.getByRole('checkbox', { name: 'test' }).setChecked(true); | 
					
						
							| 
									
										
										
										
											2023-07-17 12:29:16 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-25 16:13:38 -07:00
										 |  |  |   await expect(page.getByTestId('project-filters')).toMatchAriaSnapshot(`
 | 
					
						
							|  |  |  |     - list: | 
					
						
							|  |  |  |       - listitem: | 
					
						
							|  |  |  |         - checkbox "teardown" [checked] | 
					
						
							|  |  |  |       - listitem: | 
					
						
							|  |  |  |         - checkbox "setup" [checked] | 
					
						
							|  |  |  |       - listitem: | 
					
						
							|  |  |  |         - checkbox "test" [checked] | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 12:29:16 -07:00
										 |  |  |   await page.getByText('setup.ts').hover(); | 
					
						
							| 
									
										
										
										
											2024-10-18 13:50:43 -07:00
										 |  |  |   await page.getByRole('treeitem', { name: 'setup.ts' }).getByRole('button', { name: 'Run' }).click(); | 
					
						
							| 
									
										
										
										
											2023-07-17 12:29:16 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   await expect.poll(dumpTestTree(page)).toBe(`
 | 
					
						
							|  |  |  |     ▼ ✅ setup.ts <= | 
					
						
							|  |  |  |         ✅ setup | 
					
						
							|  |  |  |     ▼ ✅ teardown.ts | 
					
						
							|  |  |  |         ✅ teardown | 
					
						
							|  |  |  |     ▼ ◯ test.ts | 
					
						
							|  |  |  |         ◯ test | 
					
						
							|  |  |  |   `);
 | 
					
						
							| 
									
										
										
										
											2024-10-25 16:13:38 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   await expect(page.getByTestId('test-tree')).toMatchAriaSnapshot(`
 | 
					
						
							|  |  |  |     - tree: | 
					
						
							|  |  |  |       - treeitem "[icon-check] setup.ts" [expanded] [selected]: | 
					
						
							|  |  |  |         - button "Run" | 
					
						
							|  |  |  |         - button "Show source" | 
					
						
							|  |  |  |         - button "Watch" | 
					
						
							|  |  |  |         - group: | 
					
						
							|  |  |  |           - treeitem ${/\[icon-check\] setup/} | 
					
						
							|  |  |  |       - treeitem "[icon-check] teardown.ts" [expanded]: | 
					
						
							|  |  |  |         - group: | 
					
						
							|  |  |  |           - treeitem ${/\[icon-check\] teardown/} | 
					
						
							|  |  |  |       - treeitem "[icon-circle-outline] test.ts" [expanded]: | 
					
						
							|  |  |  |         - group: | 
					
						
							|  |  |  |           - treeitem "[icon-circle-outline] test" | 
					
						
							|  |  |  |   `);
 | 
					
						
							| 
									
										
										
										
											2023-07-17 12:29:16 -07:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2023-07-19 17:50:25 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | for (const useWeb of [true, false]) { | 
					
						
							|  |  |  |   test.describe(`web-mode: ${useWeb}`, () => { | 
					
						
							| 
									
										
										
										
											2024-03-22 16:04:59 -07:00
										 |  |  |     test('should run teardown with SIGINT', async ({ runUITest, nodeVersion }) => { | 
					
						
							| 
									
										
										
										
											2023-07-19 17:50:25 +02:00
										 |  |  |       test.skip(process.platform === 'win32', 'No sending SIGINT on Windows'); | 
					
						
							| 
									
										
										
										
											2024-03-22 16:04:59 -07:00
										 |  |  |       test.skip(nodeVersion.major < 18); | 
					
						
							| 
									
										
										
										
											2023-07-19 17:50:25 +02:00
										 |  |  |       const { page, testProcess } = await runUITest({ | 
					
						
							|  |  |  |         'playwright.config.ts': `
 | 
					
						
							|  |  |  |           import { defineConfig } from '@playwright/test'; | 
					
						
							|  |  |  |           export default defineConfig({ | 
					
						
							|  |  |  |             globalTeardown: './globalTeardown.ts', | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'globalTeardown.ts': `
 | 
					
						
							|  |  |  |           export default async () => { | 
					
						
							|  |  |  |             console.log('\\n%%from-global-teardown0000') | 
					
						
							|  |  |  |             await new Promise(f => setTimeout(f, 3000)); | 
					
						
							|  |  |  |             console.log('\\n%%from-global-teardown3000') | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'a.test.js': `
 | 
					
						
							|  |  |  |           import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |           test('should work', async ({}) => {}); | 
					
						
							|  |  |  |         `
 | 
					
						
							|  |  |  |       }, null, { useWeb }); | 
					
						
							|  |  |  |       await page.getByTitle('Run all').click(); | 
					
						
							|  |  |  |       await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); | 
					
						
							|  |  |  |       await testProcess.kill('SIGINT'); | 
					
						
							|  |  |  |       await expect.poll(() => testProcess.outputLines()).toEqual([ | 
					
						
							|  |  |  |         'from-global-teardown0000', | 
					
						
							|  |  |  |         'from-global-teardown3000', | 
					
						
							|  |  |  |       ]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2024-08-22 05:48:31 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test('should restart webserver on reload', async ({ runUITest }) => { | 
					
						
							|  |  |  |   const SIMPLE_SERVER_PATH = path.join(__dirname, 'assets', 'simple-server.js'); | 
					
						
							|  |  |  |   const port = test.info().workerIndex * 2 + 10500; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const { page } = await runUITest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       import { defineConfig } from '@playwright/test'; | 
					
						
							|  |  |  |       export default defineConfig({ | 
					
						
							|  |  |  |         webServer: { | 
					
						
							|  |  |  |           command: 'node ${JSON.stringify(SIMPLE_SERVER_PATH)} ${port}', | 
					
						
							|  |  |  |           port: ${port}, | 
					
						
							|  |  |  |           reuseExistingServer: false, | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'a.test.js': `
 | 
					
						
							|  |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |       test('should work', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2024-10-24 06:03:36 -07:00
										 |  |  |         await page.goto('http://localhost:${port}/hello'); | 
					
						
							| 
									
										
										
										
											2024-08-22 05:48:31 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  |     `
 | 
					
						
							|  |  |  |   }, { DEBUG: 'pw:webserver' }); | 
					
						
							|  |  |  |   await page.getByTitle('Run all').click(); | 
					
						
							|  |  |  |   await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await page.getByTitle('Toggle output').click(); | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).toContainText('[WebServer] listening'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await page.getByTitle('Clear output').click(); | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).not.toContainText('[WebServer] listening'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await page.getByTitle('Reload').click(); | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).toContainText('[WebServer] listening'); | 
					
						
							|  |  |  |   await expect(page.getByTestId('output')).not.toContainText('set reuseExistingServer:true'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await page.getByTitle('Run all').click(); | 
					
						
							|  |  |  |   await expect(page.getByTestId('status-line')).toHaveText('1/1 passed (100%)'); | 
					
						
							|  |  |  | }); |