@@ -468,6 +468,92 @@ describe("debugger", () => {
468468 testCtx . abort ( ) ;
469469 await debuggerPromise ;
470470 } ) ;
471+
472+ it ( "preserves text/binary framing end-to-end" , async ( ) => {
473+ const syncScenario = await makeSyncScenario ( { localFiles : { ".gadget/" : "" } } ) ;
474+
475+ // Remote mock WS server that records whether received frames are binary
476+ const wss = new WebSocketServer ( { port : 0 } ) ;
477+ await new Promise < void > ( ( resolve ) => wss . once ( "listening" , resolve ) ) ;
478+ const remotePort = ( wss . address ( ) as any ) . port as number ;
479+
480+ const remoteReceivedIsBinary : boolean [ ] = [ ] ;
481+ let remoteSocket ! : WebSocket ;
482+
483+ const remoteConnected = new Promise < void > ( ( resolve ) => {
484+ wss . on ( "connection" , ( ws ) => {
485+ remoteSocket = ws ;
486+ ws . on ( "message" , ( _data , isBinary ) => {
487+ remoteReceivedIsBinary . push ( isBinary ) ;
488+ } ) ;
489+ resolve ( ) ;
490+ } ) ;
491+ } ) ;
492+
493+ setupMockRemote ( getSubdomain ( syncScenario ) , `ws://localhost:${ remotePort } ` ) ;
494+
495+ const debuggerPromise = debuggerCommand . run ( testCtx , makeArgs ( debuggerCommand . args ) ) ;
496+
497+ await waitUntilUsed ( 9229 ) ;
498+
499+ const response = await fetch ( "http://127.0.0.1:9229/json/list" ) ;
500+ const result = ( await response . json ( ) ) as any ;
501+ const wsUrl = result [ 0 ] . webSocketDebuggerUrl ;
502+
503+ const clientWs = new WebSocket ( wsUrl ) ;
504+
505+ await remoteConnected ; // ensure remote side is connected
506+
507+ // Track framing for messages coming back from remote to client
508+ const clientReceivedIsBinary : boolean [ ] = [ ] ;
509+ const clientGotTwo = new Promise < void > ( ( resolve ) => {
510+ clientWs . on ( "message" , ( _data , isBinary ) => {
511+ clientReceivedIsBinary . push ( isBinary ) ;
512+ if ( clientReceivedIsBinary . length === 2 ) {
513+ resolve ( ) ;
514+ }
515+ } ) ;
516+ } ) ;
517+
518+ // Client -> Remote: send a text frame (string) and a binary frame (Buffer)
519+ clientWs . send ( JSON . stringify ( { hello : "world" } ) ) ;
520+ clientWs . send ( Buffer . from ( [ 1 , 2 , 3 ] ) , { binary : true } ) ;
521+
522+ // Wait until remote has received both messages
523+ await new Promise < void > ( ( resolve , reject ) => {
524+ const start = Date . now ( ) ;
525+ const check = ( ) : void => {
526+ if ( remoteReceivedIsBinary . length >= 2 ) {
527+ resolve ( ) ;
528+ return ;
529+ }
530+ if ( Date . now ( ) - start > 5000 ) {
531+ reject ( new Error ( "timeout waiting for remote messages" ) ) ;
532+ return ;
533+ }
534+ setTimeout ( check , 25 ) ;
535+ } ;
536+ check ( ) ;
537+ } ) ;
538+
539+ expect ( remoteReceivedIsBinary ) . toEqual ( [ false , true ] ) ;
540+
541+ // Remote -> Client: send a text frame and a binary frame and ensure client sees same framing
542+ remoteSocket . send ( JSON . stringify ( { ok : true } ) , { binary : false } ) ;
543+ remoteSocket . send ( Buffer . from ( [ 9 , 8 , 7 ] ) , { binary : true } ) ;
544+
545+ await clientGotTwo ;
546+ expect ( clientReceivedIsBinary ) . toEqual ( [ false , true ] ) ;
547+
548+ // Cleanup
549+ await new Promise < void > ( ( resolve ) => {
550+ clientWs . once ( "close" , ( ) => resolve ( ) ) ;
551+ clientWs . close ( ) ;
552+ } ) ;
553+ wss . close ( ) ;
554+ testCtx . abort ( ) ;
555+ await debuggerPromise ;
556+ } ) ;
471557 } ) ;
472558
473559 describe ( "configuration" , ( ) => {
0 commit comments