| 
									
										
										
										
											2020-08-03 15:23:53 -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. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-08-19 21:32:12 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-03 10:44:50 -07:00
										 |  |  | import { attachFrame, detachFrame } from '../config/utils'; | 
					
						
							| 
									
										
										
										
											2021-05-06 07:08:22 -07:00
										 |  |  | import { test as it, expect } from './pageTest'; | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-12-29 19:51:28 -07:00
										 |  |  | it('should work #smoke', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(() => 7 * 3); | 
					
						
							|  |  |  |   expect(result).toBe(21); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should transfer NaN', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(a => a, NaN); | 
					
						
							|  |  |  |   expect(Object.is(result, NaN)).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should transfer -0', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(a => a, -0); | 
					
						
							|  |  |  |   expect(Object.is(result, -0)).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should transfer Infinity', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(a => a, Infinity); | 
					
						
							|  |  |  |   expect(Object.is(result, Infinity)).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should transfer -Infinity', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(a => a, -Infinity); | 
					
						
							|  |  |  |   expect(Object.is(result, -Infinity)).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should roundtrip unserializable values', async ({ page }) => { | 
					
						
							|  |  |  |   const value = { | 
					
						
							|  |  |  |     infinity: Infinity, | 
					
						
							|  |  |  |     nInfinity: -Infinity, | 
					
						
							|  |  |  |     nZero: -0, | 
					
						
							|  |  |  |     nan: NaN, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   const result = await page.evaluate(value => value, value); | 
					
						
							|  |  |  |   expect(result).toEqual(value); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should roundtrip promise to value', async ({ page }) => { | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     const result = await page.evaluate(value => Promise.resolve(value), null); | 
					
						
							|  |  |  |     expect(result === null).toBeTruthy(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     const result = await page.evaluate(value => Promise.resolve(value), Infinity); | 
					
						
							|  |  |  |     expect(result === Infinity).toBeTruthy(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     const result = await page.evaluate(value => Promise.resolve(value), -0); | 
					
						
							|  |  |  |     expect(result === -0).toBeTruthy(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     const result = await page.evaluate(value => Promise.resolve(value), undefined); | 
					
						
							|  |  |  |     expect(result === undefined).toBeTruthy(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should roundtrip promise to unserializable values', async ({ page }) => { | 
					
						
							|  |  |  |   const value = { | 
					
						
							|  |  |  |     infinity: Infinity, | 
					
						
							|  |  |  |     nInfinity: -Infinity, | 
					
						
							|  |  |  |     nZero: -0, | 
					
						
							|  |  |  |     nan: NaN, | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   const result = await page.evaluate(value => Promise.resolve(value), value); | 
					
						
							|  |  |  |   expect(result).toEqual(value); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should transfer arrays', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(a => a, [1, 2, 3]); | 
					
						
							|  |  |  |   expect(result).toEqual([1, 2, 3]); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should transfer arrays as arrays, not objects', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(a => Array.isArray(a), [1, 2, 3]); | 
					
						
							|  |  |  |   expect(result).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should transfer maps as empty objects', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(a => a.x.constructor.name + ' ' + JSON.stringify(a.x), { x: new Map([[1, 2]]) }); | 
					
						
							|  |  |  |   expect(result).toBe('Object {}'); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should modify global environment', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |   await page.evaluate(() => window['globalVar'] = 123); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   expect(await page.evaluate('globalVar')).toBe(123); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should evaluate in the page context', async ({ page, server }) => { | 
					
						
							|  |  |  |   await page.goto(server.PREFIX + '/global-var.html'); | 
					
						
							|  |  |  |   expect(await page.evaluate('globalVar')).toBe(123); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should return undefined for objects with symbols', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   expect(await page.evaluate(() => [Symbol('foo4')])).toEqual([undefined]); | 
					
						
							|  |  |  |   expect(await page.evaluate(() => { | 
					
						
							|  |  |  |     const a = {}; | 
					
						
							|  |  |  |     a[Symbol('foo4')] = 42; | 
					
						
							|  |  |  |     return a; | 
					
						
							|  |  |  |   })).toEqual({}); | 
					
						
							|  |  |  |   expect(await page.evaluate(() => { | 
					
						
							|  |  |  |     return { foo: [{ a: Symbol('foo4') }] }; | 
					
						
							|  |  |  |   })).toEqual({ foo: [{ a: undefined }] }); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should work with function shorthands', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const a = { | 
					
						
							| 
									
										
										
										
											2021-04-02 14:23:42 -07:00
										 |  |  |     sum([a, b]: number[]) { return a + b; }, | 
					
						
							|  |  |  |     async mult([a, b]: number[]) { return a * b; } | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   }; | 
					
						
							|  |  |  |   expect(await page.evaluate(a.sum, [1, 2])).toBe(3); | 
					
						
							|  |  |  |   expect(await page.evaluate(a.mult, [2, 4])).toBe(8); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should work with unicode chars', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(a => a['中文字符'], { '中文字符': 42 }); | 
					
						
							|  |  |  |   expect(result).toBe(42); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should throw when evaluation triggers reload', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   let error = null; | 
					
						
							|  |  |  |   await page.evaluate(() => { | 
					
						
							|  |  |  |     location.reload(); | 
					
						
							|  |  |  |     return new Promise(() => { }); | 
					
						
							|  |  |  |   }).catch(e => error = e); | 
					
						
							|  |  |  |   expect(error.message).toContain('navigation'); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should await promise', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(() => Promise.resolve(8 * 7)); | 
					
						
							|  |  |  |   expect(result).toBe(56); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should work right after framenavigated', async ({ page, server }) => { | 
					
						
							|  |  |  |   let frameEvaluation = null; | 
					
						
							|  |  |  |   page.on('framenavigated', async frame => { | 
					
						
							|  |  |  |     frameEvaluation = frame.evaluate(() => 6 * 7); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   expect(await frameEvaluation).toBe(42); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should work right after a cross-origin navigation', async ({ page, server }) => { | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   let frameEvaluation = null; | 
					
						
							|  |  |  |   page.on('framenavigated', async frame => { | 
					
						
							|  |  |  |     frameEvaluation = frame.evaluate(() => 6 * 7); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   await page.goto(server.CROSS_PROCESS_PREFIX + '/empty.html'); | 
					
						
							|  |  |  |   expect(await frameEvaluation).toBe(42); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should work from-inside an exposed function', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   // Setup inpage callback, which calls Page.evaluate
 | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   await page.exposeFunction('callController', async function(a, b) { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |     return await page.evaluate(({ a, b }) => a * b, { a, b }); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   const result = await page.evaluate(async function() { | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |     return await window['callController'](9, 3); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  |   expect(result).toBe(27); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should reject promise with exception', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   let error = null; | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.evaluate(() => not_existing_object.property).catch(e => error = e); | 
					
						
							|  |  |  |   expect(error).toBeTruthy(); | 
					
						
							|  |  |  |   expect(error.message).toContain('not_existing_object'); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should support thrown strings as error messages', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   let error = null; | 
					
						
							|  |  |  |   await page.evaluate(() => { throw 'qwerty'; }).catch(e => error = e); | 
					
						
							|  |  |  |   expect(error).toBeTruthy(); | 
					
						
							|  |  |  |   expect(error.message).toContain('qwerty'); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should support thrown numbers as error messages', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   let error = null; | 
					
						
							|  |  |  |   await page.evaluate(() => { throw 100500; }).catch(e => error = e); | 
					
						
							|  |  |  |   expect(error).toBeTruthy(); | 
					
						
							|  |  |  |   expect(error.message).toContain('100500'); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should return complex objects', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const object = { foo: 'bar!' }; | 
					
						
							|  |  |  |   const result = await page.evaluate(a => a, object); | 
					
						
							|  |  |  |   expect(result).not.toBe(object); | 
					
						
							|  |  |  |   expect(result).toEqual(object); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should return NaN', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(() => NaN); | 
					
						
							|  |  |  |   expect(Object.is(result, NaN)).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should return -0', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(() => -0); | 
					
						
							|  |  |  |   expect(Object.is(result, -0)).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should return Infinity', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(() => Infinity); | 
					
						
							|  |  |  |   expect(Object.is(result, Infinity)).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should return -Infinity', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(() => -Infinity); | 
					
						
							|  |  |  |   expect(Object.is(result, -Infinity)).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should work with overwritten Promise', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.evaluate(() => { | 
					
						
							|  |  |  |     const originalPromise = window.Promise; | 
					
						
							|  |  |  |     class Promise2 { | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |       _promise: Promise<any>; | 
					
						
							|  |  |  |       static all(arg) { | 
					
						
							|  |  |  |         return wrap(originalPromise.all(arg)); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |       static race(arg) { | 
					
						
							|  |  |  |         return wrap(originalPromise.race(arg)); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |       static resolve(arg) { | 
					
						
							|  |  |  |         return wrap(originalPromise.resolve(arg)); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |       constructor(f) { | 
					
						
							|  |  |  |         this._promise = new originalPromise(f); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |       } | 
					
						
							|  |  |  |       then(f, r) { | 
					
						
							|  |  |  |         return wrap(this._promise.then(f, r)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       catch(f) { | 
					
						
							|  |  |  |         return wrap(this._promise.catch(f)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       finally(f) { | 
					
						
							|  |  |  |         return wrap(this._promise.finally(f)); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |     const wrap = p => { | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |       const result = new Promise2(() => { }); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |       result._promise = p; | 
					
						
							|  |  |  |       return result; | 
					
						
							|  |  |  |     }; | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |     // @ts-ignore;
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |     window.Promise = Promise2; | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |     window['__Promise2'] = Promise2; | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Sanity check.
 | 
					
						
							|  |  |  |   expect(await page.evaluate(() => { | 
					
						
							|  |  |  |     const p = Promise.all([Promise.race([]), new Promise(() => { }).then(() => { })]); | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |     return p instanceof window['__Promise2']; | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   })).toBe(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Now, the new promise should be awaitable.
 | 
					
						
							|  |  |  |   expect(await page.evaluate(() => Promise.resolve(42))).toBe(42); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should throw when passed more than one parameter', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const expectThrow = async f => { | 
					
						
							|  |  |  |     let error; | 
					
						
							|  |  |  |     await f().catch(e => error = e); | 
					
						
							|  |  |  |     expect('' + error).toContain('Too many arguments'); | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   }; | 
					
						
							|  |  |  |   // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await expectThrow(() => page.evaluate((a, b) => false, 1, 2)); | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await expectThrow(() => page.evaluateHandle((a, b) => false, 1, 2)); | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await expectThrow(() => page.$eval('sel', (a, b) => false, 1, 2)); | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await expectThrow(() => page.$$eval('sel', (a, b) => false, 1, 2)); | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await expectThrow(() => page.evaluate((a, b) => false, 1, 2)); | 
					
						
							|  |  |  |   const frame = page.mainFrame(); | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await expectThrow(() => frame.evaluate((a, b) => false, 1, 2)); | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await expectThrow(() => frame.evaluateHandle((a, b) => false, 1, 2)); | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await expectThrow(() => frame.$eval('sel', (a, b) => false, 1, 2)); | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await expectThrow(() => frame.$$eval('sel', (a, b) => false, 1, 2)); | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await expectThrow(() => frame.evaluate((a, b) => false, 1, 2)); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should accept "undefined" as one of multiple parameters', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(({ a, b }) => Object.is(a, undefined) && Object.is(b, 'foo'), { a: undefined, b: 'foo' }); | 
					
						
							|  |  |  |   expect(result).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should properly serialize undefined arguments', async ({ page }) => { | 
					
						
							|  |  |  |   expect(await page.evaluate(x => ({ a: x }), undefined)).toEqual({}); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should properly serialize undefined fields', async ({ page }) => { | 
					
						
							|  |  |  |   expect(await page.evaluate(() => ({ a: undefined }))).toEqual({}); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should return undefined properties', async ({ page }) => { | 
					
						
							|  |  |  |   const value = await page.evaluate(() => ({ a: undefined })); | 
					
						
							|  |  |  |   expect('a' in value).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should properly serialize null arguments', async ({ page }) => { | 
					
						
							|  |  |  |   expect(await page.evaluate(x => x, null)).toEqual(null); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should properly serialize null fields', async ({ page }) => { | 
					
						
							|  |  |  |   expect(await page.evaluate(() => ({ a: null }))).toEqual({ a: null }); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should return undefined for non-serializable objects', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   expect(await page.evaluate(() => window)).toBe(undefined); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should fail for circular object', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(() => { | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |     const a = {} as any; | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |     const b = { a }; | 
					
						
							|  |  |  |     a.b = b; | 
					
						
							|  |  |  |     return a; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   expect(result).toBe(undefined); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should be able to throw a tricky error', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const windowHandle = await page.evaluateHandle(() => window); | 
					
						
							|  |  |  |   const errorText = await windowHandle.jsonValue().catch(e => e.message); | 
					
						
							|  |  |  |   const error = await page.evaluate(errorText => { | 
					
						
							|  |  |  |     throw new Error(errorText); | 
					
						
							|  |  |  |   }, errorText).catch(e => e); | 
					
						
							|  |  |  |   expect(error.message).toContain(errorText); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should accept a string', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate('1 + 2'); | 
					
						
							|  |  |  |   expect(result).toBe(3); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should accept a string with semi colons', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate('1 + 5;'); | 
					
						
							|  |  |  |   expect(result).toBe(6); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should accept a string with comments', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate('2 + 5;\n// do some math!'); | 
					
						
							|  |  |  |   expect(result).toBe(7); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should accept element handle as an argument', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section>42</section>'); | 
					
						
							|  |  |  |   const element = await page.$('section'); | 
					
						
							|  |  |  |   const text = await page.evaluate(e => e.textContent, element); | 
					
						
							|  |  |  |   expect(text).toBe('42'); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should throw if underlying element was disposed', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await page.setContent('<section>39</section>'); | 
					
						
							|  |  |  |   const element = await page.$('section'); | 
					
						
							|  |  |  |   expect(element).toBeTruthy(); | 
					
						
							|  |  |  |   await element.dispose(); | 
					
						
							|  |  |  |   let error = null; | 
					
						
							|  |  |  |   await page.evaluate(e => e.textContent, element).catch(e => error = e); | 
					
						
							|  |  |  |   expect(error.message).toContain('JSHandle is disposed'); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should simulate a user gesture', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(() => { | 
					
						
							|  |  |  |     document.body.appendChild(document.createTextNode('test')); | 
					
						
							|  |  |  |     document.execCommand('selectAll'); | 
					
						
							|  |  |  |     return document.execCommand('copy'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   expect(result).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-19 07:20:35 +08:00
										 |  |  | it('should throw a nice error after a navigation', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |   const errorPromise = page.evaluate(() => new Promise(f => window['__resolve'] = f)).catch(e => e) as Promise<Error>; | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   await Promise.all([ | 
					
						
							|  |  |  |     page.waitForNavigation(), | 
					
						
							|  |  |  |     page.evaluate(() => { | 
					
						
							|  |  |  |       window.location.reload(); | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |       setTimeout(() => window['__resolve'](42), 1000); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |     }) | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  |   const error = await errorPromise; | 
					
						
							|  |  |  |   expect(error.message).toContain('navigation'); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should not throw an error when evaluation does a navigation', async ({ page, server }) => { | 
					
						
							|  |  |  |   await page.goto(server.PREFIX + '/one-style.html'); | 
					
						
							|  |  |  |   const result = await page.evaluate(() => { | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |     window.location.href = '/empty.html'; | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |     return [42]; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   expect(result).toEqual([42]); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-13 10:22:23 -07:00
										 |  |  | it('should not throw an error when evaluation does a synchronous navigation and returns an object', async ({ page, server, browserName }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   // It is imporant to be on about:blank for sync reload.
 | 
					
						
							|  |  |  |   const result = await page.evaluate(() => { | 
					
						
							|  |  |  |     window.location.reload(); | 
					
						
							|  |  |  |     return { a: 42 }; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   expect(result).toEqual({ a: 42 }); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-26 16:05:58 -07:00
										 |  |  | it('should not throw an error when evaluation does a synchronous navigation and returns undefined', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   // It is imporant to be on about:blank for sync reload.
 | 
					
						
							|  |  |  |   const result = await page.evaluate(() => { | 
					
						
							|  |  |  |     window.location.reload(); | 
					
						
							|  |  |  |     return undefined; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   expect(result).toBe(undefined); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-02 14:23:42 -07:00
										 |  |  | it('should transfer 100Mb of data from page to node.js', async ({ mode, page }) => { | 
					
						
							|  |  |  |   it.skip(mode !== 'default'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-13 16:00:23 -07:00
										 |  |  |   // This is too slow with wire.
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const a = await page.evaluate(() => Array(100 * 1024 * 1024 + 1).join('a')); | 
					
						
							|  |  |  |   expect(a.length).toBe(100 * 1024 * 1024); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-26 16:05:58 -07:00
										 |  |  | it('should throw error with detailed information on exception inside promise ', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   let error = null; | 
					
						
							|  |  |  |   await page.evaluate(() => new Promise(() => { | 
					
						
							|  |  |  |     throw new Error('Error in promise'); | 
					
						
							|  |  |  |   })).catch(e => error = e); | 
					
						
							|  |  |  |   expect(error.message).toContain('Error in promise'); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should work even when JSON is set to null', async ({ page }) => { | 
					
						
							|  |  |  |   await page.evaluate(() => { window.JSON.stringify = null; window.JSON = null; }); | 
					
						
							|  |  |  |   const result = await page.evaluate(() => ({ abc: 123 })); | 
					
						
							|  |  |  |   expect(result).toEqual({ abc: 123 }); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-28 00:32:00 -07:00
										 |  |  | it('should await promise from popup', async ({ page, server }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   // Something is wrong about the way Firefox waits for the chained promise
 | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   const result = await page.evaluate(() => { | 
					
						
							|  |  |  |     const win = window.open('about:blank'); | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |     return new win['Promise'](f => f(42)); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  |   expect(result).toBe(42); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should work with new Function() and CSP', async ({ page, server }) => { | 
					
						
							|  |  |  |   server.setCSP('/empty.html', 'script-src ' + server.PREFIX); | 
					
						
							|  |  |  |   await page.goto(server.PREFIX + '/empty.html'); | 
					
						
							|  |  |  |   expect(await page.evaluate(() => new Function('return true')())).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should work with non-strict expressions', async ({ page, server }) => { | 
					
						
							|  |  |  |   expect(await page.evaluate(() => { | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |     // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |     y = 3.14; | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |     // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |     return y; | 
					
						
							|  |  |  |   })).toBe(3.14); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-26 16:05:58 -07:00
										 |  |  | it('should respect use strict expression', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const error = await page.evaluate(() => { | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |     'use strict'; | 
					
						
							|  |  |  |     // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |     variableY = 3.14; | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |     // @ts-ignore
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |     return variableY; | 
					
						
							|  |  |  |   }).catch(e => e); | 
					
						
							|  |  |  |   expect(error.message).toContain('variableY'); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-26 16:05:58 -07:00
										 |  |  | it('should not leak utility script', async function({ page }) { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   expect(await page.evaluate(() => this === window)).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-26 16:05:58 -07:00
										 |  |  | it('should not leak handles', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |   const error = await page.evaluate('handles.length').catch(e => e); | 
					
						
							|  |  |  |   expect((error as Error).message).toContain(' handles'); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should work with CSP', async ({ page, server }) => { | 
					
						
							|  |  |  |   server.setCSP('/empty.html', `script-src 'self'`); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   expect(await page.evaluate(() => 2 + 2)).toBe(4); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-07-09 08:36:11 +02:00
										 |  |  | it('should evaluate exception with a function on the stack', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const error = await page.evaluate(() => { | 
					
						
							|  |  |  |     return (function functionOnStack() { | 
					
						
							|  |  |  |       return new Error('error message'); | 
					
						
							|  |  |  |     })(); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   expect(error).toContain('Error: error message'); | 
					
						
							|  |  |  |   expect(error).toContain('functionOnStack'); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-26 16:05:58 -07:00
										 |  |  | it('should evaluate exception', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const error = await page.evaluate(`new Error('error message')`); | 
					
						
							|  |  |  |   expect(error).toContain('Error: error message'); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should evaluate date', async ({ page }) => { | 
					
						
							|  |  |  |   const result = await page.evaluate(() => ({ date: new Date('2020-05-27T01:31:38.506Z') })); | 
					
						
							|  |  |  |   expect(result).toEqual({ date: new Date('2020-05-27T01:31:38.506Z') }); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should roundtrip date', async ({ page }) => { | 
					
						
							|  |  |  |   const date = new Date('2020-05-27T01:31:38.506Z'); | 
					
						
							|  |  |  |   const result = await page.evaluate(date => date, date); | 
					
						
							|  |  |  |   expect(result.toUTCString()).toEqual(date.toUTCString()); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should roundtrip regex', async ({ page }) => { | 
					
						
							|  |  |  |   const regex = /hello/im; | 
					
						
							|  |  |  |   const result = await page.evaluate(regex => regex, regex); | 
					
						
							|  |  |  |   expect(result.toString()).toEqual(regex.toString()); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | it('should jsonValue() date', async ({ page }) => { | 
					
						
							|  |  |  |   const resultHandle = await page.evaluateHandle(() => ({ date: new Date('2020-05-27T01:31:38.506Z') })); | 
					
						
							|  |  |  |   expect(await resultHandle.jsonValue()).toEqual({ date: new Date('2020-05-27T01:31:38.506Z') }); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-26 16:05:58 -07:00
										 |  |  | it('should not use toJSON when evaluating', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const result = await page.evaluate(() => ({ toJSON: () => 'string', data: 'data' })); | 
					
						
							|  |  |  |   expect(result).toEqual({ data: 'data', toJSON: {} }); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2020-08-04 15:09:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 10:53:30 -07:00
										 |  |  | it('should not use Array.prototype.toJSON when evaluating', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2021-05-26 23:02:21 +00:00
										 |  |  |   const result = await page.evaluate(() => { | 
					
						
							|  |  |  |     (Array.prototype as any).toJSON = () => 'busted'; | 
					
						
							|  |  |  |     return [1, 2, 3]; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   expect(result).toEqual([1,2,3]); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-10 10:53:30 -07:00
										 |  |  | it('should not add a toJSON property to newly created Arrays after evaluation', async ({ page, browserName }) => { | 
					
						
							|  |  |  |   await page.evaluate(() => []); | 
					
						
							| 
									
										
										
										
											2021-06-23 11:08:35 +02:00
										 |  |  |   const hasToJSONProperty = await page.evaluate(() => 'toJSON' in []); | 
					
						
							| 
									
										
										
										
											2021-06-10 10:53:30 -07:00
										 |  |  |   expect(hasToJSONProperty).toEqual(false); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-26 16:05:58 -07:00
										 |  |  | it('should not use toJSON in jsonValue', async ({ page }) => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const resultHandle = await page.evaluateHandle(() => ({ toJSON: () => 'string', data: 'data' })); | 
					
						
							|  |  |  |   expect(await resultHandle.jsonValue()).toEqual({ data: 'data', toJSON: {} }); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2021-01-08 16:15:05 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | it('should not expose the injected script export', async ({ page }) => { | 
					
						
							|  |  |  |   expect(await page.evaluate('typeof pwExport === "undefined"')).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2021-11-03 10:44:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | it('should throw when frame is detached', async ({ page, server }) => { | 
					
						
							|  |  |  |   await attachFrame(page, 'frame1', server.EMPTY_PAGE); | 
					
						
							|  |  |  |   const frame = page.frames()[1]; | 
					
						
							|  |  |  |   const promise = frame.evaluate(() => new Promise<void>(() => {})).catch(e => e); | 
					
						
							|  |  |  |   await detachFrame(page, 'frame1'); | 
					
						
							|  |  |  |   const error = await promise; | 
					
						
							|  |  |  |   expect(error).toBeTruthy(); | 
					
						
							|  |  |  |   expect(error.message).toMatch(/frame.evaluate: (Frame was detached|Execution context was destroyed)/); | 
					
						
							|  |  |  | }); |