feat: expand Playwright E2E coverage (#155)

* feat: comprehensive Playwright E2E test rewrite

Rewrite all E2E tests with correct CSS selectors, add new spec files,
and implement robust auth handling to work within backend rate limits.

Changes:
- Rewrite fixtures/index.ts with JWT-based /auth/me mock to avoid
  10 req/min rate limit on /auth/me during test runs
- Rewrite auth.setup.ts with offline JWT validity check to reuse
  existing auth state across runs (saves login rate-limit budget)
- Rewrite auth.spec.ts (6 tests) - login page, fields, submit,
  redirect guard, invalid credentials, login/register toggle
- Rewrite dashboard.spec.ts (8 tests) - header, nav tabs,
  navigation, overview/schedules sections, days selector, redirect
- Rewrite medications.spec.ts (8 tests) - form fields, stock
  inventory, package type toggle, intake schedule, save/cancel,
  unsaved changes guard
- Rewrite settings.spec.ts (12 tests) - language, notification
  matrix, thresholds, calculation mode, toggle switch, export/import,
  user menu navigation
- Create planner.spec.ts (9 tests) - form, date inputs, calculate,
  reset, checkbox, submit, tab state, eyebrow heading
- Create schedule.spec.ts (12 tests) - timeline, days selector,
  past/future toggles, day blocks, today highlight, collapse/expand,
  overview table, share button
- Update playwright.config.ts: remove mobile projects, enable
  webServer section for CI
- Add .github/workflows/e2e.yml CI workflow for Playwright tests

Total: 57 E2E tests across 6 spec files, all passing consistently
across 5+ consecutive runs without backend restart.

Closes #154

* feat: add comprehensive E2E data tests with medication CRUD, dashboard, planner, schedule

Add 48 new Playwright E2E tests covering real medication data scenarios:
- medication-crud: 14 tests for create/edit/delete/list via UI form
- dashboard-data: 13 tests for overview table, timeline, dose tracking
- planner-data: 9 tests for demand calculator with results/status chips
- schedule-data: 11 tests for timeline, collapse/expand, dose mark/undo

Infrastructure improvements:
- Add API helpers (createMedicationViaAPI, deleteMedicationViaAPI,
  deleteAllMedicationsViaAPI) with retry logic for rate-limit resilience
- Configure chromium-data project for serial execution with retry:1
- Add /auth/me mock to avoid rate-limit exhaustion on auth endpoint
- Increase navigateTo reliability with networkidle waits
- Increase auth token validity threshold from 2 to 10 minutes
- Make backend rate limit configurable via RATE_LIMIT_MAX env var
- Set RATE_LIMIT_MAX=300 in dev docker-compose for E2E test support

Total suite: 57 empty-state + 48 data tests = 105 tests (chromium)

* test: add E2E tests for medication editing, stock status, and share schedule

- medication-edit.spec.ts: 10 tests covering generic name, notes,
  taken-by add/remove, expiry date, refill, intake schedule editing,
  adding intake rows, reminder toggle, and package type changes
- stock-status.spec.ts: 12 tests verifying dashboard shows correct
  status chips (High/Normal/Warning/Danger) for different stock levels,
  overview table, reorder card, detail modal, and planner integration
- share-schedule.spec.ts: 10 tests for taken-by badges, share button,
  share dialog, link generation, shared schedule page navigation,
  dose tracking on shared page, and notes display
- fixtures/index.ts: add createShareTokenViaAPI, updateSettingsViaAPI
  helpers; expand createMedicationViaAPI with takenBy, notes, expiryDate
- playwright.config.ts: update testMatch/testIgnore for new test files
- docker-compose.dev.yml: increase RATE_LIMIT_MAX to 1000 for E2E tests

* docs: refine release-manager instructions for CLI safety and commit-linked release notes

* fix: resolve PR155 CI failures for frontend lint and e2e proxy

* fix: stabilize auth-related e2e checks in CI
This commit is contained in:
Daniel Volz
2026-02-12 20:06:11 +01:00
committed by GitHub
parent 0f6a580ceb
commit 98939877db
24 changed files with 3385 additions and 650 deletions
+84 -20
View File
@@ -15,6 +15,18 @@ You are the release manager for **MedAssist-ng**. Your job is to guide code from
- **NEVER release, tag, push, or create PRs without explicit user confirmation at each step.** Always present your plan and wait for approval.
- **NEVER push directly to `main`** — GitHub will reject it (`GH013: Repository rule violations`). All changes go through Pull Requests.
- **NEVER skip CI checks.** Wait for all status checks to pass before merging.
- **Track all work in the GitHub Project board.** Every PR should reference an issue. Move issues through the board as work progresses.
## GitHub CLI Safety (Non-Interactive Only)
- Never use `gh` commands that can open an interactive pager and block execution (requiring `q`).
- Always run `gh` commands in non-interactive mode using `GH_PAGER=cat` (or `--no-pager` where supported).
- Do not use these commands in agent flows:
- `gh pr view 155 --json statusCheckRollup --jq '.statusCheckRollup[] | {name:.name,conclusion:.conclusion,detailsUrl:.detailsUrl,workflowName:.workflowName}'`
- `SHA=$(gh pr view 155 --json headRefOid --jq .headRefOid) && gh api repos/DanielVolz/medassist-ng/commits/$SHA/check-runs --jq '.check_runs[] | {name,conclusion,details_url,html_url,app:.app.name}'`
- Use safe variants instead:
- `GH_PAGER=cat gh pr view <PR_NUMBER> --json statusCheckRollup --jq '<jq-filter>'`
- `GH_PAGER=cat gh api repos/<owner>/<repo>/commits/<sha>/check-runs --jq '<jq-filter>'`
---
@@ -23,7 +35,7 @@ You are the release manager for **MedAssist-ng**. Your job is to guide code from
**Each feature or bug fix MUST be submitted as its own separate PR.** Do NOT bundle multiple unrelated changes into a single PR.
**Why:**
- Each change gets its own PR number for release notes (e.g., `(#140)`, `(#141)`)
- Each change keeps a traceable PR workflow, but release notes must reference merged commit hashes
- CI tests each change in isolation — failures are easy to trace
- Git blame and rollbacks are precise
- Code review stays focused
@@ -87,10 +99,13 @@ When code changes (features or bug fixes) are complete and tested locally:
```bash
git push -u origin feat/short-description
```
2. Create a Pull Request via GitHub CLI:
2. Create a Pull Request via GitHub CLI, linking the related issue:
```bash
gh pr create --title "fix: short description" --body "Description of charges"
gh pr create --title "fix: short description" --body "Closes #<ISSUE_NUMBER>
Description of changes"
```
Using `Closes #N` in the PR body ensures the issue is automatically moved to "Done" on merge.
3. **Present the PR URL to the user and wait for confirmation.**
### Step 4: Wait for CI and Merge
@@ -245,7 +260,8 @@ Read the actual code changes (not just commit messages) to understand what was a
- Use **bold** for feature names in bullet points
- Keep descriptions on the same line as the feature name
- **No emojis** — do not use emoji in headings or bullet points
- **Include commit references** — each bullet point must end with the PR number (e.g., `(#136)`) or short commit hash (e.g., `(ab12cd3)`) linking to the commit/PR. Use PR numbers when available.
- **Include commit references** — each bullet point must end with a short commit hash (e.g., `(ab12cd3)`) that links to the commit URL.
- **Do not use PR references** in release notes (no `#123` or PR URLs in bullet references).
- Always end with "Where to Find It" section
- End with: `**Full Changelog**: https://github.com/DanielVolz/medassist-ng/compare/vPREV...vNEW`
@@ -268,14 +284,14 @@ This release introduces a medication refill tracking feature and improves the mo
### New Features
- **Medication Refill**: Track when you refill your medications with a single click. Add full packs or individual pills and view complete refill history. (#120)
- **Automatic Stock Updates**: Stock levels are automatically recalculated after each refill. (#120)
- **Refill History**: Each medication shows a complete history of all refills with timestamps. (#122)
- **Medication Refill**: Track when you refill your medications with a single click. Add full packs or individual pills and view complete refill history. (ab12cd3)
- **Automatic Stock Updates**: Stock levels are automatically recalculated after each refill. (ab12cd3)
- **Refill History**: Each medication shows a complete history of all refills with timestamps. (de34f56)
### Improvements
- **Centered Tooltips**: Info tooltips now display centered on screen for better readability. (#125)
- **Touch-friendly**: Tooltips close automatically when scrolling on touch devices. (#125)
- **Centered Tooltips**: Info tooltips now display centered on screen for better readability. (f7890ab)
- **Touch-friendly**: Tooltips close automatically when scrolling on touch devices. (f7890ab)
### Where to Find It
@@ -351,26 +367,74 @@ When the release includes **new features** (minor or major version bump), you MU
---
## Task 6: GitHub Project Management
All work is tracked in the [GitHub Project board](https://github.com/users/DanielVolz/projects/1) (Project ID: `PVT_kwHOADH82s4BO2OT`).
### Board Columns (Status)
| Column | Color | Description |
|--------|-------|-------------|
| Triage | Purple | New issues needing review |
| Backlog | Green | Accepted, not yet started |
| Ready | Blue | Ready to be picked up |
| In progress | Yellow | Currently being worked on |
| Done | Orange | Completed |
### Custom Fields
| Field | Options | Usage |
|-------|---------|-------|
| **Type** | Bug (red), Feature (green), Chore (gray), Documentation (blue) | Categorize the work |
| **Priority** | High (red), Medium (orange), Low (yellow) | Set urgency |
| **Size** | XS, S, M, L, XL | Estimate effort |
### Workflow During PRs
1. **Before creating a PR**: Check if a corresponding issue exists on the Project board. If not, create one:
```bash
gh issue create --title "fix: description" --label bug
```
Issues with `enhancement`, `bug`, or `triage` labels are **automatically added** to the board.
2. **When creating a PR**: Always reference the issue with `Closes #N` in the PR body so the issue moves to "Done" automatically on merge.
3. **After merge**: Verify the linked issue moved to "Done". If not (e.g., no `Closes` keyword was used), move it manually:
```bash
gh project item-list 1 --owner DanielVolz
```
### Issue Labels
| Label | Applied by | Purpose |
|-------|-----------|--------|
| `enhancement` | Feature request template | New features |
| `bug` | Bug report template | Bug fixes |
| `triage` | Both templates | Needs review |
All three labels trigger the `add-to-project.yml` workflow, which automatically adds the issue to the Project board.
---
## Complete Workflow Summary
```
Code complete & tests pass locally
1. Create feature branch (fix/... or feat/...)
2. Commit, push, create PR
3. Wait for CI (backend-test + frontend-build)
4. Merge PR to main (squash + delete branch)
1. Ensure a GitHub issue exists (create if not)
2. Create feature branch (fix/... or feat/...)
3. Commit, push, create PR (with "Closes #N" in body)
4. Wait for CI (backend-test + frontend-build)
5. Merge PR to main (squash + delete branch)
6. Verify issue moved to "Done" on Project board
Ready for release?
5. Check current version (git tag + package.json)
6. Analyze changes → determine SemVer level
7. If minor/major: check README.md for needed updates (Task 5)
8. Run ./scripts/release.sh <patch|minor|major>
(or manually: branch → version bump → PR → CI → merge → tag)
7. Check current version (git tag + package.json)
8. Analyze changes → determine SemVer level
9. If minor/major: check README.md for needed updates (Task 5)
10. Run ./scripts/release.sh <patch|minor|major>
(or manually: branch → version bump → PR → CI → merge → tag)
9. Write release notes (mandatory for minor/major)
10. Publish GitHub release
11. Write release notes (mandatory for minor/major)
12. Publish GitHub release
Docker images built automatically via CI
```
+62
View File
@@ -11,6 +11,7 @@
- **Tests are mandatory**: Every new feature and every bug fix MUST have corresponding tests. When modifying existing features, update or add tests accordingly. If old tests become obsolete due to code changes, remove or update them.
- **Fix bugs, don't test around them**: If you discover incorrect behavior in the code while writing tests, ALWAYS fix the buggy code first, then write tests that verify the correct behavior. NEVER write tests that mimic or assert broken behavior. The user's time is finite and irreplaceable — every bug left unfixed wastes it.
- **Keep README.md up to date**: After implementing code changes, check whether the `README.md` needs to be updated (e.g., new features, changed ENV variables, new commands, changed architecture, new endpoints, updated screenshots). If changes are relevant to the README, **ask the user for confirmation** before updating it. Do NOT silently update the README — always present the proposed README changes and wait for approval. Examples of README-relevant changes: new ENV variables, new API endpoints, new UI features, changed setup/install steps, new dependencies, changed Docker configuration.
- **Track work in GitHub Project**: All features, bugs, and tasks MUST be tracked in the [GitHub Project board](https://github.com/users/DanielVolz/projects/1). Before starting work, ensure a corresponding issue exists. Use the `enhancement`, `bug`, or `triage` labels so the issue is automatically added to the board. Update the issue status as work progresses (Triage → Backlog → Ready → In progress → Done).
## Architecture Overview
@@ -51,6 +52,17 @@ cd backend && npm test # Run all tests
cd backend && npm run test:coverage # Run with coverage report
```
## GitHub CLI Safety (Non-Interactive Only)
- Never use `gh` commands that can open an interactive pager and block execution (requiring `q`).
- Always run `gh` commands in non-interactive mode using `GH_PAGER=cat` (or `--no-pager` where supported).
- Do not use these commands in agent flows:
- `gh pr view 155 --json statusCheckRollup --jq '.statusCheckRollup[] | {name:.name,conclusion:.conclusion,detailsUrl:.detailsUrl,workflowName:.workflowName}'`
- `SHA=$(gh pr view 155 --json headRefOid --jq .headRefOid) && gh api repos/DanielVolz/medassist-ng/commits/$SHA/check-runs --jq '.check_runs[] | {name,conclusion,details_url,html_url,app:.app.name}'`
- Use safe variants instead:
- `GH_PAGER=cat gh pr view <PR_NUMBER> --json statusCheckRollup --jq '<jq-filter>'`
- `GH_PAGER=cat gh api repos/<owner>/<repo>/commits/<sha>/check-runs --jq '<jq-filter>'`
## Testing (MANDATORY)
> ⚠️ **IMPORTANT**: Every new feature MUST be covered by tests!
@@ -187,6 +199,7 @@ gh pr merge --squash --delete-branch
| `.github/workflows/docker-build.yml` | Push to main, Tags | Build and push Docker images (+ create GitHub release on tags) |
| `.github/workflows/update-test-badges.yml` | After successful docker-build | Update test count badges in README |
| `.github/workflows/codeql.yml` | Push to main, PRs, Weekly | Security analysis |
| `.github/workflows/add-to-project.yml` | Issues opened/labeled | Auto-add issues with `enhancement`, `bug`, or `triage` labels to GitHub Project |
## Key Patterns
@@ -464,3 +477,52 @@ If a breaking change is unavoidable:
| Docker prod | `docker-compose.yml` |
| Docker dev | `docker-compose.dev.yml` |
| Env template | `.env.example` |
| Project setup | `docs/PROJECT_SETUP.md` |
## GitHub Project Management
All work is tracked in the [GitHub Project board](https://github.com/users/DanielVolz/projects/1) (Project ID: `PVT_kwHOADH82s4BO2OT`).
### Board Columns (Status)
| Column | Color | Description |
|--------|-------|-------------|
| Triage | Purple | New issues needing review |
| Backlog | Green | Accepted, not yet started |
| Ready | Blue | Ready to be picked up |
| In progress | Yellow | Currently being worked on |
| Done | Orange | Completed |
### Custom Fields
| Field | Options | Usage |
|-------|---------|-------|
| **Type** | Bug (red), Feature (green), Chore (gray), Documentation (blue) | Categorize the work |
| **Priority** | High (red), Medium (orange), Low (yellow) | Set urgency |
| **Size** | XS, S, M, L, XL | Estimate effort |
### Agent Workflow for Issues
1. **Before starting work**: Check the Project board for existing issues. If the task has no issue yet, create one:
```bash
gh issue create --title "feat: description" --label enhancement
```
Issues with `enhancement`, `bug`, or `triage` labels are **automatically added** to the Project board.
2. **When starting work**: Move the issue to "In progress":
```bash
# List items to find the item ID
gh project item-list 1 --owner DanielVolz
# Update status (use GraphQL for field updates)
```
3. **When work is done locally**: Leave in "In progress" and tell the user to invoke `@release-manager`.
4. **After merge**: The issue moves to "Done" (via `closes #N` in PR body or manually).
### Issue Labels
| Label | Applied by | Purpose |
|-------|-----------|--------|
| `enhancement` | Feature request template | New features |
| `bug` | Bug report template | Bug fixes |
| `triage` | Both templates | Needs review |
All three labels trigger the `add-to-project.yml` workflow, which automatically adds the issue to the Project board.
+70
View File
@@ -0,0 +1,70 @@
name: E2E Tests
on:
pull_request:
branches: [main]
paths:
- 'frontend/**'
- 'backend/**'
- '.github/workflows/e2e.yml'
# Minimal permissions for security
permissions:
contents: read
jobs:
e2e:
name: Playwright E2E
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
cache-dependency-path: |
backend/package-lock.json
frontend/package-lock.json
- name: Install backend dependencies
working-directory: backend
run: npm ci
- name: Install frontend dependencies
working-directory: frontend
run: npm ci
- name: Install Playwright browsers
working-directory: frontend
run: npx playwright install --with-deps chromium
- name: Run E2E tests (Chromium only)
working-directory: frontend
run: npx playwright test --project=chromium
env:
CI: true
JWT_SECRET: e2e-test-secret-that-is-long-enough
SESSION_SECRET: e2e-test-session-secret-long-enough
- name: Upload Playwright report
uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: frontend/playwright-report/
retention-days: 7
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-results
path: frontend/test-results/
retention-days: 7