docs(14): capture phase context
This commit is contained in:
@@ -0,0 +1,151 @@
|
|||||||
|
# Phase 14: Desktop E2E Coverage - Context
|
||||||
|
|
||||||
|
**Gathered:** 2026-06-12
|
||||||
|
**Status:** Ready for planning
|
||||||
|
|
||||||
|
<domain>
|
||||||
|
## Phase Boundary
|
||||||
|
|
||||||
|
Add a `desktop` Playwright project (Desktop Chrome, wide viewport, no `hasTouch`) to
|
||||||
|
`apps/pwa/playwright.config.ts` and make the existing Phase 7 mobile-authored e2e specs
|
||||||
|
pass on a no-touch desktop viewport, so the Phase 8 CI regression gate validates the
|
||||||
|
**desktop** layout/flows in addition to the `iphone`/`pixel` mobile profiles.
|
||||||
|
|
||||||
|
The real work is the **spec-compat pass**, not CI plumbing — Phase 8 already runs
|
||||||
|
`pnpm test:e2e` and will pick up the new project automatically. No new test *capabilities*
|
||||||
|
are added; this is desktop-profile coverage of the layout/state bars Phase 7 already asserts.
|
||||||
|
|
||||||
|
**In scope:** desktop project config; per-spec review so the suite is green on desktop;
|
||||||
|
desktop-equivalent assertions where the mobile layout diverges.
|
||||||
|
**Out of scope:** new flows/features; live event-create against CalDAV (dev user 1 still has
|
||||||
|
no calendar credential — carried from Phase 7); Desktop WebKit; prod-SW / iOS-standalone testing.
|
||||||
|
</domain>
|
||||||
|
|
||||||
|
<decisions>
|
||||||
|
## Implementation Decisions
|
||||||
|
|
||||||
|
### Spec-Compat Strategy
|
||||||
|
- **D-01:** Keep **one set of spec files** (no separate `desktop.spec.ts`). Gate the genuinely
|
||||||
|
mobile-only tests with `test.skip()` keyed on project name (`desktop`), and add desktop-equivalent
|
||||||
|
assertions where the layout diverges. Cross-cutting tests (no-overflow, populated/empty/error
|
||||||
|
states) stay shared and run on all three profiles. Rationale: one source of truth, least
|
||||||
|
duplication, avoids drift between mobile and desktop copies of the same cross-cutting assertions.
|
||||||
|
- **D-02:** Prefer scoping/skip over deletion — do not weaken or remove the existing mobile
|
||||||
|
assertions to make desktop pass. The mobile profiles must remain exactly as authored in Phase 7.
|
||||||
|
|
||||||
|
### Desktop Gate Severity
|
||||||
|
- **D-03:** Desktop-profile failures are **blocking** — same severity as `iphone`/`pixel`.
|
||||||
|
A desktop regression must not be able to land on `main`. No `continue-on-error` / advisory
|
||||||
|
carve-out. (Resolves ROADMAP Phase 14 Success Criterion 3, which deferred blocking-vs-advisory
|
||||||
|
to planning.) Implication: the desktop specs must be deterministic before this merges —
|
||||||
|
if they flake, fix the spec, don't downgrade the gate.
|
||||||
|
|
||||||
|
### Desktop Assertion Depth
|
||||||
|
- **D-04:** **Parity-adapted** coverage. On desktop, positively assert the desktop equivalents:
|
||||||
|
DesktopNav sidebar (`nav[aria-label="Main navigation"]`) visible, nav tap targets, no horizontal
|
||||||
|
overflow, populated/empty/error states render (calendar grid, seeded event, lists card, empty
|
||||||
|
state, error heading + Retry). Skip only the assertions that have no desktop analog.
|
||||||
|
- **D-05:** Do **not** add "mobile chrome is absent on desktop" negative assertions (the rejected
|
||||||
|
"full divergence" option). Reason grounded in code: the `New Event` accessible name is **not**
|
||||||
|
mobile-only — `CalendarShell.tsx:424` renders a desktop-only toolbar "New Event" button sharing
|
||||||
|
the same name as the phone FAB. Asserting its absence would be wrong. Only the **56×56 FAB
|
||||||
|
geometry** check is mobile-specific.
|
||||||
|
|
||||||
|
### Desktop Profile / Viewport
|
||||||
|
- **D-06:** Single desktop project using `devices['Desktop Chrome']` (1280×720), **no Desktop WebKit**.
|
||||||
|
The Apple member is already covered on mobile Safari via the `iphone`/WebKit profile; Desktop
|
||||||
|
Chrome is sufficient for the shared/wall-browser use case. Keep the default viewport — no custom
|
||||||
|
width override unless planning finds the sidebar layout needs more horizontal room than 1280 gives.
|
||||||
|
|
||||||
|
### Claude's Discretion
|
||||||
|
- Exact mechanism for the skip gate (e.g. `test.skip(testInfo.project.name === 'desktop', ...)` vs.
|
||||||
|
`test.describe` blocks split by a `isDesktop` helper vs. project-level `grep`/`grepInvert`) — pick
|
||||||
|
the cleanest that keeps the shared cross-cutting tests un-duplicated. Planner/researcher to choose.
|
||||||
|
- Whether the desktop "New Event" toolbar button gets its own ≥44px tap-target assertion as the
|
||||||
|
desktop parity equivalent of the FAB's 56×56 check (recommended, but optional).
|
||||||
|
</decisions>
|
||||||
|
|
||||||
|
<canonical_refs>
|
||||||
|
## Canonical References
|
||||||
|
|
||||||
|
**Downstream agents MUST read these before planning or implementing.**
|
||||||
|
|
||||||
|
### The harness being extended (Phase 7)
|
||||||
|
- `apps/pwa/playwright.config.ts` — the two-profile matrix to extend with a third `desktop` project;
|
||||||
|
documents the carried-forward auth/SW/baseURL/webServer decisions (D-01..D-10 in its header).
|
||||||
|
- `apps/pwa/e2e/layout.spec.ts` — the spec with the most mobile-only assumptions (BottomTabBar
|
||||||
|
safe-area/in-viewport, 56×56 FAB, PhoneNav chrome, tap targets). Primary compat-pass target.
|
||||||
|
- `apps/pwa/e2e/calendar.spec.ts` — auth-bypass precondition, no-SW precondition, populated/error states.
|
||||||
|
- `apps/pwa/e2e/lists.spec.ts` — populated/empty states.
|
||||||
|
- `apps/pwa/e2e/global-setup.ts` — `/health` readiness poll + deterministic DB reset/seed (shared by
|
||||||
|
all profiles, unchanged by this phase).
|
||||||
|
- `apps/pwa/e2e/README.md` — harness run/guardrail docs; update for the new profile.
|
||||||
|
|
||||||
|
### Phase context / roadmap
|
||||||
|
- `.planning/ROADMAP.md` §"Phase 14: Desktop E2E Coverage" — goal, 3 success criteria, pitfalls.
|
||||||
|
- `.planning/phases/07-mobile-test-harness/07-CONTEXT.md` — original harness decisions to carry forward
|
||||||
|
(DEV_AUTH_BYPASS not storageState, `serviceWorkers: 'block'`, env baseURL, Vite-only webServer).
|
||||||
|
- `.planning/phases/08-gitea-ci/08-CONTEXT.md` — how CI runs `pnpm test:e2e`; confirms desktop project
|
||||||
|
is picked up automatically (only watch desktop-profile runtime/wait in CI).
|
||||||
|
|
||||||
|
### CI entry point (no plumbing change expected, but verify)
|
||||||
|
- `.gitea/workflows/ci.yml` — the harness job that runs the Playwright specs; confirm the new desktop
|
||||||
|
project runs and gates without a config change beyond runtime/wait budget.
|
||||||
|
</canonical_refs>
|
||||||
|
|
||||||
|
<code_context>
|
||||||
|
## Existing Code Insights
|
||||||
|
|
||||||
|
### Reusable Assets
|
||||||
|
- **Existing `playwright.config.ts` project array** — add a third `{ name: 'desktop', use: {
|
||||||
|
...devices['Desktop Chrome'], serviceWorkers: 'block' } }` entry. `serviceWorkers: 'block'`,
|
||||||
|
env baseURL, and the Vite `webServer` are already shared across projects.
|
||||||
|
- **`global-setup.ts`** — DB reset/seed is profile-agnostic; reused unchanged for desktop.
|
||||||
|
|
||||||
|
### Established Patterns
|
||||||
|
- **Breakpoint = 767/768px**, driven by `window.matchMedia('(max-width: 767px)')` in
|
||||||
|
`AppNav.tsx:32`, `BottomTabBar.tsx:24`, `CalendarShell.tsx:75`. Desktop Chrome at 1280px is
|
||||||
|
unambiguously in the desktop branch.
|
||||||
|
- **`getByRole('navigation', { name: 'Main navigation' })`** resolves to the **BottomTabBar** on
|
||||||
|
mobile but the **DesktopNav sidebar** on desktop — same locator, different element, both valid.
|
||||||
|
- **No strict-mode collision on desktop:** `BottomTabBar.tsx:53-57` returns `null` at ≥768px, so the
|
||||||
|
sidebar is the *sole* `Main navigation` landmark on desktop. Most nav-visibility/tap-target tests
|
||||||
|
pass as-authored, just resolving to the sidebar.
|
||||||
|
|
||||||
|
### Integration Points — desktop divergences the compat pass must handle
|
||||||
|
- **BottomTabBar safe-area / "fully in-viewport" tests** (`layout.spec.ts` describe blocks):
|
||||||
|
bottom bar is `null` on desktop → **skip on desktop**.
|
||||||
|
- **"New Event FAB meets 56×56px"** (`layout.spec.ts:91`): on desktop the `New Event` name resolves
|
||||||
|
to the toolbar button (`CalendarShell.tsx:424`), which is not 56×56 → **skip the FAB-geometry test
|
||||||
|
on desktop**; optionally assert the desktop toolbar button's ≥44px target instead (D-04 parity).
|
||||||
|
- **"PhoneNav header is visible"** (`layout.spec.ts:76`): `getByText('FamilySync', {exact:true})` also
|
||||||
|
matches the DesktopNav title (`AppNav.tsx:181`) → likely passes on desktop; verify no second match.
|
||||||
|
- **Settings button** (`/open settings/i`): present on both PhoneNav and DesktopNav → resolves on both.
|
||||||
|
- **Tap-target tests scoped to the nav landmark**: desktop sidebar links have `minHeight: 44px`
|
||||||
|
(`AppNav.tsx:151`) → pass on desktop.
|
||||||
|
</code_context>
|
||||||
|
|
||||||
|
<specifics>
|
||||||
|
## Specific Ideas
|
||||||
|
|
||||||
|
- The gate's whole point is to be real: desktop must be **blocking**, and the specs must be made
|
||||||
|
deterministic to earn that (D-03). "Make it green by weakening the assertion" is explicitly rejected.
|
||||||
|
- Mirror Phase 7's self-validation ethos where cheap: a desktop run should fail loudly if the desktop
|
||||||
|
layout actually regresses, not silently pass because everything was skipped.
|
||||||
|
</specifics>
|
||||||
|
|
||||||
|
<deferred>
|
||||||
|
## Deferred Ideas
|
||||||
|
|
||||||
|
- **Desktop WebKit (Desktop Safari) profile** — considered and declined for this phase (D-06).
|
||||||
|
Revisit only if a desktop-Safari-specific rendering bug is ever reported.
|
||||||
|
- **Live desktop event-create round-trip** — still blocked by dev user 1 having no CalDAV calendar
|
||||||
|
(carried from Phase 7); out of scope here, same as on mobile.
|
||||||
|
|
||||||
|
None of the above are blockers — discussion stayed within phase scope.
|
||||||
|
</deferred>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Phase: 14-Desktop E2E Coverage*
|
||||||
|
*Context gathered: 2026-06-12*
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
# Phase 14: Desktop E2E Coverage - Discussion Log
|
||||||
|
|
||||||
|
> **Audit trail only.** Do not use as input to planning, research, or execution agents.
|
||||||
|
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.
|
||||||
|
|
||||||
|
**Date:** 2026-06-12
|
||||||
|
**Phase:** 14-Desktop E2E Coverage
|
||||||
|
**Areas discussed:** Spec-compat strategy, Desktop gate severity, Desktop assertion depth, Desktop profile/viewport
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Spec-Compat Strategy
|
||||||
|
|
||||||
|
| Option | Description | Selected |
|
||||||
|
|--------|-------------|----------|
|
||||||
|
| Conditional skips, shared specs | One set of spec files; gate mobile-only tests with `test.skip(project==='desktop')`, assert desktop equivalents on divergence; cross-cutting tests shared. | ✓ |
|
||||||
|
| Separate desktop spec files | New `desktop.spec.ts`; mobile specs project-filtered. Clear separation, duplicates cross-cutting assertions. | |
|
||||||
|
| Locator-only, no skips | Viewport-agnostic locators, no skips. Impossible where elements don't exist on desktop (FAB, bottom bar). | |
|
||||||
|
|
||||||
|
**User's choice:** Conditional skips, shared specs
|
||||||
|
**Notes:** One source of truth, least duplication. Mobile profiles stay exactly as authored in Phase 7.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Desktop Gate Severity
|
||||||
|
|
||||||
|
| Option | Description | Selected |
|
||||||
|
|--------|-------------|----------|
|
||||||
|
| Blocking (same as mobile) | Desktop failures block the merge exactly like iphone/pixel. | ✓ |
|
||||||
|
| Advisory (non-blocking) | Desktop runs/reports but doesn't block merge (continue-on-error). | |
|
||||||
|
|
||||||
|
**User's choice:** Blocking (same as mobile)
|
||||||
|
**Notes:** Resolves ROADMAP Success Criterion 3 (deferred to planning). Implies specs must be deterministic before merge — fix flakes, don't downgrade the gate.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Desktop Assertion Depth
|
||||||
|
|
||||||
|
| Option | Description | Selected |
|
||||||
|
|--------|-------------|----------|
|
||||||
|
| Parity-adapted | Assert desktop equivalents (sidebar nav, no overflow, populated/empty/error states, nav tap targets); skip FAB/bottom-bar. | ✓ |
|
||||||
|
| Render-only smoke | Just no-overflow + states render; no desktop-chrome assertions. | |
|
||||||
|
| Full divergence assertions | Also assert mobile chrome absent + desktop-only elements present. | |
|
||||||
|
|
||||||
|
**User's choice:** Parity-adapted
|
||||||
|
**Notes:** Full-divergence rejected on code grounds — `New Event` is not mobile-only (desktop toolbar button shares the name, `CalendarShell.tsx:424`); only the 56×56 FAB geometry is mobile-specific.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Desktop Profile / Viewport
|
||||||
|
|
||||||
|
| Option | Description | Selected |
|
||||||
|
|--------|-------------|----------|
|
||||||
|
| Desktop Chrome default, no WebKit | `devices['Desktop Chrome']` (1280×720), single desktop project. | ✓ |
|
||||||
|
| Desktop Chrome at wider width | Override to ~1440×900 for more sidebar/grid real estate. | |
|
||||||
|
| Add Desktop WebKit too | Desktop Chrome + Desktop Safari/WebKit. | |
|
||||||
|
|
||||||
|
**User's choice:** Desktop Chrome default, no WebKit
|
||||||
|
**Notes:** Apple member already covered on mobile Safari (iphone/WebKit). Desktop Chrome sufficient for shared/wall browser.
|
||||||
|
|
||||||
|
## Claude's Discretion
|
||||||
|
|
||||||
|
- Exact skip-gate mechanism (`test.skip(testInfo.project.name === 'desktop')` vs. `isDesktop` describe split vs. project `grep`/`grepInvert`) — pick the cleanest that avoids duplicating cross-cutting tests.
|
||||||
|
- Whether the desktop "New Event" toolbar button gets its own ≥44px tap-target assertion as the desktop parity equivalent of the FAB check (recommended, optional).
|
||||||
|
|
||||||
|
## Deferred Ideas
|
||||||
|
|
||||||
|
- Desktop WebKit profile — declined for this phase; revisit only on a desktop-Safari-specific bug.
|
||||||
|
- Live desktop event-create round-trip — still blocked by dev user 1 having no CalDAV calendar (carried from Phase 7).
|
||||||
Reference in New Issue
Block a user