A SimBLE device is a Rhai script; add assert(...) and the same script is a
test. It runs deterministically — no radio, no timing — so a failure is
reproducible and the AI generate-check-fix loop converges. Edit below and press Run test.
One stack, two ways to run it
SimBLE is a Rust crate that also compiles to WebAssembly. This page is the wasm build — but you don't run CI on a web page. The identical script runs natively, where your tests actually live. Same engine, same result.
In the browser · this page
The wasm build. Author a script, tweak it, and see pass/fail instantly — nothing to install. Good for exploring and for the AI loop.
Natively · where CI runs
The same .rhai file through the native simble CLI (exit 0 pass / 1 fail),
or a Rust #[test]. No browser, no netsim.
simble device.rhai # exit 0 / 1
Why this matters
Every assertion runs against SimBLE's real GATT stack in a fresh engine — so it
checks the device your app will actually meet, not a mock. Because the run is deterministic,
the exact same script an LLM writes, that you check here, and that CI runs natively are one file — no
hand-translation between "the test" and "the fixture". Behavioural tests (connect, subscribe, assert a
notification over time) build on the same primitive with wait_for and the scene APIs.
Writes a chosen payload — 16 KB to 1 MB — to a peripheral over GATT and reports the transfer time in four phases: discover, connect, negotiate, transfer. On BLE, connection setup often dominates total latency, so the phase breakdown is the primary result, not aggregate throughput. Each measurement is scoped to the controller that produced it, and runs accumulate for cross-controller comparison. Failed runs are retained: a connection that never establishes is a data point.