phase: 05_autohide_stage_controls
**Phase 05 final verification pass — all green.** - Verified implementation in tree: staged `.cap`/`.actions` hidden at rest with container+children `pointer-events: none` (`app.css`); `revealStageControls()` with 3 s idle timer, `pointermove`/`pointerdown` + wall-keypress wiring, `unstage()` timer/attribute cleanup (`watch.js`); `tests/e2e/test_stage_autofade.py` (5 tests) present; `test_keyboard_wall.py` rest-state assertion updated per task 01. - Gates: `uv run ruff check . && uv run ruff format --check .` — clean; `uv run pyright` — 0 errors; `uv run pytest` — **274 passed, 4 skipped** (realdisplay-gated), coverage **95%** (>90% ✓); `MIRROR_REALDISPLAY=1 uv run pytest -m realdisplay` — **3 passed, 1 skipped** (documented platform skip: no audio source on host). - Dedicated phase suite `uv run pytest tests/e2e/test_stage_autofade.py` — **5/5 in isolation**. - Criteria: idle opacity 0 + bottom-edge hit probe ✓; mouse reveal → 1 → idle fade → 0 ✓; keypress reveal + Exit visible/clickable/unstages ✓; grid rules byte-for-byte unchanged (CSS diff touches only the staged block; grid guard tests green) ✓; suite green, coverage >90% ✓; phases 01–04 suites all green (no regression) ✓. - Documentation: README.md reviewed in full — all commands, env vars (incl. `DEBUGPY_*`, 25 Mbit/s default), `--allow-cidr`, kiosk/share key tables, index-page and auto-hide descriptions match the code; the only stale "12 Mbit/s" default lives in locked PLAN.md §6, README is correct — no change made. AGENTS.md: all facts (gates, test names, starlette 1.10, e2e flags, ~95% coverage) current — verified, no changes needed. - Notable: no code changes were required this pass — the phase work was already complete and correct; nothing to fix. - Next pending phase: none — phase 05 is the last in `todo/`.
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
**Phase 05 final verification pass — all green.**
|
||||
|
||||
- Verified implementation in tree: staged `.cap`/`.actions` hidden at rest with container+children `pointer-events: none` (`app.css`); `revealStageControls()` with 3 s idle timer, `pointermove`/`pointerdown` + wall-keypress wiring, `unstage()` timer/attribute cleanup (`watch.js`); `tests/e2e/test_stage_autofade.py` (5 tests) present; `test_keyboard_wall.py` rest-state assertion updated per task 01.
|
||||
- Gates: `uv run ruff check . && uv run ruff format --check .` — clean; `uv run pyright` — 0 errors; `uv run pytest` — **274 passed, 4 skipped** (realdisplay-gated), coverage **95%** (>90% ✓); `MIRROR_REALDISPLAY=1 uv run pytest -m realdisplay` — **3 passed, 1 skipped** (documented platform skip: no audio source on host).
|
||||
- Dedicated phase suite `uv run pytest tests/e2e/test_stage_autofade.py` — **5/5 in isolation**.
|
||||
- Criteria: idle opacity 0 + bottom-edge hit probe ✓; mouse reveal → 1 → idle fade → 0 ✓; keypress reveal + Exit visible/clickable/unstages ✓; grid rules byte-for-byte unchanged (CSS diff touches only the staged block; grid guard tests green) ✓; suite green, coverage >90% ✓; phases 01–04 suites all green (no regression) ✓.
|
||||
- Documentation: README.md reviewed in full — all commands, env vars (incl. `DEBUGPY_*`, 25 Mbit/s default), `--allow-cidr`, kiosk/share key tables, index-page and auto-hide descriptions match the code; the only stale "12 Mbit/s" default lives in locked PLAN.md §6, README is correct — no change made. AGENTS.md: all facts (gates, test names, starlette 1.10, e2e flags, ~95% coverage) current — verified, no changes needed.
|
||||
- Notable: no code changes were required this pass — the phase work was already complete and correct; nothing to fix.
|
||||
- Next pending phase: none — phase 05 is the last in `todo/`.
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
........................................................................ [ 25%]
|
||||
......................ssss.............................................. [ 51%]
|
||||
........................................................................ [ 77%]
|
||||
.............................................................. [100%]
|
||||
=============================== warnings summary ===============================
|
||||
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
|
||||
/home/ducoterra/Projects/Personal/mirror/.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
|
||||
from starlette.testclient import TestClient as TestClient # noqa
|
||||
|
||||
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
|
||||
================================ tests coverage ================================
|
||||
_______________ coverage: platform linux, python 3.14.8-final-0 ________________
|
||||
|
||||
Name Stmts Miss Cover Missing
|
||||
------------------------------------------------------
|
||||
src/mirror/__init__.py 3 0 100%
|
||||
src/mirror/__main__.py 72 3 96% 129, 145, 156
|
||||
src/mirror/access.py 60 0 100%
|
||||
src/mirror/app.py 185 12 94% 108, 113, 116-117, 182-183, 212-216, 245
|
||||
src/mirror/config.py 68 5 93% 110-111, 118-120
|
||||
src/mirror/debug.py 15 10 33% 19-28
|
||||
src/mirror/protocol.py 59 0 100%
|
||||
src/mirror/registry.py 191 3 98% 166, 180, 355
|
||||
------------------------------------------------------
|
||||
TOTAL 653 33 95%
|
||||
=========================== short test summary info ============================
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:281: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:321: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:364: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:446: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
274 passed, 4 skipped, 1 warning in 96.65s (0:01:36)
|
||||
All checks passed!
|
||||
31 files already formatted
|
||||
0 errors, 0 warnings, 0 informations
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
All gates verified green after the final code changes. Done.
|
||||
|
||||
**Report — Task 01 (phase 05): hide the staged overlay at rest**
|
||||
|
||||
- `app.css`: staged `.cap` `opacity: 0.28 → 0`; deleted the three staged reveal rules and staged `.actions { opacity: 1 }`; added id-scoped `#watch-stage .tile .actions { opacity: 0 }` (outranks the grid `data-selected`/`focus-within`/`hover:none` rules — verified by the E2E computed-opacity assertion, not assumption); `pointer-events: none` scoped to both containers *and their children* (no dead zones); comment block replaced with the new contract (hidden at rest, task-02 `data-reveal` is the only staged reveal, `::after` audio mark untouched)
|
||||
- `test_keyboard_wall.py`: `test_focus_moves_to_the_stage_and_back_with_g` now waits (10 s) for staged `.cap` **and** `.actions` computed opacity `0`; grid guard test untouched
|
||||
- `test_live_mirror.py` ×2 + `test_audio_share.py` ×1 (deviation, forced by the task's own CSS): with the overlay pointer-transparent at rest and no reveal yet, the existing `#watch-stage .exit` / staged `.audio` clicks are impossible — replaced those unstage/mute actions with the `g`/`m` keys (comment notes the revealed-state Exit click is asserted by task 03's E2E); `to_be_visible` assertions kept
|
||||
- README: one accurate-now-and-still-true line — staged caption/controls are hidden at rest so the video is never covered. No AGENTS.md impact (no statement touched by this task went stale)
|
||||
|
||||
Gates (all green, in order):
|
||||
- `uv run ruff check . && uv run ruff format --check .` → passed / 30 files formatted
|
||||
- `uv run pyright` → 0 errors
|
||||
- `uv run pytest` → **269 passed, 4 skipped** (realdisplay marker)
|
||||
- `MIRROR_REALDISPLAY=1 uv run pytest -m realdisplay` → **3 passed, 1 skipped** (host has no audio source for real capture — documented platform limit)
|
||||
|
||||
Next pending task: `02_reveal_on_activity.md`
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
........................................................................ [ 26%]
|
||||
.................ssss................................................... [ 52%]
|
||||
........................................................................ [ 79%]
|
||||
......................................................... [100%]
|
||||
=============================== warnings summary ===============================
|
||||
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
|
||||
/home/ducoterra/Projects/Personal/mirror/.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
|
||||
from starlette.testclient import TestClient as TestClient # noqa
|
||||
|
||||
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
|
||||
================================ tests coverage ================================
|
||||
_______________ coverage: platform linux, python 3.14.8-final-0 ________________
|
||||
|
||||
Name Stmts Miss Cover Missing
|
||||
------------------------------------------------------
|
||||
src/mirror/__init__.py 3 0 100%
|
||||
src/mirror/__main__.py 72 3 96% 129, 145, 156
|
||||
src/mirror/access.py 60 0 100%
|
||||
src/mirror/app.py 185 11 94% 108, 113, 117, 182-183, 212-216, 245
|
||||
src/mirror/config.py 68 5 93% 110-111, 118-120
|
||||
src/mirror/debug.py 15 10 33% 19-28
|
||||
src/mirror/protocol.py 59 0 100%
|
||||
src/mirror/registry.py 191 3 98% 166, 180, 355
|
||||
------------------------------------------------------
|
||||
TOTAL 653 32 95%
|
||||
=========================== short test summary info ============================
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:281: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:321: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:364: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:446: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
269 passed, 4 skipped, 1 warning in 92.81s (0:01:32)
|
||||
All checks passed!
|
||||
30 files already formatted
|
||||
0 errors, 0 warnings, 0 informations
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
Everything is green and in order. Final report:
|
||||
|
||||
**Implemented (task 02 — reveal on activity, auto-hide when idle)**
|
||||
- `watch.js`: `STAGE_REVEAL_IDLE_MS = 3000` + `let stageRevealTimer = 0` + `revealStageControls()` — sets `data-reveal` on the staged tile, clears/re-arms the timer; callback deletes the attribute only if `state.staged === tile.id` (tile may be unstaged/replaced before it fires)
|
||||
- Triggers wired per spec: `pointermove` + `pointerdown` (touch tap, A5) on `#watch-stage`; `if (state.staged) revealStageControls()` in `onWallKey` after bail-outs, before the `switch`, never `preventDefault`
|
||||
- `unstage()`: clears the pending timer and deletes `data-reveal` from the departing tile — no stale reveal can leak into the grid (grid rules never read it; re-staging starts hidden)
|
||||
- `app.css`: id-scoped `[data-reveal]` reveal pair for `.cap`/`.actions` + children (`opacity: 1; pointer-events: auto`), outranking the task-01 hide rules; existing transitions give the fade, `prefers-reduced-motion` already degrades it to instant
|
||||
|
||||
**Verification (temporary E2E, deleted after — the dedicated suite is task 03's deliverable)**
|
||||
- 5 browser tests on a real staged tile (fake-media capture): mouse reveal → 3 s idle fade, `m`-keypress reveal → fade, unstage clears attribute+timer (survived 3.6 s timer window), n/p + 1-9 replacement leaves no stale `data-reveal`, Exit clickable while revealed and unstages — all passed
|
||||
- `uv run ruff check . && uv run ruff format --check .` — clean; `uv run pyright` — 0 errors
|
||||
- `uv run pytest` — 269 passed, 4 skipped (realdisplay-gated), coverage 95% (no Python code changed; JS/CSS verified in-browser per convention)
|
||||
- `MIRROR_REALDISPLAY=1 uv run pytest -m realdisplay` — 3 passed, 1 env skip (host has no audio source)
|
||||
|
||||
**Docs**: README.md — staged-overlay paragraph extended with the reveal/~3 s auto-hide behaviour; AGENTS.md — no impact (no statement became stale)
|
||||
|
||||
**Notable**: a keypress that *causes* staging (Enter) doesn't reveal — `state.staged` is null pre-switch, so the overlay stays hidden at rest, keeping task 01's 10 s rest-state test green.
|
||||
|
||||
**Next pending task**: `03_e2e_autofade_lifecycle.md`
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
........................................................................ [ 26%]
|
||||
.................ssss................................................... [ 52%]
|
||||
........................................................................ [ 79%]
|
||||
......................................................... [100%]
|
||||
=============================== warnings summary ===============================
|
||||
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
|
||||
/home/ducoterra/Projects/Personal/mirror/.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
|
||||
from starlette.testclient import TestClient as TestClient # noqa
|
||||
|
||||
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
|
||||
================================ tests coverage ================================
|
||||
_______________ coverage: platform linux, python 3.14.8-final-0 ________________
|
||||
|
||||
Name Stmts Miss Cover Missing
|
||||
------------------------------------------------------
|
||||
src/mirror/__init__.py 3 0 100%
|
||||
src/mirror/__main__.py 72 3 96% 129, 145, 156
|
||||
src/mirror/access.py 60 0 100%
|
||||
src/mirror/app.py 185 11 94% 108, 113, 117, 182-183, 212-216, 245
|
||||
src/mirror/config.py 68 5 93% 110-111, 118-120
|
||||
src/mirror/debug.py 15 10 33% 19-28
|
||||
src/mirror/protocol.py 59 0 100%
|
||||
src/mirror/registry.py 191 3 98% 166, 180, 355
|
||||
------------------------------------------------------
|
||||
TOTAL 653 32 95%
|
||||
=========================== short test summary info ============================
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:281: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:321: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:364: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:446: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
269 passed, 4 skipped, 1 warning in 95.80s (0:01:35)
|
||||
All checks passed!
|
||||
30 files already formatted
|
||||
0 errors, 0 warnings, 0 informations
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
All four gates green. Task complete.
|
||||
|
||||
**Report**
|
||||
|
||||
- **Implemented:** `tests/e2e/test_stage_autofade.py` — 5-test suite pinning the staged overlay lifecycle on a real capture: `rest` (opacity 0 for `.cap`/`.actions` + `elementFromPoint` bottom-centre hit is the `<video>` itself), `mouse reveal`, `idle fade` (3 s + transition), `key reveal + Exit` (`m` mute flip tolerated/asserted; Exit visible + clickable while revealed; click unstages; no stale `data-reveal` leaks to the grid), `grid guard` (unselected `.actions` 0 / `data-selected` 1). `device` fixture, `share_one_and_stage` helper, `staged_overlay` probe; `pageerror`+`console` asserted `[]` in every test; docstring names the bug (staged tile kept `data-selected`/focus → grid rules forced `.cap` opaque over a shared terminal's bottom line) and its repro probe.
|
||||
- **Gates:** `uv run ruff check . && uv run ruff format --check .` → clean (31 files); `uv run pyright` → 0 errors; `uv run pytest` → 274 passed, 4 skipped (realdisplay, env-gated); `uv run pytest -m e2e` → 94 passed, 4 skipped; `MIRROR_REALDISPLAY=1 uv run pytest -m realdisplay` → 3 passed, 1 skipped (host audio, documented); suite in isolation: 5 passed.
|
||||
- **Regressions:** `test_keyboard_wall.py` 35/35 passed — phases 01–04 intact.
|
||||
- **Docs:** no doc impact — README already documented the auto-hide behaviour (updated in tasks 01/02); AGENTS.md has no stale statements.
|
||||
- **Decisions:** one Playwright API fix — `wait_for_function` takes `arg` keyword-only in this version. No Python behaviour changes, no new assets/dependencies.
|
||||
- **Next pending task:** none — this was the last task of phase 05; phase completion criteria are met.
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
...F.................................................................... [ 25%]
|
||||
......................ssss.............................................. [ 51%]
|
||||
........................................................................ [ 77%]
|
||||
.............................................................. [100%]
|
||||
=================================== FAILURES ===================================
|
||||
_ TestStagedAudioPlayback.test_unstaging_re_mutes_and_re_staging_does_not_revive_audio _
|
||||
|
||||
self = <tests.e2e.test_audio_share.TestStagedAudioPlayback object at 0x7f1fdf890cd0>
|
||||
base_url = 'http://127.0.0.1:38615'
|
||||
browser = <Browser type=<BrowserType name=chromium executable_path=/home/ducoterra/.cache/ms-playwright/chromium-1248/chrome-linux64/chrome> version=156.0.8078.4>
|
||||
request = <FixtureRequest for <Function test_unstaging_re_mutes_and_re_staging_does_not_revive_audio>>
|
||||
device = <function device.<locals>._open at 0x7f1fdf2e9590>
|
||||
|
||||
def test_unstaging_re_mutes_and_re_staging_does_not_revive_audio(
|
||||
self, base_url, browser, request, device
|
||||
):
|
||||
"""`g` returns the wall to silence, and re-staging the same mirror does
|
||||
not revive the sound — every audible state must trace back to a
|
||||
gesture (SECURITY.md §4)."""
|
||||
errors: list = []
|
||||
sharer = device("/mirror", errors)
|
||||
start_sharing(sharer)
|
||||
viewer = open_viewer(browser, base_url, request, errors=errors)
|
||||
expect(viewer.locator(".tile")).to_have_count(1, timeout=15_000)
|
||||
|
||||
viewer.keyboard.press("Enter") # nothing selected yet: the first tile
|
||||
expect(viewer.locator("body")).to_have_class(re.compile("staged"), timeout=5_000)
|
||||
time.sleep(2.0)
|
||||
assert viewer.evaluate(f"() => {self.STAGE_MUTED}") is True
|
||||
viewer.keyboard.press("m")
|
||||
assert viewer.evaluate(f"() => {self.STAGE_MUTED}") is False
|
||||
|
||||
# Back to the wall: the tile the stage leaves behind is muted.
|
||||
viewer.keyboard.press("g")
|
||||
expect(viewer.locator("body")).not_to_have_class(re.compile("staged"), timeout=5_000)
|
||||
assert viewer.evaluate(f"() => {self.GRID_MUTED}") is True
|
||||
|
||||
# Re-staging the same mirror does not bring the sound back.
|
||||
viewer.keyboard.press("Enter")
|
||||
> expect(viewer.locator("body")).to_have_class(re.compile("staged"), timeout=5_000)
|
||||
E AssertionError: Locator expected to have class 're.compile('staged')'
|
||||
E Actual value:
|
||||
E Call log:
|
||||
E - Expect "to_have_class" locator("body") with timeout 5000ms
|
||||
E - waiting for locator("body")
|
||||
E 14 × locator resolved to <body class="">…</body>
|
||||
E - unexpected value ""
|
||||
E
|
||||
E Aria snapshot:
|
||||
E - banner:
|
||||
E - text: mirror 1 mirror · 1 live online
|
||||
E - link "Share a screen":
|
||||
E - /url: http://127.0.0.1:38615/mirror
|
||||
E - main:
|
||||
E - article "Watch screen:-3:0"
|
||||
|
||||
tests/e2e/test_audio_share.py:448: AssertionError
|
||||
=============================== warnings summary ===============================
|
||||
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
|
||||
/home/ducoterra/Projects/Personal/mirror/.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
|
||||
from starlette.testclient import TestClient as TestClient # noqa
|
||||
|
||||
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
|
||||
================================ tests coverage ================================
|
||||
_______________ coverage: platform linux, python 3.14.8-final-0 ________________
|
||||
|
||||
Name Stmts Miss Cover Missing
|
||||
------------------------------------------------------
|
||||
src/mirror/__init__.py 3 0 100%
|
||||
src/mirror/__main__.py 72 3 96% 129, 145, 156
|
||||
src/mirror/access.py 60 0 100%
|
||||
src/mirror/app.py 185 12 94% 108, 113, 116-117, 182-183, 212-216, 245
|
||||
src/mirror/config.py 68 5 93% 110-111, 118-120
|
||||
src/mirror/debug.py 15 10 33% 19-28
|
||||
src/mirror/protocol.py 59 0 100%
|
||||
src/mirror/registry.py 191 3 98% 166, 180, 355
|
||||
------------------------------------------------------
|
||||
TOTAL 653 33 95%
|
||||
=========================== short test summary info ============================
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:281: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:321: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:364: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:446: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
FAILED tests/e2e/test_audio_share.py::TestStagedAudioPlayback::test_unstaging_re_mutes_and_re_staging_does_not_revive_audio
|
||||
1 failed, 273 passed, 4 skipped, 1 warning in 102.56s (0:01:42)
|
||||
All checks passed!
|
||||
31 files already formatted
|
||||
0 errors, 0 warnings, 0 informations
|
||||
validation FAILED (see output above)
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
All checks complete. Final verification of the full gate state:
|
||||
|
||||
- `validate.sh` (harness gate: full pytest + ruff + format + pyright + repo hygiene): **274 passed, 4 skipped** (realdisplay, env-gated), `All checks passed!`, `31 files already formatted`, `0 errors`, no hygiene findings
|
||||
- `MIRROR_REALDISPLAY=1 uv run pytest -m realdisplay`: **3 passed, 1 skipped** (host audio, documented in the module docstring)
|
||||
- Failing test `test_unstaging_re_mutes_and_re_staging_does_not_revive_audio`: 6/6 clean runs after the fix (plus 6/6 pre-fix runs were green when isolated — the failure is load/timing-dependent, exposed under the full-suite run)
|
||||
- README consistency review: verified against code — all routes (`/`, `/mirror`, `/share`, `/watch`, `/api/config`, `/api/streams`, `/healthz`, `/ws`), all 11 config variables with defaults (`0.0.0.0`, `8055`, `25000000`, `20`, `127.0.0.0/8, ::1/128`, …), both key tables, the audio states (`shared`/`silent`/`not offered` in `share.js`), and the staged-overlay auto-hide paragraph. No inconsistencies found — no README change needed.
|
||||
- AGENTS.md stale-fact check: every referenced file/test/command (`registry.py`, `access.py`, `test_nothing_is_loaded_from_a_cdn`, the gates, `DEBUGPY=1` on 5678, `--allow-cidr`) still holds; nothing stale — no AGENTS.md change.
|
||||
|
||||
**Report**
|
||||
|
||||
- **Fixed:** pre-existing race in `src/mirror/static/watch.js` — `unstage()`'s async `exitFullscreen()` settling after an immediate re-stage (`g` → `Enter`): the late `fullscreenchange` (element null, `state.staged` = the *new* tile) tore down the fresh stage, so `body` never kept `staged`. Added a `fullscreenExitInFlight` flag set in `unstage()`: the handler now ignores the exit of an exit we initiated, clears the flag when the document re-enters fullscreen (re-stage's request won) or the exit settles, and still unstages on a genuine external/WM exit; a rejected exit clears the stale flag when the document is still fullscreen. `restoreFocus` hand-back unchanged.
|
||||
- **Gates:** `.agents/validate.sh` (full suite + linters) → 274 passed, 4 skipped (realdisplay), ruff clean, 31 files formatted, pyright 0 errors, hygiene clean; `MIRROR_REALDISPLAY=1 uv run pytest -m realdisplay` → 3 passed, 1 skipped (host audio, documented); failing audio test 6/6 green post-fix.
|
||||
- **Docs:** README fully cross-checked against code (routes, config defaults, keys, audio states, overlay auto-hide) — no inconsistencies, no change; AGENTS.md stale-fact check — no stale statements, no change.
|
||||
- **Decisions:** fixed the defect in app code (not the test) — the test's `g`→`Enter` sequence is legitimate user behaviour; the old-exit event must not kill a new stage.
|
||||
- **Next pending task:** none — phase 05 complete.
|
||||
+1
@@ -0,0 +1 @@
|
||||
ok
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
........................................................................ [ 25%]
|
||||
......................ssss.............................................. [ 51%]
|
||||
........................................................................ [ 77%]
|
||||
.............................................................. [100%]
|
||||
=============================== warnings summary ===============================
|
||||
.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1
|
||||
/home/ducoterra/Projects/Personal/mirror/.venv/lib64/python3.14/site-packages/fastapi/testclient.py:1: StarletteDeprecationWarning: Using `httpx` with `starlette.testclient` is deprecated; install `httpx2` instead.
|
||||
from starlette.testclient import TestClient as TestClient # noqa
|
||||
|
||||
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
|
||||
================================ tests coverage ================================
|
||||
_______________ coverage: platform linux, python 3.14.8-final-0 ________________
|
||||
|
||||
Name Stmts Miss Cover Missing
|
||||
------------------------------------------------------
|
||||
src/mirror/__init__.py 3 0 100%
|
||||
src/mirror/__main__.py 72 3 96% 129, 145, 156
|
||||
src/mirror/access.py 60 0 100%
|
||||
src/mirror/app.py 185 12 94% 108, 113, 116-117, 182-183, 212-216, 245
|
||||
src/mirror/config.py 68 5 93% 110-111, 118-120
|
||||
src/mirror/debug.py 15 10 33% 19-28
|
||||
src/mirror/protocol.py 59 0 100%
|
||||
src/mirror/registry.py 191 3 98% 166, 180, 355
|
||||
------------------------------------------------------
|
||||
TOTAL 653 33 95%
|
||||
=========================== short test summary info ============================
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:281: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:321: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:364: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
SKIPPED [1] tests/e2e/test_x11_capture.py:446: set MIRROR_REALDISPLAY=1 to exercise the real X11 capture backend
|
||||
274 passed, 4 skipped, 1 warning in 100.65s (0:01:40)
|
||||
All checks passed!
|
||||
31 files already formatted
|
||||
0 errors, 0 warnings, 0 informations
|
||||
Reference in New Issue
Block a user