Testing against a scripted host
./testing is a WireTransport a test hands to QgisSdk.fromBridgeSchema
(or to its own BridgeClient), so the page’s real client, the SDK’s contract
validation and the React bindings all run unchanged against a host the test
scripts. Nothing global is mutated: two harnesses are two hosts, and a test
can prove nothing crosses between their clients.
import { QgisSdk } from "@archont561/qgis-sdk";import { SILENCE, createBridgeHarness, fault } from "@archont561/qgis-sdk/testing";import schema from "./bridge.schema";
const harness = createBridgeHarness(schema); // expectations typed by the schemaconst qgis = QgisSdk.fromBridgeSchema(schema, { transport: harness });
harness.expectInvoke("sites.summary", (payload) => ({ total: 1, largest: payload.layer_id, mode: "fast" }));harness.expectInvoke("sites.summary", () => fault("forbidden", "not yours"));harness.expectInvoke("sites.summary", () => SILENCE); // the client's own timeout speaksharness.expectSubscribe("sites.watch", (_payload, stream) => { stream.emit("data", { change: "added" }); stream.skip(2); // the next frame is a gap, ended the way the kernel promises stream.end({ kind: "complete" });});
await qgis.sites.summary({ layer_id: "sites" });harness.calls; // every envelope the client sent, in order; the handshake firstharness.assertSatisfied(); // unmet expectations, unexpected calls, open subscriptions, handler throws-
Handshake. A harness built on a schema answers the SDK’s handshake by itself, from the schema and
HOST_OPERATIONS;createBridgeHarness(schema, { granted: ["layers.list"] })narrows whatqgis.host.grantedreports, for tests of a page under a restricted host. The handshake is recorded inharness.callswithkind: "handshake"; filter it out when asserting the operations a page made. -
Untyped form.
createBridgeHarness<OperationId>()without a schema is what the 0.3.0 generated client and bareBridgeClienttests use;expectInvoke<Req, Res>then takes the types by hand. -
Expectations are consumed FIFO per operation. A call no expectation covers is answered with the
unexpected_callfailure code and remembered; a handler that throws answersharness_errorand is reported byassertSatisfied(). Both areQgisSdkBridgeHarnessErrors, as is an envelope that is not protocol 1. -
Deliveries are asynchronous and ordered: an acknowledgement reaches the client before the first frame a script emitted, and
await harness.settled()waits for everything queued. -
expectSubscribe(op, script, { ack })delays the acknowledgement until theack()promise settles, for tests of what a component does while a subscription is still opening. -
Evidence boundary. A green harness test says the page handles the frames a host could send; it says nothing about a
QWebEngineViewor a running host. That evidence lives in the Python suite and the qualification harnesses of doc-14. Keep the two apart in reports and never cite a mocked run as native behaviour.