diff --git a/CLAUDE.md b/CLAUDE.md index 6104b282..ca8d2f44 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -334,6 +334,7 @@ diverge enough to warrant it; keep this root file general. ``` # tests (PySide6 harness/Qt tests need the offscreen platform) +# testpaths now also collects packaging/messagefoundry-webconsole/tests, so this covers the web console suite too. QT_QPA_PLATFORM=offscreen pytest -q # PowerShell: $env:QT_QPA_PLATFORM="offscreen"; pytest -q # format / lint / types diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md index 932bbde7..57e0f8e4 100644 --- a/docs/BACKLOG.md +++ b/docs/BACKLOG.md @@ -4969,7 +4969,7 @@ The comment immediately above says *"Scope is deliberately the posture the requi ## 1027. The documented `pytest` command silently excludes the webconsole package, so a local green is not evidence about ~344 tests -> 🔢 **Filed 2026-08-05 — not started.** Value **5/10** · Difficulty **3/10** · _fill-in_. `testpaths = ["tests"]` means the command CLAUDE.md documents as the verification gate never collects `packaging/messagefoundry-webconsole/tests`. A **failing** webconsole test sat on `main` through a full day of lanes because every quartet used the documented single path. +> ✅ **SHIPPED 2026-08-06 — the root `testpaths` now also collects `packaging/messagefoundry-webconsole/tests`, so a bare `pytest -q` from the repo root stops silently excluding the web console suite; the one webauthn-extra-dependent console test that lacked a guard (`test_webauthn_rp_fail_closed_legible`) now skips-with-reason when the optional `[webauthn]` extra is absent, so an extra-less local venv stays green.** Value **5/10** · Difficulty **3/10** · _fill-in_. Local developer-signal fix only — CI already covered the console via its dedicated `Web console tests (pytest)` step; the gap was that the documented local gate collected less than it appeared to. **Cluster:** Testing / verification integrity. **Priority:** P3. **Verdict:** build (small). **Severity:** no product effect; the defect is that the project's own verification instruction produces a green that is not evidence about roughly 344 tests, and CLAUDE.md §5 states a task is not done until it passes. diff --git a/packaging/messagefoundry-webconsole/tests/test_webui.py b/packaging/messagefoundry-webconsole/tests/test_webui.py index b59db361..35659b58 100644 --- a/packaging/messagefoundry-webconsole/tests/test_webui.py +++ b/packaging/messagefoundry-webconsole/tests/test_webui.py @@ -3671,6 +3671,7 @@ async def test_webauthn_cross_site_posts_rejected(engine: Engine) -> None: async def test_webauthn_rp_fail_closed_legible(engine: Engine) -> None: # AC-7: public_origin unset + request-derivation disallowed (the declared-proxy topology) — # ceremonies fail closed with the shared notice on every surface, never a redirect loop. + pytest.importorskip("webauthn") service = await _service(engine) await _add(service, "boss", Role.ADMINISTRATOR) transport = httpx.ASGITransport( diff --git a/pyproject.toml b/pyproject.toml index ea166252..66fb636e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -308,7 +308,7 @@ asyncio_mode = "auto" # the fixture key needs >=0.24); the dev floor below is >=0.26 to match, and the lock pins 1.4.0. asyncio_default_test_loop_scope = "session" asyncio_default_fixture_loop_scope = "session" -testpaths = ["tests"] +testpaths = ["tests", "packaging/messagefoundry-webconsole/tests"] # Per-test watchdog: a single hung await/socket is killed at 60s with a full thread-stack dump naming # the culprit, instead of burning the CI job's wall-clock. `thread` method works cross-platform (no # SIGALRM) and fires even when the main thread is blocked in a C call. Individual tests run well under diff --git a/tests/test_testpaths_webconsole_coverage.py b/tests/test_testpaths_webconsole_coverage.py new file mode 100644 index 00000000..04443d07 --- /dev/null +++ b/tests/test_testpaths_webconsole_coverage.py @@ -0,0 +1,35 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +# Copyright (C) 2026 MessageFoundry Organization and contributors +"""The default pytest gate must collect the web console package, not silently exclude it. + +BACKLOG #1027: `testpaths = ["tests"]` made a bare `pytest -q` from the repo root skip the +~344 tests under ``packaging/messagefoundry-webconsole/tests`` while the green summary line +looked complete. This guard reads the root ``pyproject.toml`` and fails if the console tree is +ever dropped from ``testpaths`` again — it lives under ``tests/`` on purpose, so the very +narrowing it guards against can never exclude the guard itself. +""" + +from __future__ import annotations + +import tomllib +from pathlib import Path + +_REPO_ROOT = Path(__file__).resolve().parents[1] +_WEBCONSOLE_TESTS = "packaging/messagefoundry-webconsole/tests" + + +def test_default_testpaths_collect_the_webconsole_package() -> None: + pyproject = _REPO_ROOT / "pyproject.toml" + data = tomllib.loads(pyproject.read_text(encoding="utf-8")) + testpaths = data["tool"]["pytest"]["ini_options"]["testpaths"] + + assert testpaths[0] == "tests", ( + f"the engine suite must stay first in testpaths, got {testpaths!r}" + ) + assert _WEBCONSOLE_TESTS in testpaths, ( + f"the web console package tests must be in testpaths so a default pytest run " + f"collects them (BACKLOG #1027), got {testpaths!r}" + ) + assert (_REPO_ROOT / _WEBCONSOLE_TESTS).is_dir(), ( + f"testpaths names {_WEBCONSOLE_TESTS!r} but that directory does not exist" + )