Beaver tests #
End-to-end tests that drive the real beavershell binary via
WebDriver. The harness spawns Beaver with --webdriver <port>, opens a
Selenium session against it, runs the test body, and tears down the
process.
Quick start #
# 1. Build the binary the harness drives.
cargo build -r -p beaver-shell
# 2. Install JS test deps.
npm install
# 3. Run.
npm test
npm test runs every *.spec.js under tests/e2e/. To run a single
shell's smoke test:
node --test tests/e2e/desktop_smoke.spec.js
Configuration #
BEAVER_BIN— override the binary path. Defaults totarget/release/beavershellrelative to the repo root.
Layout #
tests/
├── harness/
│ ├── beaver_process.js # spawn beavershell + wait for /status
│ ├── driver.js # withDriver(url, fn) — full session lifecycle
│ └── selectors.js # shared CSS selectors per shell
├── e2e/
│ ├── desktop_smoke.spec.js
│ ├── mobile_smoke.spec.js
│ └── mediacenter_smoke.spec.js
└── unit/ # (placeholder for Phase 1 — pure-logic tests)
withDriver(url, body) is the only API individual tests should need:
import { test } from "node:test";
import { By } from "selenium-webdriver";
import { withDriver } from "../harness/driver.js";
test("dock renders", () =>
withDriver("beaver://system/desktop/index.html", async (driver) => {
const dock = await driver.findElement(By.css(".dock"));
// assertions...
}));
What WebDriver covers vs doesn't #
The Beaver WebDriver implementation (in crates/beaver_shell/src/webdriver.rs)
is a subset of the W3C protocol. As of now:
Implemented: session start, navigate (LoadUrl), execute script,
viewport/window queries, input events, shutdown, cookie reset.
Stubs that reply but don't do real work: NewWindow, CloseWebView,
FocusWebView, SetWindowRect, MaximizeWebView, refresh / back /
forward, screenshots, dialog handling.
The stubs log a warning when hit so it's clear what to fill in next. Add commands on demand as tests need them.
Connecting manually #
If you want to poke at the WebDriver server outside the test harness:
target/release/beavershell --webdriver 7070 beaver://system/desktop/index.html &
curl http://127.0.0.1:7070/status
# → {"value":{"ready":true,"message":"Ready for a new session"}}
Use the IP literal 127.0.0.1, not localhost .