open-standards/wai/wai-studio/test/core.test.mjs
Transaction Science 5b0dca60f1 WAI Studio e2e: a publisher in the room before a viewer joins; WebKit on Linux in Playwright's image; scrollable blocks focusable; Quantum Studio's critique a named group
A viewer follows the room's clock, whose events track opens with the room's first participant.
The macOS runner and the Studio host run WebKit from SSH, where it never launches, so the CI
runs WebKit in Playwright's image on the linux runner.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-27 16:17:25 -04:00

95 lines
5.5 KiB
JavaScript

// Each panel's calls on the core built for the web (core/, wasm-bindgen --target web), made
// as src/cores.js TabCore makes them, on vectors of the conformance corpora:
// Inspect envelope_inspect, envelope_unwrap, registry_list
// Verify receipt_verify
// Media media_decode, media_encode, envelope_wrap
// WAI_STUDIO_CORE_PKG names the package's directory (e2e/run.sh and CI build it).
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { readFileSync, readdirSync } from 'node:fs';
import { join, resolve } from 'node:path';
import { pathToFileURL, fileURLToPath } from 'node:url';
const PKG = process.env.WAI_STUDIO_CORE_PKG;
const skip = PKG ? false : 'WAI_STUDIO_CORE_PKG names no core package';
const WAI = resolve(fileURLToPath(import.meta.url), '../../..');
const HTTP = join(WAI, 'http-conformance');
const O5 = 'e43e038c10c0494d9647444fd4daf54b19fc3a946a3c7980431bc6e0a236093b';
const O9A = '31abc1da2cdf927191f3f447f68508ead30d078690cb7bea2435ae3d1df5f4f3';
const O9C = 'a8ab2cd0cc277ef7109aacdee6bb55ff713aa0d4dc4c2e3dfe40aab759a90133';
const O10 = '1eb764beb4a8a739054341df8b5b7d065e490032b187a93787be15f1478080a8';
const O2 = '25130382f5d9c73ae59a04d1fbae1463693f3769c090744ebd5f1e80fa3b0a34';
let core = null;
async function load() {
if (core) return core;
const m = await import(pathToFileURL(join(PKG, 'wai_studio_core.js')).href);
m.initSync({ module: readFileSync(join(PKG, 'wai_studio_core_bg.wasm')) });
core = m;
return m;
}
const call = (out) => { const env = JSON.parse(out.json()); const bytes = out.bytes(); out.free(); return { env, bytes }; };
const object = (cid) => new Uint8Array(readFileSync(join(HTTP, 'objects', `${cid}.wai`)));
const rcpt = () => readdirSync(join(HTTP, 'objects/rcpt')).map((n) => [`objects/rcpt/${n}`, new Uint8Array(readFileSync(join(HTTP, 'objects/rcpt', n)))]);
test('the core names its operations as the catalogue does', { skip }, async () => {
const c = await load();
const d = JSON.parse(c.core_describe());
for (const id of d.operations) assert.equal(typeof c[id.replace('.', '_')], 'function', id);
assert.deepEqual(d.decodes, ['wai.image.png', 'wai.audio.flac', 'wai.text.zstd']);
});
test('Inspect: an envelope, its verdict here, its components, and the registry', { skip }, async () => {
const c = await load();
const { env } = call(c.envelope_inspect(object(O5)));
assert.equal(env.wai, 'envelope/1');
assert.equal(env.op, 'envelope.inspect');
assert.equal(env.data.cid, O5);
assert.equal(env.data.verdict.code, 'decodable');
const two = call(c.envelope_inspect(object(O2))).env.data;
assert.equal(two.version, 'WAI2');
assert.equal(two.pick.capability, 'wai.image.png');
// With no component named, the one SPEC §7.1 selects at a sink that advertises everything,
// in SPEC §4's energy order: AVIF before the learned rendition (http-conformance's O2).
const u = call(c.envelope_unwrap(object(O2), -1));
assert.equal(u.env.data.capability, 'wai.image.avif');
assert.ok(u.bytes.length > 0);
const bad = call(c.envelope_inspect(new Uint8Array([1, 2, 3])));
assert.equal(bad.env.ok, false);
assert.equal(bad.env.error.code, 'envelope.unreadable');
const r = call(c.registry_list()).env.data;
assert.ok(r.capabilities.some((x) => x.capability === 'wai.text.zstd' && x.decode === 'here'));
});
test('Verify: receipt indexes with their groups, as http-conformance expects them', { skip }, async () => {
const c = await load();
const files = [...rcpt(), [`objects/${O9C}.wai`, object(O9C)], [`objects/${O9C}.wai.receipts`, new Uint8Array(readFileSync(join(HTTP, 'objects', `${O9C}.wai.receipts`)))]];
const ok = call(c.receipt_verify(files.map((f) => f[0]), files.map((f) => f[1]))).env;
assert.equal(ok.data.ok, true);
// http-conformance cases.json, receipts_walk_two: O9c held whole is delivered-verified.
assert.equal(ok.data.indexes[0].lines[0].code, 'delivered-verified');
const cases = readdirSync(join(HTTP, 'cases/rcpt')).map((n) => [`cases/rcpt/${n}`, new Uint8Array(readFileSync(join(HTTP, 'cases/rcpt', n)))]);
const bad = [...rcpt(), ...cases, [`objects/${O9A}.wai`, object(O9A)], [`objects/${O9A}.wai.receipts`, new Uint8Array(readFileSync(join(HTTP, 'cases/receipts/O9a-bad-signature.wai.receipts')))]];
const no = call(c.receipt_verify(bad.map((f) => f[0]), bad.map((f) => f[1]))).env;
// receipts_group_bad_signature: signature_verify_failed.
assert.equal(no.data.ok, false);
assert.equal(no.data.indexes[0].lines[0].code, 'signature_verify_failed');
});
test('Encode, decode, package: the floor round trip, a wrap, and a codec outside the floor refused', { skip }, async () => {
const c = await load();
const flac = call(c.media_decode(object(O10)));
assert.equal(flac.env.data.kind, 'audio');
assert.equal(flac.bytes.length, 4 * flac.env.data.samples);
const rgb = new Uint8Array(4 * 3 * 3).map((_, i) => (i * 29) & 255);
const png = call(c.media_encode('png', rgb, 4, 3, 75));
assert.equal(png.env.ok, true);
const back = call(c.media_decode(png.bytes));
assert.deepEqual(Array.from(back.bytes), Array.from(rgb));
const no = call(c.media_encode('avif', rgb, 4, 3, 75)).env;
assert.equal(no.error.code, 'encode.not-here');
const w = call(c.envelope_wrap('wai.text.zstd', new Uint8Array([1, 2, 3]), undefined, undefined));
assert.equal(w.env.data.intent, 'replicate');
assert.deepEqual(Array.from(call(c.envelope_unwrap(w.bytes, -1)).bytes), [1, 2, 3]);
assert.equal(call(c.envelope_wrap('wai.no.such', new Uint8Array([1]), undefined, undefined)).env.error.code, 'capability.unknown');
});