refactor(test): derive test_seo sample from prerender + harden deploy smoke test#37
Merged
Merged
Conversation
…smoke test test_seo.py no longer hardcodes blog slugs that rot when content is renamed (the audit found three dead slugs that CI never caught because it skips when dist/ is absent). SAMPLED_ROUTES is now derived from the prerendered dist/ at import time: every existing top-level page plus the first blog article alphabetically for each language present. The selection is deterministic and degrades gracefully (empty when dist/ is not built, individual pages skipped if missing), so a vanished article can never break the suite again. Coverage went from 7 to 13 routes (one article per language). Robustness gate: removing the sampled article from dist/ keeps the suite green because the sample re-derives from what remains. FASE 2 drift sweep also fixed pagespeed_ingest.py SEED_URLS, whose two fallback blog slugs were dead (PSI would have measured 404 pages); replaced with live articles and a comment on the rot risk. Remaining known drift documented in the PR (historical update_blog_article_*.py scripts cross-link a non-existent slug; that is content debt, not test fragility, and editing the run-once scripts would not change published content). Also hardens the backend deploy smoke test: the 2026-05-28 deploy of PR #36 went green on the server (Caddy valid, service active, /blog 200) but the Action failed because the smoke test only waited ~10s while uvicorn took ~31s to boot two workers on the load-saturated shared VPS. The window is now 20 x 3s = up to 60s, which tolerates the cold start without masking a real outage. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two reliability follow-ups from the 2026-05-26 audit.
1.
test_seo.pysample derived from the prerender (no hardcoded slugs)The audit found
SAMPLED_ROUTEScontained three blog slugs that no longer existed. CI never caught it because these testsskipifwhendist/is absent and CI does not runbuild:fullon the backend job. PR #36 swapped the dead slugs by hand, but the fragile pattern remained.Now the sample is derived from the prerendered
dist/at import time:dist/is not built (skipif still fires), individual top-level pages skipped if missing instead of a hardFileNotFoundError.Robustness gate (verified locally): removing the currently-sampled article from
dist/keeps the suite green, because the sample re-derives to the next existing article.2. Drift inventory (FASE 2)
api/tests/test_seo.pyapi/jobs/pagespeed_ingest.pySEED_URLSscripts/update_blog_article_{2,3}.py/blog/big-five-vs-disc-vs-belbin(dead)api/seo_mcp/,src/3. Backend deploy smoke test hardened
PR #36's backend deploy went green on the server (Caddy validated, service active,
api.cercol.team/blog200, crawl_logs flowing) but the Action failed: the smoke test waited only ~10s (5 x 2s) while uvicorn took ~31s to boot two workers on the load-saturated shared VPS (the YELLOW 6 audit finding). False negative. Window is now 20 x 3s = up to 60s.Test plan
pytest -q api/tests/test_seo.py(full dist) — 57 passedpytest -q api/— 176 passedvitest run— 204 passedbuild:full+ test_seo against the complete dist (authoritative gate)No production behavior change. Test + CI-config only; the auto-triggered backend deploy should now pass its (longer) smoke test.
🤖 Generated with Claude Code