| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Copyright 2018 Google Inc. All rights reserved. | 
					
						
							|  |  |  |  * Modifications 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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-04 19:32:14 -07:00
										 |  |  | import { test as it, expect } from './config/pageTest'; | 
					
						
							|  |  |  | import type { Frame } from '../index'; | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  | import { TestServer } from '../utils/testserver'; | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should navigate to empty page with networkidle', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  |   const response = await page.goto(server.EMPTY_PAGE, { waitUntil: 'networkidle' }); | 
					
						
							|  |  |  |   expect(response.status()).toBe(200); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  | async function networkIdleTest(frame: Frame, server: TestServer, action: () => Promise<any>, isSetContent?: boolean) { | 
					
						
							| 
									
										
										
										
											2020-11-04 07:35:19 -08:00
										 |  |  |   const waitForRequest = (suffix: string) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  |     return Promise.all([ | 
					
						
							|  |  |  |       server.waitForRequest(suffix), | 
					
						
							| 
									
										
										
										
											2020-11-04 07:35:19 -08:00
										 |  |  |       frame.page().waitForRequest(server.PREFIX + suffix), | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  |     ]); | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   }; | 
					
						
							| 
									
										
										
										
											2020-11-04 07:35:19 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   let responseA, responseB; | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  |   // Hold on to a bunch of requests without answering.
 | 
					
						
							| 
									
										
										
										
											2020-11-04 07:35:19 -08:00
										 |  |  |   server.setRoute('/fetch-request-a.js', (req, res) => responseA = res); | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  |   const firstFetchResourceRequested = waitForRequest('/fetch-request-a.js'); | 
					
						
							| 
									
										
										
										
											2020-11-04 07:35:19 -08:00
										 |  |  |   server.setRoute('/fetch-request-b.js', (req, res) => responseB = res); | 
					
						
							|  |  |  |   const secondFetchResourceRequested = waitForRequest('/fetch-request-b.js'); | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const waitForLoadPromise = isSetContent ? Promise.resolve() : frame.waitForNavigation({ waitUntil: 'load' }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Navigate to a page which loads immediately and then does a bunch of
 | 
					
						
							|  |  |  |   // requests via javascript's fetch method.
 | 
					
						
							|  |  |  |   const actionPromise = action(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Track when the action gets completed.
 | 
					
						
							|  |  |  |   let actionFinished = false; | 
					
						
							|  |  |  |   actionPromise.then(() => actionFinished = true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Wait for the frame's 'load' event.
 | 
					
						
							|  |  |  |   await waitForLoadPromise; | 
					
						
							|  |  |  |   expect(actionFinished).toBe(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Wait for the initial resource to be requested.
 | 
					
						
							|  |  |  |   await firstFetchResourceRequested; | 
					
						
							|  |  |  |   expect(actionFinished).toBe(false); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-04 07:35:19 -08:00
										 |  |  |   // Trigger the second request.
 | 
					
						
							|  |  |  |   await frame.page().evaluate(() => window['fetchSecond']()); | 
					
						
							|  |  |  |   // Finish the first request.
 | 
					
						
							|  |  |  |   responseA.statusCode = 404; | 
					
						
							|  |  |  |   responseA.end(`File not found`); | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Wait for the second round to be requested.
 | 
					
						
							|  |  |  |   await secondFetchResourceRequested; | 
					
						
							|  |  |  |   expect(actionFinished).toBe(false); | 
					
						
							| 
									
										
										
										
											2020-11-04 07:35:19 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Finishing the second response should trigger networkidle.
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   let timerTriggered = false; | 
					
						
							|  |  |  |   const timer = setTimeout(() => timerTriggered = true, 500); | 
					
						
							| 
									
										
										
										
											2020-11-04 07:35:19 -08:00
										 |  |  |   responseB.statusCode = 404; | 
					
						
							|  |  |  |   responseB.end(`File not found`); | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const response = await actionPromise; | 
					
						
							|  |  |  |   clearTimeout(timer); | 
					
						
							|  |  |  |   expect(timerTriggered).toBe(true); | 
					
						
							|  |  |  |   if (!isSetContent) | 
					
						
							|  |  |  |     expect(response.ok()).toBe(true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should wait for networkidle to succeed navigation', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  |   await networkIdleTest(page.mainFrame(), server, () => { | 
					
						
							|  |  |  |     return page.goto(server.PREFIX + '/networkidle.html', { waitUntil: 'networkidle' }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should wait for networkidle to succeed navigation with request from previous navigation', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   server.setRoute('/foo.js', () => {}); | 
					
						
							|  |  |  |   await page.setContent(`<script>fetch('foo.js');</script>`); | 
					
						
							|  |  |  |   await networkIdleTest(page.mainFrame(), server, () => { | 
					
						
							|  |  |  |     return page.goto(server.PREFIX + '/networkidle.html', { waitUntil: 'networkidle' }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should wait for networkidle in waitForNavigation', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  |   await networkIdleTest(page.mainFrame(), server, () => { | 
					
						
							|  |  |  |     const promise = page.waitForNavigation({ waitUntil: 'networkidle' }); | 
					
						
							|  |  |  |     page.goto(server.PREFIX + '/networkidle.html'); | 
					
						
							|  |  |  |     return promise; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should wait for networkidle in setContent', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   await networkIdleTest(page.mainFrame(), server, () => { | 
					
						
							|  |  |  |     return page.setContent(`<script src='networkidle.js'></script>`, { waitUntil: 'networkidle' }); | 
					
						
							|  |  |  |   }, true); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should wait for networkidle in setContent with request from previous navigation', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   server.setRoute('/foo.js', () => {}); | 
					
						
							|  |  |  |   await page.setContent(`<script>fetch('foo.js');</script>`); | 
					
						
							|  |  |  |   await networkIdleTest(page.mainFrame(), server, () => { | 
					
						
							|  |  |  |     return page.setContent(`<script src='networkidle.js'></script>`, { waitUntil: 'networkidle' }); | 
					
						
							|  |  |  |   }, true); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should wait for networkidle when navigating iframe', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  |   await page.goto(server.PREFIX + '/frames/one-frame.html'); | 
					
						
							|  |  |  |   const frame = page.mainFrame().childFrames()[0]; | 
					
						
							|  |  |  |   await networkIdleTest(frame, server, () => frame.goto(server.PREFIX + '/networkidle.html', { waitUntil: 'networkidle' })); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should wait for networkidle in setContent from the child frame', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   await networkIdleTest(page.mainFrame(), server, () => { | 
					
						
							|  |  |  |     return page.setContent(`<iframe src='networkidle.html'></iframe>`, { waitUntil: 'networkidle' }); | 
					
						
							|  |  |  |   }, true); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  | it('should wait for networkidle from the child frame', async ({page, server}) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 16:32:10 -07:00
										 |  |  |   await networkIdleTest(page.mainFrame(), server, () => { | 
					
						
							|  |  |  |     return page.goto(server.PREFIX + '/networkidle-frame.html', { waitUntil: 'networkidle' }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-10-23 12:37:38 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-09 07:59:09 -07:00
										 |  |  | it('should wait for networkidle from the popup', async ({page, server, isAndroid}) => { | 
					
						
							|  |  |  |   it.skip(isAndroid, 'Too slow'); | 
					
						
							| 
									
										
										
										
											2021-04-04 19:32:14 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-23 12:37:38 -07:00
										 |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   await page.setContent(`
 | 
					
						
							|  |  |  |     <button id=box1 onclick="window.open('./popup/popup.html')">Button1</button> | 
					
						
							|  |  |  |     <button id=box2 onclick="window.open('./popup/popup.html')">Button2</button> | 
					
						
							|  |  |  |     <button id=box3 onclick="window.open('./popup/popup.html')">Button3</button> | 
					
						
							|  |  |  |     <button id=box4 onclick="window.open('./popup/popup.html')">Button4</button> | 
					
						
							|  |  |  |     <button id=box5 onclick="window.open('./popup/popup.html')">Button5</button> | 
					
						
							|  |  |  |   `);
 | 
					
						
							|  |  |  |   for (let i = 1; i < 6; ++i) { | 
					
						
							|  |  |  |     const [popup] = await Promise.all([ | 
					
						
							|  |  |  |       page.waitForEvent('popup'), | 
					
						
							|  |  |  |       page.click('#box' + i) | 
					
						
							|  |  |  |     ]); | 
					
						
							|  |  |  |     await popup.waitForLoadState('networkidle'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }); |