W6: browser tests for every user flow - #138
Merged
Merged
Conversation
e2e/browser drives the real app in headless Chromium through playwright-go (behind the build tag `browser`). Pages are guarded against uncaught errors, console errors, CSP violations and failed or 404/5xx requests to the app, and a failed test saves a screenshot and a trace to .ui-artifacts/. - e2e: WithRealAssets serves cmd/web/dist, Run is Main without the exit, Client.Cookies exposes the session for the browser - make ui-deps, test-ui (RUN, COUNT, HEADED, SLOWMO), ui-trace; the quiet targets take TAGS - CI: a browser job with cached Chromium, uploading traces on failure - smoke tests: login and boosted navigation (title, head merge, window kept), an action button, the error toast on a server error. Each fails when json-enc, head-support or the responseError handler is removed from index.js, or the action controller is broken - docs/testing.md gains "Browser tests"; the frontend-htmx and test-failure skills point at it playwright-go moved to github.com/mxschmitt/playwright-go; the module path changed with it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
Boosted navigation with head merge and history, flashes and toasts, the toggle and spoiler controllers, dark mode, and the error toast on a server error and a dropped connection. The mobile menu test is skipped on #140 (CSP violation when it opens). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
The editor, autosave (the URL becomes the edit URL), publish, back to draft, delete with the confirmation accepted and dismissed, the prompt variant of /write, and the rendered post. A delete right after the form re-renders itself is skipped on #141. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
Top-level comments (the form reloads the page on purpose), nested replies and collapse, notifications to the author and participants, and no form for a viewer who may not comment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
The three-user mediated connection story and every other connection action, the share lifecycle, and asking for and dismissing a post prompt, all through the real buttons. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
In-place validation errors, general settings, password change, user styles, API key generation and copying, invites, the feed lifecycle against a local server, export and import, and image upload. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
Every page, anonymous and logged in, at 1280px and 390px: no horizontal overflow, no guard violations, every image loaded. Pages hit by #139 (no CSP nonce) are skipped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
Login errors in place, a signed return_url, logout and accepting an invitation. Signup with email confirmation is skipped on #139. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
Mark W6 done, drop its wave file, record what it built, found and cost, and add the lessons: per-agent build tags for parallel work in one package, and a mutation sweep over every Stimulus controller. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
CI runs golangci-lint, which make check-q does not. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
can3p
marked this pull request as ready for review
September 26, 2026 14:13
The README had no word on browser tests, and docs/testing.md listed the flags without saying the browser is headless by default. Both now say how to run, watch and debug the suite. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
E2E and browser tests read the outgoing_emails queue because the app can't deliver to tommy yet. R2 said they would only gain a tommy assertion; now they switch to delivered mail, since the queue is an implementation detail R4 may replace. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
A body at the limit (20,000) saves. Over the limit, the error must be shown under the body; it is rendered but hidden (#142). The limit counts bytes rather than characters, so non-Latin text is cut at about half (#143). Both are pinned with skipped tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
- The visibility chosen in the editor decides who can open the post: a direct connection, a second-degree one, a stranger and an anonymous visitor, through every change on a published post. - Only the author gets the share button, and cancelling its confirmation creates no link. - A dismissed RSS item disappears without a reload and stays gone; cancelling keeps it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
The share test now starts from a direct-only post that an anonymous visitor can't open, and checks that the share link lets them read it without logging in, survives a reload, and stops working once deleted. The test of who gets the share button is dropped: it said nothing about what sharing is for. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r
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.
Adds the browser suite (playwright-go,
e2e/browser, build tagbrowser) that specifies everything a user does in a page. It is the main safety net for R1 and RS, and for frontend dependency upgrades.console.error, CSP violations and failed same-origin requests, a trace and screenshot on failure),make ui-deps/test-ui/ui-trace, theBrowserCI job, and smoke tests.-count=3.selfsubmit, which no template uses, andcollapse, which is only exercised by the test skipped on Opening the mobile menu triggers a CSP style-src-attr violation #140. Removingjson-enc,head-support, or either htmx error handler also fails a test.style-src-attr), Submitting the post form right after it re-renders in place can post natively and get a 403 #141 (a submit right after the post form re-renders itself can go out natively and get a 403).After merge: make the
Browsercheck required onmaster. It can't be required before this lands, or open PRs without the job would wait forever.🤖 Generated with Claude Code
https://claude.ai/code/session_01Cd9fFJUp1qzhpKBpjvNw3r