// Tests for the interrupt round-trip through renderer.js. // // Main.js dispatches inbound `session/interrupt` requests as // `interrupt:incoming { interruptId, sessionId, kind, spec }`; the renderer // mounts a card, waits for the user, and answers with // `window.dsh.resolveInterrupt(id, { outcome, payload? })`. The three // outcomes are `accepted` / `rejected` / `cancelled`. Two spec kinds are // live on the wire: `approval` (tool-call gating) and `form` (structured // or free-text answer). // // Coverage matrix: // approval + accepted / rejected / cancelled // form (options) + accepted (payload has selectedOptions) / cancelled // form (schema) + accepted (payload has schema field values) // form (free) + accepted (payload has answer) // interrupt:invalidate — card disabled, entry removed from state map 'use strict' const test = require('node:test') const assert = require('node:assert/strict') const { loadRenderer } = require('./renderer-harness.js') async function bootWithSession() { const bundle = await loadRenderer() bundle.renderer.ensureSession('s1', { title: 's', header: {} }) await bundle.renderer.selectSession('s1') return bundle } function findApprovalCard(document) { return document.querySelector('.card.approval') } function findFormCard(document) { return document.querySelector('.card.form') } function findButtonByText(root, text) { // Walk depth-first and match ONLY