ui-qa-sweep
GitHub对 Breeze RMM Web UI 进行全量回归测试,模拟人工 QA 执行日常流程、设置任务及 PR 历史回溯验证。记录功能通过/失败状态及 UI/UX 观察结果,并针对发现的问题提交 GitHub Issue,确保整体应用质量。
触发场景
安装
npx skills add LanternOps/breeze --skill ui-qa-sweep -g -y
SKILL.md
Frontmatter
{
"name": "ui-qa-sweep",
"description": "Broad regression QA of the Breeze RMM web UI via Playwright — exercising everyday MSP workflows and setup tasks like a human QA tester, logging functional PASS\/FAIL plus UI\/UX observations, and filing GitHub issues from findings. Use this whenever the user asks to \"QA the UI\", do \"extensive UI testing\", a \"regression sweep\", \"test everyday flows\", \"act as QA\", verify recently\/previously merged PRs end-to-end through the browser, or walk backward through PR history checking the UI. This is the whole-app sweep — for verifying ONE just-built feature use `feature-testing` instead."
}
UI QA Sweep
Purpose & scope
feature-testing verifies one freshly-implemented feature. This skill is the
opposite: a wide regression pass over the whole product as a skeptical human
QA tester would do it — log in, click everything an MSP touches day to day, try
the setup/onboarding tasks, and walk backward through merged PRs confirming each
shipped change still works in the browser. The deliverable is an evidence log
(functional results and UI/UX observations) plus GitHub issues for real
defects.
Bias toward breadth and skepticism. The most valuable findings here are not "feature X exists" — they're silent failures, dead ends, confusing copy, console errors, broken empty states, and things that look fine but give the user no feedback. Treat "the API returned a clean error but the UI showed nothing" as a bug, not a pass.
Workflow
- Environment — get a reachable local stack (this is the usual time sink).
- Baseline login + nav crawl — confirm every nav destination renders.
- Everyday-workflow checklist — run the recurring-task list below.
- Setup-task checklist — run the onboarding/configuration list below.
- Backward-through-PRs pass —
gh pr list --state merged, newest→oldest, translate each UI-affecting PR into a concrete click-path, verify it. - Log continuously — append to
docs/testing/FEATURE_TEST_LOG.mdas you go (not just at the end), with a running UI/UX observations sub-log. - File issues — use the
github-issuesskill; one focused issue per defect, dedupe against open issues first, link to the log.
Use TaskCreate to track the checklist so progress survives context limits.
Prefer dispatching this sweep to a background agent (it is long-running and
context-heavy); a single agent must own the Playwright browser — never run two
browser-driving agents concurrently against the shared MCP browser.
Phase 1 — Environment (read this first, it always bites)
The local stack is frequently misconfigured for browser access. See the
local-playwright-env-setup memory for the full rationale. Short version:
- Target
http://localhostthrough Caddy:80. Do not usehttps://2breeze.app(public tunnel is typically down → CF 530; Chromium rejects Caddy's self-signed cert and the MCP browser has noignoreHTTPSErrors). - If login throws "Network error": check
PUBLIC_API_URL. The web app preserves the URL scheme, so anhttps://value force-upgrades API calls and resets. Fix:.envPUBLIC_API_URL=http://localhost, addhttp://localhosttoCORS_ALLOWED_ORIGINS, leaveBREEZE_DOMAINunset, thendocker compose up -d --force-recreate web caddy. Dev web isastro devand re-reads env on restart (no image rebuild)..envis gitignored — local only. - After a
--buildrebuild, the API container gets a new IP; restart caddy or it 502s the API on a stale upstream. - Confirm:
curl -s -o /dev/null -w '%{http_code}' http://localhost/health→ 200. - Login:
admin@breeze.local/BreezeAdmin123!(the.envE2E_ADMIN_PASSWORDis stale). Clear login rate limits if needed (seefeature-testingPhase 2).
Load Playwright tools via ToolSearch("select:mcp__plugin_playwright_playwright__browser_navigate,...").
Phase 2 — Baseline login + nav crawl
Log in, then visit every sidebar destination once and record: does it render,
HTTP status of its primary data call, console errors/warnings. This is cheap and
catches the highest-impact regressions (a whole page 500ing). Known noise to
note but not chase: a non-platform-admin sees 403 on
/admin/account-deletion-requests/pending-count and the third-party catalog
(tracked — see issues; don't refile).
Nav surface (current): Dashboard, Devices, Alerts (Alerts/Rules/Channels), Incidents, Remote Access, Scripts, Patches (Compliance/Patches/Update Rings), Fleet, AI Workspace, Network Monitor, Security, Sensitive Data, Peripherals, AI Risk, CIS Benchmarks, Compliance Baselines, Network Discovery, Software Library, Software Policies, Config Policies, Backup, Cloud Backup, Disaster Recovery, Integrations, Reports, Analytics, Audit Trail, Event Logs, Settings (Partner, Organizations, AI Usage, Custom Fields, Saved Filters, Users, Roles, Enrollment Keys).
Phase 3 — Everyday-workflow checklist
These are the things an MSP tech does on a normal day. For each: perform the action through the UI, verify the result is visibly confirmed (toast, state change, list update — not just a 2xx in the network tab), and check no console error. A backend success with no UI feedback is a fail (this is the #1 recurring defect class — see issue #720).
- Devices: search/filter by status & OS; change page size; open a device; switch device-detail tabs (Overview, Performance, Hardware, Software, Patches, Connections, Event Log); sort columns; bulk-select; tag a device.
- Device actions: Run Script, Reboot, Wake, Connect Desktop, Remote Tools — each must show success/failure feedback. (Offline fixtures: expect graceful "can't" messaging, not silence.)
- Alerts: view active alerts; acknowledge / resolve / suppress one; open an alert rule; create + edit + delete a notification channel; click Test on a channel and confirm a visible pass/fail result.
- Scripts: create a script; import from library; edit; run on a device (script picker shows system scripts); view run output.
- Patches: view compliance; run a scan; open a device's patch list; approve/reject a patch; filter by source incl. 3rd-party.
- Remote: open a remote session list; start a session (or graceful offline-device messaging).
- Search: Cmd+K global search for a device / script / setting; result navigates correctly.
- Saved filters / tags / custom fields: create one, apply it, delete it.
- Reports / Analytics / Audit: generate/open a report; audit trail paginates and filters; export buttons respond.
- Theme / profile: toggle theme; open profile menu; sign out + back in.
Phase 4 — Setup-task checklist (onboarding / configuration)
These are the things done when setting up a tenant or a new feature. Watch
especially for: validation messages being readable (not [object Object], not
silent, not over-generic), guided next-steps after creation, and sidebar/list
sync after create/delete.
- Org/site structure: create an organization → guided "add first site" → create a site; rename; delete (named confirm dialog). Verify list + org switcher stay in sync.
- Users & roles: invite a user; create/edit a role; assign it.
- Enrollment: create an enrollment key; view the install command; revoke a key.
- Notification channels: configure each type (Email, Slack, Teams, PagerDuty, Webhook, SMS, Pushover); set partner-level defaults; verify inheritance; create a routing rule.
- Configuration policies: create a policy; link a feature; assign to an
org/site; preview effective config (use the
configuration-policyskill for internals). - Partner settings: every tab (Company, Regional, Security, Notifications,
Defaults, Branding, AI Budgets, Remote-tool providers) — save with valid and
invalid input; confirm scheme/URL validation rejects
javascript:/data:. - Monitoring / Discovery: configure a monitor; start a network discovery scan; view results.
- Backup / DR: configure a backup SLA; create a DR plan (forms render & validate).
- Integrations: open the integrations catalog; start a connect flow (OAuth/API-key form renders).
Fixture-limited items (single-org seed, offline devices, no platform admin) — note as BLOCKED with the prerequisite, don't fake a pass. Re-test guidance goes in the log.
Phase 5 — Backward-through-PRs pass
gh pr list --repo LanternOps/breeze --state merged --limit 60 \
--json number,title,mergedAt --jq 'sort_by(.mergedAt)|reverse|.[]|"\(.number) \(.title)"'
Walk newest→oldest. Skip pure chore/deps/CI/refactor/agent-only PRs (no web surface). For each UI-affecting PR, translate the title into a concrete click-path and verify the change is present and works. When the recent window is covered, keep going further back — this is a backward sweep, there is no natural stopping point except the user's call or running out of UI-affecting PRs. Record the oldest PR number reached so a later run can resume.
Logging format
Append to docs/testing/FEATURE_TEST_LOG.md under a dated
## UI QA Sweep — YYYY-MM-DD section. Write entries as you go, not at the
end (a long sweep will hit context limits; unflushed findings are lost).
Per area:
### [Area / PR#] — PASS | PARTIAL | FAIL | BLOCKED
- ✅ what worked (with the concrete check)
- ❌ BUG: symptom → API actual (status + body) vs UI actual; why it's a bug
- ⚠️ UI/UX: friction, confusing copy, layout, console noise (the parallel log)
- prerequisite/re-test note if BLOCKED
Keep a running UI/UX observations list separate from pass/fail — small papercuts (ambiguous labels, missing empty states, overlays that intercept clicks, console errors, transient toasts) are the point, not a side note.
End with a summary table (area → result) and a "Top findings" section calling out systemic patterns (e.g. "N features share a broken toast path").
Filing issues from findings
Invoke the github-issues skill. Rules that matter here:
- One focused issue per defect; don't batch unrelated findings.
gh issue list --state openand grep for keywords first — dedupe. If related but distinct (different symptom, same file), cross-link, don't refile.- Title
[UI] symptom...; body = Description (with exact API status+body vs UI behavior), suspected root cause, proposed fix, affected files, "Reported By: internal Playwright UI QA sweep, evidence in FEATURE_TEST_LOG.md". - Internal QA ⇒ no
@reporter; still don't close issues yourself.
Anti-patterns
- Declaring PASS on a 2xx without confirming the UI told the user. Silence is a fail.
- Full-page screenshots/snapshots every step — burns context. Prefer targeted
browser_snapshot target=...+browser_evaluateDOM probes; screenshot only when a visual check is the point. - Chasing already-tracked noise (the
/admin/*403s) — note once, move on. - Faking coverage for fixture-blocked items — mark BLOCKED with the prereq.
- Doing the whole sweep in the main session — dispatch to a background agent and keep the main context for triage and issue-filing.
- False silent-failure from selector choice. Many modals/drawers are plain
fixed inset-0divs with norole=dialog. Asserting "did a dialog open" by role/class will wrongly conclude an action silently failed (this bit a Reboot-button check). Assert on the modal's title/body text (or adata-testid) instead, and confirm the outcome (toast/state change), not the container.
版本历史
- 10bb1af 当前 2026-08-20 08:50


