Phase kuma M1 impl: resolves the 2026-05-28 DEFERRED uptime-kuma create-a-monitor item. Approach: Playwright (option b) — python-socketio not in cc-ci Nix env; Playwright handles Socket.IO transparently via the real browser. Selectors confirmed in 2.2.1 compiled bundle (data-cy setup wizard + data-testid monitor form/status badge). Test flow (test_monitor_wizard_and_probe): 1. Setup wizard: admin create via data-cy form → auto-login → /dashboard 2. Create self-probe monitor (https://{live_app}/) → wait ≤90s for "Up" badge 3. Heartbeat table row check: isFirstBeat=important, row has real datetime stamp 4. Negative: dead-port monitor (http://127.0.0.1:19999/dead) → wait ≤60s for "Down" All waits are bounded poll with page.wait_for_function/wait_for_url/wait_for_selector. Admin password: 64-char UUID hex, never printed/logged. Also: DECISIONS.md records Playwright choice; phase state files bootstrapped. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
62 lines
2.8 KiB
Markdown
62 lines
2.8 KiB
Markdown
# STATUS — phase `kuma` (uptime-kuma create-a-monitor functional test)
|
||
|
||
SSOT: `cc-ci-plan/plan-phase-kuma-monitor.md`
|
||
|
||
## Current state
|
||
|
||
**Gate: M1 IN PROGRESS** — test implemented, pending first drone run to confirm green.
|
||
|
||
## What is claimed
|
||
|
||
### Approach choice (DECISIONS.md)
|
||
Playwright (option b). Justification: python-socketio is NOT available in the cc-ci Nix env
|
||
(confirmed: only playwright + pytest in site-packages). Playwright drives the real browser;
|
||
Socket.IO is handled transparently. No Nix changes needed.
|
||
|
||
### Test file
|
||
`tests/uptime-kuma/playwright/test_monitor_wizard.py`
|
||
|
||
### What the test does
|
||
1. Completes uptime-kuma 2.2.1 first-run setup wizard (admin create via browser).
|
||
2. Creates HTTP monitor targeting the app's own root URL (guaranteed UP at test time).
|
||
3. Waits ≤90 s for status badge (`data-testid="monitor-status"`) to show "Up".
|
||
4. Asserts important-heartbeat table row exists with a real datetime stamp (proves probe ran).
|
||
5. Creates a second monitor targeting `http://127.0.0.1:19999/dead` (dead port → connection refused).
|
||
6. Waits ≤60 s for status badge to show "Down" (negative teeth).
|
||
|
||
### Selectors used (all confirmed in compiled bundle `dist/assets/index-D_mnxLA0.js`)
|
||
- Setup: `data-cy="username-input"`, `data-cy="password-input"`, `data-cy="password-repeat-input"`, `data-cy="submit-setup-form"`
|
||
- EditMonitor: `data-testid="friendly-name-input"`, `data-testid="url-input"`, `data-testid="save-button"`
|
||
- Details: `data-testid="monitor-status"`
|
||
- Heartbeat table: `table.table-hover tbody tr` (first row)
|
||
|
||
### Secret safety
|
||
Admin password: 64-char UUID hex, generated per-run. Never printed, never in any assertion error message.
|
||
|
||
### Probe reality
|
||
- "Up" in the status badge comes from `lastHeartbeatList` populated via Socket.IO heartbeat events
|
||
(socket.js mixin line 755). Cannot be "Up" unless a real probe completed and the server sent the
|
||
heartbeat over the socket.
|
||
- Important-heartbeat table row exists: `isFirstBeat` is always `important=true` (server/model/monitor.js
|
||
line 1420). Presence of a row with "YYYY-MM-DD HH:mm:ss" timestamp proves the probe ran after monitor
|
||
creation.
|
||
- Negative teeth: "Down" can only appear after the probe attempted and got connection-refused.
|
||
|
||
### How to verify (Adversary cold-check)
|
||
```bash
|
||
# Deploy uptime-kuma against any fresh cc-ci domain, then run:
|
||
CCCI_APP_DOMAIN=<domain> RECIPE=uptime-kuma STAGES=custom \
|
||
cc-ci-run -m pytest tests/uptime-kuma/playwright/test_monitor_wizard.py -v
|
||
# Expected: test_monitor_wizard_and_probe PASSED
|
||
# In the Drone-path, it runs under the "custom" tier via run_recipe_ci.py.
|
||
```
|
||
|
||
### Runtime
|
||
Local estimate: wizard ~10 s + 2× (navigate+fill+probe) ≤ ~60 s total. Within ≤90 s budget.
|
||
|
||
### Next step
|
||
Trigger `!testme` on a uptime-kuma PR; wait for drone run to pass; then claim M1.
|
||
|
||
## Blocked
|
||
(nothing)
|