| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Copyright Microsoft Corporation. All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 12:35:25 -07:00
										 |  |  | import { test, expect, stripAnsi } from './playwright-test-fixtures'; | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-07 10:41:56 -08:00
										 |  |  | for (const mode of ['legacy', 'default']) { | 
					
						
							|  |  |  |   test.describe(`${mode} mode`, () => { | 
					
						
							|  |  |  |     const env = { PW_TEST_LEGACY_GLOBAL_SETUP_MODE: mode === 'legacy' ? '1' : undefined }; | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-07 10:41:56 -08:00
										 |  |  |     test('globalSetup and globalTeardown should work', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |       const { results, output } = await runInlineTest({ | 
					
						
							|  |  |  |         'playwright.config.ts': `
 | 
					
						
							|  |  |  |           import * as path from 'path'; | 
					
						
							|  |  |  |           module.exports = { | 
					
						
							|  |  |  |             globalSetup: './globalSetup', | 
					
						
							|  |  |  |             globalTeardown: path.join(__dirname, 'globalTeardown.ts'), | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'globalSetup.ts': `
 | 
					
						
							|  |  |  |           module.exports = async () => { | 
					
						
							|  |  |  |             await new Promise(f => setTimeout(f, 100)); | 
					
						
							|  |  |  |             global.value = 42; | 
					
						
							|  |  |  |             process.env.FOO = String(global.value); | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'globalTeardown.ts': `
 | 
					
						
							|  |  |  |           module.exports = async () => { | 
					
						
							|  |  |  |             console.log('teardown=' + global.value); | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'a.test.js': `
 | 
					
						
							|  |  |  |           const { test } = pwt; | 
					
						
							|  |  |  |           test('should work', async ({}, testInfo) => { | 
					
						
							|  |  |  |             expect(process.env.FOO).toBe('42'); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |       }, undefined, env); | 
					
						
							|  |  |  |       expect(results[0].status).toBe('passed'); | 
					
						
							|  |  |  |       expect(output).toContain('teardown=42'); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-07 10:41:56 -08:00
										 |  |  |     test('globalTeardown runs after failures', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |       const { results, output } = await runInlineTest({ | 
					
						
							|  |  |  |         'playwright.config.ts': `
 | 
					
						
							|  |  |  |           import * as path from 'path'; | 
					
						
							|  |  |  |           module.exports = { | 
					
						
							|  |  |  |             globalSetup: 'globalSetup.ts', | 
					
						
							|  |  |  |             globalTeardown: './globalTeardown.ts', | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'globalSetup.ts': `
 | 
					
						
							|  |  |  |           module.exports = async () => { | 
					
						
							|  |  |  |             await new Promise(f => setTimeout(f, 100)); | 
					
						
							|  |  |  |             global.value = 42; | 
					
						
							|  |  |  |             process.env.FOO = String(global.value); | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'globalTeardown.ts': `
 | 
					
						
							|  |  |  |           module.exports = async () => { | 
					
						
							|  |  |  |             console.log('teardown=' + global.value); | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'a.test.js': `
 | 
					
						
							|  |  |  |           const { test } = pwt; | 
					
						
							|  |  |  |           test('should work', async ({}, testInfo) => { | 
					
						
							|  |  |  |             expect(process.env.FOO).toBe('43'); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |       }, undefined, env); | 
					
						
							|  |  |  |       expect(results[0].status).toBe('failed'); | 
					
						
							|  |  |  |       expect(output).toContain('teardown=42'); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-07 10:41:56 -08:00
										 |  |  |     test('globalTeardown does not run when globalSetup times out', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |       test.skip(!!env.PW_TEST_LEGACY_GLOBAL_SETUP_MODE); | 
					
						
							|  |  |  |       const result = await runInlineTest({ | 
					
						
							|  |  |  |         'playwright.config.ts': `
 | 
					
						
							|  |  |  |           import * as path from 'path'; | 
					
						
							|  |  |  |           module.exports = { | 
					
						
							|  |  |  |             globalSetup: './globalSetup.ts', | 
					
						
							|  |  |  |             globalTeardown: 'globalTeardown.ts', | 
					
						
							|  |  |  |             globalTimeout: 1000, | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'globalSetup.ts': `
 | 
					
						
							|  |  |  |           module.exports = async () => { | 
					
						
							|  |  |  |             await new Promise(f => setTimeout(f, 10000)); | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'globalTeardown.ts': `
 | 
					
						
							|  |  |  |           module.exports = async () => { | 
					
						
							|  |  |  |             console.log('teardown='); | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'a.test.js': `
 | 
					
						
							|  |  |  |           const { test } = pwt; | 
					
						
							|  |  |  |           test('should not run', async ({}, testInfo) => { | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |       }, undefined, env); | 
					
						
							|  |  |  |       // We did not run tests, so we should only have 1 skipped test.
 | 
					
						
							|  |  |  |       expect(result.skipped).toBe(1); | 
					
						
							|  |  |  |       expect(result.passed).toBe(0); | 
					
						
							|  |  |  |       expect(result.failed).toBe(0); | 
					
						
							|  |  |  |       expect(result.exitCode).toBe(1); | 
					
						
							|  |  |  |       expect(result.output).not.toContain('teardown='); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-07 10:41:56 -08:00
										 |  |  |     test('globalSetup should work with sync function', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |       const { passed } = await runInlineTest({ | 
					
						
							|  |  |  |         'playwright.config.ts': `
 | 
					
						
							|  |  |  |           import * as path from 'path'; | 
					
						
							|  |  |  |           module.exports = { | 
					
						
							|  |  |  |             globalSetup: './globalSetup.ts', | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'globalSetup.ts': `
 | 
					
						
							|  |  |  |           module.exports = () => { | 
					
						
							|  |  |  |             process.env.FOO = JSON.stringify({ foo: 'bar' }); | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'a.test.js': `
 | 
					
						
							|  |  |  |           const { test } = pwt; | 
					
						
							|  |  |  |           test('should work', async ({}) => { | 
					
						
							|  |  |  |             const value = JSON.parse(process.env.FOO); | 
					
						
							|  |  |  |             expect(value).toEqual({ foo: 'bar' }); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |       }, undefined, env); | 
					
						
							|  |  |  |       expect(passed).toBe(1); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-06-06 17:09:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-01 12:35:25 -07:00
										 |  |  |     test('globalSetup error should prevent tests from executing', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |       const { passed, output } = await runInlineTest({ | 
					
						
							|  |  |  |         'playwright.config.ts': `
 | 
					
						
							|  |  |  |           import * as path from 'path'; | 
					
						
							|  |  |  |           module.exports = { | 
					
						
							|  |  |  |             globalSetup: './globalSetup.ts', | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'globalSetup.ts': `
 | 
					
						
							|  |  |  |           module.exports = () => { | 
					
						
							|  |  |  |             throw new Error('failure in global setup!'); | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'a.test.js': `
 | 
					
						
							|  |  |  |           const { test } = pwt; | 
					
						
							|  |  |  |           test('a', async ({}) => { | 
					
						
							|  |  |  |             console.log('this test ran'); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           test('b', async ({}) => { | 
					
						
							|  |  |  |             console.log('this test ran'); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |       }, { reporter: 'line' }, env); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(stripAnsi(output)).not.toContain('this test ran'); | 
					
						
							|  |  |  |       expect(passed).toBe(0); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-07 10:41:56 -08:00
										 |  |  |     test('globalSetup should throw when passed non-function', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |       const { output } = await runInlineTest({ | 
					
						
							|  |  |  |         'playwright.config.ts': `
 | 
					
						
							|  |  |  |           import * as path from 'path'; | 
					
						
							|  |  |  |           module.exports = { | 
					
						
							|  |  |  |             globalSetup: './globalSetup.ts', | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'globalSetup.ts': `
 | 
					
						
							|  |  |  |           module.exports = 42; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'a.test.js': `
 | 
					
						
							|  |  |  |           const { test } = pwt; | 
					
						
							|  |  |  |           test('should work', async ({}) => { | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |       }, undefined, env); | 
					
						
							|  |  |  |       expect(output).toContain(`globalSetup.ts: globalSetup file must export a single function.`); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-07-20 15:13:40 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-07 10:41:56 -08:00
										 |  |  |     test('globalSetup should work with default export and run the returned fn', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |       const { output, exitCode, passed } = await runInlineTest({ | 
					
						
							|  |  |  |         'playwright.config.ts': `
 | 
					
						
							|  |  |  |           import * as path from 'path'; | 
					
						
							|  |  |  |           module.exports = { | 
					
						
							|  |  |  |             globalSetup: './globalSetup.ts', | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'globalSetup.ts': `
 | 
					
						
							|  |  |  |           function setup() { | 
					
						
							|  |  |  |             let x = 42; | 
					
						
							|  |  |  |             console.log('\\n%%setup: ' + x); | 
					
						
							|  |  |  |             return async () => { | 
					
						
							|  |  |  |               await x; | 
					
						
							|  |  |  |               console.log('\\n%%teardown: ' + x); | 
					
						
							|  |  |  |             }; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |           export default setup; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'a.test.js': `
 | 
					
						
							|  |  |  |           const { test } = pwt; | 
					
						
							|  |  |  |           test('should work', async ({}) => { | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |       }, undefined, env); | 
					
						
							|  |  |  |       expect(passed).toBe(1); | 
					
						
							|  |  |  |       expect(exitCode).toBe(0); | 
					
						
							|  |  |  |       expect(output).toContain(`%%setup: 42`); | 
					
						
							|  |  |  |       expect(output).toContain(`%%teardown: 42`); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-09-01 15:35:46 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-07 10:41:56 -08:00
										 |  |  |     test('globalSetup should allow requiring a package from node_modules', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |       const { results } = await runInlineTest({ | 
					
						
							|  |  |  |         'playwright.config.ts': `
 | 
					
						
							|  |  |  |           import * as path from 'path'; | 
					
						
							|  |  |  |           module.exports = { | 
					
						
							|  |  |  |             globalSetup: 'my-global-setup' | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'node_modules/my-global-setup/index.js': `
 | 
					
						
							|  |  |  |           module.exports = async () => { | 
					
						
							|  |  |  |             await new Promise(f => setTimeout(f, 100)); | 
					
						
							|  |  |  |             global.value = 42; | 
					
						
							|  |  |  |             process.env.FOO = String(global.value); | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |         'a.test.js': `
 | 
					
						
							|  |  |  |           const { test } = pwt; | 
					
						
							|  |  |  |           test('should work', async ({}, testInfo) => { | 
					
						
							|  |  |  |             expect(process.env.FOO).toBe('42'); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         `,
 | 
					
						
							|  |  |  |       }, undefined, env); | 
					
						
							|  |  |  |       expect(results[0].status).toBe('passed'); | 
					
						
							| 
									
										
										
										
											2021-09-13 17:50:31 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-07 10:41:56 -08:00
										 |  |  |     const authFiles = { | 
					
						
							|  |  |  |       'playwright.config.ts': `
 | 
					
						
							|  |  |  |         const config: pwt.PlaywrightTestConfig = { | 
					
						
							|  |  |  |           globalSetup: require.resolve('./auth'), | 
					
						
							|  |  |  |           use: { | 
					
						
							|  |  |  |             baseURL: 'https://www.example.com', | 
					
						
							|  |  |  |             storageState: 'state.json', | 
					
						
							|  |  |  |           }, | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         export default config; | 
					
						
							|  |  |  |       `,
 | 
					
						
							|  |  |  |       'auth.ts': `
 | 
					
						
							|  |  |  |         async function globalSetup(config: pwt.FullConfig) { | 
					
						
							|  |  |  |           const { baseURL, storageState } = config.projects[0].use; | 
					
						
							|  |  |  |           const browser = await pwt.chromium.launch(); | 
					
						
							|  |  |  |           const page = await browser.newPage(); | 
					
						
							|  |  |  |           await page.route('**/*', route => { | 
					
						
							|  |  |  |             route.fulfill({ body: '<html></html>' }).catch(() => {}); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |           await page.goto(baseURL!); | 
					
						
							|  |  |  |           await page.evaluate(() => { | 
					
						
							|  |  |  |             localStorage['name'] = 'value'; | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |           await page.context().storageState({ path: storageState as string }); | 
					
						
							|  |  |  |           await browser.close(); | 
					
						
							|  |  |  |         }; | 
					
						
							|  |  |  |         export default globalSetup; | 
					
						
							|  |  |  |       `,
 | 
					
						
							|  |  |  |       'a.test.ts': `
 | 
					
						
							|  |  |  |         const { test } = pwt; | 
					
						
							|  |  |  |         test('should have storage state', async ({ page }) => { | 
					
						
							|  |  |  |           await page.route('**/*', route => { | 
					
						
							|  |  |  |             route.fulfill({ body: '<html></html>' }).catch(() => {}); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |           await page.goto('/'); | 
					
						
							|  |  |  |           const value = await page.evaluate(() => localStorage['name']); | 
					
						
							|  |  |  |           expect(value).toBe('value'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       `,
 | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     test('globalSetup should work for auth', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |       const result = await runInlineTest(authFiles, undefined, env); | 
					
						
							|  |  |  |       expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |       expect(result.passed).toBe(1); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2021-09-13 17:50:31 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-07 10:41:56 -08:00
										 |  |  |     test('globalSetup auth should compile', async ({ runTSC }) => { | 
					
						
							|  |  |  |       const result = await runTSC(authFiles); | 
					
						
							|  |  |  |       expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } |