diff --git a/l4d2web/tests/e2e/test_files_overlay.py b/l4d2web/tests/e2e/test_files_overlay.py index 60c76e5..f369e55 100644 --- a/l4d2web/tests/e2e/test_files_overlay.py +++ b/l4d2web/tests/e2e/test_files_overlay.py @@ -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 + # `