| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * Copyright (c) Microsoft Corporation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
					
						
							|  |  |  |  * you may not use this file except in compliance with the License. | 
					
						
							|  |  |  |  * You may obtain a copy of the License at | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Unless required by applicable law or agreed to in writing, software | 
					
						
							|  |  |  |  * distributed under the License is distributed on an "AS IS" BASIS, | 
					
						
							|  |  |  |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
					
						
							|  |  |  |  * See the License for the specific language governing permissions and | 
					
						
							|  |  |  |  * limitations under the License. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2020-09-02 21:43:38 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-25 15:05:50 -08:00
										 |  |  | import { browserTest as it, expect } from '../config/browserTest'; | 
					
						
							| 
									
										
										
										
											2022-06-01 20:24:25 -07:00
										 |  |  | import type { Page } from 'playwright-core'; | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-10 19:42:52 +01:00
										 |  |  | it('should inherit user agent from browser context @smoke', async function({ browser, server }) { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const context = await browser.newContext({ | 
					
						
							|  |  |  |     userAgent: 'hey' | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   const page = await context.newPage(); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   await page.setContent('<a target=_blank rel=noopener href="/popup/popup.html">link</a>'); | 
					
						
							|  |  |  |   const requestPromise = server.waitForRequest('/popup/popup.html'); | 
					
						
							|  |  |  |   const [popup] = await Promise.all([ | 
					
						
							|  |  |  |     context.waitForEvent('page'), | 
					
						
							|  |  |  |     page.click('a'), | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  |   await popup.waitForLoadState('domcontentloaded'); | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   const userAgent = await popup.evaluate(() => window['initialUserAgent']); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const request = await requestPromise; | 
					
						
							|  |  |  |   await context.close(); | 
					
						
							|  |  |  |   expect(userAgent).toBe('hey'); | 
					
						
							|  |  |  |   expect(request.headers['user-agent']).toBe('hey'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('should respect routes from browser context', async function({ browser, server }) { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const context = await browser.newContext(); | 
					
						
							|  |  |  |   const page = await context.newPage(); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   await page.setContent('<a target=_blank rel=noopener href="empty.html">link</a>'); | 
					
						
							|  |  |  |   let intercepted = false; | 
					
						
							|  |  |  |   await context.route('**/empty.html', route => { | 
					
						
							| 
									
										
										
										
											2023-06-02 21:59:12 +02:00
										 |  |  |     void route.continue(); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |     intercepted = true; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   await Promise.all([ | 
					
						
							|  |  |  |     context.waitForEvent('page'), | 
					
						
							|  |  |  |     page.click('a'), | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  |   await context.close(); | 
					
						
							|  |  |  |   expect(intercepted).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('should inherit extra headers from browser context', async function({ browser, server }) { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const context = await browser.newContext({ | 
					
						
							|  |  |  |     extraHTTPHeaders: { 'foo': 'bar' }, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   const page = await context.newPage(); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   const requestPromise = server.waitForRequest('/dummy.html'); | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |   await page.evaluate(url => window['_popup'] = window.open(url), server.PREFIX + '/dummy.html'); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const request = await requestPromise; | 
					
						
							|  |  |  |   await context.close(); | 
					
						
							|  |  |  |   expect(request.headers['foo']).toBe('bar'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('should inherit offline from browser context', async function({ browser, server }) { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const context = await browser.newContext(); | 
					
						
							|  |  |  |   const page = await context.newPage(); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   await context.setOffline(true); | 
					
						
							|  |  |  |   const online = await page.evaluate(url => { | 
					
						
							|  |  |  |     const win = window.open(url); | 
					
						
							|  |  |  |     return win.navigator.onLine; | 
					
						
							|  |  |  |   }, server.PREFIX + '/dummy.html'); | 
					
						
							|  |  |  |   await context.close(); | 
					
						
							|  |  |  |   expect(online).toBe(false); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('should inherit http credentials from browser context', async function({ browser, server }) { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   server.setAuth('/title.html', 'user', 'pass'); | 
					
						
							|  |  |  |   const context = await browser.newContext({ | 
					
						
							|  |  |  |     httpCredentials: { username: 'user', password: 'pass' } | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   const page = await context.newPage(); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   const [popup] = await Promise.all([ | 
					
						
							|  |  |  |     page.waitForEvent('popup'), | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |     page.evaluate(url => window['_popup'] = window.open(url), server.PREFIX + '/title.html'), | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   ]); | 
					
						
							|  |  |  |   await popup.waitForLoadState('domcontentloaded'); | 
					
						
							|  |  |  |   expect(await popup.title()).toBe('Woof-Woof'); | 
					
						
							|  |  |  |   await context.close(); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('should inherit touch support from browser context', async function({ browser, server }) { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const context = await browser.newContext({ | 
					
						
							|  |  |  |     viewport: { width: 400, height: 500 }, | 
					
						
							|  |  |  |     hasTouch: true | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   const page = await context.newPage(); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   const hasTouch = await page.evaluate(() => { | 
					
						
							|  |  |  |     const win = window.open(''); | 
					
						
							|  |  |  |     return 'ontouchstart' in win; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   await context.close(); | 
					
						
							|  |  |  |   expect(hasTouch).toBe(true); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('should inherit viewport size from browser context', async function({ browser, server }) { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const context = await browser.newContext({ | 
					
						
							|  |  |  |     viewport: { width: 400, height: 500 } | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   const page = await context.newPage(); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   const size = await page.evaluate(() => { | 
					
						
							|  |  |  |     const win = window.open('about:blank'); | 
					
						
							|  |  |  |     return { width: win.innerWidth, height: win.innerHeight }; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   await context.close(); | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  |   expect(size).toEqual({ width: 400, height: 500 }); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-27 01:01:10 -07:00
										 |  |  | it('should use viewport size from window features', async function({ browser, server, browserName }) { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const context = await browser.newContext({ | 
					
						
							|  |  |  |     viewport: { width: 700, height: 700 } | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   const page = await context.newPage(); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   const [size, popup] = await Promise.all([ | 
					
						
							| 
									
										
										
										
											2022-06-30 15:58:11 +02:00
										 |  |  |     page.evaluate(async () => { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |       const win = window.open(window.location.href, 'Title', 'toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=600,height=300,top=0,left=0'); | 
					
						
							| 
									
										
										
										
											2022-06-30 15:58:11 +02:00
										 |  |  |       await new Promise<void>(resolve => { | 
					
						
							|  |  |  |         const interval = setInterval(() => { | 
					
						
							|  |  |  |           if (win.innerWidth === 600 && win.innerHeight === 300) { | 
					
						
							|  |  |  |             clearInterval(interval); | 
					
						
							|  |  |  |             resolve(); | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         }, 10); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |       return { width: win.innerWidth, height: win.innerHeight }; | 
					
						
							|  |  |  |     }), | 
					
						
							|  |  |  |     page.waitForEvent('popup'), | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  |   await popup.setViewportSize({ width: 500, height: 400 }); | 
					
						
							|  |  |  |   await popup.waitForLoadState(); | 
					
						
							|  |  |  |   const resized = await popup.evaluate(() => ({ width: window.innerWidth, height: window.innerHeight })); | 
					
						
							|  |  |  |   await context.close(); | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  |   expect(size).toEqual({ width: 600, height: 300 }); | 
					
						
							|  |  |  |   expect(resized).toEqual({ width: 500, height: 400 }); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('should respect routes from browser context when using window.open', async function({ browser, server }) { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const context = await browser.newContext(); | 
					
						
							|  |  |  |   const page = await context.newPage(); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   let intercepted = false; | 
					
						
							|  |  |  |   await context.route('**/empty.html', route => { | 
					
						
							| 
									
										
										
										
											2023-06-02 21:59:12 +02:00
										 |  |  |     void route.continue(); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |     intercepted = true; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   await Promise.all([ | 
					
						
							|  |  |  |     page.waitForEvent('popup'), | 
					
						
							| 
									
										
										
										
											2020-08-28 04:20:29 -07:00
										 |  |  |     page.evaluate(url => window['__popup'] = window.open(url), server.EMPTY_PAGE), | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   ]); | 
					
						
							|  |  |  |   expect(intercepted).toBe(true); | 
					
						
							|  |  |  |   await context.close(); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('BrowserContext.addInitScript should apply to an in-process popup', async function({ browser, server }) { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const context = await browser.newContext(); | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |   await context.addInitScript(() => window['injected'] = 123); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const page = await context.newPage(); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   const injected = await page.evaluate(() => { | 
					
						
							|  |  |  |     const win = window.open('about:blank'); | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |     return win['injected']; | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  |   await context.close(); | 
					
						
							|  |  |  |   expect(injected).toBe(123); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('BrowserContext.addInitScript should apply to a cross-process popup', async function({ browser, server }) { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const context = await browser.newContext(); | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |   await context.addInitScript(() => window['injected'] = 123); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const page = await context.newPage(); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   const [popup] = await Promise.all([ | 
					
						
							|  |  |  |     page.waitForEvent('popup'), | 
					
						
							|  |  |  |     page.evaluate(url => window.open(url), server.CROSS_PROCESS_PREFIX + '/title.html'), | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  |   expect(await popup.evaluate('injected')).toBe(123); | 
					
						
							|  |  |  |   await popup.reload(); | 
					
						
							|  |  |  |   expect(await popup.evaluate('injected')).toBe(123); | 
					
						
							|  |  |  |   await context.close(); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('should expose function from browser context', async function({ browser, server }) { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const context = await browser.newContext(); | 
					
						
							|  |  |  |   const messages = []; | 
					
						
							|  |  |  |   await context.exposeFunction('add', (a, b) => { | 
					
						
							|  |  |  |     messages.push('binding'); | 
					
						
							|  |  |  |     return a + b; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   const page = await context.newPage(); | 
					
						
							|  |  |  |   context.on('page', () => messages.push('page')); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   const added = await page.evaluate(async () => { | 
					
						
							|  |  |  |     const win = window.open('about:blank'); | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |     return win['add'](9, 4); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  |   await context.close(); | 
					
						
							|  |  |  |   expect(added).toBe(13); | 
					
						
							|  |  |  |   expect(messages.join('|')).toBe('page|binding'); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-09-27 18:58:08 +02:00
										 |  |  | it('should not dispatch binding on a closed page', async function({ browser, server, browserName }) { | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   const context = await browser.newContext(); | 
					
						
							|  |  |  |   const messages = []; | 
					
						
							|  |  |  |   await context.exposeFunction('add', (a, b) => { | 
					
						
							|  |  |  |     messages.push('binding'); | 
					
						
							|  |  |  |     return a + b; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   const page = await context.newPage(); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   await Promise.all([ | 
					
						
							|  |  |  |     page.waitForEvent('popup').then(popup => { | 
					
						
							|  |  |  |       if (popup.isClosed()) | 
					
						
							| 
									
										
										
										
											2020-08-20 19:48:56 -07:00
										 |  |  |         messages.push('close'); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |       else | 
					
						
							|  |  |  |         return popup.waitForEvent('close').then(() => messages.push('close')); | 
					
						
							|  |  |  |     }), | 
					
						
							|  |  |  |     page.evaluate(async () => { | 
					
						
							|  |  |  |       const win = window.open('about:blank'); | 
					
						
							| 
									
										
										
										
											2020-08-11 15:50:53 -07:00
										 |  |  |       win['add'](9, 4); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |       win.close(); | 
					
						
							|  |  |  |     }), | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  |   await context.close(); | 
					
						
							| 
									
										
										
										
											2021-05-13 10:22:23 -07:00
										 |  |  |   if (browserName === 'firefox') | 
					
						
							| 
									
										
										
										
											2020-08-20 16:51:17 -07:00
										 |  |  |     expect(messages.join('|')).toBe('close'); | 
					
						
							| 
									
										
										
										
											2020-08-03 15:23:53 -07:00
										 |  |  |   else | 
					
						
							|  |  |  |     expect(messages.join('|')).toBe('binding|close'); | 
					
						
							|  |  |  | }); | 
					
						
							| 
									
										
										
										
											2022-06-01 20:24:25 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-06-06 09:18:30 -07:00
										 |  |  | it('should not throttle rAF in the opener page', async ({ page, server }) => { | 
					
						
							| 
									
										
										
										
											2022-06-01 20:24:25 -07:00
										 |  |  |   it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/14557' }); | 
					
						
							|  |  |  |   await page.goto(server.EMPTY_PAGE); | 
					
						
							|  |  |  |   const [popup] = await Promise.all([ | 
					
						
							|  |  |  |     page.waitForEvent('popup'), | 
					
						
							|  |  |  |     page.evaluate(() => { window.open('about:blank'); }), | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  |   await Promise.all([ | 
					
						
							|  |  |  |     waitForRafs(page, 30), | 
					
						
							|  |  |  |     waitForRafs(popup, 30) | 
					
						
							|  |  |  |   ]); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | async function waitForRafs(page: Page, count: number): Promise<void> { | 
					
						
							|  |  |  |   await page.evaluate(count => new Promise<void>(resolve => { | 
					
						
							|  |  |  |     const onRaf = () => { | 
					
						
							|  |  |  |       --count; | 
					
						
							|  |  |  |       if (!count) | 
					
						
							|  |  |  |         resolve(); | 
					
						
							|  |  |  |       else | 
					
						
							|  |  |  |         requestAnimationFrame(onRaf); | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |     requestAnimationFrame(onRaf); | 
					
						
							|  |  |  |   }), count); | 
					
						
							|  |  |  | } |