You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor(test-skills): restructure test skills as self-contained architecture
Summary:
Replace the dual-purpose v1/v2 skill structure with self-contained skills
that work both standalone and as orchestrated sub-agents.
Individual skills (9):
- Remove Phase 1-4 outer structure and BEGIN/END SUB-AGENT markers
- Add Step 1-5 structure (install, start server, verify, test, cleanup)
- Use MCPCALL shorthand with dynamic port discovery
- Add recovery/retry guidance for transient failures
- Remove Follower suite from test-ui (not present in poke example)
Orchestrator (test-all):
- Orchestrator starts dev servers (sub-agents can't run background processes)
- Dynamic port discovery via .mcp.json files
- Sub-agents read skill files directly, start from Step 3
- Wait for completion notifications instead of polling
- No improvised bash commands — only pre-approved node scripts
New scripts:
- scripts/test-prep.mjs: clone/install/cleanup example directories
- scripts/test-servers.mjs: start/ports/stop dev server lifecycle
- All orchestrator bash operations converted to node scripts (zero permission prompts)
Settings: add allowlist entries for pnpm, npx, npm run fresh:install
Reviewed By: zjm-meta
Differential Revision: D95235621
fbshipit-source-id: 345a359881f045ec60f5b612fd97a9f81b898e6b
description: Automated test for the audio system (AudioSource loading, playback state, stop). Tests ECS audio state transitions using IWER MCP tools against the audio example. Dynamic entity discovery. Run from examples/audio/ with the dev server running. Note that actual audio output cannot be verified — only ECS state.
description: "Test audio system (AudioSource loading, playback state, stop, spatial audio) against the audio example using mcp-call.mjs WebSocket CLI."
**Important**: Actual audio output cannot be verified via MCP tools. These tests verify ECS state transitions only (loading, play requested, is playing, stop).
16
-
17
-
## Pre-test Setup
17
+
**SHORTHAND**: Throughout this document, `MCPCALL` means:
-`<JSON_ARGS>` is a JSON object string. Omit `--args` if no arguments needed.
30
+
- Output is JSON on stdout. Parse it to check assertions.
31
+
- Use `--timeout 20000` for operations that may take longer (reload, accept_session, screenshot).
32
+
- Always append `2>/dev/null` to suppress TLS warnings.
26
33
27
-
## Test Suites
34
+
**IMPORTANT**: Run each Bash command one at a time. Parse the JSON output and verify assertions before moving to the next command. Do NOT chain multiple mcp-call commands together.
28
35
29
-
### Suite 1: Audio Loading
36
+
**IMPORTANT**: When the instructions say "wait N seconds", use `sleep N` as a separate Bash command.
37
+
38
+
**IMPORTANT**: Boolean values in `ecs_set_component` must be actual JSON booleans (`value: true`), NOT strings (`value: "true"`). Strings silently fail to coerce.
30
39
31
-
**What we're testing**: AudioSource loads its buffer automatically.
40
+
---
32
41
33
-
#### Test 1.1: Find Audio Entity
42
+
##Step 1: Install Dependencies
34
43
44
+
```bash
45
+
cd /Users/felixz/Projects/immersive-web-sdk/examples/audio && npm run fresh:install
Start the dev server as a background task using the Bash tool's `run_in_background: true` parameter:
55
+
56
+
```bash
57
+
cd /Users/felixz/Projects/immersive-web-sdk/examples/audio && npm run dev
38
58
```
39
59
40
-
The audio example uses a GLXF level that creates entities via composition. The Spinner entity has an AudioSource.
60
+
**IMPORTANT**: This command MUST be run with `run_in_background: true` on the Bash tool — do NOT append `&` to the command itself.
61
+
62
+
Once the background task is launched, poll the output for Vite's ready message (up to 60s). Read the task output or use `tail` to watch for a line containing `Local:`. The output will contain a URL like `https://localhost:5173/`. Extract the port number from this URL and save it as `<PORT>`. All subsequent `MCPCALL` commands use this port.
41
63
42
-
#### Test 1.2: Verify Loaded State
64
+
If the server fails to start within 60 seconds, report FAIL for all suites and skip to Step 5.
If any suite fails, include which assertion failed and actual vs expected values.
217
+
218
+
---
219
+
220
+
## Recovery
221
+
222
+
If at any point a transient error occurs (server crash, WebSocket timeout, connection refused, etc.) that is NOT caused by a source code bug:
223
+
1. Kill the dev server: `kill $(lsof -t -i :<PORT>) 2>/dev/null`
224
+
2. Restart: re-run Step 2 to start a fresh dev server (port may change)
225
+
3. Re-run the Pre-test Setup (reload, accept session)
226
+
4. Retry the failed suite
227
+
228
+
Only give up after one retry attempt per suite. If the same suite fails twice, mark it FAIL and continue to the next suite.
229
+
153
230
---
154
231
155
232
## Known Issues & Workarounds
@@ -167,25 +244,10 @@ If `_stopRequested` and `_playRequested` are set simultaneously, stop wins.
167
244
IWER runs in a browser context where the AudioContext may be suspended until a user gesture. The MCP tools can verify ECS state transitions but cannot confirm actual audio output.
168
245
169
246
### Audio example uses GLXF level
170
-
The audio example loads entities from `./glxf/Composition.glxf`. Entities are not created in index.js — they come from the GLXF composition. The SpinSystem applies rotation to entities with AudioSource. Use `ecs_find_entities` to discover them dynamically.
247
+
The audio example loads entities from `./glxf/Composition.glxf`. Entities are not created in index.js — they come from the GLXF composition. Use `ecs_find_entities` to discover them dynamically.
171
248
172
-
## Architecture Notes
173
-
174
-
### Playback State Machine
175
-
```
176
-
[AudioSource added] → _loading=true → loadAudio() → _loaded=true, _pool created
177
-
↓ (_playRequested=true)
178
-
handlePlaybackRequests():
179
-
Restart: stop all → create new instance → _isPlaying=true
180
-
Overlap: add instance (steal if full) → _isPlaying=true
181
-
Ignore: skip if already playing
182
-
FadeRestart: fade out current → fade in new → _isPlaying=true
183
-
↓ (onended or _stopRequested)
184
-
releaseInstance() → if no instances left → _isPlaying=false
185
-
```
249
+
### Boolean values must be JSON booleans
250
+
When setting boolean fields (like `_playRequested`, `loop`, `_stopRequested`) via `ecs_set_component`, the `value` must be a JSON boolean (`true`), not a string (`"true"`). Strings silently fail.
186
251
187
-
### PlaybackMode Enum
188
-
-`restart` — Stop current, play new
189
-
-`overlap` — Add concurrent instance (up to maxInstances)
190
-
-`ignore` — Skip if already playing
191
-
-`fade-restart` — Crossfade from current to new
252
+
### Entity indices change on reload
253
+
Never cache entity indices across page reloads. Always re-discover via `ecs_find_entities`.
0 commit comments