import fs from 'fs' ; import colors from 'kleur' ; import os from 'os' ; import path from 'path' ; import { BrowserContext , chromium , ConsoleMessage , Page , } from 'playwright-chromium' ; export interface E2ETestContext { tmpDir : string ; browser : BrowserContext ; pages : Set < Page > ; consoleMessages : ConsoleMessage [ ] ; unhandledErrors : Error [ ] ; } interface RenderResult { page : Page ; } global . Error . stackTraceLimit = 100 ; export const DIST_DIR = path . join ( __dirname , '../../dist' ) ; export function sleep ( ms ) { return new Promise ( ( resolve ) => { setTimeout ( resolve , ms ) ; } ) ; } export async function setup ( context ) { if ( context . browser ) { throw new Error ( 'Browser instance already exists, did you forget to call teardown()?' ) ; } fs . statSync ( DIST_DIR ) ; context . tmpDir = await fs . promises . mkdtemp ( path . join ( os . tmpdir ( ) , 'newtab-test-' ) ) ; context . browser = await chromium . launchPersistentContext ( context . tmpDir , { headless : false , args : [ `--disable-extensions-except=${ DIST_DIR }` , `--load-extension=${ DIST_DIR }` , ] , timeout : 10000 , } ) ; context . pages = new Set < Page > ( ) ; } export async function teardown ( context ) { if ( ! context . browser ) { throw new Error ( 'Browser instance does not exist, did you forget to call setup()?' ) ; } await context . browser . close ( ) ; await fs . promises . rm ( context . tmpDir , { force : true , recursive : true , } ) ; } export async function renderPage ( context , url ) { if ( ! context . browser ) { throw new Error ( 'Browser instance does not exist, did you forget to call setup()?' ) ; } const page = await context . browser . newPage ( ) ; context . pages . add ( page ) ; context . unhandledErrors = [ ] ; context . consoleMessages = [ ] ; page . on ( 'crash' , ( crashedPage ) => { throw new Error ( `Page crashed: ${ crashedPage . url ( ) }` ) ; } ) ; page . on ( 'pageerror' , ( err ) => { console . error ( colors . red ( 'Page Error:' ) , err ) ; context . unhandledErrors . push ( err ) ; } ) ; page . on ( 'console' , ( msg ) => { const loc = msg . location ( ) ; console . log ( colors . dim ( `${ loc . url }:${ loc . lineNumber }:${ loc . columnNumber } [${ msg . type ( ) }]` ) , msg . text ( ) ) ; context . consoleMessages . push ( msg ) ; } ) ; await page . goto ( url ) ; return { page } ; } export async function cleanupPage ( context ) { if ( ! context . pages || context . pages . size === 0 ) { throw new Error ( 'No pages exist, did you forget to call renderPage()?' ) ; } for ( const page of context . pages ) { await page . close ( ) ; } context . unhandledErrors = context . consoleMessages = undefined ; }