2020-08-03 23:41:48 +03: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-17 05:19:52 +03:00
2021-05-08 01:25:55 +03:00
import { playwrightTest as it , expect } from './config/browserTest' ;
2020-08-07 21:19:15 +03:00
import fs from 'fs' ;
2020-08-03 23:41:48 +03:00
2021-09-27 19:58:08 +03:00
it ( 'should support hasTouch option' , async ( { server , launchPersistent } ) = > {
const { page } = await launchPersistent ( { hasTouch : true } ) ;
2020-08-03 23:41:48 +03:00
await page . goto ( server . PREFIX + '/mobile.html' ) ;
expect ( await page . evaluate ( ( ) = > 'ontouchstart' in window ) ) . toBe ( true ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should work in persistent context' , async ( { server , launchPersistent , browserName } ) = > {
2021-04-03 07:07:45 +03:00
it . skip ( browserName === 'firefox' , 'Firefox does not support mobile' ) ;
2021-09-27 19:58:08 +03:00
const { page } = await launchPersistent ( { viewport : { width : 320 , height : 480 } , isMobile : true } ) ;
2020-08-03 23:41:48 +03:00
await page . goto ( server . PREFIX + '/empty.html' ) ;
expect ( await page . evaluate ( ( ) = > window . innerWidth ) ) . toBe ( 980 ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should support colorScheme option' , async ( { launchPersistent } ) = > {
const { page } = await launchPersistent ( { colorScheme : 'dark' } ) ;
2020-08-03 23:41:48 +03:00
expect ( await page . evaluate ( ( ) = > matchMedia ( '(prefers-color-scheme: light)' ) . matches ) ) . toBe ( false ) ;
expect ( await page . evaluate ( ( ) = > matchMedia ( '(prefers-color-scheme: dark)' ) . matches ) ) . toBe ( true ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should support reducedMotion option' , async ( { launchPersistent } ) = > {
const { page } = await launchPersistent ( { reducedMotion : 'reduce' } ) ;
2021-05-22 02:56:09 +03:00
expect ( await page . evaluate ( ( ) = > matchMedia ( '(prefers-reduced-motion: reduce)' ) . matches ) ) . toBe ( true ) ;
expect ( await page . evaluate ( ( ) = > matchMedia ( '(prefers-reduced-motion: no-preference)' ) . matches ) ) . toBe ( false ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should support forcedColors option' , async ( { launchPersistent , browserName } ) = > {
2021-09-03 22:48:06 +03:00
it . skip ( browserName === 'webkit' , 'https://bugs.webkit.org/show_bug.cgi?id=225281' ) ;
2021-09-27 19:58:08 +03:00
const { page } = await launchPersistent ( { forcedColors : 'active' } ) ;
2021-09-03 22:48:06 +03:00
expect ( await page . evaluate ( ( ) = > matchMedia ( '(forced-colors: active)' ) . matches ) ) . toBe ( true ) ;
expect ( await page . evaluate ( ( ) = > matchMedia ( '(forced-colors: none)' ) . matches ) ) . toBe ( false ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should support timezoneId option' , async ( { launchPersistent , browserName } ) = > {
const { page } = await launchPersistent ( { locale : 'en-US' , timezoneId : 'America/Jamaica' } ) ;
2021-06-04 02:21:23 +03:00
expect ( await page . evaluate ( ( ) = > new Date ( 1479579154987 ) . toString ( ) ) ) . toBe ( 'Sat Nov 19 2016 13:12:34 GMT-0500 (Eastern Standard Time)' ) ;
2020-08-03 23:41:48 +03:00
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should support locale option' , async ( { launchPersistent } ) = > {
const { page } = await launchPersistent ( { locale : 'fr-CH' } ) ;
2020-08-03 23:41:48 +03:00
expect ( await page . evaluate ( ( ) = > navigator . language ) ) . toBe ( 'fr-CH' ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should support geolocation and permissions options' , async ( { server , launchPersistent } ) = > {
const { page } = await launchPersistent ( { geolocation : { longitude : 10 , latitude : 10 } , permissions : [ 'geolocation' ] } ) ;
2020-08-03 23:41:48 +03:00
await page . goto ( server . EMPTY_PAGE ) ;
const geolocation = await page . evaluate ( ( ) = > new Promise ( resolve = > navigator . geolocation . getCurrentPosition ( position = > {
2021-09-27 19:58:08 +03:00
resolve ( { latitude : position.coords.latitude , longitude : position.coords.longitude } ) ;
2020-08-03 23:41:48 +03:00
} ) ) ) ;
2021-09-27 19:58:08 +03:00
expect ( geolocation ) . toEqual ( { latitude : 10 , longitude : 10 } ) ;
2020-08-03 23:41:48 +03:00
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should support ignoreHTTPSErrors option' , async ( { httpsServer , launchPersistent } ) = > {
const { page } = await launchPersistent ( { ignoreHTTPSErrors : true } ) ;
2020-08-03 23:41:48 +03:00
let error = null ;
const response = await page . goto ( httpsServer . EMPTY_PAGE ) . catch ( e = > error = e ) ;
expect ( error ) . toBe ( null ) ;
expect ( response . ok ( ) ) . toBe ( true ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should support extraHTTPHeaders option' , async ( { server , launchPersistent } ) = > {
const { page } = await launchPersistent ( { extraHTTPHeaders : { foo : 'bar' } } ) ;
2020-08-03 23:41:48 +03:00
const [ request ] = await Promise . all ( [
server . waitForRequest ( '/empty.html' ) ,
page . goto ( server . EMPTY_PAGE ) ,
] ) ;
expect ( request . headers [ 'foo' ] ) . toBe ( 'bar' ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should accept userDataDir' , async ( { createUserDataDir , browserType , browserOptions } ) = > {
2020-09-19 01:52:14 +03:00
const userDataDir = await createUserDataDir ( ) ;
2020-10-13 23:18:36 +03:00
const context = await browserType . launchPersistentContext ( userDataDir , browserOptions ) ;
2020-09-19 01:52:14 +03:00
expect ( fs . readdirSync ( userDataDir ) . length ) . toBeGreaterThan ( 0 ) ;
2020-08-03 23:41:48 +03:00
await context . close ( ) ;
2020-09-19 01:52:14 +03:00
expect ( fs . readdirSync ( userDataDir ) . length ) . toBeGreaterThan ( 0 ) ;
2020-08-03 23:41:48 +03:00
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should restore state from userDataDir' , async ( { browserType , browserOptions , server , createUserDataDir } ) = > {
2021-05-08 01:25:55 +03:00
it . slow ( ) ;
2020-09-19 01:52:14 +03:00
const userDataDir = await createUserDataDir ( ) ;
2020-10-13 23:18:36 +03:00
const browserContext = await browserType . launchPersistentContext ( userDataDir , browserOptions ) ;
2020-08-03 23:41:48 +03:00
const page = await browserContext . newPage ( ) ;
await page . goto ( server . EMPTY_PAGE ) ;
await page . evaluate ( ( ) = > localStorage . hey = 'hello' ) ;
await browserContext . close ( ) ;
2020-10-13 23:18:36 +03:00
const browserContext2 = await browserType . launchPersistentContext ( userDataDir , browserOptions ) ;
2020-08-03 23:41:48 +03:00
const page2 = await browserContext2 . newPage ( ) ;
await page2 . goto ( server . EMPTY_PAGE ) ;
expect ( await page2 . evaluate ( ( ) = > localStorage . hey ) ) . toBe ( 'hello' ) ;
await browserContext2 . close ( ) ;
2020-09-19 01:52:14 +03:00
const userDataDir2 = await createUserDataDir ( ) ;
2020-10-13 23:18:36 +03:00
const browserContext3 = await browserType . launchPersistentContext ( userDataDir2 , browserOptions ) ;
2020-08-03 23:41:48 +03:00
const page3 = await browserContext3 . newPage ( ) ;
await page3 . goto ( server . EMPTY_PAGE ) ;
expect ( await page3 . evaluate ( ( ) = > localStorage . hey ) ) . not . toBe ( 'hello' ) ;
await browserContext3 . close ( ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should restore cookies from userDataDir' , async ( { browserType , browserOptions , server , createUserDataDir , platform , channel } ) = > {
2021-05-13 20:22:23 +03:00
it . fixme ( platform === 'win32' && channel === 'chrome' ) ;
2021-05-08 01:25:55 +03:00
it . slow ( ) ;
2021-04-03 07:07:45 +03:00
2020-09-19 01:52:14 +03:00
const userDataDir = await createUserDataDir ( ) ;
2020-10-13 23:18:36 +03:00
const browserContext = await browserType . launchPersistentContext ( userDataDir , browserOptions ) ;
2020-08-03 23:41:48 +03:00
const page = await browserContext . newPage ( ) ;
await page . goto ( server . EMPTY_PAGE ) ;
const documentCookie = await page . evaluate ( ( ) = > {
document . cookie = 'doSomethingOnlyOnce=true; expires=Fri, 31 Dec 9999 23:59:59 GMT' ;
return document . cookie ;
} ) ;
expect ( documentCookie ) . toBe ( 'doSomethingOnlyOnce=true' ) ;
await browserContext . close ( ) ;
2020-10-13 23:18:36 +03:00
const browserContext2 = await browserType . launchPersistentContext ( userDataDir , browserOptions ) ;
2020-08-03 23:41:48 +03:00
const page2 = await browserContext2 . newPage ( ) ;
await page2 . goto ( server . EMPTY_PAGE ) ;
expect ( await page2 . evaluate ( ( ) = > document . cookie ) ) . toBe ( 'doSomethingOnlyOnce=true' ) ;
await browserContext2 . close ( ) ;
2020-09-19 01:52:14 +03:00
const userDataDir2 = await createUserDataDir ( ) ;
2020-10-13 23:18:36 +03:00
const browserContext3 = await browserType . launchPersistentContext ( userDataDir2 , browserOptions ) ;
2020-08-03 23:41:48 +03:00
const page3 = await browserContext3 . newPage ( ) ;
await page3 . goto ( server . EMPTY_PAGE ) ;
expect ( await page3 . evaluate ( ( ) = > document . cookie ) ) . not . toBe ( 'doSomethingOnlyOnce=true' ) ;
await browserContext3 . close ( ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should have default URL when launching browser' , async ( { launchPersistent } ) = > {
const { context } = await launchPersistent ( ) ;
2020-08-03 23:41:48 +03:00
const urls = context . pages ( ) . map ( page = > page . url ( ) ) ;
expect ( urls ) . toEqual ( [ 'about:blank' ] ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should throw if page argument is passed' , async ( { browserType , browserOptions , server , createUserDataDir , browserName } ) = > {
2021-04-03 07:07:45 +03:00
it . skip ( browserName === 'firefox' ) ;
2021-09-27 19:58:08 +03:00
const options = { . . . browserOptions , args : [ server . EMPTY_PAGE ] } ;
2020-09-19 01:52:14 +03:00
const error = await browserType . launchPersistentContext ( await createUserDataDir ( ) , options ) . catch ( e = > e ) ;
2020-08-03 23:41:48 +03:00
expect ( error . message ) . toContain ( 'can not specify page' ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should have passed URL when launching with ignoreDefaultArgs: true' , async ( { browserType , browserOptions , server , createUserDataDir , toImpl , mode , browserName } ) = > {
2021-04-03 07:07:45 +03:00
it . skip ( mode !== 'default' ) ;
2020-09-19 01:52:14 +03:00
const userDataDir = await createUserDataDir ( ) ;
2020-10-13 23:18:36 +03:00
const args = toImpl ( browserType ) . _defaultArgs ( browserOptions , 'persistent' , userDataDir , 0 ) . filter ( a = > a !== 'about:blank' ) ;
2020-08-03 23:41:48 +03:00
const options = {
2020-10-13 23:18:36 +03:00
. . . browserOptions ,
2021-05-13 20:22:23 +03:00
args : browserName === 'firefox' ? [ . . . args , '-new-tab' , server . EMPTY_PAGE ] : [ . . . args , server . EMPTY_PAGE ] ,
2020-08-03 23:41:48 +03:00
ignoreDefaultArgs : true ,
} ;
2020-09-19 01:52:14 +03:00
const browserContext = await browserType . launchPersistentContext ( userDataDir , options ) ;
2020-08-03 23:41:48 +03:00
if ( ! browserContext . pages ( ) . length )
await browserContext . waitForEvent ( 'page' ) ;
await browserContext . pages ( ) [ 0 ] . waitForLoadState ( ) ;
const gotUrls = browserContext . pages ( ) . map ( page = > page . url ( ) ) ;
expect ( gotUrls ) . toEqual ( [ server . EMPTY_PAGE ] ) ;
await browserContext . close ( ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should handle timeout' , async ( { browserType , browserOptions , createUserDataDir , mode } ) = > {
2021-04-03 07:07:45 +03:00
it . skip ( mode !== 'default' ) ;
2020-10-13 23:18:36 +03:00
const options = { . . . browserOptions , timeout : 5000 , __testHookBeforeCreateBrowser : ( ) = > new Promise ( f = > setTimeout ( f , 6000 ) ) } ;
2020-09-19 01:52:14 +03:00
const error = await browserType . launchPersistentContext ( await createUserDataDir ( ) , options ) . catch ( e = > e ) ;
2020-08-03 23:41:48 +03:00
expect ( error . message ) . toContain ( ` browserType.launchPersistentContext: Timeout 5000ms exceeded. ` ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should handle exception' , async ( { browserType , browserOptions , createUserDataDir , mode } ) = > {
2021-04-03 07:07:45 +03:00
it . skip ( mode !== 'default' ) ;
2020-08-03 23:41:48 +03:00
const e = new Error ( 'Dummy' ) ;
2020-10-13 23:18:36 +03:00
const options = { . . . browserOptions , __testHookBeforeCreateBrowser : ( ) = > { throw e ; } } ;
2020-09-19 01:52:14 +03:00
const error = await browserType . launchPersistentContext ( await createUserDataDir ( ) , options ) . catch ( e = > e ) ;
2020-08-03 23:41:48 +03:00
expect ( error . message ) . toContain ( 'Dummy' ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should fire close event for a persistent context' , async ( { launchPersistent } ) = > {
const { context } = await launchPersistent ( ) ;
2020-08-03 23:41:48 +03:00
let closed = false ;
context . on ( 'close' , ( ) = > closed = true ) ;
await context . close ( ) ;
expect ( closed ) . toBe ( true ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'coverage should work' , async ( { server , launchPersistent , browserName } ) = > {
2021-04-03 07:07:45 +03:00
it . skip ( browserName !== 'chromium' ) ;
2021-09-27 19:58:08 +03:00
const { page } = await launchPersistent ( ) ;
2020-08-03 23:41:48 +03:00
await page . coverage . startJSCoverage ( ) ;
await page . goto ( server . PREFIX + '/jscoverage/simple.html' , { waitUntil : 'load' } ) ;
const coverage = await page . coverage . stopJSCoverage ( ) ;
expect ( coverage . length ) . toBe ( 1 ) ;
expect ( coverage [ 0 ] . url ) . toContain ( '/jscoverage/simple.html' ) ;
expect ( coverage [ 0 ] . functions . find ( f = > f . functionName === 'foo' ) . ranges [ 0 ] . count ) . toEqual ( 1 ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should respect selectors' , async ( { playwright , launchPersistent } ) = > {
const { page } = await launchPersistent ( ) ;
2020-09-03 02:15:43 +03:00
const defaultContextCSS = ( ) = > ( {
query ( root , selector ) {
return root . querySelector ( selector ) ;
} ,
queryAll ( root : HTMLElement , selector : string ) {
return Array . from ( root . querySelectorAll ( selector ) ) ;
}
} ) ;
2020-09-19 01:52:14 +03:00
await playwright . selectors . register ( 'defaultContextCSS' , defaultContextCSS ) ;
2020-09-03 02:15:43 +03:00
await page . setContent ( ` <div>hello</div> ` ) ;
expect ( await page . innerHTML ( 'css=div' ) ) . toBe ( 'hello' ) ;
expect ( await page . innerHTML ( 'defaultContextCSS=div' ) ) . toBe ( 'hello' ) ;
} ) ;
2021-03-15 19:50:17 +03:00
2021-09-27 19:58:08 +03:00
it ( 'should connect to a browser with the default page' , async ( { browserType , browserOptions , createUserDataDir , mode } ) = > {
2021-04-03 07:07:45 +03:00
it . skip ( mode !== 'default' ) ;
2021-03-15 19:50:17 +03:00
const options = { . . . browserOptions , __testHookOnConnectToBrowser : ( ) = > new Promise ( f = > setTimeout ( f , 3000 ) ) } ;
const context = await browserType . launchPersistentContext ( await createUserDataDir ( ) , options ) ;
expect ( context . pages ( ) . length ) . toBe ( 1 ) ;
2021-03-17 05:31:35 +03:00
await context . close ( ) ;
2021-03-15 19:50:17 +03:00
} ) ;