@@ -37,6 +37,28 @@ async function runCli(args, cwd = __dirname) {
3737 } ;
3838}
3939
40+ function parseJsonFromOutput ( raw ) {
41+ const trimmed = raw . trim ( ) ;
42+ if ( ! trimmed ) {
43+ throw new Error ( "Expected JSON output but received an empty string" ) ;
44+ }
45+
46+ try {
47+ return JSON . parse ( trimmed ) ;
48+ } catch {
49+ const lines = trimmed . split ( / \r ? \n / ) . filter ( Boolean ) ;
50+ for ( let index = lines . length - 1 ; index >= 0 ; index -= 1 ) {
51+ try {
52+ return JSON . parse ( lines [ index ] ) ;
53+ } catch {
54+ // Keep scanning until we find the trailing JSON payload.
55+ }
56+ }
57+ }
58+
59+ throw new Error ( `Unable to parse JSON output: ${ trimmed } ` ) ;
60+ }
61+
4062async function writeJson ( filePath , value ) {
4163 await fsp . mkdir ( path . dirname ( filePath ) , { recursive : true } ) ;
4264 await fsp . writeFile ( filePath , `${ JSON . stringify ( value , null , 2 ) } \n` , "utf8" ) ;
@@ -153,7 +175,7 @@ test("prepare-runtime: emits resolved runtime payload with governance and enforc
153175 ) ;
154176
155177 assert . equal ( result . exitCode , 0 , result . stderr ) ;
156- const payload = JSON . parse ( result . stdout ) ;
178+ const payload = parseJsonFromOutput ( result . stdout ) ;
157179
158180 assert . equal ( payload . surface . surfaceId , "demo-surface" ) ;
159181 assert . equal ( payload . bundle . sourcePaths . runtime , path . join ( bundleRoot , "surfaces" , "demo-surface" , "runtime.json" ) ) ;
@@ -192,7 +214,7 @@ test("prepare-runtime: fails with adapter error when runtime bundle is missing",
192214 ) ;
193215
194216 assert . equal ( result . exitCode , 10 , result . stderr ) ;
195- const payload = JSON . parse ( result . stderr ) ;
217+ const payload = parseJsonFromOutput ( result . stderr ) ;
196218 assert . equal ( payload . code , "adapter.bundle.runtime-missing" ) ;
197219 } finally {
198220 await fsp . rm ( tempDir , { recursive : true , force : true } ) ;
0 commit comments