import { test, expect } from "@playwright/test"; import { start, stop, restart, baseUrl } from "./evcc"; import { expectModalVisible, expectModalHidden, editorClear, editorPaste, LoadpointType, addDemoCharger, addDemoMeter, addVehicle, newLoadpoint, finishLoadpoint, } from "./utils"; const CONFIG_ONE_LP = "config-one-lp.evcc.yaml"; test.use({ baseURL: baseUrl() }); test.describe.configure({ mode: "parallel" }); test.afterEach(async () => { await stop(); }); test.describe("charging loadpoint", async () => { test("create, update and delete", async ({ page }) => { await start(); await page.goto("/#/config"); const lpModal = page.getByTestId("loadpoint-modal"); const chargerModal = page.getByTestId("charger-modal"); await expect(page.getByTestId("loadpoint")).toHaveCount(0); // new loadpoint await newLoadpoint(page, "Solar Carport"); await lpModal.getByRole("button", { name: "Add charger" }).click(); // add charger await chargerModal.getByLabel("Manufacturer").selectOption("Demo charger"); await chargerModal.getByLabel("Charge status").selectOption("C"); await chargerModal.getByLabel("Power").fill("11000"); await chargerModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(chargerModal); await expectModalVisible(lpModal); // instant-create success screen await expect(lpModal.getByRole("heading", { name: "Charging point created" })).toBeVisible(); await expect(lpModal).toContainText("“Solar Carport” was created and uses sensible defaults."); await lpModal.getByRole("link", { name: "Advanced configuration" }).click(); await expect(lpModal.getByLabel("Title")).toHaveValue("Solar Carport"); // verify defaults await expect(lpModal.getByLabel("Default mode")).toHaveValue(""); // mode await expect(lpModal.getByTestId("loadpointSolarMode-default")).toHaveClass(/active/); await expect(lpModal.getByTestId("loadpointSolarMode-custom")).not.toHaveClass(/active/); // min/max current await expect(lpModal.getByTestId("chargerPower-11kw")).toHaveClass(/active/); await expect(lpModal.getByTestId("chargerPower-22kw")).not.toHaveClass(/active/); await expect(lpModal.getByTestId("chargerPower-other")).not.toHaveClass(/active/); // phases await expect(lpModal.getByTestId("loadpointParamPhases-1")).not.toHaveClass(/active/); await expect(lpModal.getByTestId("loadpointParamPhases-3")).toHaveClass(/active/); // create loadpoint await lpModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(lpModal); await expect(page.getByTestId("loadpoint")).toHaveCount(1); await expect(page.getByTestId("loadpoint")).toContainText("Solar Carport"); await expect(page.getByTestId("loadpoint")).toContainText("charging"); await expect(page.getByTestId("loadpoint")).toContainText("11.0 kW"); // restart button appears const restartButton = await page .getByTestId("bottom-banner") .getByRole("button", { name: "Restart" }); await expect(restartButton).toBeVisible(); // restart await restart(); await page.reload(); await expect(page.getByTestId("loadpoint")).toHaveCount(1); await expect(page.getByTestId("loadpoint")).toContainText("Solar Carport"); // 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"); // unsaved changes: backdrop click keeps modal open await lpModal.click({ position: { x: 10, y: 10 } }); await expectModalVisible(lpModal); await lpModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(lpModal); await expect(page.getByTestId("loadpoint")).toContainText("Solar Carport 2"); // restart await restart(); await page.reload(); await expect(page.getByTestId("loadpoint")).toHaveCount(1); await expect(page.getByTestId("loadpoint")).toContainText("Solar Carport 2"); // update loadpoint power await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click(); await expectModalVisible(lpModal); await lpModal.getByTestId("chargerPower-22kw").click(); // update charger mode await expect(lpModal.getByText("Demo charger")).toBeVisible(); await lpModal.getByText("Demo charger").click(); await chargerModal.getByLabel("Charge status").selectOption("A"); await chargerModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(chargerModal); await expectModalVisible(lpModal); await lpModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(lpModal); // restart await restart(); await page.reload(); await expect(page.getByTestId("loadpoint")).toHaveCount(1); await expect(page.getByTestId("loadpoint")).toContainText("not connected"); await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click(); await expectModalVisible(lpModal); await expect(lpModal.getByTestId("chargerPower-22kw")).toHaveClass(/active/); await expect(lpModal.getByLabel("Title")).toHaveValue("Solar Carport 2"); await lpModal.getByRole("button", { name: "Close" }).click(); // delete loadpoint await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click(); await expectModalVisible(lpModal); await lpModal.getByRole("button", { name: "Delete" }).click(); await expectModalHidden(lpModal); await expect(page.getByTestId("loadpoint")).toHaveCount(0); // restart await restart(); await page.reload(); await expect(page.getByTestId("loadpoint")).toHaveCount(0); }); test("priority", async ({ page }) => { await start(CONFIG_ONE_LP); await page.goto("/#/config"); const lpModal = page.getByTestId("loadpoint-modal"); // loadpoint from yaml await expect(page.getByTestId("loadpoint")).toHaveCount(1); await expect(page.getByTestId("loadpoint")).toContainText("Carport"); // add loadpoint via UI await newLoadpoint(page, "Garage"); await addDemoCharger(page); await finishLoadpoint(page); // two loadpoints await expect(page.getByTestId("loadpoint")).toHaveCount(2); await expect(page.getByTestId("loadpoint").nth(0)).toContainText("Carport"); await expect(page.getByTestId("loadpoint").nth(1)).toContainText("Garage"); // second loadpoint: increase priority await page.getByTestId("loadpoint").nth(1).getByRole("button", { name: "edit" }).click(); await expectModalVisible(lpModal); await expect(lpModal.getByLabel("Priority")).toHaveValue("0"); await lpModal.getByLabel("Priority").selectOption("1"); await lpModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(lpModal); // restart await restart(CONFIG_ONE_LP); await page.reload(); // check priorities await page.getByTestId("loadpoint").nth(1).getByRole("button", { name: "edit" }).click(); await expectModalVisible(lpModal); await expect(lpModal.getByLabel("Priority")).toHaveValue("1"); // change back to 0 await lpModal.getByLabel("Priority").selectOption("0 (default)"); await lpModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(lpModal); // restart await restart(CONFIG_ONE_LP); await page.reload(); // check priorities await page.getByTestId("loadpoint").nth(1).getByRole("button", { name: "edit" }).click(); await expectModalVisible(lpModal); await expect(lpModal.getByLabel("Priority")).toHaveValue("0"); }); test("second loadpoint gets its own charger, not the first one's", async ({ page }) => { await start(); await page.goto("/#/config"); const lpModal = page.getByTestId("loadpoint-modal"); const chargerModal = page.getByTestId("charger-modal"); // first loadpoint with its own charger await newLoadpoint(page, "Carport"); await lpModal.getByRole("button", { name: "Add charger" }).click(); await expectModalVisible(chargerModal); await expect(chargerModal.getByRole("heading", { name: "Add Charger" })).toBeVisible(); await chargerModal.getByLabel("Manufacturer").selectOption("Demo charger"); await chargerModal.getByLabel("Power").fill("11000"); await chargerModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(chargerModal); await expectModalVisible(lpModal); await finishLoadpoint(page); await expect(page.getByTestId("loadpoint")).toHaveCount(1); await expect(page.getByTestId("loadpoint")).toContainText("11.0 kW"); // second loadpoint, added right after without a page reload in between await newLoadpoint(page, "Garage"); await lpModal.getByRole("button", { name: "Add charger" }).click(); await expectModalVisible(chargerModal); // must open a fresh charger, not reopen the first one for editing await expect(chargerModal.getByRole("heading", { name: "Add Charger" })).toBeVisible(); await chargerModal.getByLabel("Manufacturer").selectOption("Demo charger"); await chargerModal.getByLabel("Power").fill("22000"); await chargerModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(chargerModal); await expectModalVisible(lpModal); await finishLoadpoint(page); // two loadpoints, each with its own distinct charger await expect(page.getByTestId("loadpoint")).toHaveCount(2); await expect(page.getByTestId("loadpoint").nth(0)).toContainText("11.0 kW"); await expect(page.getByTestId("loadpoint").nth(1)).toContainText("22.0 kW"); // restart to confirm the persisted config really has two distinct charger devices await restart(); await page.reload(); await expect(page.getByTestId("loadpoint")).toHaveCount(2); await expect(page.getByTestId("loadpoint").nth(0)).toContainText("11.0 kW"); await expect(page.getByTestId("loadpoint").nth(1)).toContainText("22.0 kW"); }); test("vehicle", async ({ page }) => { await start(); await page.goto("/#/config"); const LP_1 = "Carport"; const LP_2 = "Garage"; const VEHICLE_1 = "Green Car"; const VEHICLE_2 = "Yellow Van"; const lpModal = page.getByTestId("loadpoint-modal"); // add loadpoint > no vehicle option await newLoadpoint(page, LP_1); await addDemoCharger(page); await lpModal.getByRole("link", { name: "Advanced configuration" }).click(); await expect(lpModal.getByLabel("Default vehicle")).not.toBeVisible(); await lpModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(lpModal); // edit loadpoint await page.getByTestId("loadpoint").nth(0).getByRole("button", { name: "edit" }).click(); await expectModalVisible(lpModal); await expect(lpModal).toContainText("No vehicles are configured."); await lpModal.getByRole("button", { name: "Close" }).click(); // add vehicles for (const title of [VEHICLE_1, VEHICLE_2]) { await addVehicle(page, title); } // set vehicle as default for loadpoint 1 await page.getByTestId("loadpoint").nth(0).getByRole("button", { name: "edit" }).click(); await expectModalVisible(lpModal); await expect(lpModal.getByTestId("loadpointPollMode-charging")).toHaveClass(/active/); await expect(lpModal.getByRole("checkbox", { name: "Interpolate charge level" })).toBeChecked(); await lpModal.getByLabel("Default vehicle").selectOption(VEHICLE_1); await lpModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(lpModal); // add second loadpoint await newLoadpoint(page, LP_2); await addDemoCharger(page); await lpModal.getByRole("link", { name: "Advanced configuration" }).click(); await lpModal.getByLabel("Default vehicle").selectOption(VEHICLE_2); await lpModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(lpModal); await expect(page.getByTestId("loadpoint")).toHaveCount(2); // restart await restart(); await page.reload(); // check loadpoint default vehicles for (const [index, vehicle] of [VEHICLE_1, VEHICLE_2].entries()) { await page.getByTestId("loadpoint").nth(index).getByRole("button", { name: "edit" }).click(); await expectModalVisible(lpModal); await expect(lpModal.locator("#loadpointParamVehicle option:checked")).toHaveText(vehicle); await lpModal.getByRole("button", { name: "Close" }).click(); await expectModalHidden(lpModal); } }); test("keep mode", async ({ page }) => { await start(); await page.goto("/#/config"); // add grid meter await page.getByRole("button", { name: "Add grid meter" }).click(); const meterModal = page.getByTestId("meter-modal"); await meterModal.getByLabel("Manufacturer").selectOption("Demo meter"); await meterModal.getByLabel("Power").fill("-1000"); await meterModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(meterModal); // add a loadpoint with dummy charger, const lpModal = page.getByTestId("loadpoint-modal"); await newLoadpoint(page, "Carport"); await addDemoCharger(page); await lpModal.getByRole("link", { name: "Advanced configuration" }).click(); await lpModal.getByLabel("Default mode").selectOption("---"); await lpModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(lpModal); await restart(); await page.reload(); // change on main ui await page.goto("/"); await expect(page.getByRole("button", { name: "Off" })).toHaveClass(/active/); await page.getByRole("button", { name: "Solar", exact: true }).click(); await page.waitForLoadState("networkidle"); await expect(page.getByRole("button", { name: "Solar", exact: true })).toHaveClass(/active/); await restart(); await page.reload(); await expect(page.getByRole("button", { name: "Solar", exact: true })).toHaveClass(/active/); // change default mode in config to fast await page.goto("/#/config"); // open first loadpoint await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click(); await expectModalVisible(lpModal); await lpModal.getByLabel("Default mode").selectOption("Fast"); await lpModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(lpModal); await restart(); // check loadpoint mode await page.goto("/"); await expect(page.getByRole("button", { name: "Fast" })).toHaveClass(/active/); }); test("delete vehicle references", async ({ page }) => { await start(); await page.goto("/#/config"); // add vehicle, add loadpoint, add charger await addVehicle(page, "Porsche"); await addVehicle(page, "Tesla"); await newLoadpoint(page, "Garage"); await addDemoCharger(page); const lpModal = page.getByTestId("loadpoint-modal"); await expectModalVisible(lpModal); await lpModal.getByRole("link", { name: "Advanced configuration" }).click(); await lpModal.getByLabel("Default vehicle").selectOption("Porsche"); await lpModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(lpModal); await restart(); await page.reload(); // delete vehicle await page.getByTestId("vehicle").nth(0).getByRole("button", { name: "edit" }).click(); const vehicleModal = page.getByTestId("vehicle-modal"); await expectModalVisible(vehicleModal); await vehicleModal.getByRole("button", { name: "Delete" }).click(); await expectModalHidden(vehicleModal); // restart await restart(); await page.reload(); // check loadpoint default vehicle await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click(); await expectModalVisible(lpModal); await expect(lpModal.getByLabel("Default vehicle")).toHaveValue(""); }); test("delete charger references", async ({ page }) => { await start(); await page.goto("/#/config"); // add loadpoint, add charger await newLoadpoint(page, "Garage"); await addDemoCharger(page); const lpModal = page.getByTestId("loadpoint-modal"); await finishLoadpoint(page); // delete charger await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click(); await expectModalVisible(lpModal); await lpModal.getByText("Demo charger").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 Charging Point or Heater" }) ).toBeVisible(); // close modal before restarting await lpModal.getByRole("button", { name: "Close" }).click(); await expectModalHidden(lpModal); // restart without saving loadpoint await restart(); await page.reload(); // 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.getByLabel("Title")).toHaveValue("Garage"); await expect(lpModal).toContainText("Configuring a charger is required."); }); test("delete meter references", async ({ page }) => { await start(); await page.goto("/#/config"); // add loadpoint, add charger await newLoadpoint(page, "Garage"); await addDemoCharger(page); await addDemoMeter(page, "11000"); const lpModal = page.getByTestId("loadpoint-modal"); await lpModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(lpModal); await restart(); await page.reload(); await expect(page.getByTestId("loadpoint")).toContainText("11.0 kW"); // delete charger await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click(); await expectModalVisible(lpModal); await lpModal.getByText("Demo meter").click(); const meterModal = page.getByTestId("meter-modal"); await expectModalVisible(meterModal); await meterModal.getByRole("button", { name: "Delete" }).click(); await expectModalHidden(meterModal); await expectModalVisible(lpModal); await lpModal.getByRole("button", { name: "Close" }).click(); await expectModalHidden(lpModal); // restart without saving loadpoint await restart(); await page.reload(); // check loadpoint default vehicle await expect(page.getByTestId("loadpoint")).not.toContainText("11.0 kW"); await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click(); await expectModalVisible(lpModal); await expect(lpModal.getByLabel("Title")).toHaveValue("Garage"); await expect(lpModal.getByRole("button", { name: "Add dedicated energy meter" })).toBeVisible(); }); test("user-defined charger", async ({ page }) => { await start(); await page.goto("/#/config"); // add loadpoint await newLoadpoint(page, "Carport"); const lpModal = page.getByTestId("loadpoint-modal"); await lpModal.getByRole("button", { name: "Add charger" }).click(); // add user-defined charger const chargerModal = page.getByTestId("charger-modal"); await expectModalVisible(chargerModal); 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: not connected, B: connected, C: charging)" ); await editorClear(chargerEditor); await editorPaste( chargerEditor, page, `status: source: const value: 'C' enabled: source: const value: true enable: source: js script: console.log(enable) maxcurrent: source: js script: console.log(maxcurrent) power: source: const value: 11000` ); const chargerRestResult = chargerModal.getByTestId("test-result"); await expect(chargerRestResult).toContainText("Status: unknown"); await chargerRestResult.getByRole("link", { name: "validate" }).click(); await expect(chargerRestResult).toContainText("Status: successful"); await expect(chargerRestResult).toContainText(["Status", "charging"].join("")); await expect(chargerRestResult).toContainText(["Enabled", "yes"].join("")); await expect(chargerRestResult).toContainText(["Power", "11.0 kW"].join("")); await chargerModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(chargerModal); await expectModalVisible(lpModal); // add user-defined meter await lpModal.getByRole("link", { name: "Advanced configuration" }).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"); await page.waitForLoadState("networkidle"); const meterEditor = meterModal.getByTestId("yaml-editor"); await editorClear(meterEditor); await editorPaste( meterEditor, page, `power: source: const value: 5000` ); const meterRestResult = meterModal.getByTestId("test-result"); await expect(meterRestResult).toContainText("Status: unknown"); await meterRestResult.getByRole("link", { name: "validate" }).click(); await expect(meterRestResult).toContainText("Status: successful"); await expect(meterRestResult).toContainText(["Power", "5.0 kW"].join("")); await meterModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(meterModal); await expectModalVisible(lpModal); // create await lpModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(lpModal); await expect(page.getByTestId("loadpoint")).toHaveCount(1); await expect(page.getByTestId("loadpoint")).toContainText("Carport"); // restart evcc await restart(); await page.reload(); const lpEntry = page.getByTestId("loadpoint"); await expect(lpEntry).toHaveCount(1); await expect(lpEntry).toContainText("Carport"); await expect(lpEntry).toContainText(["Status", "charging"].join("")); await expect(lpEntry).toContainText(["Enabled", "yes"].join("")); await expect(lpEntry).toContainText(["Power", "5.0 kW"].join("")); await lpEntry.getByRole("button", { name: "edit" }).click(); await expectModalVisible(lpModal); await expect(lpModal.getByText("User-defined charger")).toBeVisible(); await expect(lpModal.getByText("User-defined device")).toBeVisible(); await lpModal.getByText("User-defined charger").click(); await expectModalVisible(chargerModal); 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("user-defined switch socket (pool pump)", async ({ page }) => { await start(); await page.goto("/#/config"); // add loadpoint await newLoadpoint(page, "Pool pump"); const lpModal = page.getByTestId("loadpoint-modal"); await lpModal.getByRole("button", { name: "Add charger" }).click(); const chargerModal = page.getByTestId("charger-modal"); await expectModalVisible(chargerModal); await chargerModal.getByLabel("Manufacturer").selectOption("User-defined switch socket"); await page.waitForLoadState("networkidle"); await expect(chargerModal.getByTestId("yaml-editor")).toContainText("switchdevice"); const result = chargerModal.getByTestId("test-result"); await result.getByRole("link", { name: "validate" }).click(); await expect(result).toContainText("Status: successful"); await expect(result).toContainText(["Power", "11.0 kW"].join("")); await expect(result).toContainText(["Current control", "no"].join("")); await chargerModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(chargerModal); await expectModalVisible(lpModal); await lpModal.getByRole("link", { name: "Advanced configuration" }).click(); const modeSelect = lpModal.getByLabel("Default mode"); await expect(modeSelect.getByRole("option", { name: "Solar", exact: true })).toHaveCount(1); await expect(modeSelect.getByRole("option", { name: "Min+Solar" })).toHaveCount(0); await expect(lpModal.getByText("Electrics")).toHaveCount(0); await expect(lpModal.getByText("Charger type", { exact: true })).toHaveCount(0); // create await lpModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(lpModal); await expect(page.getByTestId("loadpoint")).toHaveCount(1); await expect(page.getByTestId("loadpoint")).toContainText("Pool pump"); }); }); test.describe("heating loadpoint", async () => { test("create, update and delete", async ({ page }) => { await start(); await page.goto("/#/config"); // add loadpoint await newLoadpoint(page, "Wärmepumpe", LoadpointType.Heating); const lpModal = page.getByTestId("loadpoint-modal"); await addDemoCharger(page, LoadpointType.Heating); await expect(lpModal.getByRole("heading", { name: "Heater created" })).toBeVisible(); await finishLoadpoint(page); // 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 Heater" })).toBeVisible(); await lpModal.getByRole("button", { name: "Save" }).click(); await expectModalHidden(lpModal); // set min temperature on main screen (stored in loadpoint device config) await page.goto("/"); const settingsModal = page.getByTestId("loadpoint-settings-modal").first(); await page.getByTestId("loadpoint-settings-button").last().click(); await expectModalVisible(settingsModal); await settingsModal.getByLabel("Min. temperature").selectOption("50.0°C"); await settingsModal.getByRole("button", { name: "Close" }).click(); await expectModalHidden(settingsModal); // min temperature survives restart await restart(); await page.reload(); await page.getByTestId("loadpoint-settings-button").last().click(); await expectModalVisible(settingsModal); await expect(settingsModal.getByLabel("Min. temperature")).toHaveValue("50"); await settingsModal.getByRole("button", { name: "Close" }).click(); await expectModalHidden(settingsModal); await page.goto("/#/config"); // 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"); // add loadpoint await newLoadpoint(page, "Wärmepumpe", LoadpointType.Heating); const lpModal = page.getByTestId("loadpoint-modal"); await lpModal.getByRole("button", { name: "Add heating device" }).click(); // add user-defined heat pump const modal = page.getByTestId("charger-modal"); await expectModalVisible(modal); await modal.getByLabel("Manufacturer").selectOption("User-defined heating device"); await modal.getByLabel("Manufacturer").selectOption("User-defined heat pump"); await modal .getByLabel("Manufacturer") .selectOption("User-defined heat pump (sg-ready via plugins)"); await modal .getByLabel("Manufacturer") .selectOption("User-defined heat pump (sg-ready via relays)"); 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); 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", "700 Wh"].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 finishLoadpoint(page); 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"); // add loadpoint await newLoadpoint(page, "Wärmepumpe", LoadpointType.Heating); await addDemoCharger(page, LoadpointType.Heating); const lpModal = page.getByTestId("loadpoint-modal"); await finishLoadpoint(page); // delete heater await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click(); await expectModalVisible(lpModal); await lpModal.getByText("Demo heat pump").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 Charging Point or Heater" }) ).toBeVisible(); await expect(lpModal.getByRole("button", { name: "Add charging point" })).toBeVisible(); await expect(lpModal.getByRole("button", { name: "Add heater" })).toBeVisible(); }); }); test.describe("sponsor token", () => { test("create charger with missing sponsor token", async ({ page }) => { await start(); await page.goto("/#/config"); // add loadpoint with Peblar charger await newLoadpoint(page, "Peblar Test Charger"); await page.getByTestId("loadpoint-modal").getByRole("button", { name: "Add charger" }).click(); const chargerModal = page.getByTestId("charger-modal"); await expectModalVisible(chargerModal); await chargerModal.getByLabel("Manufacturer").selectOption({ label: "Peblar Business" }); // verify disabled save button await expect(chargerModal.getByRole("button", { name: "Save" })).toBeDisabled(); // verify sponsor notice await expect(chargerModal).toContainText( "You must configure a sponsor token before you can create this device." ); const testResult = chargerModal.getByTestId("test-result"); await testResult.getByRole("link", { name: "Validate" }).click(); const sponsorMessage = testResult.getByText("No sponsor token configured."); await expect(sponsorMessage).toBeVisible(); // verify click on sponsor await sponsorMessage.click(); const sponsorModal = page.getByTestId("sponsor-modal"); await expectModalVisible(sponsorModal); await expect(sponsorModal.getByRole("heading")).toContainText("Sponsorship"); }); });