11import arg from 'arg' ;
2+ import chalk from 'chalk' ;
23import { existsSync , readFileSync } from 'fs' ;
34import path , { join } from 'path' ;
45import { APIClient } from './APIClient' ;
56import type { APIEvent , SerialMonitorDataPayload } from './APITypes' ;
67import { parseConfig } from './config' ;
7- import { readVersion } from './readVersion' ;
88import { cliHelp } from './help' ;
9+ import { readVersion } from './readVersion' ;
10+ import { ExpectEngine } from './ExpectEngine' ;
911
1012async function main ( ) {
1113 const args = arg (
1214 {
1315 '--help' : Boolean ,
1416 '--quiet' : Boolean ,
1517 '--version' : Boolean ,
18+ '--expect-text' : String ,
19+ '--fail-text' : String ,
20+ '--timeout' : Number ,
1621 '-h' : '--help' ,
1722 '-q' : '--quiet' ,
1823 } ,
1924 { argv : process . argv . slice ( 2 ) }
2025 ) ;
2126
2227 const quiet = args [ '--quiet' ] ;
28+ const expectText = args [ '--expect-text' ] ;
29+ const failText = args [ '--fail-text' ] ;
30+ const timeout = args [ '--timeout' ] ?? 0 ;
31+ const timeoutNanos = timeout * 1_000_000 ;
32+
2333 if ( ! quiet ) {
2434 const { sha, version } = readVersion ( ) ;
2535 console . log ( `Wokwi CLI v${ version } (${ sha } )` ) ;
@@ -69,6 +79,28 @@ async function main() {
6979 process . exit ( 1 ) ;
7080 }
7181
82+ const expectEngine = new ExpectEngine ( ) ;
83+
84+ if ( expectText ) {
85+ expectEngine . expectTexts . push ( expectText ) ;
86+ expectEngine . on ( 'match' , ( text ) => {
87+ if ( ! quiet ) {
88+ console . log ( chalk `\n\nExpected text found: {green "${ expectText } "}` ) ;
89+ console . log ( 'TEST PASSED.' ) ;
90+ }
91+ process . exit ( 0 ) ;
92+ } ) ;
93+ }
94+
95+ if ( failText ) {
96+ expectEngine . failTexts . push ( failText ) ;
97+ expectEngine . on ( 'fail' , ( text ) => {
98+ console . error ( chalk `\n\n{red Error:} Unexpected text found: {yellow "${ text } "}` ) ;
99+ console . error ( 'TEST FAILED.' ) ;
100+ process . exit ( 1 ) ;
101+ } ) ;
102+ }
103+
72104 const client = new APIClient ( token ) ;
73105 client . onConnected = ( hello ) => {
74106 if ( ! quiet ) {
@@ -85,13 +117,24 @@ async function main() {
85117 }
86118
87119 await client . serialMonitorListen ( ) ;
88- await client . simStart ( { elf : 'test.elf' , firmware : 'firmware' } ) ;
120+ await client . simStart ( { elf : 'test.elf' , firmware : 'firmware' , pause : timeoutNanos > 0 } ) ;
121+ if ( timeout > 0 ) {
122+ await client . simResume ( timeoutNanos ) ;
123+ }
89124
90125 client . onEvent = ( event ) => {
126+ if ( event . event === 'sim:pause' ) {
127+ if ( timeoutNanos && event . nanos >= timeoutNanos ) {
128+ console . error ( `Timeout: simulation did not finish in ${ timeout } ms` ) ;
129+ process . exit ( 42 ) ;
130+ }
131+ }
91132 if ( event . event === 'serial-monitor:data' ) {
92- for ( const byte of ( event as APIEvent < SerialMonitorDataPayload > ) . payload . bytes ) {
133+ const { bytes } = ( event as APIEvent < SerialMonitorDataPayload > ) . payload ;
134+ for ( const byte of bytes ) {
93135 process . stdout . write ( String . fromCharCode ( byte ) ) ;
94136 }
137+ expectEngine . feed ( bytes ) ;
95138 }
96139 } ;
97140}
0 commit comments