# Scheduling real-stack E2E — verified 2026-09-07

## Current verdict

**PASS: all 11 authored cases passed together, with no skips, retries, failures or source changes.**

- Command: `python3 e2e-scheduling-real/run.py` (unfiltered), exit 0; Playwright duration 39.7 seconds.
- Evidence: `.cache/scheduling-qa/E2E-aefca6b2495572a7/`.
- `results.json`: 11 expected, 0 unexpected, 0 skipped, 0 flaky. Parent enumerated all 11 unique cases and verified one passed attempt each.
- `freshness.json`: start/end/current source SHA256 `07cd190233d13e5afc75eb797c4f381865a2cd5a1137273c8b64aaf72817866e`; no changed paths.
- `cleanup.json` plus independent filesystem/socket readback: exact private database, credentials and environment removed; no listeners on 8105/3100.
- `readiness.json`: both real servers passed HTTP health checks before testing. They are intentionally stopped after completion.
- Sanitized case inventory and proof: `alqove-api/docs/porting/scheduling-browser-verification.json`.

Coverage includes real login/store switching, owner schedule editing/publishing/copying, staff published schedule and clock/break buttons, manager correction/approval, owner CSV download/replay, tenant/revision/DST/immutable-history guards, and three invitation acceptance/rejection cases. No response interception substitutes for the application API.

This is local SQLite/Chromium acceptance, not a production database concurrency or deployment attestation. See the cross-repository integration audit for the separate code-review and regression gates.

## Historical failures (resolved)

Staff Schedule and Clock previously threw `No QueryClient set, use QueryClientProvider to set one`. The real staff shell now has its generation-keyed provider; the current unfiltered browser run passes both routes without a harness-injected provider. The owner locator and concurrent-source failures below are also superseded by the current run.

**Working real-browser workflows:**

- Manager login → membership discovery → switch A/B → reload preserves B.
- Owner assigned/open shift create → drafts absent staff API → publish → staff own/team API visibility → edit clears publication → copy preview writes0 → copy commit creates2 drafts → switch B shows no A shifts.
- Manager correction → exact120-minute timesheet recalculation → approval → owner browser CSV export/download → API same-key replay and byte-identical download → exported corrections/unlock rejected.

**Working independent real-API workflows:** manager/staff capability gates, cross-store shift/membership/punch/timesheet IDs, opaque stale revisions, March2→March9 DST9am copy (17:00Z→16:00Z), atomic overlap rejection, stranded-clock approval/export hard blocks, payroll CSV SHA256, snapshot replay after mutable settings change, idempotency mismatch409, exported punch immutability.

## Historical evidence (all under `.cache/scheduling-qa/`)

- `E2E-48eb3c3454c31b2d/results.json`: last complete8-case run: **5 passed,3 failed,0 skipped**. Failures were owner native-control locator plus the two staff provider failures. Manager browser correction/export passed; both independent API guard/export tests passed.
- `E2E-034879bddf2a34d6/results.json`: owner-only rerun **1 passed** after correcting native-control locators. `schedule-browser-draft-publish-edit-copy-switch.json` contains authoritative API/SQL evidence. Runner exit3 because source freshness detected a concurrent edit to seller/listings/__tests__/item-form-context.test.tsx; the product test itself passed.
- `E2E-0968a87f033accf8/results.json`: independent API payroll **1 passed**, no concurrent source change; `freshness.json` plus start/end source hashes included.
- `E2E-bb6168a707df86d4/manager-correction-approval.json` and `payroll-browser-download-replay.json`: real browser correction/approval/CSV proof. Its API export case was initially poisoned by the prior stranded fixture; harness now closes that fixture through the real API, verified in the later full run.
- Each run has `cleanup.json`: exact private DB and credential files removed, owned servers stopped. Failure traces/screenshots remain private and may contain synthetic test tokens.

## Harness fixes (not production changes)

- Explicit StoreSettings fixture, as Store factory does not create settings.
- Await actual login redirect after membership discovery before navigating; token presence alone races login completion.
- Native wrapping-label controls selected by accessible role/name (`combobox Employee`, `textbox Notes`); wrapping label text can include options/current textarea content. This was the owner-case locator issue, not a production modal bug.
- Stranded guard fixture closes with a real clock-out after asserting hard guards, so later weeks' exports are not intentionally poisoned.
- Preflight accepts stopped-server TIME_WAIT but refuses active listeners; runner owns/kills exact process groups only.
- Snapshot start/end hashes cover API/web/harness source, including API bootstrap/config. If tests pass while source changes, exit3 requests a stable-source rerun instead of returning a misleading green gate.
- Final cleanup audit verified12 owned run directories,345 artifacts private0700/0600, no SQLite/manifest/environment leftovers and no8105/3100 listeners. The iterative `test-running.py` now explicitly sets umask077; early iterative artifacts were normalized (their parent run directory was always0700).

## Reproduce

From `alqove-web`:

```sh
python3 e2e-scheduling-real/run.py --grep 'staff browser|staff clocks'
python3 e2e-scheduling-real/run.py --grep 'owner creates'
python3 e2e-scheduling-real/run.py  # complete suite; always use a fresh isolated run
```

Harness safety tests: 8 passed. Harness TypeScript `tsc --noEmit` passed. The harness makes no production-code, root environment, root gitignore, commit/push, Redis or production DB reset changes. Invitation/auth continuation is covered by three real browser cases in `60-invitations.spec.ts`; synthetic token delivery occurs before hydration to keep credentials out of HTTP logs.
