test(files): cover new-folder + delete cycle
Creates a folder via the inline new-folder dialog's Enter-keydown submit path, then deletes it via the inline delete-confirm dialog. Each step asserts disk + tree state. The Enter path is the direct-bound listener (not delegated), so it's the most likely to break under future refactors — pinning it here surfaces such regressions immediately. Row-action buttons (`✕`) live inside `<li draggable="true">` — the draggable ancestor confuses Playwright's hit-test even though real browsers click through fine. The click uses force=True to skip the hit-test (documented inline). Per docs/superpowers/plans/2026-05-17-files-overlay-e2e-handoff.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6b0fbb75bf
commit
3ea57b2bdb
1 changed files with 59 additions and 0 deletions
|
|
@ -277,3 +277,62 @@ def test_binary_replace_via_browse_writes_new_bytes(page: Page, files_overlay_se
|
|||
# The filename on disk stays the same (no rename) — only the bytes
|
||||
# changed.
|
||||
assert (overlay_root / "icon.png").read_bytes() == new_bytes
|
||||
|
||||
|
||||
def test_new_folder_then_delete(page: Page, files_overlay_server) -> None:
|
||||
"""Create a folder via the inline new-folder dialog (Enter-to-submit
|
||||
keydown path), then delete it via the inline delete-confirm dialog.
|
||||
Each step asserts disk + tree state, so a regression in either the
|
||||
mkdir or delete route — or in the modal close + refresh wiring —
|
||||
fails loudly.
|
||||
|
||||
The new-folder dialog has TWO submit paths (click on
|
||||
.files-new-folder-create + Enter keydown on the name input); this
|
||||
test pins the keydown path, which is direct-bound rather than
|
||||
delegated, because it's the one most likely to break under future
|
||||
refactors.
|
||||
"""
|
||||
base = files_overlay_server["base_url"]
|
||||
overlay_id = files_overlay_server["overlay_id"]
|
||||
overlay_root = files_overlay_server["overlay_root"]
|
||||
_open_overlay(page, base, overlay_id)
|
||||
|
||||
# --- Create folder via Enter-to-submit -----------------------------
|
||||
page.click('button[data-action="new-folder"][data-target-path=""]')
|
||||
new_folder_modal = page.locator("#files-new-folder-modal")
|
||||
expect(new_folder_modal).to_be_visible(timeout=5000)
|
||||
|
||||
folder_name = "sourcemod"
|
||||
page.fill(".files-new-folder-name", folder_name)
|
||||
page.locator(".files-new-folder-name").press("Enter")
|
||||
|
||||
expect(new_folder_modal).to_be_hidden(timeout=5000)
|
||||
assert (overlay_root / folder_name).is_dir()
|
||||
folder_row = page.locator(
|
||||
f'.file-tree-row-dir[data-target-path="{folder_name}"]'
|
||||
)
|
||||
expect(folder_row).to_be_visible(timeout=5000)
|
||||
|
||||
# --- Delete folder via inline confirm ------------------------------
|
||||
# `force=True`: the row-action buttons are positioned inside a
|
||||
# `<li draggable="true">`, and Playwright's hit-test treats the
|
||||
# draggable ancestor as intercepting pointer events even though
|
||||
# real browsers dispatch the click correctly. Forcing skips the
|
||||
# hit-test and dispatches on the target — matches user behavior.
|
||||
page.locator(
|
||||
f'button[data-action="delete"]'
|
||||
f'[data-target-path="{folder_name}"]'
|
||||
f'[data-row-kind="dir"]'
|
||||
).click(force=True)
|
||||
delete_modal = page.locator("#files-delete-modal")
|
||||
expect(delete_modal).to_be_visible(timeout=5000)
|
||||
# The dialog should name the row being deleted — the user must see
|
||||
# what they're confirming.
|
||||
expect(delete_modal.locator(".files-delete-name")).to_have_text(folder_name)
|
||||
|
||||
page.click(".files-delete-confirm")
|
||||
|
||||
expect(delete_modal).to_be_hidden(timeout=5000)
|
||||
assert not (overlay_root / folder_name).exists()
|
||||
# The tree refresh removes the row.
|
||||
expect(folder_row).to_have_count(0, timeout=5000)
|
||||
|
|
|
|||
Loading…
Reference in a new issue