Conversation
tests/test_app.py read public/site.css 17 times and runner.js, editor.js, syntax-highlight.js and search.js repeatedly, asserting literal text such as "transform: scale(0.96)" and "execution: 'execute'". Those tests broke on harmless refactors and passed when the rendered page regressed. scripts/check_browser_layout.mjs, which already drives a real Worker and Chrome in CI, now checks the same intentions on the page: - computed transforms under a forced :active for Run, Copy link, the copy button and home cards; - 40px touch targets for runner buttons and nav links, underlined nav links, balanced headings, antialiased text, tabular execution time, no "transition: all"; - the reader's browser font size (Page.setFontSizes), the skip link appearing on focus, the share button sitting at the toolbar end, the copy button anchored to its cell; - light/dark page, body-text, Run-button and terminal contrast, and marginalia figures staying on light paper in dark mode; - header fallbacks under emulated prefers-reduced-transparency and prefers-contrast: more, and the nav visible on landing; - long output wrapping and tall output growing the panel, and the fallback textarea not overflowing; - behaviour: network errors end a run with a message, unedited Copy link copies the plain URL, copy falls back to execCommand, arrow keys ignore modifiers and buttons and walk back to a no-op at the first example, search exposes combobox/listbox/option state, and the Turnstile widget renders in execute mode and is removed afterwards; - About-page design tokens all resolve. Arrow-key guards now count attempted navigations with the Navigation API instead of checking the pathname 50ms later, which could not see a navigation that had started but not committed. The source-text assertions and the 19 tests made only of them are removed; HTML rendering assertions stay. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012eisRQmQvg4TphwztxhQGJ
make deploy stopped after `pywrangler deploy`; the documented scripts/smoke_deployment.py ran only if someone remembered. It now ends with a post-deploy-smoke step against DEPLOY_URL (default https://www.pythonbyexample.dev) and exits non-zero, saying the new version is live and how to roll back, if any GET or POST check fails. SMOKE_ARGS passes extra smoke flags explicitly. The hello-world quality waiver expires on 2026-12-01, after which CI would fail every pull request with no earlier signal. check_quality_scores.py now warns when a waiver has 30 days or fewer left, and --fail-within-days N turns that window into an error. A new weekly Scheduled quality workflow runs `make quality-checks` and `make check-waiver-expiry` (--fail-within-days 30), so the expiry turns a scheduled run red a month early instead of breaking unrelated PRs. --as-of makes the date explicit for tests and manual checks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012eisRQmQvg4TphwztxhQGJ
docs/lessons-learned.md said "54 tests today cover 9 contract families"; tests/test_marginalia_geometry.py has 31 tests in 13 contract classes. The sentence now points at the classes instead of quoting a number that drifts. It also said the golden fixture is "refreshed explicitly by scripts/refresh_golden_fixture.py"; the script and fixture were deleted in 0929c25, so it now names what catches loader and parser regressions today. tests/test_markdown_migration_prereqs.py checked that the finished migration's spec contained particular phrases, including "Red", "Green" and "Refactor" in that order, which proves nothing about the process. Those tests are dropped; the README and CI command contract stays. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012eisRQmQvg4TphwztxhQGJ
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
This PR implements the pythonbyexample recommendations from the September 2026 verification audit (https://github.com/adewale/testing-best-practices/blob/claude/github-testing-practices-review-n5749j/research/PORTFOLIO_VERIFICATION_AUDIT_2026-09.md, pythonbyexample row). There are three commits.
1. P1: rendered-style contracts replace CSS/JS source-text tests.
tests/test_app.pyreadpublic/site.css17 times and read the JS sources repeatedly. It asserted literal text such as"transform: scale(0.96)","text-wrap: balance"or"execution: 'execute'".docs/lessons-learned.mdrecords these tests breaking on the harmlesshas-figurechange, and they still pass when the rendered page regresses.scripts/check_browser_layout.mjsalready drives a real Worker and Chrome in CI. It now measures the same intentions on the page::active(viaCSS.forcePseudoState) for Run, Copy link and the copy button (0.96), and for home cards (0.99).h1, antialiased body text, tabular execution time, and no element withtransition: all.Page.setFontSizesat 20px).prefers-reduced-transparencyandprefers-contrast: more, and nav links get the full text colour under more contrast. The nav is visible on landing.Run failed: ….execCommand('copy')without the Clipboard API. Its status is an off-screen polite live region, and its mask glyph changes.execution: 'execute'and nosize, and is removed and hidden afterwards.2. P1:
make deploysmoke-tests the deployed origin. Deploy now ends with apost-deploy-smokestep. It runsscripts/smoke_deployment.pyagainstDEPLOY_URL(defaulthttps://www.pythonbyexample.dev). If any GET or POST check fails, it exits non-zero with "the new version is already live: investigate now, or roll back".SMOKE_ARGSpasses extra flags explicitly.2 (continued). P2: waiver expiry warns 30 days ahead, and a weekly run fails early.
check_quality_scores.pywarns when a waiver has 30 days or fewer left.--fail-within-days Nturns that window into an error, and--as-offixes the date.Scheduled qualityworkflow (also onworkflow_dispatch) runsmake quality-checksand thenmake check-waiver-expiry.hello-worldwaiver expires 2026-12-01. Before this change, its first signal would have been a failure on every PR from that day. Now it turns the scheduled run red from the first Monday in its final 30 days.3. P2/P3: stale docs and phrase-order tests.
docs/lessons-learned.mdsaid "54 tests today cover 9 contract families".tests/test_marginalia_geometry.pyhas 31 tests in 13 contract classes. The sentence now points at the classes instead of giving a number.scripts/refresh_golden_fixture.py, which was deleted in 0929c25. It now names what catches loader and parser regressions today.tests/test_markdown_migration_prereqs.pyloses its spec-wording tests, including the "Red" < "Green" < "Refactor" order check. The README/CI command-contract test stays.Verification
make verify. I ran each target against a localpywrangler devon port 9796 (to avoid clashing with other local servers) with Chrome for Testing 154:make build test seo-cache-lint verify-examples quality-checks search-ranking-test lint check-generatedexited 0, with 227 tests OK.node scripts/check_browser_layout.mjs http://127.0.0.1:9796/examples/valuesexited 0.scripts/format_examples.py --check: exit 0.make verify-python-version VERSION=3.13: exit 0, "Verified 109 example(s)".git diff --checkis clean,npm audit --audit-level=highexits 0, andgit diff --exit-code -- pylock.tomlshows no change.make post-deploy-smoke DEPLOY_URL=http://127.0.0.1:9796against the local Worker printed "Deployment smoke OK (9 GETs, 5 POSTs)". The first attempt hit a local-devProxyWorker … Network connection lostonPOST /examples/subprocesses. Retried by itself, that POST returned 200 three times, and the rerun passed.Red, then green.
Browser contracts. I applied 11 mutations at once, ran
make build, and ran the browser test:site.css:fontset to16px/1.6;.share-button { margin-left: auto; },.button:active,.skip-link:focus, the dark figure-paper rule, the reduced-transparencybackdrop-filter: none, and.cell-source { position: relative; };white-space: pre.runner.js:size: 'invisible'instead ofexecution: 'execute', and themetaKeyguard dropped.syntax-highlight.js: theexecCommandresult forced tofalse.It exited 1 and named all 11:
After restoring and rerunning
make build, the test exited 0 andgit statuswas clean.The first drafts of two checks missed their mutations: the modifier-key check (pathname after 50 ms) and the wrapping check (
scrollWidth). I rewrote them, using the Navigation API and a text range measured against the panel edge, until they failed on the mutation.Waiver expiry.
origin/main's script, becauseexpiry_warningandwaiver_expiry_findingsdo not exist there.check_expiry_date('2026-12-01', today=2026-11-05)returnsNone, so it stays silent.--as-of 2026-11-05WARNING: quality waiver hello-world: expires on 2026-12-01 (26 days left)…--as-of 2026-11-05 --fail-within-days 30--as-of 2026-12-01--fail-within-days 30(today)Deploy smoke.
make -n deployshowspywrangler deployfollowed bypost-deploy-smoke.make post-deploy-smoke DEPLOY_URL=http://127.0.0.1:9exited 2 withDeployment smoke FAILED … The new version is already live.Test counts. 249 on
origin/main, 227 now: 19 source-text-only tests and 5 spec-wording tests removed, 2 expiry tests added. Each intermediate commit also passes on its own (230 and 232 tests).Not run: GitHub Actions itself. What I did check for
scheduled-quality.yml:yaml.safe_load.verify.ymldoes (SHA-pinnedsetup-uv,@v7for the rest).contents: readand no secrets.make quality-checksandmake check-waiver-expirypassed locally with only theuv syncenvironment.Not in this PR
src/main.py, the git hooks,Makefileand workflows (test_turnstile_verification_is_session_gated_in_worker,test_worker_entrypoint_uses_fastapi_asgi_bridge,test_dynamic_worker_execution_uses_hash_keyed_get_cache,test_generated_drift_is_blocked_before_commit_and_merge). The recommendation targeted the CSS/JS tests, and 466f616 already added behavioural coverage for most of themain.pypaths.#FF4801,#F5F1EB,#521000,#EBD5C1,.runner-grid,--space-6andbox-shadow:were dropped rather than converted, because they pinned text, not behaviour. Legibility is covered by the contrast checks instead.make deploy. It touches production.Notes
PBE_SMOKE_BYPASS_SECRETexported, as the script's docstring already says. Without it,make deploywill now fail loudly after deploying.SMOKE_ARGS=--skip-postis available only as a deliberate choice.DOM/CSSdomains,Emulation.setFocusEmulationEnabled,Page.setFontSizesand media-feature emulation, all of which currentgoogle-chromeonubuntu-latestsupports.--no-sandbox. It also needed to trust this session's egress-proxy CA, which I did with--ignore-certificate-errors-spki-listfor the proxy CA keys only. Both lived in a localCHROME_PATHwrapper; the committed script is unchanged in that respect.🤖 Generated with Claude Code
https://claude.ai/code/session_012eisRQmQvg4TphwztxhQGJ