import { test, expect } from "@playwright/test"; import { highlightAndExpectVisible } from "@playwright/utils/highlight"; /** * Loop (RSL) Modal UI / Behavior Regression Test * Covers: * - Opening Schleifenwiderstand modal * - Fullscreen + close buttons * - View dropdown (Messkurve / Meldungen) using loop slice title * - Toolbar elements + RSL Start button + progress overlay simulation (dev only) * - Mode dropdown copy */ test.describe("Loop / RSL Modal", () => { test("opens and validates RSL UI & controls", async ({ page }) => { await page.goto("/kabelueberwachung"); // Open first Loop modal (assumes second blue button or identical). Use heading filter first. // Fallback: click the same first blue button again then switch heading if needed. const firstBlue = page.locator(".bg-littwin-blue.text-white").first(); await highlightAndExpectVisible(page, firstBlue); await firstBlue.click(); // If heading not Schleifenwiderstand, close & pick another? We'll accept either heading present. const heading = page.getByRole("heading", { name: /Schleifenwiderstand|Isolationswiderstand/, }); await heading.waitFor(); // If we landed in Iso instead of Loop, try second blue button inside the cable card bar. if ( await page .getByRole("heading", { name: "Isolationswiderstand" }) .isVisible() .catch(() => false) ) { // Close and reopen to get loop: click close icon then second blue button (if available) await page.locator("button:has(i.bi-x-lg)").click(); const secondBlue = page.locator(".bg-littwin-blue.text-white").nth(1); await highlightAndExpectVisible(page, secondBlue); await secondBlue.click(); await highlightAndExpectVisible( page, page.getByRole("heading", { name: "Schleifenwiderstand" }) ); } const dialog = page.getByRole("dialog"); await expect(dialog).toBeVisible(); // Fullscreen + close icons await expect( dialog .locator("button:has(i.bi-arrows-fullscreen, i.bi-fullscreen-exit)") .first() ).toBeVisible(); await expect(dialog.locator("button:has(i.bi-x-lg)")).toBeVisible(); // Toolbar presence await expect(dialog.locator(".toolbar")).toBeVisible(); await expect(dialog.locator(".toolbar").getByText("KÜ")).toBeVisible(); // Date labels visible in Messkurve await expect(dialog.getByText("Von")).toBeVisible(); await expect(dialog.getByText("Bis")).toBeVisible(); // Mode dropdown const modeBtn = dialog.getByRole("button", { name: /Alle Messwerte|Stündlich|Täglich/, }); await modeBtn.click(); await expect( page.getByRole("option", { name: /Alle Messwerte/ }) ).toBeVisible(); await expect(page.getByRole("option", { name: /Stündlich/ })).toBeVisible(); await expect(page.getByRole("option", { name: /Täglich/ })).toBeVisible(); await page.getByRole("option", { name: "Stündlich" }).click(); // RSL Start button (text may be dynamic; look for partial) const rslButton = dialog.getByRole("button", { name: /RSL/i }); await expect(rslButton).toBeVisible(); // Daten laden button present const loadBtn = dialog.getByRole("button", { name: "Daten laden" }); await expect(loadBtn).toBeVisible(); // Chart canvas should appear (allow some time after load click) await loadBtn.click(); await dialog.locator("canvas").waitFor({ timeout: 5000 }); await expect(dialog.locator("canvas")).toBeVisible(); }); });