Config UI: add heating support (#22177)

This commit is contained in:
Michael Geers 2025-07-07 21:36:32 +02:00 • committed by GitHub
parent b6ff1cad92
commit f3b60644e8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
60 changed files with 1399 additions and 486 deletions

View file

@ -23,7 +23,7 @@ test.describe("boost", async () => {
});
test("activate boost in solar mode", async ({ page }) => {
await enableExperimental(page);
await enableExperimental(page, false);
await expect(page.getByTestId("vehicle-status-batteryboost")).not.toBeVisible();
await page
.getByTestId("mode")
@ -42,7 +42,7 @@ test.describe("boost", async () => {
});
test("disabled in fast mode", async ({ page }) => {
await enableExperimental(page);
await enableExperimental(page, false);
await page.getByTestId("mode").first().getByRole("button", { name: "Fast" }).click();
await page.getByTestId("loadpoint-settings-button").nth(1).click();
const modal = page.getByTestId("loadpoint-settings-modal");

View file

@ -22,7 +22,7 @@ test.afterEach(async () => {
test.describe("aux meter", async () => {
test("create and remove aux meter", async ({ page }) => {
await page.goto("/#/config");
await enableExperimental(page);
await enableExperimental(page, false);
await expect(page.getByTestId("aux")).toHaveCount(0);
@ -67,7 +67,7 @@ test.describe("aux meter", async () => {
test("user-defined meter", async ({ page }) => {
await page.goto("/#/config");
await enableExperimental(page);
await enableExperimental(page, false);
await page.getByRole("button", { name: "Add additional meter" }).click();
const modal = page.getByTestId("meter-modal");
@ -160,7 +160,7 @@ energy:
test("user-defined meter with errors", async ({ page }) => {
await page.goto("/#/config");
await enableExperimental(page);
await enableExperimental(page, false);
await page.getByRole("button", { name: "Add additional meter" }).click();

View file

@ -16,7 +16,7 @@ test.afterAll(async () => {
test.describe("battery meter", async () => {
test("create, edit and remove battery meter", async ({ page }) => {
await page.goto("/#/config");
await enableExperimental(page);
await enableExperimental(page, false);
await expect(page.getByTestId("battery")).toHaveCount(0);
@ -69,7 +69,7 @@ test.describe("battery meter", async () => {
test("advanced fields", async ({ page }) => {
await page.goto("/#/config");
await enableExperimental(page);
await enableExperimental(page, false);
await page.getByRole("button", { name: "Add solar or battery" }).click();

View file

@ -21,7 +21,7 @@ test.describe("circuit", async () => {
await start(CONFIG_YAML);
await page.goto("/#/config");
await enableExperimental(page);
await enableExperimental(page, false);
await expect(page.getByTestId("loadpoint")).toHaveCount(1);
await expect(page.getByTestId("loadpoint")).toContainText(["Power", "1.0 kW"].join(""));
@ -60,8 +60,9 @@ test.describe("circuit", async () => {
// add loadpoint and charger
const lpModal = page.getByTestId("loadpoint-modal");
await page.getByRole("button", { name: "Add charge point" }).click();
await page.getByRole("button", { name: "Add charger or heater" }).click();
await expectModalVisible(lpModal);
await lpModal.getByRole("button", { name: "Add charging point" }).click();
await lpModal.getByLabel("Title").fill("Carport");
// add charger

View file

@ -32,7 +32,7 @@ test.describe("grid meter", async () => {
await page.getByRole("button", { name: "Apply changes" }).click();
await page.goto("/#/config");
await enableExperimental(page);
await enableExperimental(page, false);
await expect(page.getByTestId("grid")).toHaveCount(0);
await expect(page.getByTestId("add-grid")).toBeVisible();

View file

@ -5,27 +5,41 @@ import { expectModalVisible, expectModalHidden, editorClear, editorPaste } from
const CONFIG_ONE_LP = "config-one-lp.evcc.yaml";
test.use({ baseURL: baseUrl() });
test.describe.configure({ mode: "parallel" });
test.afterEach(async () => {
await stop();
});
async function enableExperimental(page: Page) {
await page
.getByTestId("generalconfig-experimental")
.getByRole("button", { name: "edit" })
.click();
await page.getByLabel("Experimental 🧪").click();
await page.getByRole("button", { name: "Close" }).click();
enum LoadpointType {
Charging = "charging",
Heating = "heating",
}
async function addDemoCharger(page: Page) {
async function enableExperimental(page: Page, inline = true) {
if (inline) {
await page.getByRole("button", { name: "Enable Experimental Features" }).click();
} else {
await page
.getByTestId("generalconfig-experimental")
.getByRole("button", { name: "edit" })
.click();
await page.getByLabel("Experimental 🧪").click();
await page.getByRole("button", { name: "Close" }).click();
}
}
async function addDemoCharger(page: Page, type: LoadpointType = LoadpointType.Charging) {
const lpModal = page.getByTestId("loadpoint-modal");
await lpModal.getByRole("button", { name: "Add charger" }).click();
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("Demo charger");
await modal
.getByLabel("Manufacturer")
.selectOption(type === LoadpointType.Heating ? "Demo heat pump" : "Demo charger");
await modal.getByRole("button", { name: "Save" }).click();
await expectModalHidden(modal);
await expectModalVisible(lpModal);
@ -33,7 +47,7 @@ async function addDemoCharger(page: Page) {
async function addDemoMeter(page: Page, power = "0") {
const lpModal = page.getByTestId("loadpoint-modal");
await lpModal.getByRole("button", { name: "Add dedicated charger meter" }).click();
await lpModal.getByRole("button", { name: "Add dedicated energy meter" }).click();
const modal = page.getByTestId("meter-modal");
await expectModalVisible(modal);
@ -54,14 +68,23 @@ async function addVehicle(page: Page, title: string) {
await expectModalHidden(modal);
}
async function newLoadpoint(page: Page, title: string) {
async function newLoadpoint(
page: Page,
title: string,
type: LoadpointType = LoadpointType.Charging
) {
const lpModal = page.getByTestId("loadpoint-modal");
await page.getByRole("button", { name: "Add charge point" }).click();
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);
}
test.describe("loadpoint", async () => {
test.describe("charging loadpoint", async () => {
test("create, update and delete", async ({ page }) => {
await start();
@ -106,6 +129,7 @@ test.describe("loadpoint", async () => {
// update loadpoint title
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
await expectModalVisible(lpModal);
await expect(lpModal.getByRole("heading", { name: "Edit Charging Point" })).toBeVisible();
await lpModal.getByLabel("Title").fill("Solar Carport 2");
await lpModal.getByRole("button", { name: "Save" }).click();
await expect(page.getByTestId("loadpoint")).toContainText("Solar Carport 2");
@ -160,7 +184,7 @@ test.describe("loadpoint", async () => {
test("priority", async ({ page }) => {
await start(CONFIG_ONE_LP);
await page.goto("/#/config");
await enableExperimental(page);
await enableExperimental(page, false);
const lpModal = page.getByTestId("loadpoint-modal");
@ -368,6 +392,8 @@ test.describe("loadpoint", async () => {
await expectModalVisible(chargerModal);
await chargerModal.getByRole("button", { name: "Delete" }).click();
await expectModalHidden(chargerModal);
await expectModalVisible(lpModal);
await expect(lpModal.getByRole("heading", { name: "Edit Charger or Heater" })).toBeVisible();
// restart without saving loadpoint
await restart();
@ -376,6 +402,7 @@ test.describe("loadpoint", async () => {
// check loadpoint default vehicle
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
await expectModalVisible(lpModal);
await lpModal.getByRole("button", { name: "Add charging point" }).click();
await expect(lpModal.getByRole("textbox", { name: "Title" })).toHaveValue("Garage");
await expect(lpModal).toContainText("Configuring a charger is required.");
});
@ -412,9 +439,7 @@ test.describe("loadpoint", async () => {
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
await expectModalVisible(lpModal);
await expect(lpModal.getByRole("textbox", { name: "Title" })).toHaveValue("Garage");
await expect(
lpModal.getByRole("button", { name: "Add dedicated charger meter" })
).toBeVisible();
await expect(lpModal.getByRole("button", { name: "Add dedicated energy meter" })).toBeVisible();
});
test("user-defined charger", async ({ page }) => {
@ -430,10 +455,12 @@ test.describe("loadpoint", async () => {
// add user-defined charger
const chargerModal = page.getByTestId("charger-modal");
await expectModalVisible(chargerModal);
await chargerModal.getByLabel("Manufacturer").selectOption("User-defined device");
await chargerModal.getByLabel("Manufacturer").selectOption("User-defined charger");
await page.waitForLoadState("networkidle");
const chargerEditor = chargerModal.getByTestId("yaml-editor");
await expect(chargerEditor).toContainText("status: # charger status [A..F]");
await expect(chargerEditor).toContainText(
"status: # charger status (A: not connected, B: connected, C: charging)"
);
await editorClear(chargerEditor, 20);
await editorPaste(
@ -468,7 +495,7 @@ power:
await expectModalVisible(lpModal);
// add user-defined meter
await lpModal.getByRole("button", { name: "Add dedicated charger meter" }).click();
await lpModal.getByRole("button", { name: "Add dedicated energy meter" }).click();
const meterModal = page.getByTestId("meter-modal");
await expectModalVisible(meterModal);
await meterModal.getByLabel("Manufacturer").selectOption("User-defined device");
@ -512,16 +539,158 @@ power:
await lpEntry.getByRole("button", { name: "edit" }).click();
await expectModalVisible(lpModal);
await expect(lpModal.getByLabel("Charger").first()).toHaveValue("User-defined device [db:1]");
await expect(lpModal.getByLabel("Charger").first()).toHaveValue("User-defined charger [db:1]");
await expect(lpModal.getByLabel("Energy meter").first()).toHaveValue(
"User-defined device [db:2]"
);
await lpModal.getByLabel("Charger").first().click();
await expectModalVisible(chargerModal);
await expect(chargerModal.getByLabel("Manufacturer")).toHaveValue("User-defined device");
await expect(chargerModal.getByLabel("Manufacturer")).toHaveValue("User-defined charger");
await page.waitForLoadState("networkidle");
await expect(chargerEditor).toContainText("value: 'C'");
await expect(chargerEditor).toContainText("value: 11000");
});
});
test.describe("heating loadpoint", async () => {
test("create, update and delete", async ({ page }) => {
await start();
await page.goto("/#/config");
await enableExperimental(page);
// add loadpoint
await newLoadpoint(page, "Wärmepumpe", LoadpointType.Heating);
const lpModal = page.getByTestId("loadpoint-modal");
await lpModal.getByRole("button", { name: "Add heater" }).click();
await addDemoCharger(page, LoadpointType.Heating);
// check heading
await expect(lpModal.getByRole("heading", { name: "Add Heating Device" })).toBeVisible();
await lpModal.getByRole("button", { name: "Save" }).click();
await expectModalHidden(lpModal);
// restart edit
await restart();
await page.reload();
const lpEntry = page.getByTestId("loadpoint");
await expect(lpEntry.getByRole("img", { name: "heatpump" })).toBeVisible();
await expect(lpEntry).toContainText("Wärmepumpe");
await lpEntry.getByRole("button", { name: "edit" }).click();
await expectModalVisible(lpModal);
await expect(lpModal.getByRole("heading", { name: "Edit Heating Device" })).toBeVisible();
await lpModal.getByRole("button", { name: "Save" }).click();
await expectModalHidden(lpModal);
// delete
await lpEntry.getByRole("button", { name: "edit" }).click();
await expectModalVisible(lpModal);
await lpModal.getByRole("button", { name: "Delete" }).click();
await expectModalHidden(lpModal);
// restart delete
await restart();
await page.reload();
// check loadpoint
await expect(page.getByTestId("loadpoint")).not.toBeVisible();
});
// add user-defined heat pump
test("user-defined heat pump", async ({ page }) => {
await start();
await page.goto("/#/config");
await enableExperimental(page);
// add loadpoint
await newLoadpoint(page, "Wärmepumpe", LoadpointType.Heating);
const lpModal = page.getByTestId("loadpoint-modal");
await lpModal.getByRole("button", { name: "Add heater" }).click();
// add user-defined heat pump
const modal = page.getByTestId("charger-modal");
await expectModalVisible(modal);
await modal.getByLabel("Manufacturer").selectOption("User-defined heater");
await modal.getByLabel("Manufacturer").selectOption("User-defined heat pump");
await modal.getByLabel("Manufacturer").selectOption("User-defined heat pump (sg-ready, all)");
await modal.getByLabel("Manufacturer").selectOption("User-defined heat pump (sg-ready, boost)");
await modal.getByLabel("Manufacturer").selectOption("User-defined switch socket");
await modal.getByLabel("Manufacturer").selectOption("User-defined heat pump");
const editor = modal.getByTestId("yaml-editor");
await editorClear(editor, 20);
await editorPaste(
editor,
page,
`setmaxpower:
source: js
script: console.log(setmaxpower);
getmaxpower:
source: const
value: 2000
power:
source: const
value: 1000
energy:
source: const
value: 0.7
limittemp:
source: const
value: 50
temp:
source: const
value: 25
`
);
const restResult = modal.getByTestId("test-result");
await expect(restResult).toContainText("Status: unknown");
await restResult.getByRole("link", { name: "validate" }).click();
await expect(restResult).toContainText("Status: successful");
await expect(restResult).toContainText(["Power", "1.0 kW"].join(""));
await expect(restResult).toContainText(["Energy", "0.7 kWh"].join(""));
await expect(restResult).toContainText(["Temperature", "25.0°C"].join(""));
await expect(restResult).toContainText(["Heater limit", "50.0°C"].join(""));
await modal.getByRole("button", { name: "Save" }).click();
await expectModalHidden(modal);
await expectModalVisible(lpModal);
// create
await lpModal.getByRole("button", { name: "Save" }).click();
await expectModalHidden(lpModal);
await expect(page.getByTestId("loadpoint")).toHaveCount(1);
const lpEntry = page.getByTestId("loadpoint").first();
await expect(lpEntry.getByRole("img", { name: "heatpump" })).toBeVisible();
await expect(lpEntry).toContainText("Wärmepumpe");
await expect(lpEntry).toContainText(["Power", "1.0 kW"].join(""));
});
test("delete charger/heater reverts to loadpoint type select screen", async ({ page }) => {
await start();
await page.goto("/#/config");
await enableExperimental(page);
// add loadpoint
await newLoadpoint(page, "Wärmepumpe", LoadpointType.Heating);
await addDemoCharger(page, LoadpointType.Heating);
const lpModal = page.getByTestId("loadpoint-modal");
await lpModal.getByRole("button", { name: "Save" }).click();
await expectModalHidden(lpModal);
// delete heater
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
await expectModalVisible(lpModal);
await lpModal.getByRole("textbox", { name: "Heater" }).click();
const chargerModal = page.getByTestId("charger-modal");
await expectModalVisible(chargerModal);
await chargerModal.getByRole("button", { name: "Delete" }).click();
await expectModalHidden(chargerModal);
await expectModalVisible(lpModal);
await expect(lpModal.getByRole("heading", { name: "Edit Charger or Heater" })).toBeVisible();
await expect(lpModal.getByRole("button", { name: "Add charging point" })).toBeVisible();
await expect(lpModal.getByRole("button", { name: "Add heating device" })).toBeVisible();
});
});

View file

@ -2,8 +2,6 @@ import { test, expect, type Page } from "@playwright/test";
import { start, stop, baseUrl } from "./evcc";
import { enableExperimental, expectModalHidden, expectModalVisible } from "./utils";
const CONFIG_GRID_ONLY = "config-grid-only.evcc.yaml";
test.use({ baseURL: baseUrl() });
test.afterEach(async () => {
@ -19,7 +17,7 @@ async function goToConfig(page: Page) {
test.describe("messaging", async () => {
test("save a comment", async ({ page }) => {
await start(CONFIG_GRID_ONLY);
await start();
await goToConfig(page);
await page.getByTestId("messaging").getByRole("button", { name: "edit" }).click();

View file

@ -3,15 +3,13 @@ import { start, stop, restart, baseUrl } from "./evcc";
import { enableExperimental, expectModalHidden, expectModalVisible } from "./utils";
import { isMqttReachable } from "./mqtt";
const CONFIG = "config-grid-only.evcc.yaml";
test.use({ baseURL: baseUrl() });
test.describe.configure({ mode: "parallel" });
test.beforeEach(async ({ page }) => {
await start(CONFIG);
await start();
await page.goto("/#/config");
await enableExperimental(page);
await enableExperimental(page, false);
});
test.afterEach(async () => {
@ -57,7 +55,7 @@ test.describe("mqtt", async () => {
.getByRole("button", { name: "Restart" });
await expect(restartButton).toBeVisible();
await restart(CONFIG);
await restart();
// config error
await expect(page.getByTestId("mqtt")).toHaveClass(/round-box--error/);
@ -80,7 +78,7 @@ test.describe("mqtt", async () => {
await expect(page.getByTestId("mqtt")).toContainText(
["Broker", VALID_BROKER, "Topic", VALID_TOPIC].join("")
);
await restart(CONFIG);
await restart();
await expect(page.getByTestId("fatal-error")).not.toBeVisible();
await expect(page.getByTestId("mqtt")).not.toHaveClass(/round-box--error/);

View file

@ -48,6 +48,8 @@ test.describe("onboarding", async () => {
await expect(page.getByTestId("loadpoint-required")).toBeVisible();
await page.getByTestId("add-loadpoint").click();
const lpModal = page.getByTestId("loadpoint-modal");
await expectModalVisible(lpModal);
await lpModal.getByRole("button", { name: "Add charging point" }).click();
await lpModal.getByLabel("Title").fill("Solar Carport");
await lpModal.getByRole("button", { name: "Add charger" }).click();

View file

@ -17,7 +17,7 @@ test.afterAll(async () => {
test.describe("pv meter", async () => {
test("create, edit and remove pv meter", async ({ page }) => {
await page.goto("/#/config");
await enableExperimental(page);
await enableExperimental(page, false);
await expect(page.getByTestId("pv")).toHaveCount(0);
@ -77,7 +77,7 @@ test.describe("pv meter", async () => {
await startSimulator();
await page.goto("/#/config");
await enableExperimental(page);
await enableExperimental(page, false);
// create meter
await page.getByRole("button", { name: "Add solar or battery" }).click();

View file

@ -8,7 +8,6 @@ import {
editorPaste,
} from "./utils";
const CONFIG_GRID_ONLY = "config-grid-only.evcc.yaml";
const CONFIG_WITH_TARIFFS = "config-with-tariffs.evcc.yaml";
test.use({ baseURL: baseUrl() });
@ -25,7 +24,7 @@ async function goToConfig(page: Page) {
test.describe("tariffs", async () => {
test("tariffs not configured", async ({ page }) => {
await start(CONFIG_GRID_ONLY);
await start();
await goToConfig(page);
await expect(page.getByTestId("tariffs")).not.toBeVisible();
@ -33,7 +32,7 @@ test.describe("tariffs", async () => {
});
test("tariffs via ui", async ({ page }) => {
await start(CONFIG_GRID_ONLY);
await start();
await goToConfig(page);
await page.getByTestId("add-tariffs").click();
@ -74,7 +73,7 @@ grid:
.getByRole("button", { name: "Restart" });
await expect(restartButton).toBeVisible();
await restart(CONFIG_GRID_ONLY);
await restart();
// restart done
await expect(restartButton).not.toBeVisible();
@ -86,7 +85,8 @@ grid:
test("tariffs from evcc.yaml", async ({ page }) => {
await start(CONFIG_WITH_TARIFFS);
await goToConfig(page);
await page.goto("/#/config");
await enableExperimental(page, false);
await expect(page.getByTestId("tariffs")).toBeVisible();
await expect(page.getByTestId("tariffs")).toContainText(

View file

@ -8,7 +8,6 @@ import {
expectModalVisible,
} from "./utils";
const CONFIG_GRID_ONLY = "config-grid-only.evcc.yaml";
const CONFIG_WITH_VEHICLE = "config-with-vehicle.evcc.yaml";
test.use({ baseURL: baseUrl() });
@ -22,10 +21,10 @@ const GENERIC_VEHICLE = "Generic vehicle (without API)";
test.describe("vehicles", async () => {
test("create, edit and delete vehicles", async ({ page }) => {
await start(CONFIG_GRID_ONLY);
await start();
await page.goto("/#/config");
await enableExperimental(page);
await enableExperimental(page, false);
await expect(page.getByTestId("vehicle")).toHaveCount(0);
const vehicleModal = page.getByTestId("vehicle-modal");
@ -81,7 +80,7 @@ test.describe("vehicles", async () => {
});
test("config should survive restart", async ({ page }) => {
await start(CONFIG_GRID_ONLY);
await start();
await page.goto("/#/config");
await enableExperimental(page);
@ -109,7 +108,7 @@ test.describe("vehicles", async () => {
await expect(page.getByTestId("vehicle")).toHaveCount(2);
// restart evcc
await restart(CONFIG_GRID_ONLY);
await restart();
await page.reload();
await expect(page.getByTestId("vehicle")).toHaveCount(2);
@ -121,7 +120,7 @@ test.describe("vehicles", async () => {
await start(CONFIG_WITH_VEHICLE);
await page.goto("/#/config");
await enableExperimental(page);
await enableExperimental(page, false);
await expect(page.getByTestId("vehicle")).toHaveCount(1);
const vehicleModal = page.getByTestId("vehicle-modal");
@ -140,7 +139,7 @@ test.describe("vehicles", async () => {
});
test("advanced fields", async ({ page }) => {
await start(CONFIG_GRID_ONLY);
await start();
await page.goto("/#/config");
await enableExperimental(page);
@ -179,7 +178,7 @@ test.describe("vehicles", async () => {
});
test("save and restore rfid identifiers", async ({ page }) => {
await start(CONFIG_GRID_ONLY);
await start();
await page.goto("/#/config");
await enableExperimental(page);
@ -198,7 +197,7 @@ test.describe("vehicles", async () => {
await expect(page.getByTestId("restart-needed")).toBeVisible();
// restart evcc
await restart(CONFIG_GRID_ONLY);
await restart();
await page.reload();
await expect(page.getByTestId("vehicle")).toHaveCount(1);
@ -212,10 +211,10 @@ test.describe("vehicles", async () => {
});
test("user-defined vehicle", async ({ page }) => {
await start(CONFIG_GRID_ONLY);
await start();
await page.goto("/#/config");
await enableExperimental(page);
await enableExperimental(page, false);
await page.getByTestId("add-vehicle").click();
const modal = page.getByTestId("vehicle-modal");
@ -250,7 +249,7 @@ soc:
await expect(page.getByTestId("vehicle")).toHaveCount(1);
// restart evcc
await restart(CONFIG_GRID_ONLY);
await restart();
await page.reload();
await expect(page.getByTestId("vehicle")).toHaveCount(1);
@ -291,7 +290,7 @@ soc:
await expect(page.getByTestId("vehicle")).toHaveCount(0);
// restart evcc
await restart(CONFIG_GRID_ONLY);
await restart();
await page.reload();
await expect(page.getByTestId("vehicle")).toHaveCount(0);

View file

@ -30,7 +30,7 @@ test.describe("general", async () => {
// change value in config
await page.goto("/#/config");
await enableExperimental(page);
await enableExperimental(page, false);
await expect(page.getByTestId("generalconfig-title")).toContainText("Hello World");
await page.getByTestId("generalconfig-title").getByRole("button", { name: "edit" }).click();

View file

@ -1,15 +1,19 @@
import { expect, type Page, type Locator } from "@playwright/test";
export async function enableExperimental(page: Page): Promise<void> {
await expect(page.getByTestId("topnavigation-button")).toBeVisible();
await page.getByTestId("topnavigation-button").click();
await page.getByTestId("topnavigation-settings").click();
const modal = page.getByTestId("global-settings-modal");
await expectModalVisible(modal);
await modal.getByLabel("Experimental 🧪").click();
await modal.getByRole("button", { name: "Close" }).click();
await expectModalHidden(modal);
await expect(page.locator(".modal-backdrop")).not.toBeVisible();
export async function enableExperimental(page: Page, inline = true): Promise<void> {
if (inline) {
await page.getByRole("button", { name: "Enable Experimental Features" }).click();
} else {
await expect(page.getByTestId("topnavigation-button")).toBeVisible();
await page.getByTestId("topnavigation-button").click();
await page.getByTestId("topnavigation-settings").click();
const modal = page.getByTestId("global-settings-modal");
await expectModalVisible(modal);
await modal.getByLabel("Experimental 🧪").click();
await modal.getByRole("button", { name: "Close" }).click();
await expectModalHidden(modal);
await expect(page.locator(".modal-backdrop")).not.toBeVisible();
}
}
export async function expectModalVisible(modal: Locator): Promise<void> {