2022-12-16 10:04:27 +00:00
#!/usr/bin/node
/ *
This allows us to test apps using the Bangle . js emulator
IT IS UNFINISHED
It searches for ` test.json ` in each app ' s directory and will
run them in sequence .
2024-05-07 19:58:59 +00:00
The return code is the number of failed tests .
2022-12-16 10:04:27 +00:00
TODO :
* more code to test with
* run tests that we have found and loaded ( currently we just use TEST )
* documentation
* actual tests
* detecting 'Uncaught Error'
* logging of success / fail
* ...
* /
2024-05-07 19:58:59 +00:00
const DEMOAPP = {
"id" : "demoappfortestformat" ,
"name" : "demo" ,
"version" : "0.01" ,
"type" : "app" ,
"supports" : [ "BANGLEJS2" ] ,
"storage" : [ ] ,
} ;
const DEMOTEST = {
"app" : "demoappfortestformat" ,
"setup" : [ {
"id" : "arbitraryid" ,
"steps" : [
{ "t" : "cmd" , "js" : "global.testfunction = ()=>{}" , "text" : "Runs some code on the device" } ,
{ "t" : "wrap" , "fn" : "global.testfunction" , "id" : "testfunc" , text : "Wraps a function to count calls and store the last set of arguments on the device" }
]
} ] ,
"tests" : [ {
"description" : "Optional description of the test, will be shown in results table" ,
"steps" : [
{ "t" : "setup" , "id" : "arbitraryid" , "text" : "Calls a set of predefined steps" } ,
2024-05-09 12:00:06 +00:00
{ "t" : "eval" , "js" : "'test' + 'value'" , "eq" : "testvalue" , "text" : "Evals code on the device and compares the resulting string to the value in 'eq'" } ,
// {"t":"console", "text": "Starts an interactive console for debugging"},
2024-05-07 19:58:59 +00:00
{ "t" : "saveMemoryUsage" , "text" : "Gets and stores the current memory usage" } ,
{ "t" : "checkMemoryUsage" , "text" : "Checks the current memory to be equal to the stored value" } ,
{ "t" : "assert" , "js" : "0" , "is" : "falsy" , "text" : "Evaluates the content of 'js' on the device and asserts if the result is falsy" } ,
{ "t" : "assert" , "js" : "1" , "is" : "truthy" , "text" : "Evaluates the content of 'js' on the device and asserts if the result is truthy" } ,
{ "t" : "assert" , "js" : "false" , "is" : "false" , "text" : "Evaluates the content of 'js' on the device and asserts if the result is false" } ,
{ "t" : "assert" , "js" : "true" , "is" : "true" , "text" : "Evaluates the content of 'js' on the device and asserts if the result is true" } ,
{ "t" : "assert" , "js" : "()=>{}" , "is" : "function" , "text" : "Evaluates the content of 'js' and on the device and asserts if the result is a function" } ,
2024-05-07 21:17:36 +00:00
{ "t" : "assert" , "js" : "123" , "is" : "equal" , "to" : "123" , "text" : "Evaluates the content of 'js' and 'to' on the device and asserts if the result is equal" } ,
2024-05-07 19:58:59 +00:00
{ "t" : "assertArray" , "js" : "[]" , "is" : "undefinedOrEmpty" , "text" : "Evaluates the content of 'js' on the device and asserts if the result is undefined or an empty array" } ,
2024-05-07 21:17:36 +00:00
{ "t" : "assertArray" , "js" : "[1,2,3]" , "is" : "notEmpty" , "text" : "Evaluates the content of 'js' on the device and asserts if the result is an array with more than 0 entries" } ,
{ "t" : "cmd" , "js" : "global.testfunction(1)" , "text" : "Call function for the following asserts" } ,
2024-05-07 19:58:59 +00:00
{ "t" : "assertCall" , "id" : "testfunc" , "argAsserts" : [ { "t" : "assert" , "arg" : "0" , "is" : "equal" , "to" : 1 } ] , "text" : "Asserts if a wrapped function has been called with the expected arguments" } ,
{ "t" : "assertCall" , "id" : "testfunc" , "count" : 1 , "text" : "Asserts if a wrapped function has been called the expected number of times" }
]
} ]
}
2022-12-16 10:04:27 +00:00
var EMULATOR = "banglejs2" ;
var DEVICEID = "BANGLEJS2" ;
var BASE _DIR = _ _dirname + "/.." ;
var APP _DIR = BASE _DIR + "/apps" ;
var DIR _IDE = BASE _DIR + "/../EspruinoWebIDE" ;
if ( ! require ( "fs" ) . existsSync ( DIR _IDE ) ) {
console . log ( "You need to:" ) ;
console . log ( " git clone https://github.com/espruino/EspruinoWebIDE" ) ;
console . log ( "At the same level as this project" ) ;
process . exit ( 1 ) ;
}
2024-05-07 17:37:31 +00:00
const verbose = process . argv . includes ( "--verbose" ) || process . argv . includes ( "-v" ) ;
2024-05-04 08:45:54 +00:00
var AppInfo = require ( BASE _DIR + "/core/js/appinfo.js" ) ;
2023-07-07 14:19:32 +00:00
var apploader = require ( BASE _DIR + "/core/lib/apploader.js" ) ;
2022-12-16 10:04:27 +00:00
apploader . init ( {
DEVICEID : DEVICEID
} ) ;
2023-07-07 14:19:32 +00:00
var emu = require ( BASE _DIR + "/core/lib/emulator.js" ) ;
2022-12-16 10:04:27 +00:00
// Last set of text received
var lastTxt ;
2024-05-07 17:33:53 +00:00
function getSanitizedLastLine ( ) {
return emu . getLastLine ( ) . replaceAll ( "\r" , "" ) ;
}
2022-12-16 10:04:27 +00:00
function ERROR ( s ) {
console . error ( s ) ;
process . exit ( 1 ) ;
}
2024-04-20 05:50:44 +00:00
function getValue ( js ) {
2024-05-07 17:37:31 +00:00
if ( verbose )
2024-05-07 17:33:53 +00:00
console . log ( ` > GETTING VALUE FOR \` ${ js } \` ` ) ;
2024-04-20 05:50:44 +00:00
emu . tx ( ` \x 10print(JSON.stringify( ${ js } )) \n ` ) ;
2024-05-07 17:33:53 +00:00
var result = getSanitizedLastLine ( ) ;
if ( verbose )
console . log ( ` GOT \` ${ result } \` ` ) ;
2024-05-04 20:57:19 +00:00
return JSON . parse ( result ) ;
2024-04-20 05:50:44 +00:00
}
function assertArray ( step ) {
2024-05-04 20:57:19 +00:00
let isOK ;
switch ( step . is . toLowerCase ( ) ) {
2024-05-07 17:33:53 +00:00
case "notempty" : isOK = getValue ( ` ${ step . js } && ${ step . js } .length > 0 ` ) ; break ;
case "undefinedorempty" : isOK = getValue ( ` ! ${ step . js } || ( ${ step . js } && ${ step . js } .length === 0) ` ) ; break ;
2024-04-20 05:50:44 +00:00
}
2024-05-04 20:57:19 +00:00
if ( isOK )
2024-05-07 17:33:53 +00:00
console . log ( "> OK - ASSERT ARRAY " + step . is . toUpperCase ( ) , step . text ? "- " + step . text : "" ) ;
2024-05-04 20:57:19 +00:00
else
2024-05-07 17:33:53 +00:00
console . log ( "> FAIL - ASSERT ARRAY " + step . is . toUpperCase ( ) , step . text ? "- " + step . text : "" ) ;
2024-05-04 20:57:19 +00:00
return isOK ;
2024-04-20 05:50:44 +00:00
}
function assertValue ( step ) {
2024-05-04 20:57:19 +00:00
let isOK ;
2024-05-05 06:59:43 +00:00
switch ( step . is . toLowerCase ( ) ) {
2024-05-07 19:56:49 +00:00
case "truthy" : isOK = getValue ( ` !! ${ step . js } ` ) ; break ;
case "falsy" : isOK = getValue ( ` ! ${ step . js } ` ) ; break ;
case "true" : isOK = getValue ( ` ${ step . js } === true ` ) ; break ;
case "false" : isOK = getValue ( ` ${ step . js } === false ` ) ; break ;
case "equal" : isOK = getValue ( ` ${ step . js } == ${ step . to } ` ) ; break ;
case "function" : isOK = getValue ( ` typeof ${ step . js } === "function" ` ) ; break ;
2024-04-20 05:50:44 +00:00
}
2024-05-04 20:57:19 +00:00
if ( isOK )
2024-05-07 17:33:53 +00:00
console . log ( "> OK - ASSERT " + step . is . toUpperCase ( ) , step . text ? "- " + step . text : "" ) ;
2024-05-04 20:57:19 +00:00
else
2024-05-07 17:33:53 +00:00
console . log ( "> FAIL - ASSERT " + step . is . toUpperCase ( ) , step . text ? "- " + step . text : "" ) ;
2024-05-04 20:57:19 +00:00
return isOK ;
2024-04-20 05:50:44 +00:00
}
function wrap ( func , id ) {
console . log ( ` > Wrapping " ${ func } " ` ) ;
let wrappingCode = `
if ( ! global . APPTESTS ) global . APPTESTS = { } ;
if ( ! global . APPTESTS . funcCalls ) global . APPTESTS . funcCalls = { } ;
if ( ! global . APPTESTS . funcArgs ) global . APPTESTS . funcArgs = { } ;
global . APPTESTS . funcCalls . $ { id } = 0 ;
( function ( o ) {
$ { func } = function ( ) {
global . APPTESTS . funcCalls . $ { id } ++ ;
global . APPTESTS . funcArgs . $ { id } = arguments ;
return o . apply ( this , arguments ) ;
} ;
2024-05-09 12:00:06 +00:00
} ( $ { func } ) ) ; \ n ` ;
2024-04-20 05:50:44 +00:00
emu . tx ( wrappingCode ) ;
}
function assertCall ( step ) {
2024-05-07 21:21:40 +00:00
let isOK = true ;
2024-04-20 05:50:44 +00:00
let id = step . id ;
let args = step . argAsserts ;
2024-05-07 21:21:40 +00:00
if ( step . count !== undefined ) {
2024-04-20 05:50:44 +00:00
let calls = getValue ( ` global.APPTESTS.funcCalls. ${ id } ` ) ;
2024-05-07 21:21:40 +00:00
isOK = step . count == calls
}
if ( args && args . length > 0 ) {
2024-04-20 05:50:44 +00:00
let callArgs = getValue ( ` global.APPTESTS.funcArgs. ${ id } ` ) ;
for ( let a of args ) {
let current = {
2024-05-07 21:21:40 +00:00
js : callArgs [ a . arg ] ,
2024-04-20 05:50:44 +00:00
is : a . is ,
to : a . to ,
text : step . text
} ;
switch ( a . t ) {
case "assertArray" :
2024-05-07 21:21:40 +00:00
isOK = isOK && assertArray ( current ) ;
2024-04-20 05:50:44 +00:00
break ;
case "assert" :
2024-05-07 21:21:40 +00:00
isOK = isOK && assertValue ( current ) ;
2024-04-20 05:50:44 +00:00
break ;
}
}
2024-05-04 20:57:19 +00:00
}
if ( isOK )
2024-05-07 17:33:53 +00:00
console . log ( "OK - ASSERT CALL" , step . text ? "- " + step . text : "" ) ;
2024-05-04 20:57:19 +00:00
else
2024-05-07 17:33:53 +00:00
console . log ( "FAIL - ASSERT CALL" , step . text ? "- " + step . text : "" ) ;
2024-05-04 20:57:19 +00:00
return isOK ;
2024-04-20 05:50:44 +00:00
}
2024-05-03 21:38:10 +00:00
function runStep ( step , subtest , test , state ) {
2024-05-04 07:01:55 +00:00
let p = Promise . resolve ( ) ;
2024-05-03 21:38:10 +00:00
if ( state . ok ) switch ( step . t ) {
case "setup" :
test . setup . filter ( e => e . id == step . id ) [ 0 ] . steps . forEach ( setupStep => {
2024-05-04 13:00:37 +00:00
p = p . then ( ( ) => {
2024-05-04 20:57:19 +00:00
let np = runStep ( setupStep , subtest , test , state ) ;
emu . idle ( ) ;
return np ;
2024-05-04 13:00:37 +00:00
} ) ;
2024-05-03 21:38:10 +00:00
} ) ;
break ;
case "load" :
2024-05-04 07:01:55 +00:00
p = p . then ( ( ) => {
2024-05-07 17:33:53 +00:00
console . log ( ` > LOADING FILE " ${ step . fn } " ` ) ;
2024-05-03 21:38:10 +00:00
emu . tx ( ` load( ${ JSON . stringify ( step . fn ) } ) \n ` ) ;
2024-05-04 07:01:55 +00:00
} ) ;
break ;
2024-05-03 21:38:10 +00:00
case "cmd" :
2024-05-04 07:01:55 +00:00
p = p . then ( ( ) => {
2024-05-07 17:33:53 +00:00
console . log ( ` > SENDING JS \` ${ step . js } \` ` , step . text ? "- " + step . text : "" ) ;
2024-05-04 07:01:55 +00:00
emu . tx ( ` ${ step . js } \n ` ) ;
} ) ;
2024-05-03 21:38:10 +00:00
break ;
case "wrap" :
2024-05-04 07:01:55 +00:00
p = p . then ( ( ) => {
wrap ( step . fn , step . id ) ;
} ) ;
break ;
case "gb" :
p = p . then ( ( ) => {
2024-05-04 08:46:25 +00:00
let obj = Object . apply ( {
src : 'Messenger' ,
t : 'notify' ,
type : 'text' ,
id : Date . now ( ) . toFixed ( 0 ) ,
title : 'title' ,
body : 'body'
} , step . obj || { } ) ;
emu . tx ( ` GB( ${ JSON . stringify ( obj ) } ) \n ` ) ;
2024-05-04 07:01:55 +00:00
} ) ;
break ;
2024-05-04 08:46:59 +00:00
case "emit" :
2024-05-04 07:01:55 +00:00
p = p . then ( ( ) => {
2024-05-04 16:35:57 +00:00
let parent = step . parent ? step . parent : "Bangle" ;
if ( ! step . paramsArray ) step . paramsArray = [ ] ;
2024-05-04 08:46:59 +00:00
let args = JSON . stringify ( [ step . event ] . concat ( step . paramsArray ) ) ;
2024-05-07 17:33:53 +00:00
console . log ( ` > EMIT " ${ step . event } " on ${ parent } with parameters ${ JSON . stringify ( step . paramsArray , null , null ) } ` ) ;
2024-05-04 16:35:57 +00:00
2024-05-04 08:46:59 +00:00
emu . tx ( ` ${ parent } .emit.apply( ${ parent } , ${ args } ) \n ` ) ;
2024-05-04 07:01:55 +00:00
} ) ;
2024-05-03 21:38:10 +00:00
break ;
case "eval" :
2024-05-04 07:01:55 +00:00
p = p . then ( ( ) => {
console . log ( ` > Evaluate " ${ step . js } " ` ) ;
emu . tx ( ` \x 10print(JSON.stringify( ${ step . js } )) \n ` ) ;
2024-05-07 17:33:53 +00:00
var result = getSanitizedLastLine ( ) ;
2024-05-04 07:01:55 +00:00
var expected = JSON . stringify ( step . eq ) ;
2024-05-07 17:33:53 +00:00
console . log ( "> GOT `" + result + "`" ) ;
2024-05-04 07:01:55 +00:00
if ( result != expected ) {
console . log ( "> FAIL: EXPECTED " + expected ) ;
state . ok = false ;
}
} ) ;
2024-05-03 21:38:10 +00:00
break ;
// tap/touch/drag/button press
// delay X milliseconds?
case "assertArray" :
2024-05-04 07:01:55 +00:00
p = p . then ( ( ) => {
2024-05-04 20:57:19 +00:00
state . ok &= assertArray ( step ) ;
2024-05-04 07:01:55 +00:00
} ) ;
2024-05-03 21:38:10 +00:00
break ;
case "assertCall" :
2024-05-04 07:01:55 +00:00
p = p . then ( ( ) => {
2024-05-04 20:57:19 +00:00
state . ok &= assertCall ( step ) ;
2024-05-04 07:01:55 +00:00
} ) ;
2024-05-03 21:38:10 +00:00
break ;
case "assert" :
2024-05-04 07:01:55 +00:00
p = p . then ( ( ) => {
2024-05-04 20:57:19 +00:00
state . ok &= assertValue ( step ) ;
2024-05-04 07:01:55 +00:00
} ) ;
2024-05-03 21:38:10 +00:00
break ;
case "screenshot" :
2024-05-04 07:01:55 +00:00
p = p . then ( ( ) => {
console . log ( ` > Compare screenshots - UNIMPLEMENTED ` ) ;
} ) ;
2024-05-03 21:38:10 +00:00
break ;
case "saveMemoryUsage" :
2024-05-04 07:01:55 +00:00
p = p . then ( ( ) => {
emu . tx ( ` \x 10print(process.memory().usage) \n ` ) ;
2024-05-07 17:33:53 +00:00
subtest . memUsage = parseInt ( getSanitizedLastLine ( ) ) ;
2024-05-09 12:18:50 +00:00
console . log ( "> SAVED MEMORY USAGE" , subtest . memUsage ) ;
2024-05-04 07:01:55 +00:00
} ) ;
2024-05-03 21:38:10 +00:00
break ;
case "checkMemoryUsage" :
2024-05-04 07:01:55 +00:00
p = p . then ( ( ) => {
2024-05-04 13:00:37 +00:00
emu . tx ( ` \x 10print(process.memory().usage) \n ` ) ;
2024-05-07 17:33:53 +00:00
var memUsage = getSanitizedLastLine ( ) ;
2024-05-04 13:00:37 +00:00
console . log ( "> CURRENT MEMORY USAGE" , memUsage ) ;
if ( subtest . memUsage != memUsage ) {
console . log ( "> FAIL: EXPECTED MEMORY USAGE OF " + subtest . memUsage ) ;
state . ok = false ;
}
2024-05-04 07:01:55 +00:00
} ) ;
break ;
case "sleep" :
2024-05-04 13:00:37 +00:00
p = p . then ( ( ) => {
return new Promise ( resolve => {
setTimeout ( ( ) => {
2024-05-07 17:33:53 +00:00
console . log ( "> WAITED FOR" , step . ms ) ;
2024-05-04 13:00:37 +00:00
resolve ( ) ;
} , step . ms ) ;
} )
} ) ;
2024-05-04 08:45:54 +00:00
break ;
case "upload" :
2024-05-04 13:00:37 +00:00
p = p . then ( ( ) => {
2024-05-07 17:33:53 +00:00
console . log ( "> UPLOADING" + ( step . load ? " AND LOADING" : "" ) , step . file ) ;
2024-05-04 08:45:54 +00:00
emu . tx ( AppInfo . getFileUploadCommands ( step . as , require ( "fs" ) . readFileSync ( BASE _DIR + "/" + step . file ) . toString ( ) ) ) ;
2024-05-07 17:46:01 +00:00
if ( step . load ) {
2024-05-09 12:18:50 +00:00
emu . tx ( ` \x 10load(" ${ step . as } ") \n ` ) ;
2024-05-07 17:46:01 +00:00
}
2024-05-04 13:00:37 +00:00
} ) ;
2024-05-03 21:38:10 +00:00
break ;
2024-05-07 17:46:49 +00:00
case "console" :
p = p . then ( ( ) => {
return new Promise ( resolve => {
if ( process . stdin . isTTY ) {
console . log ( "> STARTING INTERACTIVE CONSOLE" ) ;
let shutdownHandler = function ( code ) {
console . log ( " STOPPING INTERACTIVE CONSOLE" ) ;
process . stdin . removeListener ( "readable" , stdinlistener )
process . stdin . setRawMode ( false ) ;
handleRx = ( ) => { } ;
handleConsoleOutput = handleConsoleOutputCurrent ;
resolve ( ) ;
}
let stdinlistener = ( ) => {
while ( ( chunk = process . stdin . read ( ) ) !== null ) {
if ( chunk === '\x03' ) {
shutdownHandler ( ) ;
}
emu . tx ( chunk . toString ( ) ) ;
}
} ;
handleRx = ( c ) => {
process . stdout . write ( String . fromCharCode ( c ) ) ;
}
let handleConsoleOutputCurrent = handleConsoleOutput ;
handleConsoleOutput = ( ) => { } ;
process . stdin . setRawMode ( true ) ;
process . stdin . setEncoding ( 'ASCII' ) ;
process . stdin . on ( "readable" , stdinlistener ) ;
process . stdout . write ( ">" ) ;
} else {
console . log ( "> TERMINAL NEEDS TO BE A TTY FOR INTERACTIVE CONSOLE" ) ;
resolve ( ) ;
}
} )
} ) ;
break ;
2024-05-03 21:38:10 +00:00
default : ERROR ( "Unknown step type " + step . t ) ;
}
2024-05-04 13:00:37 +00:00
p = p . then ( ( ) => {
emu . idle ( ) ;
} ) ;
return p ;
2024-05-03 21:38:10 +00:00
}
2024-05-03 22:04:46 +00:00
function runTest ( test , testState ) {
2024-05-04 20:56:37 +00:00
apploader . reset ( ) ;
2022-12-16 10:04:27 +00:00
var app = apploader . apps . find ( a => a . id == test . app ) ;
if ( ! app ) ERROR ( ` App ${ JSON . stringify ( test . app ) } not found ` ) ;
if ( app . custom ) ERROR ( ` App ${ JSON . stringify ( appId ) } requires HTML customisation ` ) ;
2024-04-20 05:50:44 +00:00
2022-12-16 10:04:27 +00:00
return apploader . getAppFilesString ( app ) . then ( command => {
2024-05-04 07:01:55 +00:00
let p = Promise . resolve ( ) ;
2022-12-16 10:04:27 +00:00
test . tests . forEach ( ( subtest , subtestIdx ) => {
2024-05-04 07:01:55 +00:00
let state = { ok : true } ;
p = p . then ( ( ) => {
console . log ( ` ============================== ` ) ;
console . log ( ` " ${ test . app } " Test ${ subtestIdx } ` ) ;
if ( test . description )
console . log ( ` " ${ test . description } ` ) ;
console . log ( ` ============================== ` ) ;
emu . factoryReset ( ) ;
2024-05-07 17:33:53 +00:00
console . log ( "> SENDING APP " + test . app ) ;
2024-05-04 07:01:55 +00:00
emu . tx ( command ) ;
2024-05-07 17:33:53 +00:00
console . log ( "> SENT APP" ) ;
2024-05-04 07:01:55 +00:00
emu . tx ( "reset()\n" ) ;
2024-05-07 17:33:53 +00:00
console . log ( "> RESET" ) ;
2024-05-04 07:01:55 +00:00
} ) ;
2024-05-03 21:38:10 +00:00
2022-12-16 10:04:27 +00:00
subtest . steps . forEach ( step => {
2024-05-04 13:00:37 +00:00
p = p . then ( ( ) => {
2024-05-04 20:57:19 +00:00
return runStep ( step , subtest , test , state ) . catch ( ( e ) => {
2024-05-07 17:33:53 +00:00
console . log ( "> STEP FAILED:" , e , step ) ;
2024-05-04 20:57:19 +00:00
state . ok = false ;
} )
2024-05-04 13:00:37 +00:00
} ) ;
2022-12-16 10:04:27 +00:00
} ) ;
2024-05-04 07:01:55 +00:00
2024-05-04 20:57:19 +00:00
p = p . finally ( ( ) => {
2024-05-07 17:33:53 +00:00
console . log ( "> RESULT -" , ( state . ok ? "OK" : "FAIL" ) , "- " + test . app + ( subtest . description ? ( " - " + subtest . description ) : "" ) ) ;
2024-05-04 07:01:55 +00:00
testState . push ( {
app : test . app ,
number : subtestIdx ,
result : state . ok ? "SUCCESS" : "FAILURE" ,
description : subtest . description
} ) ;
2024-05-03 22:04:46 +00:00
} ) ;
2022-12-16 10:04:27 +00:00
} ) ;
2024-05-04 07:01:55 +00:00
p = p . then ( ( ) => {
emu . stopIdle ( ) ;
} ) ;
return p ;
2022-12-16 10:04:27 +00:00
} ) ;
}
2024-05-07 17:46:49 +00:00
let handleRx = ( ) => { } ;
let handleConsoleOutput = ( ) => { } ;
if ( verbose ) {
handleConsoleOutput = ( d ) => {
console . log ( "<" , d ) ;
}
}
2024-05-03 22:04:46 +00:00
let testState = [ ] ;
2022-12-16 10:04:27 +00:00
emu . init ( {
EMULATOR : EMULATOR ,
2024-05-07 17:46:49 +00:00
DEVICEID : DEVICEID ,
rxCallback : ( ch ) => {
handleRx ( ch ) ;
} ,
consoleOutputCallback : ( d ) => {
handleConsoleOutput ( d ) ;
}
2022-12-16 10:04:27 +00:00
} ) . then ( function ( ) {
// Emulator is now loaded
console . log ( "Loading tests" ) ;
2024-05-03 22:04:46 +00:00
let p = Promise . resolve ( ) ;
2024-05-05 06:59:43 +00:00
let apps = apploader . apps ;
2024-05-07 21:22:06 +00:00
apps . push ( DEMOAPP ) ;
2024-05-07 17:37:31 +00:00
if ( process . argv . includes ( "--id" ) ) {
let f = process . argv [ process . argv . indexOf ( "--id" ) + 1 ] ;
apps = apps . filter ( e => e . id == f ) ;
if ( apps . length == 0 ) {
console . log ( "No apps left after filtering for " + f ) ;
process . exitCode ( 255 ) ;
}
}
2024-05-05 06:59:43 +00:00
apps . forEach ( app => {
2024-05-07 21:22:06 +00:00
let test = DEMOTEST ;
if ( app . id != DEMOAPP . id ) {
let testFile = APP _DIR + "/" + app . id + "/test.json" ;
2022-12-16 10:04:27 +00:00
if ( ! require ( "fs" ) . existsSync ( testFile ) ) return ;
2024-05-07 21:22:06 +00:00
test = JSON . parse ( require ( "fs" ) . readFileSync ( testFile ) . toString ( ) ) ;
2022-12-16 10:04:27 +00:00
test . app = app . id ;
2024-05-07 21:22:06 +00:00
}
2024-05-04 13:00:37 +00:00
p = p . then ( ( ) => {
2024-05-04 20:57:19 +00:00
return runTest ( test , testState ) ;
2024-05-04 13:00:37 +00:00
} ) ;
2024-05-03 22:04:46 +00:00
} ) ;
p . finally ( ( ) => {
console . log ( "\n\n" ) ;
console . log ( "Overall results:" ) ;
console . table ( testState ) ;
2024-05-05 07:30:58 +00:00
process . exit ( testState . reduce ( ( a , c ) => {
return a + ( ( c . result == "SUCCESS" ) ? 0 : 1 ) ;
} , 0 ) )
2022-12-16 10:04:27 +00:00
} ) ;
2024-05-03 22:04:46 +00:00
return p ;
2022-12-16 10:04:27 +00:00
} ) ;
2024-05-03 22:04:46 +00:00
2022-12-16 10:04:27 +00:00
/ *
if ( erroredApps . length ) {
erroredApps . forEach ( app => {
console . log ( ` ::error file= ${ app . id } :: ${ app . id } ` ) ;
console . log ( "::group::Log" ) ;
app . log . split ( "\n" ) . forEach ( line => console . log ( ` \u 001b[38;2;255;0;0m ${ line } ` ) ) ;
console . log ( "::endgroup::" ) ;
} ) ;
process . exit ( 1 ) ;
}
* /