demo skill: read the dev port from config; make deps installs JS packages

The skill assumed port 4000, but config/dev.exs serves on 8056 (and honours
$PORT), so a fresh demo run failed its liveness check and every rodney URL
pointed at the wrong port.

- demo skill: resolve DEMO_PORT from the app config with
  `mix run --no-start -e 'Application.get_env(:firehose,
  FirehoseWeb.Endpoint)[:http][:port]'` (Endpoint.config/1 raises without a
  started endpoint), derive $DEMO_BASE_URL from it, start the server on that
  port from app/, and use $DEMO_BASE_URL in every rodney example. The skill
  also points at .tmp/phx-demo.log and names the assets/node_modules
  highlight.js failure as a diagnosable cause.
- app/Makefile: new `assets` target that runs `npm install` only when
  node_modules/.package-lock.json is missing, and `deps` now depends on it.
  A fresh clone gets a working JS bundle from `make deps`/`make test`; later
  runs never touch the network, so offline runs keep working.

Verified: guard skips with node_modules present and installs after moving it
aside; the skill's DEMO_PORT command prints 8056 and follows PORT=9999;
make check and make test (179 + 162) green.
This commit is contained in:
Willem van den Ende
2026-10-26 21:08:00 +00:00
parent be80c89548
commit a0692056bc
2 changed files with 39 additions and 9 deletions
+26 -6
View File
@@ -56,17 +56,37 @@ From these sources, produce a demo outline:
Interactions: any clicks, form fills, or navigation sequences to perform
If no plan exists and commits are ambiguous, ask the user for a brief description of what to demo.
3. Check dev server
3. Resolve the dev port, then check the server
curl -s -o /dev/null -w "%{http_code}" http://localhost:4000/ 2>/dev/null
Never assume a port. The port lives in the project config: `app/config/dev.exs`
sets `port: String.to_integer(System.get_env("PORT") || "8056")`, so `$PORT`
wins and the config default is the fallback. Ask the app, from the repo root:
DEMO_PORT=$(cd app && mise exec -- mix run --no-start -e \
'IO.puts(Application.get_env(:firehose, FirehoseWeb.Endpoint)[:http][:port])')
DEMO_BASE_URL="http://localhost:${DEMO_PORT}"
curl -s -o /dev/null -w "%{http_code}" "$DEMO_BASE_URL/"
Use `Application.get_env/2`, not `FirehoseWeb.Endpoint.config(:http)`: with
`--no-start` the endpoint's ETS table does not exist and `config/1` raises.
If the server is not reachable:
The Phoenix dev server is not running. Start it now?
mix phx.server &
mkdir -p .tmp && (cd app && PORT=$DEMO_PORT mise exec -- mix phx.server \
> ../.tmp/phx-demo.log 2>&1 &)
After starting, wait up to 10 seconds and verify connectivity. If it still fails, proceed with backend-only evidence (skip all browser screenshots) and note the limitation in the demo document.
Then poll `$DEMO_BASE_URL` for up to 10 seconds. If it still fails, read
`.tmp/phx-demo.log`: a bundle error about `highlight.js` (or any module) means
`app/assets/node_modules` is missing - run `make -C app assets` (root
`make deps` does it too). Only when the server really cannot come up, proceed
with backend-only evidence (skip all browser screenshots) and note the
limitation in the demo document.
Use `$DEMO_BASE_URL` for every URL below - there is no default port to fall
back on.
4. Handle authentication
The app requires authentication for LiveView routes. Before capturing UI screenshots:
@@ -84,7 +104,7 @@ The app requires authentication for LiveView routes. Before capturing UI screens
Log in via rodney:
rodney start
rodney open http://localhost:4000/users/log-in
rodney open "$DEMO_BASE_URL/users/log-in"
rodney wait "input[name='user[email]']"
rodney input "input[name='user[email]']" "demo@example.com"
rodney input "input[name='user[password]']" "demodemo1234"
@@ -136,7 +156,7 @@ For each UI page identified in step 2, navigate with rodney, screenshot, and emb
Static page capture:
rodney open http://localhost:4000/<route>
rodney open "$DEMO_BASE_URL/<route>"
rodney waitidle
rodney screenshot demos/screenshots/<feature>-<page-name>.png