import * as fs from "fs" ; import * as path from "path" ; import * as playwright from "playwright" ; export namespace TestUtils { param pathName param fileEndings default param createIfNotFound default export const clearFiles = async ( pathName , fileEndings = undefined , createIfNotFound = false ) : Promise < void > => { const exists = await new Promise ( ( resolve , reject ) => fs . exists ( pathName , ( exists ) => resolve ( exists ) ) ) ; if ( ! exists && createIfNotFound ) { fs . mkdirSync ( pathName ) ; } return new Promise ( ( resolve , reject ) => fs . readdir ( pathName , ( err , files ) => err ? reject ( err ) : resolve ( files . filter ( f => ! fileEndings || fileEndings . some ( e => f . endsWith ( e ) ) ) . forEach ( f => fs . unlinkSync ( path . resolve ( pathName , f ) ) ) ) ) ) ; } ; param page param filePath param func example export const takeScreenShotOnFailure = ( pageGetter , filePath , func ) : any => { return async ( ) => { try { await Promise . resolve ( func ( ) ) ; } catch ( e ) { const page = pageGetter ( ) ; if ( page ) { const dirName = path . dirname ( filePath ) ; const folderExists = fs . existsSync ( dirName ) ; if ( ! folderExists ) { fs . mkdirSync ( dirName ) ; } console . log ( "Saving error screenshot to " + filePath ) ; await page . screenshot ( { path : filePath } ) ; } throw ( e ) ; } } ; } ; const checkForFileInternal = async ( page , pathName , fileEndings , sleepTime , numberOfTries , tries = 0 ) : Promise < boolean > => { if ( tries >= numberOfTries ) { return Promise . reject ( `Tried ${ numberOfTries } times, aborting` ) ; } const found = await new Promise ( ( resolve , reject ) => fs . readdir ( pathName , ( err , files ) => err ? reject ( err ) : resolve ( files . some ( f => fileEndings . some ( e => f . endsWith ( e ) ) ) ) ) ) ; if ( found ) { return true ; } await page . waitForTimeout ( sleepTime ) ; return checkForFileInternal ( page , pathName , fileEndings , sleepTime , numberOfTries , ++ tries ) ; } ; param page param pathName param fileEndings param sleepTime param numberOfTries export const checkForFile = async ( page , pathName , fileEndings , sleepTime = 500 , numberOfTries = 10 ) : Promise < boolean > => { return checkForFileInternal ( page , pathName , fileEndings , sleepTime , numberOfTries ) ; } ; class InflightRequests { _page : playwright . Page ; _requests : Set < Request > ; constructor ( page ) { this . _page = page ; this . _requests = new Set ( ) ; this . _onStarted = this . _onStarted . bind ( this ) ; this . _onFinished = this . _onFinished . bind ( this ) ; this . _page . on ( "request" , this . _onStarted ) ; this . _page . on ( "requestfinished" , this . _onFinished ) ; this . _page . on ( "requestfailed" , this . _onFinished ) ; } _onStarted ( request ) { this . _requests . add ( request ) ; } _onFinished ( request ) { this . _requests . delete ( request ) ; } inflightRequests ( ) { return Array . from ( this . _requests ) ; } dispose ( ) { this . _page . removeListener ( "request" , this . _onStarted ) ; this . _page . removeListener ( "requestfinished" , this . _onFinished ) ; this . _page . removeListener ( "requestfailed" , this . _onFinished ) ; } } param page param func example export const trackTimedOutRequest = async ( page , func ) => { const tracker = new InflightRequests ( page ) ; try { await Promise . resolve ( func ( ) ) ; } catch ( e ) { console . log ( "Navigation failed: " + e . message ) ; const inflight = tracker . inflightRequests ( ) ; console . log ( inflight . map ( ( request ) => "  " + request . url ( ) ) . join ( "\n" ) ) ; tracker . dispose ( ) ; throw ( e ) ; } } ; }