2020-08-05 02:32:10 +03: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-20 07:32:12 +03:00
2020-08-12 01:50:53 +03:00
import url from 'url' ;
2021-05-06 17:08:22 +03:00
import { test as it , expect } from './pageTest' ;
2021-05-06 05:10:28 +03:00
import { expectedSSLError } from '../config/utils' ;
2020-08-05 02:32:10 +03:00
2022-03-10 21:42:52 +03:00
it ( 'should work @smoke' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
await page . goto ( server . EMPTY_PAGE ) ;
expect ( page . url ( ) ) . toBe ( server . EMPTY_PAGE ) ;
} ) ;
2023-07-26 02:47:04 +03:00
it ( 'should work with file URL' , async ( { page , asset , isAndroid , mode } ) = > {
2021-04-09 17:59:09 +03:00
it . skip ( isAndroid , 'No files on Android' ) ;
2023-07-26 02:47:04 +03:00
it . skip ( mode . startsWith ( 'service' ) ) ;
2021-04-05 05:32:14 +03:00
2023-01-27 20:31:45 +03:00
const fileurl = url . pathToFileURL ( asset ( 'empty.html' ) ) . href ;
await page . goto ( fileurl ) ;
expect ( page . url ( ) . toLowerCase ( ) ) . toBe ( fileurl . toLowerCase ( ) ) ;
expect ( page . frames ( ) . length ) . toBe ( 1 ) ;
} ) ;
2023-07-26 02:47:04 +03:00
it ( 'should work with file URL with subframes' , async ( { page , asset , isAndroid , mode } ) = > {
2023-01-27 20:31:45 +03:00
it . skip ( isAndroid , 'No files on Android' ) ;
2023-07-26 02:47:04 +03:00
it . skip ( mode . startsWith ( 'service' ) ) ;
2023-01-27 20:31:45 +03:00
2021-04-06 01:51:45 +03:00
const fileurl = url . pathToFileURL ( asset ( 'frames/two-frames.html' ) ) . href ;
2020-08-05 02:32:10 +03:00
await page . goto ( fileurl ) ;
expect ( page . url ( ) . toLowerCase ( ) ) . toBe ( fileurl . toLowerCase ( ) ) ;
expect ( page . frames ( ) . length ) . toBe ( 3 ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should use http for no protocol' , async ( { page , server , isAndroid } ) = > {
2021-04-09 17:59:09 +03:00
it . skip ( isAndroid ) ;
2021-04-05 05:32:14 +03:00
2020-08-05 02:32:10 +03:00
await page . goto ( server . EMPTY_PAGE . substring ( 'http://' . length ) ) ;
expect ( page . url ( ) ) . toBe ( server . EMPTY_PAGE ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should work cross-process' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
await page . goto ( server . EMPTY_PAGE ) ;
expect ( page . url ( ) ) . toBe ( server . EMPTY_PAGE ) ;
const url = server . CROSS_PROCESS_PREFIX + '/empty.html' ;
let requestFrame ;
page . on ( 'request' , r = > {
if ( r . url ( ) === url )
requestFrame = r . frame ( ) ;
} ) ;
const response = await page . goto ( url ) ;
expect ( page . url ( ) ) . toBe ( url ) ;
expect ( response . frame ( ) ) . toBe ( page . mainFrame ( ) ) ;
expect ( requestFrame ) . toBe ( page . mainFrame ( ) ) ;
expect ( response . url ( ) ) . toBe ( url ) ;
} ) ;
2021-09-28 19:56:07 +03:00
it ( 'should work with cross-process that fails before committing' , async ( { page , server } ) = > {
server . setRoute ( '/empty.html' , ( req , res ) = > {
req . socket . destroy ( ) ;
} ) ;
const response1 = await page . goto ( server . CROSS_PROCESS_PREFIX + '/title.html' ) ;
await response1 . finished ( ) ;
const error = await page . goto ( server . EMPTY_PAGE ) . catch ( e = > e ) ;
expect ( error instanceof Error ) . toBeTruthy ( ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should work with Cross-Origin-Opener-Policy' , async ( { page , server , browserName } ) = > {
2021-09-23 18:45:40 +03:00
server . setRoute ( '/empty.html' , ( req , res ) = > {
res . setHeader ( 'Cross-Origin-Opener-Policy' , 'same-origin' ) ;
res . end ( ) ;
} ) ;
2021-09-28 19:56:07 +03:00
const requests = new Set ( ) ;
const events = [ ] ;
page . on ( 'request' , r = > {
events . push ( 'request' ) ;
requests . add ( r ) ;
} ) ;
page . on ( 'requestfailed' , r = > {
events . push ( 'requestfailed' ) ;
requests . add ( r ) ;
} ) ;
page . on ( 'requestfinished' , r = > {
events . push ( 'requestfinished' ) ;
requests . add ( r ) ;
} ) ;
page . on ( 'response' , r = > {
events . push ( 'response' ) ;
requests . add ( r . request ( ) ) ;
} ) ;
const response = await page . goto ( server . EMPTY_PAGE ) ;
expect ( page . url ( ) ) . toBe ( server . EMPTY_PAGE ) ;
await response . finished ( ) ;
expect ( events ) . toEqual ( [ 'request' , 'response' , 'requestfinished' ] ) ;
expect ( requests . size ) . toBe ( 1 ) ;
expect ( response . request ( ) . failure ( ) ) . toBeNull ( ) ;
} ) ;
it ( 'should work with Cross-Origin-Opener-Policy after redirect' , async ( { page , server , browserName } ) = > {
server . setRedirect ( '/redirect' , '/empty.html' ) ;
server . setRoute ( '/empty.html' , ( req , res ) = > {
res . setHeader ( 'Cross-Origin-Opener-Policy' , 'same-origin' ) ;
res . end ( ) ;
} ) ;
const requests = new Set ( ) ;
const events = [ ] ;
page . on ( 'request' , r = > {
events . push ( 'request' ) ;
requests . add ( r ) ;
} ) ;
page . on ( 'requestfailed' , r = > {
events . push ( 'requestfailed' ) ;
requests . add ( r ) ;
} ) ;
page . on ( 'requestfinished' , r = > {
events . push ( 'requestfinished' ) ;
requests . add ( r ) ;
} ) ;
page . on ( 'response' , r = > {
events . push ( 'response' ) ;
requests . add ( r . request ( ) ) ;
} ) ;
const response = await page . goto ( server . PREFIX + '/redirect' ) ;
2021-09-23 18:45:40 +03:00
expect ( page . url ( ) ) . toBe ( server . EMPTY_PAGE ) ;
2021-09-28 19:56:07 +03:00
await response . finished ( ) ;
expect ( events ) . toEqual ( [ 'request' , 'response' , 'requestfinished' , 'request' , 'response' , 'requestfinished' ] ) ;
expect ( requests . size ) . toBe ( 2 ) ;
expect ( response . request ( ) . failure ( ) ) . toBeNull ( ) ;
const firstRequest = response . request ( ) . redirectedFrom ( ) ;
expect ( firstRequest ) . toBeTruthy ( ) ;
expect ( firstRequest . url ( ) ) . toBe ( server . PREFIX + '/redirect' ) ;
2021-09-23 18:45:40 +03:00
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should capture iframe navigation request' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
await page . goto ( server . EMPTY_PAGE ) ;
expect ( page . url ( ) ) . toBe ( server . EMPTY_PAGE ) ;
let requestFrame ;
page . on ( 'request' , r = > {
if ( r . url ( ) === server . PREFIX + '/frames/frame.html' )
requestFrame = r . frame ( ) ;
} ) ;
const response = await page . goto ( server . PREFIX + '/frames/one-frame.html' ) ;
expect ( page . url ( ) ) . toBe ( server . PREFIX + '/frames/one-frame.html' ) ;
expect ( response . frame ( ) ) . toBe ( page . mainFrame ( ) ) ;
expect ( response . url ( ) ) . toBe ( server . PREFIX + '/frames/one-frame.html' ) ;
expect ( page . frames ( ) . length ) . toBe ( 2 ) ;
expect ( requestFrame ) . toBe ( page . frames ( ) [ 1 ] ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should capture cross-process iframe navigation request' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
await page . goto ( server . EMPTY_PAGE ) ;
expect ( page . url ( ) ) . toBe ( server . EMPTY_PAGE ) ;
let requestFrame ;
page . on ( 'request' , r = > {
if ( r . url ( ) === server . CROSS_PROCESS_PREFIX + '/frames/frame.html' )
requestFrame = r . frame ( ) ;
} ) ;
const response = await page . goto ( server . CROSS_PROCESS_PREFIX + '/frames/one-frame.html' ) ;
expect ( page . url ( ) ) . toBe ( server . CROSS_PROCESS_PREFIX + '/frames/one-frame.html' ) ;
expect ( response . frame ( ) ) . toBe ( page . mainFrame ( ) ) ;
expect ( response . url ( ) ) . toBe ( server . CROSS_PROCESS_PREFIX + '/frames/one-frame.html' ) ;
expect ( page . frames ( ) . length ) . toBe ( 2 ) ;
expect ( requestFrame ) . toBe ( page . frames ( ) [ 1 ] ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should work with anchor navigation' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
await page . goto ( server . EMPTY_PAGE ) ;
expect ( page . url ( ) ) . toBe ( server . EMPTY_PAGE ) ;
await page . goto ( server . EMPTY_PAGE + '#foo' ) ;
expect ( page . url ( ) ) . toBe ( server . EMPTY_PAGE + '#foo' ) ;
await page . goto ( server . EMPTY_PAGE + '#bar' ) ;
expect ( page . url ( ) ) . toBe ( server . EMPTY_PAGE + '#bar' ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should work with redirects' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
server . setRedirect ( '/redirect/1.html' , '/redirect/2.html' ) ;
server . setRedirect ( '/redirect/2.html' , '/empty.html' ) ;
const response = await page . goto ( server . PREFIX + '/redirect/1.html' ) ;
expect ( response . status ( ) ) . toBe ( 200 ) ;
expect ( page . url ( ) ) . toBe ( server . EMPTY_PAGE ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should navigate to about:blank' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
const response = await page . goto ( 'about:blank' ) ;
expect ( response ) . toBe ( null ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should return response when page changes its URL after load' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
const response = await page . goto ( server . PREFIX + '/historyapi.html' ) ;
expect ( response . status ( ) ) . toBe ( 200 ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should work with subframes return 204' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
server . setRoute ( '/frames/frame.html' , ( req , res ) = > {
res . statusCode = 204 ;
res . end ( ) ;
} ) ;
await page . goto ( server . PREFIX + '/frames/one-frame.html' ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should work with subframes return 204 with domcontentloaded' , async ( { page , server } ) = > {
2020-08-13 00:45:00 +03:00
server . setRoute ( '/frames/frame.html' , ( req , res ) = > {
res . statusCode = 204 ;
res . end ( ) ;
} ) ;
await page . goto ( server . PREFIX + '/frames/one-frame.html' , { waitUntil : 'domcontentloaded' } ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should fail when server returns 204' , async ( { page , server , browserName } ) = > {
2021-03-26 20:47:16 +03:00
// WebKit just loads an empty page.
2020-08-05 02:32:10 +03:00
server . setRoute ( '/empty.html' , ( req , res ) = > {
res . statusCode = 204 ;
res . end ( ) ;
} ) ;
let error = null ;
await page . goto ( server . EMPTY_PAGE ) . catch ( e = > error = e ) ;
expect ( error ) . not . toBe ( null ) ;
2021-05-13 20:22:23 +03:00
if ( browserName === 'chromium' )
2020-08-05 02:32:10 +03:00
expect ( error . message ) . toContain ( 'net::ERR_ABORTED' ) ;
2021-05-13 20:22:23 +03:00
else if ( browserName === 'webkit' )
2020-08-05 02:32:10 +03:00
expect ( error . message ) . toContain ( 'Aborted: 204 No Content' ) ;
else
expect ( error . message ) . toContain ( 'NS_BINDING_ABORTED' ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should navigate to empty page with domcontentloaded' , async ( { page , server } ) = > {
const response = await page . goto ( server . EMPTY_PAGE , { waitUntil : 'domcontentloaded' } ) ;
2020-08-05 02:32:10 +03:00
expect ( response . status ( ) ) . toBe ( 200 ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should work when page calls history API in beforeunload' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
await page . goto ( server . EMPTY_PAGE ) ;
await page . evaluate ( ( ) = > {
window . addEventListener ( 'beforeunload' , ( ) = > history . replaceState ( null , 'initial' , window . location . href ) , false ) ;
} ) ;
const response = await page . goto ( server . PREFIX + '/grid.html' ) ;
expect ( response . status ( ) ) . toBe ( 200 ) ;
} ) ;
2021-10-28 18:31:30 +03:00
it ( 'should fail when navigating to bad url' , async ( { mode , page , browserName } ) = > {
2020-08-05 02:32:10 +03:00
let error = null ;
await page . goto ( 'asdfasdf' ) . catch ( e = > error = e ) ;
2021-05-13 20:22:23 +03:00
if ( browserName === 'chromium' || browserName === 'webkit' )
2020-08-05 02:32:10 +03:00
expect ( error . message ) . toContain ( 'Cannot navigate to invalid URL' ) ;
else
expect ( error . message ) . toContain ( 'Invalid url' ) ;
} ) ;
2023-07-31 21:24:04 +03:00
it ( 'should fail when navigating to bad SSL' , async ( { page , browserName , httpsServer , platform } ) = > {
2020-08-05 02:32:10 +03:00
// Make sure that network events do not emit 'undefined'.
// @see https://crbug.com/750469
page . on ( 'request' , request = > expect ( request ) . toBeTruthy ( ) ) ;
page . on ( 'requestfinished' , request = > expect ( request ) . toBeTruthy ( ) ) ;
page . on ( 'requestfailed' , request = > expect ( request ) . toBeTruthy ( ) ) ;
let error = null ;
await page . goto ( httpsServer . EMPTY_PAGE ) . catch ( e = > error = e ) ;
2023-08-23 18:59:07 +03:00
expect ( error . message ) . toMatch ( expectedSSLError ( browserName , platform ) ) ;
2020-08-05 02:32:10 +03:00
} ) ;
2023-07-31 21:24:04 +03:00
it ( 'should fail when navigating to bad SSL after redirects' , async ( { page , browserName , server , httpsServer , platform } ) = > {
2020-08-05 02:32:10 +03:00
server . setRedirect ( '/redirect/1.html' , '/redirect/2.html' ) ;
server . setRedirect ( '/redirect/2.html' , '/empty.html' ) ;
let error = null ;
await page . goto ( httpsServer . PREFIX + '/redirect/1.html' ) . catch ( e = > error = e ) ;
2023-08-23 18:59:07 +03:00
expect ( error . message ) . toMatch ( expectedSSLError ( browserName , platform ) ) ;
2020-08-05 02:32:10 +03:00
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should not crash when navigating to bad SSL after a cross origin navigation' , async ( { page , server , httpsServer } ) = > {
2020-08-05 02:32:10 +03:00
await page . goto ( server . CROSS_PROCESS_PREFIX + '/empty.html' ) ;
await page . goto ( httpsServer . EMPTY_PAGE ) . catch ( e = > void 0 ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should not throw if networkidle0 is passed as an option' , async ( { page , server } ) = > {
2020-09-09 13:06:52 +03:00
// @ts-expect-error networkidle0 is undocumented
2021-09-27 19:58:08 +03:00
await page . goto ( server . EMPTY_PAGE , { waitUntil : 'networkidle0' } ) ;
2020-08-05 02:32:10 +03:00
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should throw if networkidle2 is passed as an option' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
let error = null ;
2020-09-09 13:06:52 +03:00
// @ts-expect-error networkidle2 is not allowed
2021-09-27 19:58:08 +03:00
await page . goto ( server . EMPTY_PAGE , { waitUntil : 'networkidle2' } ) . catch ( err = > error = err ) ;
2021-11-02 03:12:19 +03:00
expect ( error . message ) . toContain ( ` waitUntil: expected one of (load|domcontentloaded|networkidle|commit) ` ) ;
2020-08-05 02:32:10 +03:00
} ) ;
2021-10-16 02:11:53 +03:00
it ( 'should fail when main resources failed to load' , async ( { page , browserName , isWindows , mode } ) = > {
2020-08-05 02:32:10 +03:00
let error = null ;
await page . goto ( 'http://localhost:44123/non-existing-url' ) . catch ( e = > error = e ) ;
2023-07-26 02:47:04 +03:00
if ( browserName === 'chromium' ) {
if ( mode === 'service2' )
expect ( error . message ) . toContain ( 'net::ERR_SOCKS_CONNECTION_FAILED' ) ;
else
expect ( error . message ) . toContain ( 'net::ERR_CONNECTION_REFUSED' ) ;
2023-07-31 21:24:04 +03:00
} else if ( browserName === 'webkit' && isWindows && mode === 'service2' ) {
expect ( error . message ) . toContain ( ` proxy handshake error ` ) ;
2023-07-26 02:47:04 +03:00
} else if ( browserName === 'webkit' && isWindows ) {
2020-08-05 02:32:10 +03:00
expect ( error . message ) . toContain ( ` Couldn \ 't connect to server ` ) ;
2023-07-26 02:47:04 +03:00
} else if ( browserName === 'webkit' ) {
if ( mode === 'service2' )
expect ( error . message ) . toContain ( 'Connection refused' ) ;
else
expect ( error . message ) . toContain ( 'Could not connect' ) ;
} else {
2020-08-05 02:32:10 +03:00
expect ( error . message ) . toContain ( 'NS_ERROR_CONNECTION_REFUSED' ) ;
2023-07-26 02:47:04 +03:00
}
2020-08-05 02:32:10 +03:00
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should fail when exceeding maximum navigation timeout' , async ( { page , server , playwright } ) = > {
2020-08-05 02:32:10 +03:00
// Hang for request to the empty.html
server . setRoute ( '/empty.html' , ( req , res ) = > { } ) ;
let error = null ;
2021-09-27 19:58:08 +03:00
await page . goto ( server . PREFIX + '/empty.html' , { timeout : 1 } ) . catch ( e = > error = e ) ;
2020-08-05 02:32:10 +03:00
expect ( error . message ) . toContain ( 'page.goto: Timeout 1ms exceeded.' ) ;
expect ( error . message ) . toContain ( server . PREFIX + '/empty.html' ) ;
expect ( error ) . toBeInstanceOf ( playwright . errors . TimeoutError ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should fail when exceeding default maximum navigation timeout' , async ( { page , server , playwright , isAndroid } ) = > {
2021-04-09 17:59:09 +03:00
it . skip ( isAndroid , 'No context per test' ) ;
2021-04-05 05:32:14 +03:00
2020-08-05 02:32:10 +03:00
// Hang for request to the empty.html
server . setRoute ( '/empty.html' , ( req , res ) = > { } ) ;
let error = null ;
page . context ( ) . setDefaultNavigationTimeout ( 2 ) ;
page . setDefaultNavigationTimeout ( 1 ) ;
await page . goto ( server . PREFIX + '/empty.html' ) . catch ( e = > error = e ) ;
expect ( error . message ) . toContain ( 'page.goto: Timeout 1ms exceeded.' ) ;
expect ( error . message ) . toContain ( server . PREFIX + '/empty.html' ) ;
expect ( error ) . toBeInstanceOf ( playwright . errors . TimeoutError ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should fail when exceeding browser context navigation timeout' , async ( { page , server , playwright , isAndroid } ) = > {
2021-04-09 17:59:09 +03:00
it . skip ( isAndroid , 'No context per test' ) ;
2021-04-05 05:32:14 +03:00
2020-08-05 02:32:10 +03:00
// Hang for request to the empty.html
server . setRoute ( '/empty.html' , ( req , res ) = > { } ) ;
let error = null ;
page . context ( ) . setDefaultNavigationTimeout ( 2 ) ;
await page . goto ( server . PREFIX + '/empty.html' ) . catch ( e = > error = e ) ;
expect ( error . message ) . toContain ( 'page.goto: Timeout 2ms exceeded.' ) ;
expect ( error . message ) . toContain ( server . PREFIX + '/empty.html' ) ;
expect ( error ) . toBeInstanceOf ( playwright . errors . TimeoutError ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should fail when exceeding default maximum timeout' , async ( { page , server , playwright , isAndroid } ) = > {
2021-04-09 17:59:09 +03:00
it . skip ( isAndroid , 'No context per test' ) ;
2021-04-05 05:32:14 +03:00
2020-08-05 02:32:10 +03:00
// Hang for request to the empty.html
server . setRoute ( '/empty.html' , ( req , res ) = > { } ) ;
let error = null ;
2021-10-28 18:31:30 +03:00
// Undo what harness did.
page . context ( ) . setDefaultNavigationTimeout ( undefined ) ;
2020-08-05 02:32:10 +03:00
page . context ( ) . setDefaultTimeout ( 2 ) ;
page . setDefaultTimeout ( 1 ) ;
await page . goto ( server . PREFIX + '/empty.html' ) . catch ( e = > error = e ) ;
expect ( error . message ) . toContain ( 'page.goto: Timeout 1ms exceeded.' ) ;
expect ( error . message ) . toContain ( server . PREFIX + '/empty.html' ) ;
expect ( error ) . toBeInstanceOf ( playwright . errors . TimeoutError ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should fail when exceeding browser context timeout' , async ( { page , server , playwright , isAndroid } ) = > {
2021-04-09 17:59:09 +03:00
it . skip ( isAndroid , 'No context per test' ) ;
2021-04-05 05:32:14 +03:00
2020-08-05 02:32:10 +03:00
// Hang for request to the empty.html
server . setRoute ( '/empty.html' , ( req , res ) = > { } ) ;
let error = null ;
2021-10-28 18:31:30 +03:00
// Undo what harness did.
page . context ( ) . setDefaultNavigationTimeout ( undefined ) ;
2020-08-05 02:32:10 +03:00
page . context ( ) . setDefaultTimeout ( 2 ) ;
await page . goto ( server . PREFIX + '/empty.html' ) . catch ( e = > error = e ) ;
expect ( error . message ) . toContain ( 'page.goto: Timeout 2ms exceeded.' ) ;
expect ( error . message ) . toContain ( server . PREFIX + '/empty.html' ) ;
expect ( error ) . toBeInstanceOf ( playwright . errors . TimeoutError ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should prioritize default navigation timeout over default timeout' , async ( { page , server , playwright } ) = > {
2020-08-05 02:32:10 +03:00
// Hang for request to the empty.html
server . setRoute ( '/empty.html' , ( req , res ) = > { } ) ;
let error = null ;
page . setDefaultTimeout ( 0 ) ;
page . setDefaultNavigationTimeout ( 1 ) ;
await page . goto ( server . PREFIX + '/empty.html' ) . catch ( e = > error = e ) ;
expect ( error . message ) . toContain ( 'page.goto: Timeout 1ms exceeded.' ) ;
expect ( error . message ) . toContain ( server . PREFIX + '/empty.html' ) ;
expect ( error ) . toBeInstanceOf ( playwright . errors . TimeoutError ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should disable timeout when its set to 0' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
let error = null ;
let loaded = false ;
page . once ( 'load' , ( ) = > loaded = true ) ;
2021-09-27 19:58:08 +03:00
await page . goto ( server . PREFIX + '/grid.html' , { timeout : 0 , waitUntil : 'load' } ) . catch ( e = > error = e ) ;
2020-08-05 02:32:10 +03:00
expect ( error ) . toBe ( null ) ;
expect ( loaded ) . toBe ( true ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should fail when replaced by another navigation' , async ( { page , server , browserName } ) = > {
2020-08-05 02:32:10 +03:00
let anotherPromise ;
server . setRoute ( '/empty.html' , ( req , res ) = > {
anotherPromise = page . goto ( server . PREFIX + '/one-style.html' ) ;
// Hang request to empty.html.
} ) ;
const error = await page . goto ( server . PREFIX + '/empty.html' ) . catch ( e = > e ) ;
await anotherPromise ;
2023-02-23 06:18:49 +03:00
if ( browserName === 'chromium' ) {
2020-08-05 02:32:10 +03:00
expect ( error . message ) . toContain ( 'net::ERR_ABORTED' ) ;
2023-02-23 06:18:49 +03:00
} else if ( browserName === 'webkit' ) {
2023-06-21 21:10:35 +03:00
expect ( error . message ) . toContain ( ` page.goto: Navigation to " ${ server . PREFIX + '/empty.html' } " is interrupted by another navigation to " ${ server . PREFIX + '/one-style.html' } " ` ) ;
2023-02-23 06:18:49 +03:00
} else if ( browserName === 'firefox' ) {
// Firefox might yield either NS_BINDING_ABORTED or 'navigation interrupted by another one'
2023-06-21 21:10:35 +03:00
expect ( error . message . includes ( ` page.goto: Navigation to " ${ server . PREFIX + '/empty.html' } " is interrupted by another navigation to " ${ server . PREFIX + '/one-style.html' } " ` ) || error . message . includes ( 'NS_BINDING_ABORTED' ) ) . toBe ( true ) ;
2023-02-23 06:18:49 +03:00
}
2020-08-05 02:32:10 +03:00
} ) ;
2023-03-20 22:52:52 +03:00
it ( 'js redirect overrides url bar navigation ' , async ( { page , server , browserName , trace } ) = > {
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/20749' } ) ;
it . skip ( trace === 'on' , 'tracing waits for snapshot that never arrives because pending navigation' ) ;
2023-03-14 03:53:39 +03:00
server . setRoute ( '/a' , ( req , res ) = > {
res . writeHead ( 200 , { 'content-type' : 'text/html' } ) ;
res . end ( `
< body >
< script >
setTimeout ( ( ) = > {
window . location . pathname = '/c' ;
} , 1000 ) ;
< / script >
< / body >
` );
} ) ;
const events = [ ] ;
server . setRoute ( '/b' , async ( req , res ) = > {
events . push ( 'started b' ) ;
await new Promise ( f = > setTimeout ( f , 2000 ) ) ;
res . writeHead ( 200 , { 'content-type' : 'text/html' } ) ;
res . end ( ` BBB ` ) ;
events . push ( 'finished b' ) ;
} ) ;
server . setRoute ( '/c' , async ( req , res ) = > {
events . push ( 'started c' ) ;
await new Promise ( f = > setTimeout ( f , 2000 ) ) ;
res . writeHead ( 200 , { 'content-type' : 'text/html' } ) ;
res . end ( ` CCC ` ) ;
events . push ( 'finished c' ) ;
} ) ;
await page . goto ( server . PREFIX + '/a' ) ;
const error = await page . goto ( server . PREFIX + '/b' ) . then ( r = > null , e = > e ) ;
const expectEvents = ( browserName === 'chromium' ) ?
[ 'started b' , 'finished b' ] :
[ 'started b' , 'started c' , 'finished b' , 'finished c' ] ;
await expect ( ( ) = > expect ( events ) . toEqual ( expectEvents ) ) . toPass ( ) ;
expect ( events ) . toEqual ( expectEvents ) ;
if ( browserName === 'chromium' ) {
// Chromium prioritizes the url bar navigation over the js redirect.
expect ( error ) . toBeFalsy ( ) ;
2023-03-14 19:23:00 +03:00
await expect ( page ) . toHaveURL ( server . PREFIX + '/b' ) ;
2023-03-14 03:53:39 +03:00
} else if ( browserName === 'webkit' ) {
2023-06-21 21:10:35 +03:00
expect ( error . message ) . toContain ( ` page.goto: Navigation to " ${ server . PREFIX + '/b' } " is interrupted by another navigation to " ${ server . PREFIX + '/c' } " ` ) ;
2023-03-14 19:23:00 +03:00
await expect ( page ) . toHaveURL ( server . PREFIX + '/c' ) ;
2023-03-14 03:53:39 +03:00
} else if ( browserName === 'firefox' ) {
expect ( error . message ) . toContain ( 'NS_BINDING_ABORTED' ) ;
2023-03-14 19:23:00 +03:00
await expect ( page ) . toHaveURL ( server . PREFIX + '/c' ) ;
2023-03-14 03:53:39 +03:00
}
} ) ;
it ( 'should succeed on url bar navigation when there is pending navigation' , async ( { page , server , browserName } ) = > {
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/21574' } ) ;
server . setRoute ( '/a' , ( req , res ) = > {
res . writeHead ( 200 , { 'content-type' : 'text/html' } ) ;
res . end ( `
< body >
< script >
setTimeout ( ( ) = > {
window . location . pathname = '/c' ;
} , 10 ) ;
< / script >
< / body >
` );
} ) ;
const events = [ ] ;
server . setRoute ( '/b' , async ( req , res ) = > {
events . push ( 'started b' ) ;
await new Promise ( f = > setTimeout ( f , 2000 ) ) ;
res . writeHead ( 200 , { 'content-type' : 'text/html' } ) ;
res . end ( ` BBB ` ) ;
events . push ( 'finished b' ) ;
} ) ;
server . setRoute ( '/c' , async ( req , res ) = > {
events . push ( 'started c' ) ;
await new Promise ( f = > setTimeout ( f , 2000 ) ) ;
res . writeHead ( 200 , { 'content-type' : 'text/html' } ) ;
res . end ( ` CCC ` ) ;
events . push ( 'finished c' ) ;
} ) ;
await page . goto ( server . PREFIX + '/a' ) ;
await new Promise ( f = > setTimeout ( f , 1000 ) ) ;
const error = await page . goto ( server . PREFIX + '/b' ) . then ( r = > null , e = > e ) ;
const expectEvents = [ 'started c' , 'started b' , 'finished c' , 'finished b' ] ;
await expect ( ( ) = > expect ( events ) . toEqual ( expectEvents ) ) . toPass ( { timeout : 5000 } ) ;
expect ( events ) . toEqual ( expectEvents ) ;
expect ( error ) . toBeFalsy ( ) ;
expect ( page . url ( ) ) . toBe ( server . PREFIX + '/b' ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should work when navigating to valid url' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
const response = await page . goto ( server . EMPTY_PAGE ) ;
expect ( response . ok ( ) ) . toBe ( true ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should work when navigating to data url' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
const response = await page . goto ( 'data:text/html,hello' ) ;
expect ( response ) . toBe ( null ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should work when navigating to 404' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
const response = await page . goto ( server . PREFIX + '/not-found' ) ;
expect ( response . ok ( ) ) . toBe ( false ) ;
expect ( response . status ( ) ) . toBe ( 404 ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should return last response in redirect chain' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
server . setRedirect ( '/redirect/1.html' , '/redirect/2.html' ) ;
server . setRedirect ( '/redirect/2.html' , '/redirect/3.html' ) ;
server . setRedirect ( '/redirect/3.html' , server . EMPTY_PAGE ) ;
const response = await page . goto ( server . PREFIX + '/redirect/1.html' ) ;
expect ( response . ok ( ) ) . toBe ( true ) ;
expect ( response . url ( ) ) . toBe ( server . EMPTY_PAGE ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should not leak listeners during navigation' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
let warning = null ;
const warningHandler = w = > warning = w ;
process . on ( 'warning' , warningHandler ) ;
for ( let i = 0 ; i < 20 ; ++ i )
await page . goto ( server . EMPTY_PAGE ) ;
2020-08-12 01:50:53 +03:00
process . off ( 'warning' , warningHandler ) ;
2020-08-05 02:32:10 +03:00
expect ( warning ) . toBe ( null ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should not leak listeners during bad navigation' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
let warning = null ;
const warningHandler = w = > warning = w ;
process . on ( 'warning' , warningHandler ) ;
for ( let i = 0 ; i < 20 ; ++ i )
await page . goto ( 'asdf' ) . catch ( e = > { /* swallow navigation error */ } ) ;
2020-08-12 01:50:53 +03:00
process . off ( 'warning' , warningHandler ) ;
2020-08-05 02:32:10 +03:00
expect ( warning ) . toBe ( null ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should not leak listeners during 20 waitForNavigation' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
let warning = null ;
const warningHandler = w = > warning = w ;
process . on ( 'warning' , warningHandler ) ;
const promises = [ . . . Array ( 20 ) ] . map ( ( ) = > page . waitForNavigation ( ) ) ;
await page . goto ( server . EMPTY_PAGE ) ;
await Promise . all ( promises ) ;
2020-08-12 01:50:53 +03:00
process . off ( 'warning' , warningHandler ) ;
2020-08-05 02:32:10 +03:00
expect ( warning ) . toBe ( null ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should navigate to dataURL and not fire dataURL requests' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
const requests = [ ] ;
page . on ( 'request' , request = > requests . push ( request ) ) ;
const dataURL = 'data:text/html,<div>yo</div>' ;
const response = await page . goto ( dataURL ) ;
expect ( response ) . toBe ( null ) ;
expect ( requests . length ) . toBe ( 0 ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should navigate to URL with hash and fire requests without hash' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
const requests = [ ] ;
page . on ( 'request' , request = > requests . push ( request ) ) ;
const response = await page . goto ( server . EMPTY_PAGE + '#hash' ) ;
expect ( response . status ( ) ) . toBe ( 200 ) ;
expect ( response . url ( ) ) . toBe ( server . EMPTY_PAGE ) ;
expect ( requests . length ) . toBe ( 1 ) ;
expect ( requests [ 0 ] . url ( ) ) . toBe ( server . EMPTY_PAGE ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should work with self requesting page' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
const response = await page . goto ( server . PREFIX + '/self-request.html' ) ;
expect ( response . status ( ) ) . toBe ( 200 ) ;
expect ( response . url ( ) ) . toContain ( 'self-request.html' ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should fail when navigating and show the url at the error message' , async function ( { page , server , httpsServer } ) {
2020-08-05 02:32:10 +03:00
const url = httpsServer . PREFIX + '/redirect/1.html' ;
let error = null ;
try {
await page . goto ( url ) ;
} catch ( e ) {
error = e ;
}
expect ( error . message ) . toContain ( url ) ;
} ) ;
2021-10-02 05:40:47 +03:00
it ( 'should be able to navigate to a page controlled by service worker' , async ( { page , server , isElectron } ) = > {
it . skip ( isElectron ) ;
2020-08-05 02:32:10 +03:00
await page . goto ( server . PREFIX + '/serviceworkers/fetch/sw.html' ) ;
2020-08-28 14:20:29 +03:00
await page . evaluate ( ( ) = > window [ 'activationPromise' ] ) ;
2020-08-05 02:32:10 +03:00
await page . goto ( server . PREFIX + '/serviceworkers/fetch/sw.html' ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should send referer' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
const [ request1 , request2 ] = await Promise . all ( [
server . waitForRequest ( '/grid.html' ) ,
server . waitForRequest ( '/digits/1.png' ) ,
page . goto ( server . PREFIX + '/grid.html' , {
referer : 'http://google.com/' ,
} ) ,
] ) ;
expect ( request1 . headers [ 'referer' ] ) . toBe ( 'http://google.com/' ) ;
// Make sure subresources do not inherit referer.
expect ( request2 . headers [ 'referer' ] ) . toBe ( server . PREFIX + '/grid.html' ) ;
expect ( page . url ( ) ) . toBe ( server . PREFIX + '/grid.html' ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should reject referer option when setExtraHTTPHeaders provides referer' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
await page . setExtraHTTPHeaders ( { 'referer' : 'http://microsoft.com/' } ) ;
let error ;
await page . goto ( server . PREFIX + '/grid.html' , {
referer : 'http://google.com/' ,
} ) . catch ( e = > error = e ) ;
expect ( error . message ) . toContain ( '"referer" is already specified as extra HTTP header' ) ;
expect ( error . message ) . toContain ( server . PREFIX + '/grid.html' ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should override referrer-policy' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
server . setRoute ( '/grid.html' , ( req , res ) = > {
res . setHeader ( 'Referrer-Policy' , 'no-referrer' ) ;
2020-08-31 18:43:14 +03:00
server . serveFile ( req , res ) ;
2020-08-05 02:32:10 +03:00
} ) ;
const [ request1 , request2 ] = await Promise . all ( [
server . waitForRequest ( '/grid.html' ) ,
server . waitForRequest ( '/digits/1.png' ) ,
page . goto ( server . PREFIX + '/grid.html' , {
referer : 'http://microsoft.com/' ,
} ) ,
] ) ;
expect ( request1 . headers [ 'referer' ] ) . toBe ( 'http://microsoft.com/' ) ;
// Make sure subresources do not inherit referer.
expect ( request2 . headers [ 'referer' ] ) . toBe ( undefined ) ;
expect ( page . url ( ) ) . toBe ( server . PREFIX + '/grid.html' ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should fail when canceled by another navigation' , async ( { page , server } ) = > {
2020-08-05 02:32:10 +03:00
server . setRoute ( '/one-style.html' , ( req , res ) = > { } ) ;
const failed = page . goto ( server . PREFIX + '/one-style.html' ) . catch ( e = > e ) ;
await server . waitForRequest ( '/one-style.html' ) ;
await page . goto ( server . PREFIX + '/empty.html' ) ;
const error = await failed ;
expect ( error . message ) . toBeTruthy ( ) ;
} ) ;
2021-09-27 19:58:08 +03:00
it ( 'should work with lazy loading iframes' , async ( { page , server , isElectron , isAndroid } ) = > {
2021-04-09 17:59:09 +03:00
it . fixme ( isElectron ) ;
2021-08-25 15:27:44 +03:00
it . fixme ( isAndroid ) ;
2021-04-08 20:26:26 +03:00
2020-08-20 01:58:13 +03:00
await page . goto ( server . PREFIX + '/frames/lazy-frame.html' ) ;
expect ( page . frames ( ) . length ) . toBe ( 2 ) ;
} ) ;
2020-10-20 06:40:21 +03:00
2021-09-27 19:58:08 +03:00
it ( 'should report raw buffer for main resource' , async ( { page , server , browserName , platform } ) = > {
2021-04-05 05:32:14 +03:00
it . fail ( browserName === 'chromium' , 'Chromium sends main resource as text' ) ;
it . fail ( browserName === 'webkit' && platform === 'win32' , 'Same here' ) ;
2020-10-20 06:40:21 +03:00
server . setRoute ( '/empty.html' , ( req , res ) = > {
res . statusCode = 200 ;
res . end ( Buffer . from ( 'Ü (lowercase ü)' , 'utf-8' ) ) ;
} ) ;
const response = await page . goto ( server . PREFIX + '/empty.html' ) ;
const body = await response . body ( ) ;
expect ( body . toString ( ) ) . toBe ( 'Ü (lowercase ü)' ) ;
} ) ;
2021-01-26 01:49:51 +03:00
2021-09-27 19:58:08 +03:00
it ( 'should not throw unhandled rejections on invalid url' , async ( { page , server } ) = > {
2021-01-26 01:49:51 +03:00
const e = await page . goto ( 'https://www.youtube Panel Title.com/' ) . catch ( e = > e ) ;
expect ( e . toString ( ) ) . toContain ( 'Panel Title' ) ;
} ) ;
2021-03-31 07:53:20 +03:00
2021-04-09 18:54:18 +03:00
it ( 'should not crash when RTCPeerConnection is used' , async ( { page , server , browserName , platform } ) = > {
2021-03-31 07:53:20 +03:00
server . setRoute ( '/rtc.html' , ( _ , res ) = > {
res . end ( `
< ! DOCTYPE html >
< html >
< body >
< script >
2021-03-31 20:29:43 +03:00
window . RTCPeerConnection && new window . RTCPeerConnection ( {
2021-03-31 07:53:20 +03:00
iceServers : [ ]
} ) ;
< / script >
< / body >
< / html >
` );
} ) ;
await page . goto ( server . PREFIX + '/rtc.html' ) ;
await page . evaluate ( ( ) = > {
2021-03-31 20:29:43 +03:00
// RTCPeerConnection is not present on WebKit Linux
window . RTCPeerConnection && new window . RTCPeerConnection ( {
2021-03-31 07:53:20 +03:00
iceServers : [ ]
} ) ;
} ) ;
} ) ;
2021-09-09 22:42:46 +03:00
2021-09-27 19:58:08 +03:00
it ( 'should properly wait for load' , async ( { page , server , browserName } ) = > {
2021-09-09 22:42:46 +03:00
server . setRoute ( '/slow.js' , async ( req , res ) = > {
await new Promise ( x = > setTimeout ( x , 100 ) ) ;
2021-09-27 19:58:08 +03:00
res . writeHead ( 200 , { 'Content-Type' : 'application/javascript' } ) ;
2021-09-09 22:42:46 +03:00
res . end ( ` window.results.push('slow module');export const foo = 'slow'; ` ) ;
} ) ;
await page . goto ( server . PREFIX + '/load-event/load-event.html' ) ;
const results = await page . evaluate ( 'window.results' ) ;
expect ( results ) . toEqual ( [
'script tag after after module' ,
'slow module' ,
'module' ,
'DOMContentLoaded' ,
'load'
] ) ;
} ) ;
2021-11-02 03:12:19 +03:00
2022-08-26 23:48:05 +03:00
it ( 'should not resolve goto upon window.stop()' , async ( { browserName , page , server } ) = > {
2022-09-02 18:35:29 +03:00
it . fixme ( browserName === 'firefox' , 'load/domcontentloaded events are flaky' ) ;
2022-08-26 23:48:05 +03:00
let response ;
server . setRoute ( '/module.js' , ( req , res ) = > {
res . writeHead ( 200 , { 'Content-Type' : 'text/javascript' } ) ;
response = res ;
} ) ;
let done = false ;
2022-09-03 01:45:01 +03:00
page . goto ( server . PREFIX + '/window-stop.html' ) . then ( ( ) = > done = true ) . catch ( ( ) = > { } ) ;
2022-08-26 23:48:05 +03:00
await server . waitForRequest ( '/module.js' ) ;
expect ( done ) . toBe ( false ) ;
await page . waitForTimeout ( 1000 ) ; // give it some time to erroneously resolve
response . end ( '' ) ;
await page . waitForTimeout ( 1000 ) ; // give it more time to erroneously resolve
2022-09-02 18:35:29 +03:00
expect ( done ) . toBe ( false ) ;
2021-11-06 02:51:22 +03:00
} ) ;
2022-08-03 11:51:45 +03:00
it ( 'should return from goto if new navigation is started' , async ( { page , server , browserName , isAndroid } ) = > {
it . fixme ( isAndroid ) ;
2021-11-06 02:51:22 +03:00
server . setRoute ( '/slow.js' , async ( req , res ) = > void 0 ) ;
let finished = false ;
const navigation = page . goto ( server . PREFIX + '/load-event/load-event.html' ) . then ( r = > {
finished = true ;
return r ;
} ) ;
await new Promise ( r = > setTimeout ( r , 500 ) ) ;
expect ( finished ) . toBeFalsy ( ) ;
await page . goto ( server . EMPTY_PAGE ) ;
expect ( ( await navigation ) . status ( ) ) . toBe ( 200 ) ;
} ) ;
2021-11-02 03:12:19 +03:00
it ( 'should return when navigation is committed if commit is specified' , async ( { page , server } ) = > {
2023-01-11 21:16:51 +03:00
server . setRoute ( '/script.js' , ( req , res ) = > { } ) ;
2021-11-02 03:12:19 +03:00
server . setRoute ( '/empty.html' , ( req , res ) = > {
2023-01-11 21:16:51 +03:00
res . setHeader ( 'content-type' , 'text/html' ) ;
res . end ( '<title>Hello</title><script src="script.js"></script>' ) ;
2021-11-02 03:12:19 +03:00
} ) ;
const response = await page . goto ( server . EMPTY_PAGE , { waitUntil : 'commit' } ) ;
expect ( response . status ( ) ) . toBe ( 200 ) ;
2023-01-11 21:16:51 +03:00
expect ( await page . title ( ) ) . toBe ( 'Hello' ) ;
2021-11-02 03:12:19 +03:00
} ) ;
2022-07-23 05:44:02 +03:00
it ( 'should wait for load when iframe attaches and detaches' , async ( { page , server } ) = > {
server . setRoute ( '/empty.html' , ( req , res ) = > {
res . writeHead ( 200 , { 'content-type' : 'text/html' } ) ;
res . end ( `
< body >
< script >
const iframe = document . createElement ( 'iframe' ) ;
iframe . src = './iframe.html' ;
document . body . appendChild ( iframe ) ;
setTimeout ( ( ) = > iframe . remove ( ) , 1000 ) ;
< / script >
< / body >
` );
} ) ;
server . setRoute ( '/iframe.html' , ( req , res ) = > {
res . writeHead ( 200 , { 'content-type' : 'text/html' } ) ;
res . end ( `
< link rel = "stylesheet" href = "./style2.css" >
` );
} ) ;
// Stall the css so that 'load' does not fire.
server . setRoute ( '/style2.css' , ( ) = > { } ) ;
const frameDetached = page . waitForEvent ( 'framedetached' ) ;
const done = page . goto ( server . EMPTY_PAGE , { waitUntil : 'load' } ) ;
await frameDetached ; // Make sure that iframe is gone.
await done ;
expect ( await page . $ ( 'iframe' ) ) . toBe ( null ) ;
} ) ;
2023-06-17 22:10:20 +03:00
2023-06-20 12:06:30 +03:00
it ( 'should return url with basic auth info' , async ( { page , server , loopback } ) = > {
2023-06-17 22:10:20 +03:00
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/23138' } ) ;
2023-06-20 12:06:30 +03:00
const url = ` http://admin:admin@ ${ loopback || 'localhost' } : ${ server . PORT } /empty.html ` ;
2023-06-17 22:10:20 +03:00
await page . goto ( url ) ;
2023-06-20 12:06:30 +03:00
expect ( page . url ( ) ) . toBe ( url ) ;
2023-06-17 22:10:20 +03:00
} ) ;