test(files): cover Escape closes editor with no stale state
Opens server.cfg, drives the CM6 controller to a dirty buffer, presses Escape to close without saving, then reopens the same file and asserts the editor shows the original disk content — not the discarded buffer. Pins two invariants: native <dialog>'s cancel→close path stays intact (no JS shortcut around Escape), and the reopened editor fetches a FRESH fragment via htmx.ajax with CM6 re-mounting on the new textarea. A regression that cached buffer state to "feel snappy" would fail this test loudly. Per docs/superpowers/plans/2026-05-17-files-overlay-e2e-handoff.md (Tier 2 case B). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b222fdc918
commit
a6be29c6d2
1 changed files with 41 additions and 0 deletions
|
|
@ -412,3 +412,44 @@ def test_share_url_deep_link_reopens_editor(page: Page, files_overlay_server) ->
|
|||
|
||||
_wait_for_routed_editor(page)
|
||||
assert page.locator('textarea[data-rel-path="server.cfg"]').count() == 1
|
||||
|
||||
|
||||
def test_modal_close_on_escape_preserves_no_state(page: Page, files_overlay_server) -> None:
|
||||
"""Open server.cfg, drive the CM6 controller to a dirty buffer,
|
||||
press Escape to close the modal without saving, then reopen the
|
||||
same file and assert the editor shows the original disk content
|
||||
— not the dirty buffer the user just discarded.
|
||||
|
||||
Pins two invariants:
|
||||
* modals.js's `cancel` → preventDefault → close() path on
|
||||
`<dialog id="modal-container">` actually closes the modal on
|
||||
Escape (no JS shortcuts away from the native behavior).
|
||||
* The reopened editor fetches a fresh fragment via htmx.ajax;
|
||||
the CM6 controller re-mounts on the FRESH textarea (seeded
|
||||
from disk content), not a stale cache of the prior session.
|
||||
|
||||
A regression that survived the close event — e.g., a future commit
|
||||
that cached buffer state in a module-scope variable to "feel
|
||||
snappy" — would surface here as the dirty content reappearing.
|
||||
"""
|
||||
base = files_overlay_server["base_url"]
|
||||
overlay_id = files_overlay_server["overlay_id"]
|
||||
overlay_root = files_overlay_server["overlay_root"]
|
||||
original_content = (overlay_root / "server.cfg").read_text()
|
||||
_open_overlay(page, base, overlay_id)
|
||||
|
||||
# --- First open: type something but don't save ----------------------
|
||||
page.click('button.file-tree-name-button[data-target-path="server.cfg"]')
|
||||
_wait_for_routed_editor(page)
|
||||
dirty = "DIRTY UNSAVED BUFFER " + "x" * 40
|
||||
page.evaluate("(t) => window.__filesEditor.setContent(t)", dirty)
|
||||
page.keyboard.press("Escape")
|
||||
expect(page.locator("#modal-container")).to_be_hidden(timeout=5000)
|
||||
# Disk must still hold the original — never saved.
|
||||
assert (overlay_root / "server.cfg").read_text() == original_content
|
||||
|
||||
# --- Reopen and confirm CM6 starts fresh from disk ------------------
|
||||
page.click('button.file-tree-name-button[data-target-path="server.cfg"]')
|
||||
_wait_for_routed_editor(page)
|
||||
reopened = page.evaluate("() => window.__filesEditor.getValue()")
|
||||
assert reopened == original_content
|
||||
|
|
|
|||
Loading…
Reference in a new issue