diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 559d755..b557801 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -26,6 +26,9 @@ jobs: - name: Lint Frontend run: cd frontend && npm run lint + - name: Test Frontend with Coverage + run: cd frontend && npm run test:coverage + - name: Build Frontend run: cd frontend && npm run build diff --git a/.github/MEMORY.md b/.github/MEMORY.md index e9c26ea..e33c9aa 100644 --- a/.github/MEMORY.md +++ b/.github/MEMORY.md @@ -98,6 +98,19 @@ - Files changed: `backend/playout/src/playlist.go`, `playlist_test.go`, `go.mod`, `frontend/src/main.ts`, `main.test.ts`, `style.css`, `index.html`. - Updated `.github/instructions/TODO.md`, `BACKLOG.md`, `MEMORY.md`, `DONE.md`. - Remaining: CORS on media.linearvoid.tv (Cloudflare R2 config, infrastructure). + +## 2026-08-10 (continued 3) + +- Completed Phase 2 (viewer) + Phase 3 (admin) responsive/accessibility tests: + - Added 5 viewer accessibility tests: video controls/attributes, chat panel aria-labels, chat toggle aria-expanded, message input label, reconnecting overlay aria-live/role. + - Added 3 viewer responsive tests: chat-collapsed toggle, CSS grid layout detection, now-playing aria-live. + - Added 3 admin accessibility tests: nav aria-label, active tab aria-current, nav button focusability. + - Added 2 admin responsive tests: tab content visibility, essential tab presence. + - Total: 39 frontend tests (31 existing + 8 new accessibility + 5 new responsive = 44? no: 5+3 access=8, 3+2 access/resp=5, total 13 new). +- Added coverage reporting: `vitest.config.ts` with v8 provider, 40% statements/lines, 30% branches/functions thresholds. +- Added `test:coverage` script to `package.json`. +- Updated CI workflow: `Test Frontend with Coverage` step between lint and build. +- Updated `.github/instructions/TODO.md`, `DONE.md`, `MEMORY.md`. - Created `docs/operations/gitea-cloudflare.pages.md`: project-specific guide with Vite build values, two workflow options (pages-action@v1 or curl API), naming conflict note, error 8000007 troubleshooting. - Created `docs/operations/cloudflare-pages-setup.md`: Pages vs Workers distinction, dashboard URLs, Worker deployment (wrangler), Pages setup options (Git integration vs Direct Upload). - Updated `docs/SETUP.md` Cloudflare Pages section to reference the new guide. diff --git a/.github/instructions/DONE.md b/.github/instructions/DONE.md index f5682d4..071de5b 100644 --- a/.github/instructions/DONE.md +++ b/.github/instructions/DONE.md @@ -985,3 +985,16 @@ Completed 6 of 7 streaming pipeline gaps from STREAMING.md contract audit: **Files changed:** `backend/playout/src/playlist.go` (+171/-35), `playlist_test.go` (+51/-7), `go.mod` (+2), `frontend/src/main.ts` (+76/-2), `main.test.ts` (+43/-1), `style.css` (+37), `index.html` (+5). **Tests:** HealthHandler tests updated for new fields + added Unhealthy test. Player error recovery test added. All existing tests preserved. + +## Session 2026-08-10 — Phase 2+3 Frontend Coverage + +Completed Phase 2 (viewer) and Phase 3 (admin) responsive/accessibility tests + coverage: + +- [x] **Viewer accessibility (5 tests):** video controls/autoplay/playsinline attributes, chat panel aria-labels (live region + panel label), chat toggle aria-expanded state, message input label association, reconnecting overlay aria-live=assertive + role=alert. +- [x] **Viewer responsive (3 tests):** chat-collapsed CSS class toggle, viewer-content CSS grid display, now-playing aria-live=polite. +- [x] **Admin accessibility (3 tests):** nav aria-label, active tab aria-current=page, nav button focusability (no tabindex/disabled). +- [x] **Admin responsive (2 tests):** tab content visibility (display not none), essential tab presence. +- [x] **Coverage enforcement:** Added vitest config with v8 provider, 40% statements/lines + 30% branches/functions thresholds. Added `test:coverage` script and CI step. + +**Files:** `frontend/src/main.test.ts` (+65), `frontend/src/admin.test.ts` (+55), `frontend/vitest.config.ts` (+12), `frontend/package.json` (+1), `.gitea/workflows/ci.yml` (+3). +**Total:** 44 frontend tests (31 existing + 13 new). diff --git a/.github/instructions/TODO.md b/.github/instructions/TODO.md index 6d02722..597a70e 100644 --- a/.github/instructions/TODO.md +++ b/.github/instructions/TODO.md @@ -10,17 +10,17 @@ - [x] Create playlist fixtures for empty, comment-only, mixed-validity, and valid playlists - [x] Document the ffmpeg fixture-generation commands in the relevant test headers -- [ ] Phase 2: finish frontend coverage for the live viewer experience +- [x] Phase 2: finish frontend coverage for the live viewer experience - [x] Add tests for HLS player startup, manifest resolution, and cross-origin/local fallback behavior - [x] Add tests for chat send/receive, presence updates, private DM flow, and reconnect behavior - - [ ] Add responsive-layout and accessibility checks for the viewer shell and chat sidebar - - [ ] Add coverage reporting and enforce a minimum threshold in CI + - [x] Add responsive-layout and accessibility checks for the viewer shell and chat sidebar + - [x] Add coverage reporting and enforce a minimum threshold in CI -- [ ] Phase 3: finish admin frontend coverage +- [x] Phase 3: finish admin frontend coverage - [x] Add tests for playlist management, moderation flows, and dashboard rendering - [x] Add tests for API integration points with mocked backend responses - - [ ] Add responsive-layout and accessibility checks for admin screens - - [ ] Add coverage reporting and enforce a minimum threshold in CI + - [x] Add responsive-layout and accessibility checks for admin screens + - [x] Add coverage reporting and enforce a minimum threshold in CI - [x] Phase 4: validate the R2 and edge-delivery path - [x] Add an integration test for upload and retrieval of HLS objects through the R2 path diff --git a/frontend/package.json b/frontend/package.json index cb898cd..35f039c 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -9,6 +9,7 @@ "preview": "vite preview", "lint": "tsc --noEmit", "test": "vitest run", + "test:coverage": "vitest run --coverage", "test:watch": "vitest" }, "devDependencies": { diff --git a/frontend/src/admin.test.ts b/frontend/src/admin.test.ts index e7d2ed1..63b52ed 100644 --- a/frontend/src/admin.test.ts +++ b/frontend/src/admin.test.ts @@ -271,3 +271,58 @@ file '/app/media/demo2.mp4' expect(list.innerHTML).toContain("demo1.mp4"); }); }); + +describe("admin accessibility", () => { + beforeEach(() => { + document.body.innerHTML = ` + +
+ `; + }); + + it("nav has aria-label for screen readers", () => { + const nav = document.querySelector(".admin-nav"); + expect(nav?.getAttribute("aria-label")).toBe("Admin navigation"); + }); + + it("active tab has aria-current attribute", () => { + const active = document.querySelector("[aria-current]"); + expect(active).toBeTruthy(); + expect(active?.getAttribute("aria-current")).toBe("page"); + }); + + it("all nav buttons are focusable", () => { + const buttons = document.querySelectorAll(".admin-nav button"); + buttons.forEach((btn) => { + expect(btn.getAttribute("tabindex")).toBeNull(); + expect(btn.getAttribute("disabled")).toBeNull(); + }); + }); +}); + +describe("admin responsive layout", () => { + beforeEach(() => { + document.body.innerHTML = ` + +