2022-08-01 02:04:00 +00:00
const path = require ( 'path' )
2021-03-24 13:04:30 +00:00
const puppeteer = require ( 'puppeteer' )
2022-08-01 02:04:00 +00:00
const minimatch = require ( 'minimatch' )
const glob = require ( 'glob' )
const rootDir = path . join ( _ _dirname , '../../..' )
2023-04-11 08:43:47 +00:00
const pkgJson = require ( path . join ( rootDir , 'package.json' ) )
2021-03-24 13:04:30 +00:00
2022-01-17 10:04:55 +00:00
const browserTests = async (
{
logWarnings = false ,
serverPort = 38000 ,
keepServerRunning = false ,
puppeteerOptions = {
headless : false ,
devtools : true
}
2022-08-01 02:04:00 +00:00
} , testFiles ) => {
const server = require ( './server.cjs' ) . server
await server . init ( testFiles )
2021-03-24 13:04:30 +00:00
await server . listen ( serverPort )
const browser = await puppeteer . launch ( puppeteerOptions )
2022-01-17 10:04:55 +00:00
const page = ( await browser . pages ( ) ) [ 0 ]
2021-03-24 13:04:30 +00:00
page . on ( 'console' , function ( message ) {
2023-04-11 08:43:47 +00:00
const ignore = message . type ( ) === 'warning' && ! logWarnings
2021-03-24 13:04:30 +00:00
if ( ignore ) return
2022-10-03 15:35:35 +00:00
let text = ( message . args ( ) . length > 0 ) ? message . args ( ) [ 0 ] . remoteObject ( ) . value : message . text ( )
2021-03-24 13:04:30 +00:00
const args = [ ]
if ( message . args ( ) !== undefined && message . args ( ) . length > 1 ) {
for ( let i = 1 ; i < message . args ( ) . length ; i ++ ) {
2022-10-03 15:35:35 +00:00
args . push ( message . args ( ) [ i ] . remoteObject ( ) . value )
2021-03-24 13:04:30 +00:00
}
}
if ( message . type ( ) === 'error' && message . location ( ) ) {
text = ` ${ message . location ( ) . url } : ${ text } `
}
let consoleType = 'log'
switch ( message . type ( ) ) {
case 'error' :
consoleType = 'error'
break
case 'warning' :
consoleType = 'warn'
break
default :
break
}
console [ consoleType ] ( text , ... args )
} )
2022-01-17 10:04:55 +00:00
2021-03-24 13:04:30 +00:00
page . on ( 'error' , function ( err ) { page . emit ( new Error ( err ) ) } )
2022-01-17 10:04:55 +00:00
page . on ( 'close' , async ( ) => {
await close ( )
} )
page . goto ( 'http://localhost:38000/' ) . then ( async ( ) => {
const watchDog = page . waitForFunction ( '_mocha.state === \'stopped\'' , { timeout : 0 } )
await watchDog . catch ( async ( reason ) => {
console . error ( reason )
} )
if ( puppeteerOptions . headless === true ) {
await close ( )
}
} ) . catch ( async ( reason ) => {
console . error ( reason )
} )
2021-03-24 13:04:30 +00:00
2022-01-17 10:04:55 +00:00
async function close ( ) {
console . log ( 'Closing browser tests...' )
await browser . close ( ) . catch ( ( ) => { } )
if ( keepServerRunning !== true ) {
await server . close ( ) . catch ( ( ) => { } )
}
2021-03-24 13:04:30 +00:00
}
}
2022-08-01 02:04:00 +00:00
function processedTestFiles ( testFilesStr ) {
if ( testFilesStr === undefined ) {
2023-04-11 08:43:47 +00:00
testFilesStr = [ pkgJson . directories . test + '/**/*.ts' , pkgJson . directories . src + '/**/*.spec.ts' ]
} else {
// Let us first remove surrounding quotes in string (it gives issues in windows)
testFilesStr = testFilesStr . replace ( /^['"]/ , '' ) . replace ( /['"]$/ , '' )
2022-08-01 02:04:00 +00:00
}
const filenames = glob . sync ( testFilesStr , { cwd : rootDir , matchBase : true } )
2023-04-11 08:43:47 +00:00
if ( filenames . length === 0 ) {
throw new Error ( 'no test files found for ' + testFilesStr )
} else {
2022-08-01 02:04:00 +00:00
filenames . forEach ( file => {
const isTsTestFile = minimatch ( file , '{test/**/*.ts,src/**/*.spec.ts}' , { matchBase : true } )
if ( ! isTsTestFile ) {
throw new Error ( ` test file ' ${ file } ' not found ` )
}
} )
}
return filenames
}
2021-03-24 13:04:30 +00:00
const opts = {
// puppeteer options
puppeteerOptions : {
2022-01-17 10:04:55 +00:00
headless : false ,
devtools : true
2021-03-24 13:04:30 +00:00
// slowMo: 100,
// timeout: 10000
} ,
2022-01-17 10:04:55 +00:00
logWarnings : false , // log warnings in Node console (usually not needed)
2021-03-24 13:04:30 +00:00
keepServerRunning : false , // keep server running until manually closed with ctrl-c. In combination with puppeteerOptions.headless (or just connecting any browser to the test page) allows debugging in browser
serverPort : 38000
}
2022-01-17 10:04:55 +00:00
const args = process . argv . slice ( 2 )
if ( args [ 0 ] === 'headless' ) {
opts . puppeteerOptions . headless = true
2022-08-01 02:04:00 +00:00
args . shift ( )
2022-01-17 10:04:55 +00:00
}
2022-08-01 02:04:00 +00:00
browserTests ( opts , processedTestFiles ( args [ 0 ] ) )