From 2d28d9f80031697b46365f3f94246ab6f84be487 Mon Sep 17 00:00:00 2001 From: mwiegand Date: Sun, 17 May 2026 21:32:19 +0200 Subject: [PATCH] test(e2e): tab switching + expand-to-modal on server detail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Append two new e2e tests that cover the inspection strip: - test_tabs_switch_between_log_console_files: verifies data-active-tab attribute mirrors tab clicks and the correct tabpanel is shown/hidden - test_expand_opens_matching_modal: verifies the ⛶ button opens the matching the active tab name Also fix the pre-existing test_hover_download_initiates_file_download for the new tab-based layout: click the Files tab first (rows were inside a hidden tabpanel), and scope the row locator to the tab pane to avoid a strict-mode violation now that the modal also contains a duplicate file tree. Co-Authored-By: Claude Sonnet 4.6 --- l4d2web/tests/e2e/test_server_detail.py | 56 +++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/l4d2web/tests/e2e/test_server_detail.py b/l4d2web/tests/e2e/test_server_detail.py index 50973c3..7a1e2d2 100644 --- a/l4d2web/tests/e2e/test_server_detail.py +++ b/l4d2web/tests/e2e/test_server_detail.py @@ -43,10 +43,17 @@ def test_hover_download_initiates_file_download(page: Page, server_with_files) - login(page, base) page.goto(f"{base}/servers/{server_id}") + # The file tree lives inside the Files tab pane (hidden by default). + # Switch to it first so the row is visible and hover-clickable. + strip = page.locator("[data-tab-strip]") + strip.locator('[role="tab"][data-tab="files"]').click() + # On server detail, files_overlay=False in the template, so the - # row
  • has no data-target-path. Match by row class + visible - # filename text instead. - row = page.locator("li.file-tree-row-file", has_text="server.cfg") + # row
  • has no data-target-path. Scope to the tab pane (not the + # expand modal which also contains a copy of the file tree) and match + # by row class + visible filename text. + files_pane = strip.locator('[role="tabpanel"][data-tab="files"]') + row = files_pane.locator("li.file-tree-row-file", has_text="server.cfg") expect(row).to_be_visible(timeout=5000) row.hover() @@ -58,3 +65,46 @@ def test_hover_download_initiates_file_download(page: Page, server_with_files) - assert download.suggested_filename == "server.cfg" # Playwright auto-saves to a temp dir we can read back from. assert download.path().read_bytes() == expected_bytes + + +def test_tabs_switch_between_log_console_files(page: Page, server_with_files) -> None: + """The inspection strip on /servers/ defaults to the Log tab and + switches tab + tabpane visibility on click. Active-tab state is + mirrored on the strip via data-active-tab. + """ + base = server_with_files["base_url"] + sid = server_with_files["server_id"] + login(page, base) + page.goto(f"{base}/servers/{sid}") + + strip = page.locator("[data-tab-strip]") + expect(strip).to_be_visible() + expect(strip).to_have_attribute("data-active-tab", "log") + + # Click Console + strip.locator('[role="tab"][data-tab="console"]').click() + expect(strip).to_have_attribute("data-active-tab", "console") + expect(strip.locator('[role="tabpanel"][data-tab="console"]')).to_be_visible() + expect(strip.locator('[role="tabpanel"][data-tab="log"]')).to_be_hidden() + + # Click Files + strip.locator('[role="tab"][data-tab="files"]').click() + expect(strip).to_have_attribute("data-active-tab", "files") + expect(strip.locator('[role="tabpanel"][data-tab="files"]')).to_be_visible() + + +def test_expand_opens_matching_modal(page: Page, server_with_files) -> None: + """Clicking ⛶ on the inspection strip opens the whose id + matches the active tab name (data-active-tab="files" → #files-modal). + """ + base = server_with_files["base_url"] + sid = server_with_files["server_id"] + login(page, base) + page.goto(f"{base}/servers/{sid}") + + strip = page.locator("[data-tab-strip]") + strip.locator('[role="tab"][data-tab="files"]').click() + strip.locator(".strip-expand").click() + + dialog = page.locator("dialog#files-modal") + expect(dialog).to_have_attribute("open", "")