test(e2e): close the rest of the pre-migration coverage gaps - #17
Merged
Conversation
Completes the baseline started in 9dd4d7d. Those were unit tests over a real bound editor; these are the four gaps that genuinely need the stack, because they cross the API, the database, the Rust serializer or a second browser session. No production code changes. comment-anchors.spec.ts is new and is the important one. comments.spec.ts posts every comment straight to the API with position_y: null and never clicks the floating button, so nothing exercised anchoring at all. The failure it now guards is silent by construction: when the ySync binding cannot be reached the encoder returns null and the caller persists an empty string, so the comment saves, the sidebar lists it, and only the highlight is missing. Asserts the stored anchor is non-empty, that a highlight renders over the right words, that it survives a reload (decoding against a binding that did not encode it), and that it follows the TEXT when a peer inserts ahead of it -- which a byte offset fails and a relative position passes. Verified by stubbing getMapping() to null: all three fail, while comments.spec and comments-realtime stay green. editor-markdown-roundtrip.spec.ts is new. Only paragraph, image and excalidraw_board ever travelled editor -> Y.Doc -> to_markdown; everything else was exercised in the import direction or not at all. Drift is punished asymmetrically -- an unknown node makes the export 500, but an unknown mark hits to_markdown's catch-all and vanishes without a trace. Authors every canonical node and mark by pasting Markdown, so the nodes are built by the editor's own schema, then asserts each construct survives the export by name. Verified by renaming the underline mark: "underline did not survive the round trip", while import-markdown and collab stay green. two-users-converge now asserts Alice can SEE Bob. Its docText() helper deliberately strips caret labels, so a caret that stopped rendering left every assertion in the file green. Also checks the caret has a real colour, since the awareness payload is validated against a 6-digit hex pattern. Verified by forcing colorFor to "transparent". editor-toolbar now asserts aria-pressed tracks the caret rather than the click, and that the table controls gated on isActive("table") appear and disappear. The existing test only ever asserted on document contents, so a toolbar frozen at its initial state would have passed. docText() moves to support/ since two files need it now. Local run: 60 passed. The three failures are environmental and unrelated -- ws-reconnect needs toxiproxy (network_mode: host does not work on Docker Desktop), oidc needs Dex env this run did not set, and tree-reorder's "nest" is the known macOS-only failure that passes in CI. Co-Authored-By: Claude Opus 5 <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.
Completes the baseline started in #15. Those were unit tests over a real bound editor; these are the four gaps that genuinely need the stack — they cross the API, the database, the Rust serializer, or a second browser session.
No production code changes. 3 new e2e files, 2 modified.
comment-anchors.spec.ts— new, and the important onecomments.spec.tsposts every comment straight to the API withposition_y: nulland never clicks the floating button, so nothing exercised anchoring at all.The failure it guards is silent by construction: when the ySync binding can't be reached, the encoder returns
nulland the caller persists an empty string. The comment saves, the sidebar lists it, only the highlight is missing.Asserts the stored anchor is non-empty, a highlight renders over the right words, it survives a reload (decoding against a binding that didn't encode it), and it follows the text when a peer inserts ahead of it — which a byte offset fails and a relative position passes.
editor-markdown-roundtrip.spec.ts— newOnly
paragraph,imageandexcalidraw_boardever travelled editor → Y.Doc →to_markdown. Drift is punished asymmetrically: an unknown node makes the export 500, but an unknown mark hitsto_markdown's catch-all arm and vanishes without a trace.Authors every canonical node and mark by pasting Markdown — so the nodes are built by the editor's own schema, not the server's parser — then asserts each construct survives the export, by name.
This also covers the link-
titlefix from #16 end to end: the export contains[link](https://example.test "Link title").two-users-converge— Alice can now actually see BobIts
docText()helper deliberately strips caret labels, so a caret that stopped rendering left every assertion in the file green. Now asserts the caret exists, carries the peer's name, and has a real colour — the awareness payload is validated against a 6-digit hex pattern.editor-toolbar—aria-pressedtracks the caretThe existing test only asserted on document contents, so a toolbar frozen at its initial state would have passed. Now checks that state follows the selection rather than the click, and that the
isActive("table")-gated controls appear and disappear.(While writing this I had an assertion passing on a typo —
toolbar-add-rowinstead oftoolbar-table-add-row. Fixed, and it now exercises the gate in both directions.)docText()moves tosupport/since two files need it.Local run: 60 passed. Three failures, all environmental and unrelated:
ws-reconnectneeds toxiproxy (network_mode: hostdoesn't work on Docker Desktop),oidcneeds Dex env this run didn't set, andtree-reorder's "nest" is the known macOS-only failure that passes in CI.🤖 Generated with Claude Code