| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Copyright 2017 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. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-08-19 21:32:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-06 07:08:22 -07:00
										 |  |  | import { test as it, expect } from './pageTest'; | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-07 20:09:22 +02:00
										 |  |  | it('should reject all promises when page is closed', async ({ page, isWebView2 }) => { | 
					
						
							|  |  |  |   it.skip(isWebView2, 'Page.close() is not supported in WebView2'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   let error = null; | 
					
						
							|  |  |  |   await Promise.all([ | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  |     page.evaluate(() => new Promise(r => {})).catch(e => error = e), | 
					
						
							|  |  |  |     page.close(), | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   ]); | 
					
						
							| 
									
										
										
										
											2021-08-26 18:44:49 -07:00
										 |  |  |   expect(error.message).toContain('Target closed'); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-07 20:09:22 +02:00
										 |  |  | it('should set the page close state', async ({ page, isWebView2 }) => { | 
					
						
							|  |  |  |   it.skip(isWebView2, 'Page.close() is not supported in WebView2'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  |   expect(page.isClosed()).toBe(false); | 
					
						
							|  |  |  |   await page.close(); | 
					
						
							|  |  |  |   expect(page.isClosed()).toBe(true); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-07 20:09:22 +02:00
										 |  |  | it('should pass page to close event', async ({ page, isAndroid, isWebView2 }) => { | 
					
						
							| 
									
										
										
										
											2021-04-09 07:59:09 -07:00
										 |  |  |   it.fixme(isAndroid); | 
					
						
							| 
									
										
										
										
											2022-09-07 20:09:22 +02:00
										 |  |  |   it.skip(isWebView2, 'Page.close() is not supported in WebView2'); | 
					
						
							| 
									
										
										
										
											2021-04-04 19:32:14 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-22 09:58:31 -08:00
										 |  |  |   const [closedPage] = await Promise.all([ | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  |     page.waitForEvent('close'), | 
					
						
							|  |  |  |     page.close() | 
					
						
							| 
									
										
										
										
											2021-01-22 09:58:31 -08:00
										 |  |  |   ]); | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  |   expect(closedPage).toBe(page); | 
					
						
							| 
									
										
										
										
											2021-01-22 09:58:31 -08:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-07 20:09:22 +02:00
										 |  |  | it('should terminate network waiters', async ({ page, server, isAndroid, isWebView2 }) => { | 
					
						
							| 
									
										
										
										
											2021-05-15 16:41:35 +02:00
										 |  |  |   it.fixme(isAndroid); | 
					
						
							| 
									
										
										
										
											2022-09-07 20:09:22 +02:00
										 |  |  |   it.skip(isWebView2, 'Page.close() is not supported in WebView2'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   const results = await Promise.all([ | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  |     page.waitForRequest(server.EMPTY_PAGE).catch(e => e), | 
					
						
							|  |  |  |     page.waitForResponse(server.EMPTY_PAGE).catch(e => e), | 
					
						
							|  |  |  |     page.close() | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   ]); | 
					
						
							|  |  |  |   for (let i = 0; i < 2; i++) { | 
					
						
							|  |  |  |     const message = results[i].message; | 
					
						
							|  |  |  |     expect(message).toContain('Page closed'); | 
					
						
							|  |  |  |     expect(message).not.toContain('Timeout'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-07 20:09:22 +02:00
										 |  |  | it('should be callable twice', async ({ page, isWebView2 }) => { | 
					
						
							|  |  |  |   it.skip(isWebView2, 'Page.close() is not supported in WebView2'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   await Promise.all([ | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  |     page.close(), | 
					
						
							|  |  |  |     page.close(), | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   ]); | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  |   await page.close(); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('should fire load when expected', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   await Promise.all([ | 
					
						
							|  |  |  |     page.goto('about:blank'), | 
					
						
							|  |  |  |     page.waitForEvent('load'), | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('async stacks should work', async ({ page, server }) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   server.setRoute('/empty.html', (req, res) => { | 
					
						
							|  |  |  |     req.socket.end(); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   let error = null; | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE).catch(e => error = e); | 
					
						
							|  |  |  |   expect(error).not.toBe(null); | 
					
						
							|  |  |  |   expect(error.stack).toContain(__filename); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('should provide access to the opener page', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   const [popup] = await Promise.all([ | 
					
						
							|  |  |  |     page.waitForEvent('popup'), | 
					
						
							|  |  |  |     page.evaluate(() => window.open('about:blank')), | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  |   const opener = await popup.opener(); | 
					
						
							|  |  |  |   expect(opener).toBe(page); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-07 20:09:22 +02:00
										 |  |  | it('should return null if parent page has been closed', async ({ page, isWebView2 }) => { | 
					
						
							|  |  |  |   it.skip(isWebView2, 'Page.close() is not supported in WebView2'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   const [popup] = await Promise.all([ | 
					
						
							|  |  |  |     page.waitForEvent('popup'), | 
					
						
							|  |  |  |     page.evaluate(() => window.open('about:blank')), | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  |   await page.close(); | 
					
						
							|  |  |  |   const opener = await popup.opener(); | 
					
						
							|  |  |  |   expect(opener).toBe(null); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('should fire domcontentloaded when expected', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   const navigatedPromise = page.goto('about:blank'); | 
					
						
							|  |  |  |   await page.waitForEvent('domcontentloaded'); | 
					
						
							|  |  |  |   await navigatedPromise; | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('should pass self as argument to domcontentloaded event', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2021-01-22 09:58:31 -08:00
										 |  |  |   const [eventArg] = await Promise.all([ | 
					
						
							|  |  |  |     new Promise(f => page.on('domcontentloaded', f)), | 
					
						
							|  |  |  |     page.goto('about:blank') | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  |   expect(eventArg).toBe(page); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('should pass self as argument to load event', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2021-01-22 09:58:31 -08:00
										 |  |  |   const [eventArg] = await Promise.all([ | 
					
						
							|  |  |  |     new Promise(f => page.on('load', f)), | 
					
						
							|  |  |  |     page.goto('about:blank') | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  |   expect(eventArg).toBe(page); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-07 20:09:22 +02:00
										 |  |  | it('should fail with error upon disconnect', async ({ page, isAndroid, isWebView2 }) => { | 
					
						
							|  |  |  |   it.skip(isWebView2, 'Page.close() is not supported in WebView2'); | 
					
						
							| 
									
										
										
										
											2021-04-09 07:59:09 -07:00
										 |  |  |   it.fixme(isAndroid); | 
					
						
							| 
									
										
										
										
											2021-04-04 19:32:14 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   let error; | 
					
						
							|  |  |  |   const waitForPromise = page.waitForEvent('download').catch(e => error = e); | 
					
						
							|  |  |  |   await page.close(); | 
					
						
							|  |  |  |   await waitForPromise; | 
					
						
							|  |  |  |   expect(error.message).toContain('Page closed'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-28 15:41:32 +02:00
										 |  |  | it('page.url should work', async ({ page, server }) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   expect(page.url()).toBe('about:blank'); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   expect(page.url()).toBe(server.EMPTY_PAGE); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('page.url should include hashes', async ({ page, server }) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   await page.goto(server.EMPTY_PAGE + '#hash'); | 
					
						
							|  |  |  |   expect(page.url()).toBe(server.EMPTY_PAGE + '#hash'); | 
					
						
							|  |  |  |   await page.evaluate(() => { | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |     window.location.hash = 'dynamic'; | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  |   expect(page.url()).toBe(server.EMPTY_PAGE + '#dynamic'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('page.title should return the page title', async ({ page, server }) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   await page.goto(server.PREFIX + '/title.html'); | 
					
						
							|  |  |  |   expect(await page.title()).toBe('Woof-Woof'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('page.close should work with window.close', async function({ page }) { | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   const newPagePromise = page.waitForEvent('popup'); | 
					
						
							|  |  |  |   await page.evaluate(() => window['newPage'] = window.open('about:blank')); | 
					
						
							|  |  |  |   const newPage = await newPagePromise; | 
					
						
							|  |  |  |   const closedPromise = new Promise(x => newPage.on('close', x)); | 
					
						
							|  |  |  |   await page.evaluate(() => window['newPage'].close()); | 
					
						
							|  |  |  |   await closedPromise; | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-07 20:09:22 +02:00
										 |  |  | it('page.close should work with page.close', async function({ page, isWebView2 }) { | 
					
						
							|  |  |  |   it.skip(isWebView2, 'Page.close() is not supported in WebView2'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  |   const closedPromise = new Promise(x => page.on('close', x)); | 
					
						
							|  |  |  |   await page.close(); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   await closedPromise; | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('page.frame should respect name', async function({ page }) { | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   await page.setContent(`<iframe name=target></iframe>`); | 
					
						
							|  |  |  |   expect(page.frame({ name: 'bogus' })).toBe(null); | 
					
						
							|  |  |  |   const frame = page.frame({ name: 'target' }); | 
					
						
							|  |  |  |   expect(frame).toBeTruthy(); | 
					
						
							|  |  |  |   expect(frame === page.mainFrame().childFrames()[0]).toBeTruthy(); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('page.frame should respect url', async function({ page, server }) { | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   await page.setContent(`<iframe src="${server.EMPTY_PAGE}"></iframe>`); | 
					
						
							|  |  |  |   expect(page.frame({ url: /bogus/ })).toBe(null); | 
					
						
							|  |  |  |   expect(page.frame({ url: /empty/ }).url()).toBe(server.EMPTY_PAGE); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('should have sane user agent', async ({ page, browserName, isElectron, isAndroid }) => { | 
					
						
							| 
									
										
										
										
											2021-04-09 07:59:09 -07:00
										 |  |  |   it.skip(isAndroid); | 
					
						
							|  |  |  |   it.skip(isElectron); | 
					
						
							| 
									
										
										
										
											2021-04-04 19:32:14 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   const userAgent = await page.evaluate(() => navigator.userAgent); | 
					
						
							|  |  |  |   const [ | 
					
						
							|  |  |  |     part1, | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |     /* part2 */, | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |     part3, | 
					
						
							|  |  |  |     part4, | 
					
						
							|  |  |  |     part5, | 
					
						
							|  |  |  |   ] = userAgent.split(/[()]/).map(part => part.trim()); | 
					
						
							|  |  |  |   // First part is always "Mozilla/5.0"
 | 
					
						
							|  |  |  |   expect(part1).toBe('Mozilla/5.0'); | 
					
						
							|  |  |  |   // Second part in parenthesis is platform - ignore it.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Third part for Firefox is the last one and encodes engine and browser versions.
 | 
					
						
							| 
									
										
										
										
											2021-05-13 10:22:23 -07:00
										 |  |  |   if (browserName === 'firefox') { | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |     const [engine, browser] = part3.split(' '); | 
					
						
							|  |  |  |     expect(engine.startsWith('Gecko')).toBe(true); | 
					
						
							|  |  |  |     expect(browser.startsWith('Firefox')).toBe(true); | 
					
						
							|  |  |  |     expect(part4).toBe(undefined); | 
					
						
							|  |  |  |     expect(part5).toBe(undefined); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2020-08-20 12:51:05 -07:00
										 |  |  |   // For both options.CHROMIUM and options.WEBKIT, third part is the AppleWebKit version.
 | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   expect(part3.startsWith('AppleWebKit/')).toBe(true); | 
					
						
							|  |  |  |   expect(part4).toBe('KHTML, like Gecko'); | 
					
						
							|  |  |  |   // 5th part encodes real browser name and engine version.
 | 
					
						
							|  |  |  |   const [engine, browser] = part5.split(' '); | 
					
						
							|  |  |  |   expect(browser.startsWith('Safari/')).toBe(true); | 
					
						
							| 
									
										
										
										
											2021-05-13 10:22:23 -07:00
										 |  |  |   if (browserName === 'chromium') | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |     expect(engine.includes('Chrome/')).toBe(true); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     expect(engine.startsWith('Version/')).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('page.press should work', async ({ page, server }) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   await page.goto(server.PREFIX + '/input/textarea.html'); | 
					
						
							|  |  |  |   await page.press('textarea', 'a'); | 
					
						
							|  |  |  |   expect(await page.evaluate(() => document.querySelector('textarea').value)).toBe('a'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('page.press should work for Enter', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-09-05 22:38:29 -07:00
										 |  |  |   await page.setContent(`<input onkeypress="console.log('press')"></input>`); | 
					
						
							|  |  |  |   const messages = []; | 
					
						
							|  |  |  |   page.on('console', message => messages.push(message)); | 
					
						
							|  |  |  |   await page.press('input', 'Enter'); | 
					
						
							|  |  |  |   expect(messages[0].text()).toBe('press'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('frame.press should work', async ({ page, server }) => { | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  |   await page.setContent(`<iframe name=inner src="${server.PREFIX}/input/textarea.html"></iframe>`); | 
					
						
							|  |  |  |   const frame = page.frame('inner'); | 
					
						
							|  |  |  |   await frame.press('textarea', 'a'); | 
					
						
							|  |  |  |   expect(await frame.evaluate(() => document.querySelector('textarea').value)).toBe('a'); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2022-11-28 18:03:49 -10:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-30 19:13:11 -08:00
										 |  |  | it('has navigator.webdriver set to true', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2022-11-28 18:03:49 -10:00
										 |  |  |   expect(await page.evaluate(() => navigator.webdriver)).toBe(true); | 
					
						
							|  |  |  | }); |