| 
									
										
										
										
											2022-09-07 19:15:04 -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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import { test, expect } from './playwright-test-fixtures'; | 
					
						
							| 
									
										
										
										
											2023-01-04 13:19:05 -08:00
										 |  |  | import { parseTrace } from '../config/utils'; | 
					
						
							| 
									
										
										
										
											2022-12-28 16:58:34 -08:00
										 |  |  | import fs from 'fs'; | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | test('should reuse context', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'src/reuse.test.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  |       let lastContextGuid; | 
					
						
							|  |  |  |       test('one', async ({ context }) => { | 
					
						
							|  |  |  |         lastContextGuid = context._guid; | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('two', async ({ context }) => { | 
					
						
							|  |  |  |         expect(context._guid).toBe(lastContextGuid); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test.describe(() => { | 
					
						
							|  |  |  |         test.use({ colorScheme: 'dark' }); | 
					
						
							|  |  |  |         test('dark', async ({ context }) => { | 
					
						
							|  |  |  |           expect(context._guid).toBe(lastContextGuid); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test.describe(() => { | 
					
						
							|  |  |  |         test.use({ userAgent: 'UA' }); | 
					
						
							|  |  |  |         test('UA', async ({ context }) => { | 
					
						
							|  |  |  |           expect(context._guid).toBe(lastContextGuid); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test.describe(() => { | 
					
						
							|  |  |  |         test.use({ timezoneId: 'Europe/Berlin' }); | 
					
						
							|  |  |  |         test('tz', async ({ context }) => { | 
					
						
							|  |  |  |           expect(context._guid).not.toBe(lastContextGuid); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }, { PW_TEST_REUSE_CONTEXT: '1' }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(5); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-28 16:58:34 -08:00
										 |  |  | test('should not reuse context with video if mode=when-possible', async ({ runInlineTest }, testInfo) => { | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       export default { | 
					
						
							|  |  |  |         use: { video: 'on' }, | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'src/reuse.test.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2022-12-28 16:58:34 -08:00
										 |  |  |       let lastContextGuid; | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       test('one', async ({ context }) => { | 
					
						
							| 
									
										
										
										
											2022-12-28 16:58:34 -08:00
										 |  |  |         lastContextGuid = context._guid; | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('two', async ({ context }) => { | 
					
						
							| 
									
										
										
										
											2022-12-28 16:58:34 -08:00
										 |  |  |         expect(context._guid).not.toBe(lastContextGuid); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }, { PW_TEST_REUSE_CONTEXT: 'when-possible' }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(2); | 
					
						
							|  |  |  |   expect(fs.existsSync(testInfo.outputPath('test-results', 'reuse-one', 'video.webm'))).toBeFalsy(); | 
					
						
							|  |  |  |   expect(fs.existsSync(testInfo.outputPath('test-results', 'reuse-two', 'video.webm'))).toBeFalsy(); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test('should reuse context and disable video if mode=force', async ({ runInlineTest }, testInfo) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       export default { | 
					
						
							|  |  |  |         use: { video: 'on' }, | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'reuse.test.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2022-12-28 16:58:34 -08:00
										 |  |  |       let lastContextGuid; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('one', async ({ context, page }) => { | 
					
						
							|  |  |  |         lastContextGuid = context._guid; | 
					
						
							|  |  |  |         await page.waitForTimeout(2000); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('two', async ({ context, page }) => { | 
					
						
							|  |  |  |         expect(context._guid).toBe(lastContextGuid); | 
					
						
							|  |  |  |         await page.waitForTimeout(2000); | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }, { PW_TEST_REUSE_CONTEXT: '1' }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(2); | 
					
						
							| 
									
										
										
										
											2022-12-28 16:58:34 -08:00
										 |  |  |   expect(fs.existsSync(testInfo.outputPath('test-results', 'reuse-one', 'video.webm'))).toBeFalsy(); | 
					
						
							|  |  |  |   expect(fs.existsSync(testInfo.outputPath('test-results', 'reuse-two', 'video.webm'))).toBeFalsy(); | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-05 14:50:47 -08:00
										 |  |  | test('should reuse context with trace if mode=when-possible', async ({ runInlineTest }, testInfo) => { | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       export default { | 
					
						
							|  |  |  |         use: { trace: 'on' }, | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  |     `,
 | 
					
						
							| 
									
										
										
										
											2023-01-05 14:50:47 -08:00
										 |  |  |     'reuse.spec.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2022-12-28 16:58:34 -08:00
										 |  |  |       let lastContextGuid; | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-05 14:50:47 -08:00
										 |  |  |       test('one', async ({ context, page }) => { | 
					
						
							| 
									
										
										
										
											2022-12-28 16:58:34 -08:00
										 |  |  |         lastContextGuid = context._guid; | 
					
						
							| 
									
										
										
										
											2023-01-05 14:50:47 -08:00
										 |  |  |         await page.setContent('<button>Click</button>'); | 
					
						
							|  |  |  |         await page.click('button'); | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-05 14:50:47 -08:00
										 |  |  |       test('two', async ({ context, page }) => { | 
					
						
							|  |  |  |         expect(context._guid).toBe(lastContextGuid); | 
					
						
							|  |  |  |         await page.setContent('<input>'); | 
					
						
							|  |  |  |         await page.fill('input', 'value'); | 
					
						
							|  |  |  |         await page.locator('input').click(); | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							| 
									
										
										
										
											2022-12-28 16:58:34 -08:00
										 |  |  |   }, { workers: 1 }, { PW_TEST_REUSE_CONTEXT: 'when-possible' }); | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(2); | 
					
						
							| 
									
										
										
										
											2023-01-05 14:50:47 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const trace1 = await parseTrace(testInfo.outputPath('test-results', 'reuse-one', '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', | 
					
						
							|  |  |  |     'fixture: page', | 
					
						
							| 
									
										
										
										
											2023-01-05 14:50:47 -08:00
										 |  |  |     'browserContext.newPage', | 
					
						
							|  |  |  |     'page.setContent', | 
					
						
							|  |  |  |     'page.click', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'After Hooks', | 
					
						
							| 
									
										
										
										
											2023-05-06 10:25:32 -07:00
										 |  |  |     'fixture: page', | 
					
						
							|  |  |  |     'fixture: context', | 
					
						
							| 
									
										
										
										
											2023-01-05 14:50:47 -08:00
										 |  |  |   ]); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |   expect(trace1.traceModel.storage().snapshotsForTest().length).toBeGreaterThan(0); | 
					
						
							| 
									
										
										
										
											2023-01-05 14:50:47 -08:00
										 |  |  |   expect(fs.existsSync(testInfo.outputPath('test-results', 'reuse-one', 'trace-1.zip'))).toBe(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const trace2 = await parseTrace(testInfo.outputPath('test-results', 'reuse-two', 'trace.zip')); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |   expect(trace2.apiNames).toEqual([ | 
					
						
							|  |  |  |     'Before Hooks', | 
					
						
							| 
									
										
										
										
											2023-05-06 10:25:32 -07:00
										 |  |  |     'fixture: context', | 
					
						
							|  |  |  |     'fixture: page', | 
					
						
							| 
									
										
										
										
											2023-02-28 13:26:23 -08:00
										 |  |  |     'expect.toBe', | 
					
						
							| 
									
										
										
										
											2023-01-05 14:50:47 -08:00
										 |  |  |     'page.setContent', | 
					
						
							|  |  |  |     'page.fill', | 
					
						
							|  |  |  |     'locator.click', | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     'After Hooks', | 
					
						
							| 
									
										
										
										
											2023-05-06 10:25:32 -07:00
										 |  |  |     'fixture: page', | 
					
						
							|  |  |  |     'fixture: context', | 
					
						
							| 
									
										
										
										
											2023-01-05 14:50:47 -08:00
										 |  |  |   ]); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |   expect(trace2.traceModel.storage().snapshotsForTest().length).toBeGreaterThan(0); | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test('should work with manually closed pages', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'src/button.test.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       test('closes page', async ({ page }) => { | 
					
						
							|  |  |  |         await page.close(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('creates a new page', async ({ page, context }) => { | 
					
						
							|  |  |  |         await page.setContent('<button>Submit</button>'); | 
					
						
							|  |  |  |         await expect(page.locator('button')).toHaveText('Submit'); | 
					
						
							|  |  |  |         await page.locator('button').click(); | 
					
						
							|  |  |  |         await page.close(); | 
					
						
							|  |  |  |         await context.newPage(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('still works', async ({ page }) => { | 
					
						
							|  |  |  |         await page.setContent('<button>Submit</button>'); | 
					
						
							|  |  |  |         await expect(page.locator('button')).toHaveText('Submit'); | 
					
						
							|  |  |  |         await page.locator('button').click(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }, { PW_TEST_REUSE_CONTEXT: '1' }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(3); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test('should clean storage', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'src/reuse.test.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  |       let lastContextGuid; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test.beforeEach(async ({ page }) => { | 
					
						
							|  |  |  |         await page.route('**/*', route => route.fulfill('<html></html>')); | 
					
						
							|  |  |  |         await page.goto('http://example.com'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('one', async ({ context, page }) => { | 
					
						
							|  |  |  |         lastContextGuid = context._guid; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Spam local storage.
 | 
					
						
							|  |  |  |         page.evaluate(async () => { | 
					
						
							|  |  |  |           while (true) { | 
					
						
							|  |  |  |             localStorage.foo = 'bar'; | 
					
						
							|  |  |  |             sessionStorage.foo = 'bar'; | 
					
						
							|  |  |  |             await new Promise(f => setTimeout(f, 0)); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         }).catch(() => {}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         const local = await page.evaluate('localStorage.foo'); | 
					
						
							|  |  |  |         const session = await page.evaluate('sessionStorage.foo'); | 
					
						
							|  |  |  |         expect(local).toBe('bar'); | 
					
						
							|  |  |  |         expect(session).toBe('bar'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('two', async ({ context, page }) => { | 
					
						
							|  |  |  |         expect(context._guid).toBe(lastContextGuid); | 
					
						
							|  |  |  |         const local = await page.evaluate('localStorage.foo'); | 
					
						
							|  |  |  |         const session = await page.evaluate('sessionStorage.foo'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(local).toBeFalsy(); | 
					
						
							|  |  |  |         expect(session).toBeFalsy(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }, { PW_TEST_REUSE_CONTEXT: '1' }); | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(2); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test('should restore localStorage', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'src/reuse.test.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  |       let lastContextGuid; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test.use({ | 
					
						
							|  |  |  |         storageState: { | 
					
						
							|  |  |  |           origins: [{ | 
					
						
							|  |  |  |             origin: 'http://example.com', | 
					
						
							|  |  |  |             localStorage: [{ | 
					
						
							|  |  |  |               name: 'foo', | 
					
						
							|  |  |  |               value: 'fooValue' | 
					
						
							|  |  |  |             }] | 
					
						
							|  |  |  |           }, { | 
					
						
							|  |  |  |             origin: 'http://another.com', | 
					
						
							|  |  |  |             localStorage: [{ | 
					
						
							|  |  |  |               name: 'foo', | 
					
						
							|  |  |  |               value: 'anotherValue' | 
					
						
							|  |  |  |             }] | 
					
						
							|  |  |  |           }] | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test.beforeEach(async ({ page }) => { | 
					
						
							|  |  |  |         await page.route('**/*', route => route.fulfill('<html></html>')); | 
					
						
							|  |  |  |         await page.goto('http://example.com'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('one', async ({ context, page }) => { | 
					
						
							|  |  |  |         lastContextGuid = context._guid; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           const local = await page.evaluate('localStorage.foo'); | 
					
						
							|  |  |  |           const session = await page.evaluate('sessionStorage.foo'); | 
					
						
							|  |  |  |           expect(local).toBe('fooValue'); | 
					
						
							|  |  |  |           expect(session).toBeFalsy(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Overwrite localStorage.
 | 
					
						
							|  |  |  |         await page.evaluate(() => { | 
					
						
							|  |  |  |           localStorage.foo = 'bar'; | 
					
						
							|  |  |  |           sessionStorage.foo = 'bar'; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           const local = await page.evaluate('localStorage.foo'); | 
					
						
							|  |  |  |           const session = await page.evaluate('sessionStorage.foo'); | 
					
						
							|  |  |  |           expect(local).toBe('bar'); | 
					
						
							|  |  |  |           expect(session).toBe('bar'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('two', async ({ context, page }) => { | 
					
						
							|  |  |  |         expect(context._guid).toBe(lastContextGuid); | 
					
						
							|  |  |  |         const local = await page.evaluate('localStorage.foo'); | 
					
						
							|  |  |  |         const session = await page.evaluate('sessionStorage.foo'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(local).toBe('fooValue'); | 
					
						
							|  |  |  |         expect(session).toBeFalsy(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('three', async ({ context, page }) => { | 
					
						
							|  |  |  |         await page.goto('http://another.com'); | 
					
						
							|  |  |  |         expect(context._guid).toBe(lastContextGuid); | 
					
						
							|  |  |  |         const local = await page.evaluate('localStorage.foo'); | 
					
						
							|  |  |  |         expect(local).toBe('anotherValue'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }, { PW_TEST_REUSE_CONTEXT: '1' }); | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(3); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test('should clean db', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |   test.slow(); | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'src/reuse.test.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  |       let lastContextGuid; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test.beforeEach(async ({ page }) => { | 
					
						
							|  |  |  |         await page.route('**/*', route => route.fulfill('<html></html>')); | 
					
						
							|  |  |  |         await page.goto('http://example.com'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('one', async ({ context, page }) => { | 
					
						
							|  |  |  |         lastContextGuid = context._guid; | 
					
						
							|  |  |  |         await page.evaluate(async () => { | 
					
						
							|  |  |  |           const dbRequest = indexedDB.open('db', 1); | 
					
						
							|  |  |  |           await new Promise(f => dbRequest.onsuccess = f); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         const dbnames = await page.evaluate(async () => { | 
					
						
							|  |  |  |           const dbs = await indexedDB.databases(); | 
					
						
							|  |  |  |           return dbs.map(db => db.name); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         expect(dbnames).toEqual(['db']); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('two', async ({ context, page }) => { | 
					
						
							|  |  |  |         expect(context._guid).toBe(lastContextGuid); | 
					
						
							|  |  |  |         const dbnames = await page.evaluate(async () => { | 
					
						
							|  |  |  |           const dbs = await indexedDB.databases(); | 
					
						
							|  |  |  |           return dbs.map(db => db.name); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(dbnames).toEqual([]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }, { PW_TEST_REUSE_CONTEXT: '1' }); | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(2); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test('should restore cookies', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'src/reuse.test.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2022-09-07 19:15:04 -07:00
										 |  |  |       let lastContextGuid; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test.use({ | 
					
						
							|  |  |  |         storageState: { | 
					
						
							|  |  |  |           cookies: [{ | 
					
						
							|  |  |  |             name: 'name', | 
					
						
							|  |  |  |             value: 'value', | 
					
						
							|  |  |  |             domain: 'example.com', | 
					
						
							|  |  |  |             path: '/', | 
					
						
							|  |  |  |           }] | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test.beforeEach(async ({ page }) => { | 
					
						
							|  |  |  |         await page.route('**/*', route => route.fulfill('<html></html>')); | 
					
						
							|  |  |  |         await page.goto('http://example.com'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('one', async ({ context, page }) => { | 
					
						
							|  |  |  |         lastContextGuid = context._guid; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           const cookie = await page.evaluate('document.cookie'); | 
					
						
							|  |  |  |           expect(cookie).toBe('name=value'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // Overwrite cookie.
 | 
					
						
							|  |  |  |         await page.evaluate(async () => { | 
					
						
							|  |  |  |           document.cookie = 'name=value2'; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           const cookie = await page.evaluate('document.cookie'); | 
					
						
							|  |  |  |           expect(cookie).toBe('name=value2'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('two', async ({ context, page }) => { | 
					
						
							|  |  |  |         expect(context._guid).toBe(lastContextGuid); | 
					
						
							|  |  |  |         const cookie = await page.evaluate('document.cookie'); | 
					
						
							|  |  |  |         expect(cookie).toBe('name=value'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('three', async ({ context, page }) => { | 
					
						
							|  |  |  |         await page.goto('http://another.com'); | 
					
						
							|  |  |  |         const cookie = await page.evaluate('document.cookie'); | 
					
						
							|  |  |  |         expect(cookie).toBe(''); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }, { PW_TEST_REUSE_CONTEXT: '1' }); | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(3); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2022-10-26 15:17:40 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | test('should reuse context with beforeunload', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'src/reuse.test.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2022-10-26 15:17:40 -07:00
										 |  |  |       let lastContextGuid; | 
					
						
							|  |  |  |       test('one', async ({ page, context }) => { | 
					
						
							|  |  |  |         lastContextGuid = context._guid; | 
					
						
							|  |  |  |         await page.evaluate(() => { | 
					
						
							|  |  |  |           window.addEventListener('beforeunload', event => { | 
					
						
							|  |  |  |             event.preventDefault(); | 
					
						
							|  |  |  |             return event.returnValue = "Are you sure you want to exit?"; | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('two', async ({ context }) => { | 
					
						
							|  |  |  |         expect(context._guid).toBe(lastContextGuid); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }, { PW_TEST_REUSE_CONTEXT: '1' }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(2); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2022-11-22 15:21:20 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | test('should cancel pending operations upon reuse', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'src/reuse.test.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2022-11-22 15:21:20 -08:00
										 |  |  |       test('one', async ({ page }) => { | 
					
						
							|  |  |  |         await Promise.race([ | 
					
						
							|  |  |  |           page.getByText('click me').click().catch(e => {}), | 
					
						
							|  |  |  |           page.waitForTimeout(2000), | 
					
						
							|  |  |  |         ]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('two', async ({ page }) => { | 
					
						
							|  |  |  |         await page.setContent('<button onclick="window._clicked=true">click me</button>'); | 
					
						
							|  |  |  |         // Give it time to erroneously click.
 | 
					
						
							|  |  |  |         await page.waitForTimeout(2000); | 
					
						
							|  |  |  |         expect(await page.evaluate('window._clicked')).toBe(undefined); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }, { PW_TEST_REUSE_CONTEXT: '1' }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(2); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2023-01-04 13:19:05 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | test('should reset tracing', async ({ runInlineTest }, testInfo) => { | 
					
						
							|  |  |  |   const traceFile1 = testInfo.outputPath('trace1.zip'); | 
					
						
							|  |  |  |   const traceFile2 = testInfo.outputPath('trace2.zip'); | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'reuse.spec.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							| 
									
										
										
										
											2023-01-04 13:19:05 -08:00
										 |  |  |       test('one', async ({ page }) => { | 
					
						
							|  |  |  |         await page.context().tracing.start({ snapshots: true }); | 
					
						
							|  |  |  |         await page.setContent('<button>Click</button>'); | 
					
						
							|  |  |  |         await page.click('button'); | 
					
						
							|  |  |  |         await page.context().tracing.stopChunk({ path: ${JSON.stringify(traceFile1)} }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       test('two', async ({ page }) => { | 
					
						
							|  |  |  |         await page.context().tracing.start({ snapshots: true }); | 
					
						
							|  |  |  |         await page.setContent('<input>'); | 
					
						
							|  |  |  |         await page.fill('input', 'value'); | 
					
						
							|  |  |  |         await page.locator('input').click(); | 
					
						
							|  |  |  |         await page.context().tracing.stopChunk({ path: ${JSON.stringify(traceFile2)} }); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }, { PW_TEST_REUSE_CONTEXT: '1' }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const trace1 = await parseTrace(traceFile1); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |   expect(trace1.apiNames).toEqual([ | 
					
						
							| 
									
										
										
										
											2023-01-04 13:19:05 -08:00
										 |  |  |     'page.setContent', | 
					
						
							|  |  |  |     'page.click', | 
					
						
							|  |  |  |   ]); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |   expect(trace1.traceModel.storage().snapshotsForTest().length).toBeGreaterThan(0); | 
					
						
							| 
									
										
										
										
											2023-01-04 13:19:05 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const trace2 = await parseTrace(traceFile2); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |   expect(trace2.apiNames).toEqual([ | 
					
						
							| 
									
										
										
										
											2023-01-04 13:19:05 -08:00
										 |  |  |     'page.setContent', | 
					
						
							|  |  |  |     'page.fill', | 
					
						
							|  |  |  |     'locator.click', | 
					
						
							|  |  |  |   ]); | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |   expect(trace1.traceModel.storage().snapshotsForTest().length).toBeGreaterThan(0); | 
					
						
							| 
									
										
										
										
											2023-01-04 13:19:05 -08:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2023-02-14 12:56:47 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | test('should not delete others contexts', async ({ runInlineTest }) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'src/reuse.test.ts': `
 | 
					
						
							| 
									
										
										
										
											2023-02-14 19:20:56 -08:00
										 |  |  |       import { test as base, expect } from '@playwright/test'; | 
					
						
							|  |  |  |       const test = base.extend<{ loggedInPage: Page }>({ | 
					
						
							| 
									
										
										
										
											2023-02-14 12:56:47 -08:00
										 |  |  |         loggedInPage: async ({ browser }, use) => { | 
					
						
							|  |  |  |           const page = await browser.newPage(); | 
					
						
							|  |  |  |           await use(page); | 
					
						
							|  |  |  |           await page.close(); | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       test("passes", async ({ loggedInPage, page }) => { | 
					
						
							|  |  |  |         await loggedInPage.goto('data:text/plain,Hello world'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }, { PW_TEST_REUSE_CONTEXT: '1' }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(1); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2023-03-16 14:32:12 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | test('should survive serial mode with tracing and reuse', async ({ runInlineTest }, testInfo) => { | 
					
						
							|  |  |  |   const result = await runInlineTest({ | 
					
						
							|  |  |  |     'playwright.config.ts': `
 | 
					
						
							|  |  |  |       import { defineConfig } from '@playwright/test'; | 
					
						
							|  |  |  |       export default defineConfig({ use: { trace: 'on' } }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |     'reuse.spec.ts': `
 | 
					
						
							|  |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |       let page; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test.describe.configure({ mode: 'serial' }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test.beforeAll(async ({ browser }) => { | 
					
						
							|  |  |  |         page = await browser.newPage(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('one', async ({}) => { | 
					
						
							|  |  |  |         await page.setContent('<button>Click</button>'); | 
					
						
							|  |  |  |         await page.click('button'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('two', async ({}) => { | 
					
						
							|  |  |  |         await page.setContent('<input>'); | 
					
						
							|  |  |  |         await page.fill('input', 'value'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }, { workers: 1 }, { PW_TEST_REUSE_CONTEXT: '1' }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(result.exitCode).toBe(0); | 
					
						
							|  |  |  |   expect(result.passed).toBe(2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   expect(fs.existsSync(testInfo.outputPath('test-results', 'reuse-one', 'trace.zip'))).toBe(true); | 
					
						
							|  |  |  |   expect(fs.existsSync(testInfo.outputPath('test-results', 'reuse-two', 'trace.zip'))).toBe(true); | 
					
						
							|  |  |  | }); |