9 lines
2.3 KiB
JavaScript
9 lines
2.3 KiB
JavaScript
import {test} from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import {createCdpCalls} from './cdp-client.mjs';
|
|
function fixture(){const handlers=new Map(),sent=[],timers=new Map();let id=0;const socket={addEventListener:(event,callback)=>handlers.set(event,callback),send:text=>sent.push(JSON.parse(text))},events=[],call=createCdpCalls(socket,{timeoutMs:30,onEvent:event=>events.push(event),setTimer:callback=>{timers.set(++id,callback);return id;},clearTimer:key=>timers.delete(key)});return{call,sent,timers,events,event:(name,data)=>handlers.get(name)({data:JSON.stringify(data)})};}
|
|
test('CDP responses route by request ID, forward events and release deadline timers',async()=>{const f=fixture(),one=f.call('one'),two=f.call('two');f.event('message',{method:'Runtime.event'});f.event('message',{id:2,result:{value:'two'}});f.event('message',{id:1,result:{value:'one'}});assert.deepEqual(await one,{value:'one'});assert.deepEqual(await two,{value:'two'});assert.equal(f.events.length,1);assert.equal(f.timers.size,0);});
|
|
test('a stalled CDP call rejects all pending work and cannot hide behind another unbounded report read',async()=>{const f=fixture(),one=assert.rejects(f.call('Runtime.evaluate'),/timed out/),two=assert.rejects(f.call('Page.captureScreenshot'),/timed out/);[...f.timers.values()][0]();await Promise.all([one,two]);assert.equal(f.timers.size,0);f.event('message',{id:1,result:{late:true}});await assert.rejects(f.call('Runtime.evaluate'),/timed out/);});
|
|
test('connection loss and fatal target events reject pending calls without accepting dialogs',async()=>{for(const event of ['close','error','Inspector.targetCrashed','Target.targetCrashed','Inspector.detached','Page.javascriptDialogOpening']){const f=fixture(),result=assert.rejects(f.call('Runtime.evaluate'),/CDP/);event.includes('.')?f.event('message',{method:event}):f.event(event);await result;assert.equal(f.timers.size,0);assert.deepEqual(f.sent.map(row=>row.method),['Runtime.evaluate']);}});
|
|
test('one protocol command error does not corrupt another request or leak its timer',async()=>{const f=fixture(),one=assert.rejects(f.call('bad'),/invalid/),two=f.call('good');f.event('message',{id:1,error:{message:'invalid'}});f.event('message',{id:2,result:{ok:true}});await one;assert.deepEqual(await two,{ok:true});assert.equal(f.timers.size,0);});
|