| 
									
										
										
										
											2021-11-04 21:08:42 -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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-01 08:52:52 -08:00
										 |  |  | import { test, expect } from './playwright-test-fixtures'; | 
					
						
							| 
									
										
										
										
											2023-02-27 22:31:47 -08:00
										 |  |  | import { parseTrace } from '../config/utils'; | 
					
						
							| 
									
										
										
										
											2021-11-04 21:08:42 -07:00
										 |  |  | import fs from 'fs'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-16 18:17:07 -07:00
										 |  |  | test.describe.configure({ mode: 'parallel' }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 21:08:42 -07:00
										 |  |  | test('should stop tracing with trace: on-first-retry, when not retrying', async ({ runInlineTest }, testInfo) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       module.exports = { use: { trace: 'on-first-retry' } }; | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'a.spec.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2021-11-04 21:08:42 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       test.describe('shared', () => { | 
					
						
							|  |  |  |         let page; | 
					
						
							|  |  |  |         test.beforeAll(async ({ browser }) => { | 
					
						
							|  |  |  |           page = await browser.newPage(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         test.afterAll(async () => { | 
					
						
							|  |  |  |           await page.close(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         test('flaky', async ({}, testInfo) => { | 
					
						
							|  |  |  |           expect(testInfo.retry).toBe(1); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         test('no tracing', async ({}, testInfo) => { | 
					
						
							|  |  |  |           const e = await page.context().tracing.stop({ path: 'ignored' }).catch(e => e); | 
					
						
							|  |  |  |           expect(e.message).toContain('Must start tracing before stopping'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1, retries: 1 }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(1); | 
					
						
							|  |  |  |   expect(result.flaky).toBe(1); | 
					
						
							|  |  |  |   expect(fs.existsSync(testInfo.outputPath('test-results', 'a-shared-flaky-retry1', 'trace.zip'))).toBeTruthy(); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-02-09 08:54:09 -08:00
										 |  |  | test('should record api trace', async ({ runInlineTest, server }, testInfo) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       module.exports = { use: { trace: 'on' } }; | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'a.spec.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2022-02-09 08:54:09 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       test('pass', async ({request, page}, testInfo) => { | 
					
						
							|  |  |  |         await page.goto('about:blank'); | 
					
						
							|  |  |  |         await request.get('${server.EMPTY_PAGE}'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('api pass', async ({playwright}, testInfo) => { | 
					
						
							|  |  |  |         const request = await playwright.request.newContext(); | 
					
						
							|  |  |  |         await request.get('${server.EMPTY_PAGE}'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('fail', async ({request, page}, testInfo) => { | 
					
						
							|  |  |  |         await page.goto('about:blank'); | 
					
						
							|  |  |  |         await request.get('${server.EMPTY_PAGE}'); | 
					
						
							|  |  |  |         expect(1).toBe(2); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(1); | 
					
						
							|  |  |  |   expect(result.passed).toBe(2); | 
					
						
							|  |  |  |   expect(result.failed).toBe(1); | 
					
						
							|  |  |  |   // One trace file for request context and one for each APIRequestContext
 | 
					
						
							| 
									
										
										
										
											2023-02-27 22:31:47 -08:00
										 |  |  |   const trace1 = await parseTrace(testInfo.outputPath('test-results', 'a-pass', 'trace.zip')); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |   expect(trace1.apiNames).toEqual([ | 
					
						
							|  |  |  |     'Before Hooks', | 
					
						
							| 
									
										
										
										
											2023-05-06 10:25:32 -07:00
										 |  |  |     'fixture: request', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'apiRequest.newContext', | 
					
						
							|  |  |  |     'tracing.start', | 
					
						
							| 
									
										
										
										
											2023-05-12 19:15:31 -07:00
										 |  |  |     'fixture: browser', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'browserType.launch', | 
					
						
							| 
									
										
										
										
											2023-05-06 10:25:32 -07:00
										 |  |  |     'fixture: context', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'browser.newContext', | 
					
						
							|  |  |  |     'tracing.start', | 
					
						
							| 
									
										
										
										
											2023-05-06 10:25:32 -07:00
										 |  |  |     'fixture: page', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'browserContext.newPage', | 
					
						
							|  |  |  |     'page.goto', | 
					
						
							|  |  |  |     'apiRequestContext.get', | 
					
						
							|  |  |  |     'After Hooks', | 
					
						
							| 
									
										
										
										
											2023-05-06 10:25:32 -07:00
										 |  |  |     'fixture: page', | 
					
						
							|  |  |  |     'fixture: context', | 
					
						
							|  |  |  |     'fixture: request', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'tracing.stopChunk', | 
					
						
							|  |  |  |     'apiRequestContext.dispose', | 
					
						
							|  |  |  |   ]); | 
					
						
							| 
									
										
										
										
											2023-02-27 22:31:47 -08:00
										 |  |  |   const trace2 = await parseTrace(testInfo.outputPath('test-results', 'a-api-pass', 'trace.zip')); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |   expect(trace2.apiNames).toEqual([ | 
					
						
							|  |  |  |     'Before Hooks', | 
					
						
							|  |  |  |     'apiRequest.newContext', | 
					
						
							|  |  |  |     'tracing.start', | 
					
						
							|  |  |  |     'apiRequestContext.get', | 
					
						
							|  |  |  |     'After Hooks', | 
					
						
							|  |  |  |     'tracing.stopChunk', | 
					
						
							|  |  |  |   ]); | 
					
						
							| 
									
										
										
										
											2023-02-27 22:31:47 -08:00
										 |  |  |   const trace3 = await parseTrace(testInfo.outputPath('test-results', 'a-fail', 'trace.zip')); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |   expect(trace3.apiNames).toEqual([ | 
					
						
							|  |  |  |     'Before Hooks', | 
					
						
							|  |  |  |     'tracing.startChunk', | 
					
						
							| 
									
										
										
										
											2023-05-06 10:25:32 -07:00
										 |  |  |     'fixture: request', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'apiRequest.newContext', | 
					
						
							|  |  |  |     'tracing.start', | 
					
						
							| 
									
										
										
										
											2023-05-06 10:25:32 -07:00
										 |  |  |     'fixture: context', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'browser.newContext', | 
					
						
							|  |  |  |     'tracing.start', | 
					
						
							| 
									
										
										
										
											2023-05-06 10:25:32 -07:00
										 |  |  |     'fixture: page', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'browserContext.newPage', | 
					
						
							|  |  |  |     'page.goto', | 
					
						
							|  |  |  |     'apiRequestContext.get', | 
					
						
							|  |  |  |     'expect.toBe', | 
					
						
							|  |  |  |     'After Hooks', | 
					
						
							| 
									
										
										
										
											2023-05-06 10:25:32 -07:00
										 |  |  |     'fixture: page', | 
					
						
							|  |  |  |     'fixture: context', | 
					
						
							|  |  |  |     'fixture: request', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'tracing.stopChunk', | 
					
						
							|  |  |  |     'apiRequestContext.dispose', | 
					
						
							|  |  |  |     'tracing.stopChunk', | 
					
						
							|  |  |  |   ]); | 
					
						
							| 
									
										
										
										
											2022-02-09 08:54:09 -08:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-04 21:08:42 -07:00
										 |  |  | test('should not throw with trace: on-first-retry and two retries in the same worker', async ({ runInlineTest }, testInfo) => { | 
					
						
							|  |  |  |   const files = {}; | 
					
						
							|  |  |  |   for (let i = 0; i < 6; i++) { | 
					
						
							|  |  |  |     files[`a${i}.spec.ts`] = `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from './helper'; | 
					
						
							| 
									
										
										
										
											2021-11-04 21:08:42 -07:00
										 |  |  |       test('flaky', async ({ myContext }, testInfo) => { | 
					
						
							|  |  |  |         await new Promise(f => setTimeout(f, 200 + Math.round(Math.random() * 1000))); | 
					
						
							|  |  |  |         expect(testInfo.retry).toBe(1); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       test('passing', async ({ myContext }, testInfo) => { | 
					
						
							|  |  |  |         await new Promise(f => setTimeout(f, 200 + Math.round(Math.random() * 1000))); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `;
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     ...files, | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       module.exports = { use: { trace: 'on-first-retry' } }; | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'helper.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test as base } from '@playwright/test'; | 
					
						
							|  |  |  |       export * from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2021-11-04 21:08:42 -07:00
										 |  |  |       export const test = base.extend({ | 
					
						
							|  |  |  |         myContext: [async ({ browser }, use) => { | 
					
						
							|  |  |  |           const c = await browser.newContext(); | 
					
						
							|  |  |  |           await use(c); | 
					
						
							|  |  |  |           await c.close(); | 
					
						
							|  |  |  |         }, { scope: 'worker' }] | 
					
						
							|  |  |  |       }) | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 3, retries: 1 }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(6); | 
					
						
							|  |  |  |   expect(result.flaky).toBe(6); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-31 17:29:39 -07:00
										 |  |  | test('should not mixup network files between contexts', async ({ runInlineTest, server }, testInfo) => { | 
					
						
							|  |  |  |   // NOTE: this test reproduces the issue 10% of the time. Running with --repeat-each=20 helps.
 | 
					
						
							|  |  |  |   test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/22089' }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       export default { use: { trace: 'on' } }; | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'a.spec.ts': `
 | 
					
						
							|  |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       let page1, page2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test.beforeAll(async ({ browser }) => { | 
					
						
							|  |  |  |         page1 = await browser.newPage(); | 
					
						
							|  |  |  |         await page1.goto("${server.EMPTY_PAGE}"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         page2 = await browser.newPage(); | 
					
						
							|  |  |  |         await page2.goto("${server.EMPTY_PAGE}"); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test.afterAll(async () => { | 
					
						
							|  |  |  |         await page1.close(); | 
					
						
							|  |  |  |         await page2.close(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('example', async ({ page }) => { | 
					
						
							|  |  |  |         await page.goto("${server.EMPTY_PAGE}"); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1, timeout: 15000 }); | 
					
						
							|  |  |  |   expect(result.exitCode).toEqual(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(1); | 
					
						
							|  |  |  |   expect(fs.existsSync(testInfo.outputPath('test-results', 'a-example', 'trace.zip'))).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-08 15:39:58 -08:00
										 |  |  | test('should save sources when requested', async ({ runInlineTest }, testInfo) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       module.exports = { | 
					
						
							|  |  |  |         use: { | 
					
						
							|  |  |  |           trace: 'on', | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'a.spec.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2021-11-08 15:39:58 -08:00
										 |  |  |       test('pass', async ({ page }) => { | 
					
						
							|  |  |  |         await page.evaluate(2 + 2); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }); | 
					
						
							|  |  |  |   expect(result.exitCode).toEqual(0); | 
					
						
							| 
									
										
										
										
											2023-02-27 22:31:47 -08:00
										 |  |  |   const { resources } = await parseTrace(testInfo.outputPath('test-results', 'a-pass', 'trace.zip')); | 
					
						
							|  |  |  |   expect([...resources.keys()].filter(name => name.startsWith('resources/src@'))).toHaveLength(1); | 
					
						
							| 
									
										
										
										
											2021-11-08 15:39:58 -08:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test('should not save sources when not requested', async ({ runInlineTest }, testInfo) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       module.exports = { | 
					
						
							|  |  |  |         use: { | 
					
						
							|  |  |  |           trace: { | 
					
						
							|  |  |  |             mode: 'on', | 
					
						
							|  |  |  |             sources: false, | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'a.spec.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2021-11-08 15:39:58 -08:00
										 |  |  |       test('pass', async ({ page }) => { | 
					
						
							|  |  |  |         await page.evaluate(2 + 2); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }); | 
					
						
							|  |  |  |   expect(result.exitCode).toEqual(0); | 
					
						
							| 
									
										
										
										
											2023-02-27 22:31:47 -08:00
										 |  |  |   const { resources } = await parseTrace(testInfo.outputPath('test-results', 'a-pass', 'trace.zip')); | 
					
						
							|  |  |  |   expect([...resources.keys()].filter(name => name.startsWith('resources/src@'))).toHaveLength(0); | 
					
						
							| 
									
										
										
										
											2021-11-08 15:39:58 -08:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-13 11:17:20 +01:00
										 |  |  | test('should work in serial mode', async ({ runInlineTest }, testInfo) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       module.exports = { use: { trace: 'retain-on-failure' } }; | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'a.spec.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2022-05-13 11:17:20 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |       test.describe.serial('serial', () => { | 
					
						
							|  |  |  |         let page; | 
					
						
							|  |  |  |         test.beforeAll(async ({ browser }) => { | 
					
						
							|  |  |  |           page = await browser.newPage(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         test.afterAll(async () => { | 
					
						
							|  |  |  |           await page.close(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         test('passes', async ({}, testInfo) => { | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         test('fails', async ({}, testInfo) => { | 
					
						
							|  |  |  |           throw new Error('oh my'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(1); | 
					
						
							|  |  |  |   expect(result.passed).toBe(1); | 
					
						
							|  |  |  |   expect(result.failed).toBe(1); | 
					
						
							|  |  |  |   expect(fs.existsSync(testInfo.outputPath('test-results', 'a-serial-passes', 'trace.zip'))).toBeFalsy(); | 
					
						
							|  |  |  |   expect(fs.existsSync(testInfo.outputPath('test-results', 'a-serial-fails', 'trace.zip'))).toBeTruthy(); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-31 15:21:51 -07:00
										 |  |  | test('should not override trace file in afterAll', async ({ runInlineTest, server }, testInfo) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       module.exports = { use: { trace: 'retain-on-failure' } }; | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'a.spec.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2022-05-31 15:21:51 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       test('test 1', async ({ page }) => { | 
					
						
							|  |  |  |         await page.goto('about:blank'); | 
					
						
							|  |  |  |         throw 'oh no!'; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // Another test in the same file to affect after hooks order.
 | 
					
						
							| 
									
										
										
										
											2023-02-27 22:31:47 -08:00
										 |  |  |       test('test 2', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2022-05-31 15:21:51 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test.afterAll(async ({ request }) => { | 
					
						
							|  |  |  |         await request.get('${server.EMPTY_PAGE}'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(1); | 
					
						
							|  |  |  |   expect(result.passed).toBe(1); | 
					
						
							|  |  |  |   expect(result.failed).toBe(1); | 
					
						
							| 
									
										
										
										
											2023-02-27 22:31:47 -08:00
										 |  |  |   const trace1 = await parseTrace(testInfo.outputPath('test-results', 'a-test-1', 'trace.zip')); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   expect(trace1.apiNames).toEqual([ | 
					
						
							|  |  |  |     'Before Hooks', | 
					
						
							| 
									
										
										
										
											2023-05-12 19:15:31 -07:00
										 |  |  |     'fixture: browser', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'browserType.launch', | 
					
						
							| 
									
										
										
										
											2023-05-06 10:25:32 -07:00
										 |  |  |     'fixture: context', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'browser.newContext', | 
					
						
							|  |  |  |     'tracing.start', | 
					
						
							| 
									
										
										
										
											2023-05-06 10:25:32 -07:00
										 |  |  |     'fixture: page', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'browserContext.newPage', | 
					
						
							|  |  |  |     'page.goto', | 
					
						
							|  |  |  |     'After Hooks', | 
					
						
							| 
									
										
										
										
											2023-05-06 10:25:32 -07:00
										 |  |  |     'fixture: page', | 
					
						
							|  |  |  |     'fixture: context', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'afterAll hook', | 
					
						
							| 
									
										
										
										
											2023-05-06 10:25:32 -07:00
										 |  |  |     'fixture: request', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'apiRequest.newContext', | 
					
						
							|  |  |  |     'tracing.start', | 
					
						
							|  |  |  |     'apiRequestContext.get', | 
					
						
							| 
									
										
										
										
											2023-05-06 10:25:32 -07:00
										 |  |  |     'fixture: request', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'tracing.stopChunk', | 
					
						
							|  |  |  |     'apiRequestContext.dispose', | 
					
						
							| 
									
										
										
										
											2023-05-12 19:15:31 -07:00
										 |  |  |     'fixture: browser', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |   ]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-27 22:31:47 -08:00
										 |  |  |   const error = await parseTrace(testInfo.outputPath('test-results', 'a-test-2', 'trace.zip')).catch(e => e); | 
					
						
							|  |  |  |   expect(error).toBeTruthy(); | 
					
						
							| 
									
										
										
										
											2022-05-31 15:21:51 -07:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-03 15:25:25 -07:00
										 |  |  | test('should retain traces for interrupted tests', async ({ runInlineTest }, testInfo) => { | 
					
						
							| 
									
										
										
										
											2022-07-19 13:50:52 -07:00
										 |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       module.exports = { use: { trace: 'retain-on-failure' }, maxFailures: 1 }; | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'a.spec.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |       test('test 1', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2022-08-04 09:18:18 -07:00
										 |  |  |         await page.waitForTimeout(2000); | 
					
						
							| 
									
										
										
										
											2022-07-19 13:50:52 -07:00
										 |  |  |         expect(1).toBe(2); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'b.spec.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |       test('test 2', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2022-07-19 13:50:52 -07:00
										 |  |  |         await page.goto('about:blank'); | 
					
						
							| 
									
										
										
										
											2022-08-04 09:18:18 -07:00
										 |  |  |         await page.waitForTimeout(5000); | 
					
						
							| 
									
										
										
										
											2022-07-19 13:50:52 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 2 }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(1); | 
					
						
							|  |  |  |   expect(result.failed).toBe(1); | 
					
						
							| 
									
										
										
										
											2022-08-03 15:25:25 -07:00
										 |  |  |   expect(result.interrupted).toBe(1); | 
					
						
							| 
									
										
										
										
											2022-07-19 13:50:52 -07:00
										 |  |  |   expect(fs.existsSync(testInfo.outputPath('test-results', 'a-test-1', 'trace.zip'))).toBeTruthy(); | 
					
						
							| 
									
										
										
										
											2022-08-03 15:25:25 -07:00
										 |  |  |   expect(fs.existsSync(testInfo.outputPath('test-results', 'b-test-2', 'trace.zip'))).toBeTruthy(); | 
					
						
							| 
									
										
										
										
											2022-07-19 13:50:52 -07:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2022-05-31 15:21:51 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-05 09:20:39 -07:00
										 |  |  | test('should respect --trace', async ({ runInlineTest }, testInfo) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'a.spec.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |       test('test 1', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2022-08-05 09:20:39 -07:00
										 |  |  |         await page.goto('about:blank'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { trace: 'on' }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(1); | 
					
						
							|  |  |  |   expect(fs.existsSync(testInfo.outputPath('test-results', 'a-test-1', 'trace.zip'))).toBeTruthy(); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2023-03-29 13:35:31 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | test('should respect PW_TEST_DISABLE_TRACING', async ({ runInlineTest }, testInfo) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       export default { use: { trace: 'on' } }; | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'a.spec.ts': `
 | 
					
						
							|  |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |       test('test 1', async ({ page }) => { | 
					
						
							|  |  |  |         await page.goto('about:blank'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, {}, { PW_TEST_DISABLE_TRACING: '1' }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(1); | 
					
						
							|  |  |  |   expect(fs.existsSync(testInfo.outputPath('test-results', 'a-test-1', 'trace.zip'))).toBe(false); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2023-04-10 13:29:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | for (const mode of ['off', 'retain-on-failure', 'on-first-retry', 'on-all-retries']) { | 
					
						
							|  |  |  |   test(`trace:${mode} should not create trace zip artifact if page test passed`, async ({ runInlineTest }) => { | 
					
						
							|  |  |  |     const result = await runInlineTest({ | 
					
						
							|  |  |  |       'a.spec.ts': `
 | 
					
						
							|  |  |  |         import { test as base, expect } from '@playwright/test'; | 
					
						
							|  |  |  |         import fs from 'fs'; | 
					
						
							|  |  |  |         const test = base.extend<{ | 
					
						
							|  |  |  |           locale: string | undefined, | 
					
						
							|  |  |  |           _artifactsDir: () => string, | 
					
						
							|  |  |  |         }>({ | 
					
						
							|  |  |  |           // Override locale fixture to check in teardown that no temporary trace zip was created.
 | 
					
						
							|  |  |  |           locale: [async ({ locale, _artifactsDir }, use) => { | 
					
						
							|  |  |  |             await use(locale); | 
					
						
							|  |  |  |             const entries =  fs.readdirSync(_artifactsDir()); | 
					
						
							|  |  |  |             expect(entries.filter(e => e.endsWith('.zip'))).toEqual([]); | 
					
						
							|  |  |  |           }, { option: true }], | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         test('passing test', async ({ page }) => { | 
					
						
							|  |  |  |           await page.goto('about:blank'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       `,
 | 
					
						
							|  |  |  |     }, { trace: 'retain-on-failure' }); | 
					
						
							|  |  |  |     expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |     expect(result.passed).toBe(1); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   test(`trace:${mode} should not create trace zip artifact if APIRequestContext test passed`, async ({ runInlineTest, server }) => { | 
					
						
							|  |  |  |     const result = await runInlineTest({ | 
					
						
							|  |  |  |       'a.spec.ts': `
 | 
					
						
							|  |  |  |         import { test as base, expect } from '@playwright/test'; | 
					
						
							|  |  |  |         import fs from 'fs'; | 
					
						
							|  |  |  |         const test = base.extend<{ | 
					
						
							|  |  |  |           locale: string | undefined, | 
					
						
							|  |  |  |           _artifactsDir: () => string, | 
					
						
							|  |  |  |         }>({ | 
					
						
							|  |  |  |           // Override locale fixture to check in teardown that no temporary trace zip was created.
 | 
					
						
							|  |  |  |           locale: [async ({ locale, _artifactsDir }, use) => { | 
					
						
							|  |  |  |             await use(locale); | 
					
						
							|  |  |  |             const entries =  fs.readdirSync(_artifactsDir()); | 
					
						
							|  |  |  |             expect(entries.filter(e => e.endsWith('.zip'))).toEqual([]); | 
					
						
							|  |  |  |           }, { option: true }], | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         test('passing test', async ({ request }) => { | 
					
						
							|  |  |  |           expect(await request.get('${server.EMPTY_PAGE}')).toBeOK(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       `,
 | 
					
						
							|  |  |  |     }, { trace: 'retain-on-failure' }); | 
					
						
							|  |  |  |     expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |     expect(result.passed).toBe(1); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2023-04-18 09:02:33 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test(`trace:retain-on-failure should create trace if context is closed before failure in the test`, async ({ runInlineTest }) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       module.exports = { use: { trace: 'retain-on-failure' } }; | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'a.spec.ts': `
 | 
					
						
							|  |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |       test('passing test', async ({ page, context }) => { | 
					
						
							|  |  |  |         await page.goto('about:blank'); | 
					
						
							|  |  |  |         await context.close(); | 
					
						
							|  |  |  |         expect(1).toBe(2); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { trace: 'retain-on-failure' }); | 
					
						
							|  |  |  |   const tracePath = test.info().outputPath('test-results', 'a-passing-test', 'trace.zip'); | 
					
						
							|  |  |  |   const trace = await parseTrace(tracePath); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |   expect(trace.apiNames).toContain('page.goto'); | 
					
						
							| 
									
										
										
										
											2023-04-18 09:02:33 -07:00
										 |  |  |   expect(result.failed).toBe(1); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test(`trace:retain-on-failure should create trace if context is closed before failure in afterEach`, async ({ runInlineTest }) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       module.exports = { use: { trace: 'retain-on-failure' } }; | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'a.spec.ts': `
 | 
					
						
							|  |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |       test('passing test', async ({ page, context }) => { | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       test.afterEach(async ({ page, context }) => { | 
					
						
							|  |  |  |         await page.goto('about:blank'); | 
					
						
							|  |  |  |         await context.close(); | 
					
						
							|  |  |  |         expect(1).toBe(2); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { trace: 'retain-on-failure' }); | 
					
						
							|  |  |  |   const tracePath = test.info().outputPath('test-results', 'a-passing-test', 'trace.zip'); | 
					
						
							|  |  |  |   const trace = await parseTrace(tracePath); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |   expect(trace.apiNames).toContain('page.goto'); | 
					
						
							| 
									
										
										
										
											2023-04-18 09:02:33 -07:00
										 |  |  |   expect(result.failed).toBe(1); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test(`trace:retain-on-failure should create trace if request context is disposed before failure`, async ({ runInlineTest, server }) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       module.exports = { use: { trace: 'retain-on-failure' } }; | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'a.spec.ts': `
 | 
					
						
							|  |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |       test('passing test', async ({ request }) => { | 
					
						
							|  |  |  |         expect(await request.get('${server.EMPTY_PAGE}')).toBeOK(); | 
					
						
							|  |  |  |         await request.dispose(); | 
					
						
							|  |  |  |         expect(1).toBe(2); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { trace: 'retain-on-failure' }); | 
					
						
							|  |  |  |   const tracePath = test.info().outputPath('test-results', 'a-passing-test', 'trace.zip'); | 
					
						
							|  |  |  |   const trace = await parseTrace(tracePath); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |   expect(trace.apiNames).toContain('apiRequestContext.get'); | 
					
						
							| 
									
										
										
										
											2023-04-18 09:02:33 -07:00
										 |  |  |   expect(result.failed).toBe(1); | 
					
						
							|  |  |  | }); |