import { expect, type Page, type Locator } from "@playwright/test"; export async function enableExperimental(page: Page): Promise { await page.goto("/#/config"); await page.getByTestId("generalconfig-experimental").click(); const modal = page.getByTestId("experimental-modal"); await expectModalVisible(modal); await modal.getByLabel("Show experimental UI features.").click(); await modal.getByRole("button", { name: "Close" }).click(); await expectModalHidden(modal); await expect(page.locator(".modal-backdrop")).not.toBeVisible(); } export async function openTopNavigation(page: Page): Promise { await expect(page.getByTestId("topnavigation-button")).toBeVisible(); await page.getByTestId("topnavigation-button").click(); await expectTopNavigationOpened(page); } export async function closeTopNavigation(page: Page): Promise { await expectTopNavigationOpened(page); await page.getByTestId("topnavigation-button").click(); await expectTopNavigationClosed(page); } export async function expectTopNavigationOpened(page: Page): Promise { await expect(page.getByTestId("topnavigation-dropdown")).toBeVisible(); await expect(page.getByTestId("topnavigation-button")).toHaveAttribute("aria-expanded", "true"); } export async function expectTopNavigationClosed(page: Page): Promise { await expect(page.getByTestId("topnavigation-button")).toHaveAttribute("aria-expanded", "false"); await expect(page.getByTestId("topnavigation-dropdown")).not.toBeVisible(); } export async function expectModalVisible(modal: Locator): Promise { await expect(modal).toBeVisible(); await expect(modal).toHaveAttribute("aria-hidden", "false"); } export async function expectModalHidden(modal: Locator): Promise { await expect(modal).not.toBeVisible(); await expect(modal).toHaveAttribute("aria-hidden", "true"); } export async function editorClear(editor: Locator, iterations = 10): Promise { for (let i = 0; i < iterations; i++) { await editor.locator(".view-line").nth(0).click(); await editor.page().keyboard.press("ControlOrMeta+KeyA", { delay: 50 }); await editor.page().keyboard.press("Backspace", { delay: 50 }); } } export async function editorPaste(editor: Locator, page: Page, text: string): Promise { await editor.locator(".view-line").nth(0).click(); await page.evaluate((text) => navigator.clipboard.writeText(text), text); await page.keyboard.press("ControlOrMeta+KeyV", { delay: 100 }); } export enum LoadpointType { Charging = "charging", Heating = "heating", } export enum ChargerStatus { Disconnected = "A", Connected = "B", Charging = "C", } export async function addDemoCharger( page: Page, type: LoadpointType = LoadpointType.Charging, status?: ChargerStatus ): Promise { const lpModal = page.getByTestId("loadpoint-modal"); await lpModal .getByRole("button", { name: type === LoadpointType.Heating ? "Add heater" : "Add charger" }) .click(); const modal = page.getByTestId("charger-modal"); await expectModalVisible(modal); await modal .getByLabel("Manufacturer") .selectOption(type === LoadpointType.Heating ? "Demo heat pump" : "Demo charger"); if (status) { await modal.getByLabel("Charge status").selectOption(status); } await modal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(modal); await expectModalVisible(lpModal); } export async function addDemoMeter(page: Page, power = "0"): Promise { const lpModal = page.getByTestId("loadpoint-modal"); await lpModal.getByRole("button", { name: "Add dedicated energy meter" }).click(); const modal = page.getByTestId("meter-modal"); await expectModalVisible(modal); await modal.getByLabel("Manufacturer").selectOption("Demo meter"); await modal.getByLabel("Power").fill(power); await modal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(modal); await expectModalVisible(lpModal); } export async function addVehicle(page: Page, title: string): Promise { await page.getByRole("button", { name: "Add vehicle" }).click(); const modal = page.getByTestId("vehicle-modal"); await expectModalVisible(modal); await modal.getByLabel("Manufacturer").selectOption("Generic vehicle (without API)"); await modal.getByLabel("Title").fill(title); await modal.getByRole("button", { name: "Validate & save" }).click(); await expectModalHidden(modal); } export async function newLoadpoint( page: Page, title: string, type: LoadpointType = LoadpointType.Charging ): Promise { const lpModal = page.getByTestId("loadpoint-modal"); await page.getByRole("button", { name: "Add charger or heater" }).click(); await expectModalVisible(lpModal); await lpModal .getByRole("button", { name: type === LoadpointType.Heating ? "Add heating device" : "Add charging point", }) .click(); await lpModal.getByLabel("Title").fill(title); } export async function dragElement( page: Page, sourceElement: Locator, targetElement: Locator ): Promise { // Get bounding boxes to calculate actual positions const sourceBox = await sourceElement.boundingBox(); const targetBox = await targetElement.boundingBox(); if (sourceBox && targetBox) { // Move from center of source item to center of target item const startX = sourceBox.x + sourceBox.width / 2; const startY = sourceBox.y + sourceBox.height / 2; const endX = targetBox.x + targetBox.width / 2; const endY = targetBox.y + targetBox.height / 2; await page.mouse.move(startX, startY); await page.mouse.down(); await page.mouse.move(endX, endY, { steps: 10 }); await page.mouse.up(); } } export async function getDatalistOptions(input: Locator): Promise { return input.evaluate((element: HTMLInputElement) => { const datalistId = element.getAttribute("list"); if (!datalistId) return []; const datalist = document.getElementById(datalistId); return Array.from(datalist?.querySelectorAll("option") || []).map((opt) => opt.value); }); }