| 
									
										
										
										
											2023-03-16 20:09:09 -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 { ManualPromise } from '../../packages/playwright-core/lib/utils/manualPromise'; | 
					
						
							| 
									
										
										
										
											2023-05-18 11:28:28 -07:00
										 |  |  | import { test, expect, retries, dumpTestTree } from './ui-mode-fixtures'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test.describe.configure({ mode: 'parallel', retries }); | 
					
						
							| 
									
										
										
										
											2023-03-16 20:09:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | test('should update trace live', async ({ runUITest, server }) => { | 
					
						
							|  |  |  |   const onePromise = new ManualPromise(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   server.setRoute('/one.html', async (req, res) => { | 
					
						
							|  |  |  |     await onePromise; | 
					
						
							|  |  |  |     res.end('<html>One</html>'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const twoPromise = new ManualPromise(); | 
					
						
							|  |  |  |   server.setRoute('/two.html', async (req, res) => { | 
					
						
							|  |  |  |     await twoPromise; | 
					
						
							|  |  |  |     res.end('<html>Two</html>'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-29 13:57:19 -07:00
										 |  |  |   const { page } = await runUITest({ | 
					
						
							| 
									
										
										
										
											2023-03-16 20:09:09 -07:00
										 |  |  |     'a.test.ts': `
 | 
					
						
							|  |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |       test('live test', async ({ page }) => { | 
					
						
							|  |  |  |         await page.goto('${server.PREFIX}/one.html'); | 
					
						
							|  |  |  |         await page.goto('${server.PREFIX}/two.html'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Start test.
 | 
					
						
							|  |  |  |   await page.getByText('live test').dblclick(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // It should halt on loading one.html.
 | 
					
						
							| 
									
										
										
										
											2023-09-07 17:14:39 -07:00
										 |  |  |   const listItem = page.getByTestId('actions-tree').getByRole('listitem'); | 
					
						
							| 
									
										
										
										
											2023-03-16 20:09:09 -07:00
										 |  |  |   await expect( | 
					
						
							|  |  |  |       listItem, | 
					
						
							|  |  |  |       'action list' | 
					
						
							|  |  |  |   ).toHaveText([ | 
					
						
							| 
									
										
										
										
											2023-08-22 15:46:41 -07:00
										 |  |  |     /Before Hooks[\d.]+m?s/, | 
					
						
							| 
									
										
										
										
											2023-03-16 20:09:09 -07:00
										 |  |  |     /page.gotohttp:\/\/localhost:\d+\/one.html/ | 
					
						
							| 
									
										
										
										
											2023-04-28 14:18:46 -07:00
										 |  |  |   ]); | 
					
						
							| 
									
										
										
										
											2023-03-16 20:09:09 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   await expect( | 
					
						
							|  |  |  |       listItem.locator(':scope.selected'), | 
					
						
							|  |  |  |       'last action to be selected' | 
					
						
							|  |  |  |   ).toHaveText(/page.goto/); | 
					
						
							|  |  |  |   await expect( | 
					
						
							|  |  |  |       listItem.locator(':scope.selected .codicon.codicon-loading'), | 
					
						
							|  |  |  |       'spinner' | 
					
						
							|  |  |  |   ).toBeVisible(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await expect( | 
					
						
							|  |  |  |       page.locator('.CodeMirror .source-line-running'), | 
					
						
							|  |  |  |       'check source tab', | 
					
						
							|  |  |  |   ).toHaveText(/4        await page.goto\('http:\/\/localhost:\d+\/one.html/); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Unlock the navigation step.
 | 
					
						
							|  |  |  |   onePromise.resolve(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await expect( | 
					
						
							| 
									
										
										
										
											2023-03-21 07:40:54 -07:00
										 |  |  |       page.frameLocator('iframe.snapshot-visible[name=snapshot]').locator('body'), | 
					
						
							| 
									
										
										
										
											2023-03-16 20:09:09 -07:00
										 |  |  |       'verify snapshot' | 
					
						
							| 
									
										
										
										
											2023-04-28 14:18:46 -07:00
										 |  |  |   ).toHaveText('One'); | 
					
						
							| 
									
										
										
										
											2023-03-16 20:09:09 -07:00
										 |  |  |   await expect(listItem).toHaveText([ | 
					
						
							| 
									
										
										
										
											2023-08-22 15:46:41 -07:00
										 |  |  |     /Before Hooks[\d.]+m?s/, | 
					
						
							| 
									
										
										
										
											2023-03-16 20:09:09 -07:00
										 |  |  |     /page.gotohttp:\/\/localhost:\d+\/one.html[\d.]+m?s/, | 
					
						
							|  |  |  |     /page.gotohttp:\/\/localhost:\d+\/two.html/ | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  |   await expect( | 
					
						
							|  |  |  |       listItem.locator(':scope.selected'), | 
					
						
							|  |  |  |       'last action to be selected' | 
					
						
							|  |  |  |   ).toHaveText(/page.goto/); | 
					
						
							|  |  |  |   await expect( | 
					
						
							|  |  |  |       listItem.locator(':scope.selected .codicon.codicon-loading'), | 
					
						
							|  |  |  |       'spinner' | 
					
						
							|  |  |  |   ).toBeVisible(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await expect( | 
					
						
							|  |  |  |       page.locator('.CodeMirror .source-line-running'), | 
					
						
							|  |  |  |       'check source tab', | 
					
						
							|  |  |  |   ).toHaveText(/5        await page.goto\('http:\/\/localhost:\d+\/two.html/); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Unlock the navigation step.
 | 
					
						
							|  |  |  |   twoPromise.resolve(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await expect( | 
					
						
							| 
									
										
										
										
											2023-03-21 07:40:54 -07:00
										 |  |  |       page.frameLocator('iframe.snapshot-visible[name=snapshot]').locator('body'), | 
					
						
							| 
									
										
										
										
											2023-03-16 20:09:09 -07:00
										 |  |  |       'verify snapshot' | 
					
						
							|  |  |  |   ).toHaveText('Two'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await expect(listItem).toHaveText([ | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     /Before Hooks[\d.]+m?s/, | 
					
						
							| 
									
										
										
										
											2023-05-23 09:36:35 -07:00
										 |  |  |     /page.gotohttp:\/\/localhost:\d+\/one.html[\d.]+m?s/, | 
					
						
							|  |  |  |     /page.gotohttp:\/\/localhost:\d+\/two.html[\d.]+m?s/, | 
					
						
							| 
									
										
										
										
											2023-05-05 15:12:18 -07:00
										 |  |  |     /After Hooks[\d.]+m?s/, | 
					
						
							| 
									
										
										
										
											2023-03-16 20:09:09 -07:00
										 |  |  |   ]); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2023-03-31 18:34:51 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | test('should preserve action list selection upon live trace update', async ({ runUITest, server, createLatch }) => { | 
					
						
							|  |  |  |   const latch = createLatch(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const { page } = await runUITest({ | 
					
						
							|  |  |  |     'a.test.ts': `
 | 
					
						
							|  |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |       test('live test', async ({ page }) => { | 
					
						
							|  |  |  |         await page.goto('about:blank'); | 
					
						
							|  |  |  |         await page.setContent('hello'); | 
					
						
							|  |  |  |         ${latch.blockingCode} | 
					
						
							|  |  |  |         await page.setContent('world'); | 
					
						
							|  |  |  |         await new Promise(() => {}); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Start test.
 | 
					
						
							|  |  |  |   await page.getByText('live test').dblclick(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // It should wait on the latch.
 | 
					
						
							| 
									
										
										
										
											2023-09-07 17:14:39 -07:00
										 |  |  |   const listItem = page.getByTestId('actions-tree').getByRole('listitem'); | 
					
						
							| 
									
										
										
										
											2023-03-31 18:34:51 -07:00
										 |  |  |   await expect( | 
					
						
							|  |  |  |       listItem, | 
					
						
							|  |  |  |       'action list' | 
					
						
							|  |  |  |   ).toHaveText([ | 
					
						
							| 
									
										
										
										
											2023-08-22 15:46:41 -07:00
										 |  |  |     /Before Hooks[\d.]+m?s/, | 
					
						
							| 
									
										
										
										
											2023-03-31 18:34:51 -07:00
										 |  |  |     /page.gotoabout:blank[\d.]+m?s/, | 
					
						
							|  |  |  |     /page.setContent[\d.]+m?s/, | 
					
						
							| 
									
										
										
										
											2023-04-28 14:18:46 -07:00
										 |  |  |   ]); | 
					
						
							| 
									
										
										
										
											2023-03-31 18:34:51 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Manually select page.goto.
 | 
					
						
							| 
									
										
										
										
											2023-09-07 17:14:39 -07:00
										 |  |  |   await page.getByTestId('actions-tree').getByText('page.goto').click(); | 
					
						
							| 
									
										
										
										
											2023-03-31 18:34:51 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Generate more actions and check that we are still on the page.goto action.
 | 
					
						
							|  |  |  |   latch.open(); | 
					
						
							|  |  |  |   await expect( | 
					
						
							|  |  |  |       listItem, | 
					
						
							|  |  |  |       'action list' | 
					
						
							|  |  |  |   ).toHaveText([ | 
					
						
							| 
									
										
										
										
											2023-08-22 15:46:41 -07:00
										 |  |  |     /Before Hooks[\d.]+m?s/, | 
					
						
							| 
									
										
										
										
											2023-03-31 18:34:51 -07:00
										 |  |  |     /page.gotoabout:blank[\d.]+m?s/, | 
					
						
							|  |  |  |     /page.setContent[\d.]+m?s/, | 
					
						
							|  |  |  |     /page.setContent[\d.]+m?s/, | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  |   await expect( | 
					
						
							|  |  |  |       listItem.locator(':scope.selected'), | 
					
						
							|  |  |  |       'selected action stays the same' | 
					
						
							|  |  |  |   ).toHaveText(/page.goto/); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | test('should update tracing network live', async ({ runUITest, server }) => { | 
					
						
							|  |  |  |   server.setRoute('/style.css', async (req, res) => { | 
					
						
							|  |  |  |     res.end('body { background: red; }'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   server.setRoute('/one.html', async (req, res) => { | 
					
						
							|  |  |  |     res.end(`
 | 
					
						
							|  |  |  |       <head> | 
					
						
							|  |  |  |         <link rel=stylesheet href="./style.css"></link> | 
					
						
							|  |  |  |       </head> | 
					
						
							|  |  |  |       <body> | 
					
						
							|  |  |  |         One | 
					
						
							|  |  |  |       </body> | 
					
						
							|  |  |  |     `);
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const { page } = await runUITest({ | 
					
						
							|  |  |  |     'a.test.ts': `
 | 
					
						
							|  |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |       test('live test', async ({ page }) => { | 
					
						
							|  |  |  |         await page.goto('${server.PREFIX}/one.html'); | 
					
						
							|  |  |  |         await page.setContent('hello'); | 
					
						
							|  |  |  |         await new Promise(() => {}); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Start test.
 | 
					
						
							|  |  |  |   await page.getByText('live test').dblclick(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // It should wait on the latch.
 | 
					
						
							| 
									
										
										
										
											2023-09-07 17:14:39 -07:00
										 |  |  |   const listItem = page.getByTestId('actions-tree').getByRole('listitem'); | 
					
						
							| 
									
										
										
										
											2023-03-31 18:34:51 -07:00
										 |  |  |   await expect( | 
					
						
							|  |  |  |       listItem, | 
					
						
							|  |  |  |       'action list' | 
					
						
							|  |  |  |   ).toHaveText([ | 
					
						
							| 
									
										
										
										
											2023-08-22 15:46:41 -07:00
										 |  |  |     /Before Hooks[\d.]+m?s/, | 
					
						
							| 
									
										
										
										
											2023-03-31 18:34:51 -07:00
										 |  |  |     /page.gotohttp:\/\/localhost:\d+\/one.html[\d.]+m?s/, | 
					
						
							|  |  |  |     /page.setContent[\d.]+m?s/, | 
					
						
							| 
									
										
										
										
											2023-04-28 14:18:46 -07:00
										 |  |  |   ]); | 
					
						
							| 
									
										
										
										
											2023-03-31 18:34:51 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Once page.setContent is visible, we can be sure that page.goto has all required
 | 
					
						
							|  |  |  |   // resources in the trace. Switch to it and check that everything renders.
 | 
					
						
							| 
									
										
										
										
											2023-09-07 17:14:39 -07:00
										 |  |  |   await page.getByTestId('actions-tree').getByText('page.goto').click(); | 
					
						
							| 
									
										
										
										
											2023-03-31 18:34:51 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   await expect( | 
					
						
							|  |  |  |       page.frameLocator('iframe.snapshot-visible[name=snapshot]').locator('body'), | 
					
						
							|  |  |  |       'verify background' | 
					
						
							| 
									
										
										
										
											2023-04-28 14:18:46 -07:00
										 |  |  |   ).toHaveCSS('background-color', 'rgb(255, 0, 0)'); | 
					
						
							| 
									
										
										
										
											2023-03-31 18:34:51 -07:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2023-04-20 08:19:00 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | test('should show trace w/ multiple contexts', async ({ runUITest, server, createLatch }) => { | 
					
						
							|  |  |  |   const latch = createLatch(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const { page } = await runUITest({ | 
					
						
							|  |  |  |     'a.test.ts': `
 | 
					
						
							|  |  |  |       import { test, expect } from '@playwright/test'; | 
					
						
							|  |  |  |       test.beforeEach(async ({ request }) => { | 
					
						
							|  |  |  |         await request.get('${server.EMPTY_PAGE}'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |       test('live test', async ({ page }) => { | 
					
						
							|  |  |  |         await page.goto('about:blank'); | 
					
						
							|  |  |  |         ${latch.blockingCode} | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Start test.
 | 
					
						
							|  |  |  |   await page.getByText('live test').dblclick(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // It should wait on the latch.
 | 
					
						
							| 
									
										
										
										
											2023-09-07 17:14:39 -07:00
										 |  |  |   const listItem = page.getByTestId('actions-tree').getByRole('listitem'); | 
					
						
							| 
									
										
										
										
											2023-04-20 08:19:00 -07:00
										 |  |  |   await expect( | 
					
						
							|  |  |  |       listItem, | 
					
						
							|  |  |  |       'action list' | 
					
						
							|  |  |  |   ).toHaveText([ | 
					
						
							| 
									
										
										
										
											2023-08-22 15:46:41 -07:00
										 |  |  |     /Before Hooks[\d.]+m?s/, | 
					
						
							| 
									
										
										
										
											2023-04-20 08:19:00 -07:00
										 |  |  |     /page.gotoabout:blank[\d.]+m?s/, | 
					
						
							| 
									
										
										
										
											2023-04-28 14:18:46 -07:00
										 |  |  |   ]); | 
					
						
							| 
									
										
										
										
											2023-04-20 08:19:00 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   latch.open(); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2023-04-28 17:47:57 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | test('should show live trace for serial', async ({ runUITest, server, createLatch }) => { | 
					
						
							|  |  |  |   const latch = createLatch(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   const { page } = await runUITest({ | 
					
						
							|  |  |  |     'a.test.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('<input id=checkbox type=checkbox></input>'); | 
					
						
							|  |  |  |         await page.locator('input').check(); | 
					
						
							|  |  |  |         await expect(page.locator('input')).toBeChecked(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       test('two', async ({ }) => { | 
					
						
							|  |  |  |         await page.locator('input').uncheck(); | 
					
						
							|  |  |  |         await expect(page.locator('input')).not.toBeChecked(); | 
					
						
							|  |  |  |         ${latch.blockingCode} | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     `,
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   await expect.poll(dumpTestTree(page)).toBe(`
 | 
					
						
							|  |  |  |     ▼ ◯ a.test.ts | 
					
						
							|  |  |  |         ◯ one | 
					
						
							|  |  |  |         ◯ two | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  |   await page.getByText('two', { exact: true }).click(); | 
					
						
							|  |  |  |   await page.getByTitle('Run all').click(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-09-07 17:14:39 -07:00
										 |  |  |   const listItem = page.getByTestId('actions-tree').getByRole('listitem'); | 
					
						
							| 
									
										
										
										
											2023-04-28 17:47:57 -07:00
										 |  |  |   await expect( | 
					
						
							|  |  |  |       listItem, | 
					
						
							|  |  |  |       'action list' | 
					
						
							|  |  |  |   ).toHaveText([ | 
					
						
							| 
									
										
										
										
											2023-08-22 15:46:41 -07:00
										 |  |  |     /Before Hooks[\d.]+m?s/, | 
					
						
							| 
									
										
										
										
											2023-04-28 17:47:57 -07:00
										 |  |  |     /locator.unchecklocator\('input'\)[\d.]+m?s/, | 
					
						
							|  |  |  |     /expect.not.toBeCheckedlocator\('input'\)[\d.]/, | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  | }); |