Per your direction: tests must be able to debug UI/UX behaviors and
must be performant. Playwright's bundled Chromium falls to SwiftShader
on Linux which is fine for visual scenarios but tanks anything where
fps matters. New attach-mode lets us drive YOUR Chrome (hardware GPU)
without needing Playwright to spawn its own.
test/attach.py:
- One-shot health check that connects to localhost:9222 (Chrome
already running with --remote-debugging-port). Doesn't spawn,
doesn't close. Just confirms attach + reports the FPS HUD value.
- peek.py and run.py already attach via CDP, so they work as-is
once Chrome is started with the debug port.
test/README.md:
- New "Two modes" section up front: attach (your real Chrome,
hardware) vs launch (Playwright Chromium, software). Each has a
legitimate use; perf-sensitive work goes through attach.
- Workflow:
google-chrome --remote-debugging-port=9222 \\
--user-data-dir=/tmp/voxel-dev-chrome http://localhost:8080/
python3 attach.py # health check
python3 run.py scenarios/ui-menu-open-close.yaml
New UI scenarios that drive interactions via DOM events / wasm calls,
not pixel screenshots. Render-independent, fast on any backend:
ui-menu-open-close.yaml Click ≡ → assert menu-open class →
click resume → assert closed.
ui-hotbar.yaml pointerdown on slot 4 → assert .active
moved. Digit1 keypress → assert .active
back to slot 0.
ui-respawn.yaml teleport into void → wait → assert
is_alive()===false + body.dead class +
death screen visible. Click respawn-btn
→ assert hp===20, alive===true.
ui-settings-sliders.yaml Slider .value = N + dispatch 'input' →
assert displayed value updates → unwind
so the page isn't left frozen.
README updates list all scenarios. No code in the game changed —
this is pure test-harness additions.
39 lines
1.3 KiB
YAML
39 lines
1.3 KiB
YAML
name: ui-menu-open-close
|
|
description: |
|
|
Verify the settings menu opens, closes, and its presence is
|
|
reflected in body class state. Drives the menu button directly
|
|
(DOM click) so this works whether the canvas has pointer-lock
|
|
or not. Independent of render perf.
|
|
|
|
steps:
|
|
- wait_for: "window.voxel_game && document.getElementById('menu-btn')"
|
|
|
|
# Menu starts closed.
|
|
- assert: "!document.body.classList.contains('menu-open')"
|
|
|
|
# Click the menu-btn ≡ in the top-right. Open.
|
|
- eval: "document.getElementById('menu-btn').click()"
|
|
- wait: 200
|
|
- assert: "document.body.classList.contains('menu-open')"
|
|
|
|
# Game should be paused while menu is open.
|
|
- assert: "document.body.classList.contains('menu-open')"
|
|
|
|
# Screenshot for visual confirmation.
|
|
- screenshot: 01-menu-open.png
|
|
|
|
# Click resume button. Closes (or requests pointer-lock in PC mode).
|
|
- eval: "document.getElementById('menu-resume').click()"
|
|
- wait: 200
|
|
- screenshot: 02-after-resume.png
|
|
|
|
# Re-open via Escape (mobile mode only — Escape is handled by
|
|
# the menu setup when inputMode === "mobile"). Skip the assertion
|
|
# in PC mode since Escape would unlock pointer instead.
|
|
- eval: |
|
|
const isTouch = document.body.classList.contains('touch');
|
|
if (isTouch) {
|
|
document.getElementById('menu-btn').click();
|
|
}
|
|
- wait: 200
|
|
- screenshot: 03-final.png
|