chore: e2e stability, modal visibility (#20438)

This commit is contained in:
Michael Geers 2025-04-06 14:57:22 +02:00 • committed by GitHub
parent 2460dbd6c8
commit 143373e1c3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 113 additions and 96 deletions

View file

@ -726,7 +726,6 @@ export default {
this.updatePhases();
},
async loadConfiguration() {
console.log("loadpoint modal loadConfiguration");
try {
const res = await api.get(`config/loadpoints/${this.id}`);
this.values = deepClone(res.data.result);
@ -766,7 +765,6 @@ export default {
await api.post("config/loadpoints", this.values);
this.$emit("updated");
this.$refs.modal.close();
this.reset();
} catch (e) {
console.error(e);
const error = e.response?.data?.error;

View file

@ -6,7 +6,7 @@
:class="classes"
tabindex="-1"
role="dialog"
aria-hidden="true"
:aria-hidden="isModalVisible ? 'false' : 'true'"
:data-bs-backdrop="uncloseable ? 'static' : 'true'"
:data-bs-keyboard="uncloseable ? 'false' : 'true'"
:data-testid="dataTestid"
@ -88,9 +88,11 @@ export default {
},
methods: {
handleShow() {
console.log(this.dataTestid, "> show");
this.$emit("open");
},
handleShown() {
console.log(this.dataTestid, "> shown");
this.$emit("opened");
// focus first input or select
this.$nextTick(() => {
@ -102,16 +104,20 @@ export default {
this.isModalVisible = true;
},
handleHide() {
console.log(this.dataTestid, "> hide");
this.$emit("close");
},
handleHidden() {
console.log(this.dataTestid, "> hidden");
this.$emit("closed");
this.isModalVisible = false;
},
open() {
console.log(this.dataTestid, "> open", this.$refs.modal._isShown);
Modal.getOrCreateInstance(this.$refs.modal).show();
},
close() {
console.log(this.dataTestid, "> close", this.$refs.modal._isShown);
Modal.getOrCreateInstance(this.$refs.modal).hide();
},
},

View file

@ -762,6 +762,7 @@ export default {
},
newLoadpoint() {
this.selectedLoadpointId = undefined;
this.$refs.loadpointModal.reset();
this.$nextTick(() => this.loadpointModal().show());
},
async loadpointChanged() {

View file

@ -7,7 +7,7 @@ export default defineConfig({
testDir: "./tests",
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 4 : 0,
timeout: 20000, // default 30s
timeout: 30000, // default 30s
workers: process.env.CI ? 3 : 4,
reporter: "html",
use: {

View file

@ -1,6 +1,6 @@
import { test, expect } from "@playwright/test";
import { start, stop, baseUrl } from "./evcc";
import { expectModalHidden, expectModalVisible } from "./utils";
test.use({ baseURL: baseUrl() });
const BASIC = "basics.evcc.yaml";
@ -11,7 +11,7 @@ test("set initial password", async ({ page }) => {
const modal = page.getByTestId("password-modal");
await expect(modal).toBeVisible();
await expectModalVisible(modal);
await expect(modal.getByRole("heading", { name: "Set Administrator Password" })).toBeVisible();
// empty password
@ -28,7 +28,7 @@ test("set initial password", async ({ page }) => {
await modal.getByLabel("New password").fill("secret");
await modal.getByLabel("Repeat password").fill("secret");
await modal.getByRole("button", { name: "Create Password" }).click();
await expect(modal).not.toBeVisible();
await expectModalHidden(modal);
await stop();
});
@ -43,7 +43,7 @@ test("login", async ({ page }) => {
// login modal
const login = page.getByTestId("login-modal");
await expect(login).toBeVisible();
await expectModalVisible(login);
await expect(login.getByRole("heading", { name: "Authentication" })).toBeVisible();
// enter wrong password
@ -54,7 +54,7 @@ test("login", async ({ page }) => {
// enter correct password
await login.getByLabel("Password").fill("secret");
await login.getByRole("button", { name: "Login" }).click();
await expect(login).not.toBeVisible();
await expectModalHidden(login);
await expect(page.getByRole("heading", { name: "Configuration" })).toBeVisible();
await stop();
@ -70,7 +70,7 @@ test("http iframe hint", async ({ page }) => {
// login modal
const login = page.getByTestId("login-modal");
await expect(login).toBeVisible();
await expectModalVisible(login);
await expect(login.getByRole("heading", { name: "Authentication" })).toBeVisible();
// rewrite api call to simulate lost auth cookie
@ -97,10 +97,10 @@ test("update password", async ({ page }) => {
// login modal
await page.goto("/#/config");
const loginModal = page.getByTestId("login-modal");
await expect(loginModal).toBeVisible();
await expectModalVisible(loginModal);
await loginModal.getByLabel("Password").fill(oldPassword);
await loginModal.getByRole("button", { name: "Login" }).click();
await expect(loginModal).not.toBeVisible();
await expectModalHidden(loginModal);
// update password
await page.getByTestId("generalconfig-password").getByRole("button", { name: "edit" }).click();
@ -123,11 +123,11 @@ test("update password", async ({ page }) => {
await expect(page.getByRole("button", { name: "Logout" })).not.toBeVisible();
await page.getByRole("link", { name: "Configuration" }).click();
const loginNew = page.getByTestId("login-modal");
await expect(loginNew).toBeVisible();
await expectModalVisible(loginNew);
await loginNew.getByLabel("Password").fill(newPassword);
await loginNew.getByRole("button", { name: "Login" }).click();
await expect(page.getByRole("heading", { name: "Configuration" })).toBeVisible();
await expect(loginNew).not.toBeVisible();
await expectModalHidden(loginNew);
// revert to old password
await page.getByTestId("generalconfig-password").getByRole("button", { name: "edit" }).click();
@ -148,7 +148,7 @@ test("disable auth", async ({ page }) => {
// no password modal
const modal = page.getByTestId("password-modal");
await expect(modal).not.toBeVisible();
await expectModalHidden(modal);
// configuration page without login
await page.getByTestId("topnavigation-button").click();

View file

@ -1,6 +1,6 @@
import { test, expect } from "@playwright/test";
import { start, stop, baseUrl } from "./evcc";
import { enableExperimental } from "./utils";
import { enableExperimental, expectModalHidden } from "./utils";
test.use({ baseURL: baseUrl() });
test.beforeAll(async () => {
@ -37,7 +37,7 @@ test.describe("boost", async () => {
"Boost active for this charging session."
);
await modal.getByLabel("Close").click();
await expect(modal).not.toBeVisible();
await expectModalHidden(modal);
await expect(page.getByTestId("vehicle-status-batteryboost")).toBeVisible();
});

View file

@ -1,6 +1,6 @@
import { test, expect } from "@playwright/test";
import { start, stop, restart, baseUrl } from "./evcc";
import { enableExperimental } from "./utils";
import { enableExperimental, expectModalHidden } from "./utils";
const CONFIG_GRID_ONLY = "config-grid-only.evcc.yaml";
@ -29,7 +29,7 @@ test.describe("aux meter", async () => {
await meterModal.getByLabel("Manufacturer").selectOption("Demo meter");
await meterModal.getByLabel("Power (W)").fill("1200");
await meterModal.getByRole("button", { name: "Validate & save" }).click();
await expect(meterModal).not.toBeVisible();
await expectModalHidden(meterModal);
// check
await expect(page.getByTestId("aux")).toBeVisible(1);

View file

@ -1,7 +1,7 @@
import { test, expect } from "@playwright/test";
import { start, stop, restart, baseUrl } from "./evcc";
import { startSimulator, stopSimulator, simulatorUrl, simulatorHost } from "./simulator";
import { enableExperimental } from "./utils";
import { enableExperimental, expectModalHidden, expectModalVisible } from "./utils";
const CONFIG_GRID_ONLY = "config-grid-only.evcc.yaml";
@ -42,16 +42,16 @@ test.describe("battery meter", async () => {
await expect(meterModal.getByTestId("device-tag-soc")).toContainText("75.0%");
await expect(meterModal.getByTestId("device-tag-power")).toContainText("-2.5 kW");
await meterModal.getByRole("button", { name: "Save" }).click();
await expect(meterModal).not.toBeVisible();
await expectModalHidden(meterModal);
await expect(page.getByTestId("battery")).toBeVisible(1);
await expect(page.getByTestId("battery")).toContainText("Battery Basement");
// edit #1
await page.getByTestId("battery").getByRole("button", { name: "edit" }).click();
await expect(meterModal).toBeVisible();
await expectModalVisible(meterModal);
await meterModal.getByLabel("Battery capacity in kWh").fill("20");
await meterModal.getByRole("button", { name: "Validate & save" }).click();
await expect(meterModal).not.toBeVisible();
await expectModalHidden(meterModal);
const battery = page.getByTestId("battery");
await expect(battery).toBeVisible(1);

View file

@ -1,7 +1,7 @@
import { test, expect } from "@playwright/test";
import { start, stop, restart, baseUrl } from "./evcc";
import { startSimulator, stopSimulator, simulatorUrl, simulatorHost } from "./simulator";
import { enableExperimental } from "./utils";
import { enableExperimental, expectModalHidden } from "./utils";
const CONFIG_ONE_LP = "config-one-lp.evcc.yaml";
@ -47,7 +47,7 @@ test.describe("grid meter", async () => {
await meterModal.getByRole("link", { name: "validate" }).click();
await expect(meterModal.getByTestId("device-tag-power")).toContainText("5.0 kW");
await meterModal.getByRole("button", { name: "Save" }).click();
await expect(meterModal).not.toBeVisible();
await expectModalHidden(meterModal);
// restart
await restart(CONFIG_ONE_LP);
@ -62,7 +62,7 @@ test.describe("grid meter", async () => {
await page.goto("/#/config");
await page.getByTestId("grid").getByRole("button", { name: "edit" }).click();
await meterModal.getByRole("button", { name: "Delete" }).click();
await expect(meterModal).not.toBeVisible();
await expectModalHidden(meterModal);
await expect(page.getByTestId("grid")).not.toBeVisible();
await expect(page.getByTestId("add-grid")).toBeVisible();

View file

@ -1,5 +1,6 @@
import { test, expect } from "@playwright/test";
import { start, stop, restart, baseUrl } from "./evcc";
import { expectModalVisible, expectModalHidden } from "./utils";
const CONFIG_EMPTY = "config-empty.evcc.yaml";
const CONFIG_ONE_LP = "config-one-lp.evcc.yaml";
@ -24,11 +25,11 @@ async function addDemoCharger(page) {
await lpModal.getByRole("button", { name: "Add charger" }).click();
const modal = page.getByTestId("charger-modal");
await expect(modal).toBeVisible();
await expectModalVisible(modal);
await modal.getByLabel("Manufacturer").selectOption("Demo charger");
await modal.getByRole("button", { name: "Save" }).click();
await expect(modal).not.toBeVisible();
await expect(lpModal).toBeVisible();
await expectModalHidden(modal);
await expectModalVisible(lpModal);
}
async function addDemoMeter(page, power = "0") {
@ -36,28 +37,28 @@ async function addDemoMeter(page, power = "0") {
await lpModal.getByRole("button", { name: "Add dedicated charger meter" }).click();
const modal = page.getByTestId("meter-modal");
await expect(modal).toBeVisible();
await expectModalVisible(modal);
await modal.getByLabel("Manufacturer").selectOption("Demo meter");
await modal.getByLabel("Power").fill(power);
await modal.getByRole("button", { name: "Save" }).click();
await expect(modal).not.toBeVisible();
await expect(lpModal).toBeVisible();
await expectModalHidden(modal);
await expectModalVisible(lpModal);
}
async function addVehicle(page, title) {
await page.getByRole("button", { name: "Add vehicle" }).click();
const modal = page.getByTestId("vehicle-modal");
await expect(modal).toBeVisible();
await expectModalVisible(modal);
await modal.getByLabel("Manufacturer").selectOption("Generic vehicle");
await modal.getByLabel("Title").fill(title);
await modal.getByRole("button", { name: "Validate & save" }).click();
await expect(modal).not.toBeVisible();
await expectModalHidden(modal);
}
async function newLoadpoint(page, title) {
const lpModal = page.getByTestId("loadpoint-modal");
await page.getByRole("button", { name: "Add charge point" }).click();
await expect(lpModal).toBeVisible();
await expectModalVisible(lpModal);
await lpModal.getByLabel("Title").fill(title);
}
@ -105,7 +106,7 @@ test.describe("loadpoint", async () => {
// update loadpoint title
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
await expect(lpModal).toBeVisible();
await expectModalVisible(lpModal);
await lpModal.getByLabel("Title").fill("Solar Carport 2");
await lpModal.getByRole("button", { name: "Save" }).click();
await expect(page.getByTestId("loadpoint")).toContainText("Solar Carport 2");
@ -118,7 +119,7 @@ test.describe("loadpoint", async () => {
// update loadpoint power
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
await expect(lpModal).toBeVisible();
await expectModalVisible(lpModal);
await lpModal.getByTestId("chargerPower-22kw").click();
// update charger mode
@ -128,10 +129,10 @@ test.describe("loadpoint", async () => {
await lpModal.getByRole("textbox", { name: "Charger" }).click();
await chargerModal.getByLabel("Charge status").selectOption("A");
await chargerModal.getByRole("button", { name: "Save" }).click();
await expect(chargerModal).not.toBeVisible();
await expectModalHidden(chargerModal);
await lpModal.getByRole("button", { name: "Save" }).click();
await expect(lpModal).not.toBeVisible();
await expectModalHidden(lpModal);
// restart
await restart(CONFIG_EMPTY);
@ -140,14 +141,14 @@ test.describe("loadpoint", async () => {
await expect(page.getByTestId("loadpoint")).toContainText("not connected");
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
await expect(lpModal).toBeVisible();
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 expect(lpModal).toBeVisible();
await expectModalVisible(lpModal);
await lpModal.getByRole("button", { name: "Delete" }).click();
await expect(page.getByTestId("loadpoint")).toHaveCount(0);
@ -172,7 +173,7 @@ test.describe("loadpoint", async () => {
await newLoadpoint(page, "Garage");
await addDemoCharger(page);
await lpModal.getByRole("button", { name: "Save" }).click();
await expect(lpModal).not.toBeVisible();
await expectModalHidden(lpModal);
// two loadpoints
await expect(page.getByTestId("loadpoint")).toHaveCount(2);
@ -181,11 +182,11 @@ test.describe("loadpoint", async () => {
// second loadpoint: increase priority
await page.getByTestId("loadpoint").nth(1).getByRole("button", { name: "edit" }).click();
await expect(lpModal).toBeVisible();
await expectModalVisible(lpModal);
await expect(lpModal.getByLabel("Priority")).toHaveValue("0 (default)");
await lpModal.getByLabel("Priority").selectOption("1");
await lpModal.getByRole("button", { name: "Save" }).click();
await expect(lpModal).not.toBeVisible();
await expectModalHidden(lpModal);
// restart
await restart(CONFIG_ONE_LP);
@ -193,7 +194,7 @@ test.describe("loadpoint", async () => {
// check priorities
await page.getByTestId("loadpoint").nth(1).getByRole("button", { name: "edit" }).click();
await expect(lpModal).toBeVisible();
await expectModalVisible(lpModal);
await expect(lpModal.getByLabel("Priority")).toHaveValue("1");
});
@ -214,11 +215,11 @@ test.describe("loadpoint", async () => {
await addDemoCharger(page);
await expect(lpModal.getByLabel("Default vehicle")).not.toBeVisible();
await lpModal.getByRole("button", { name: "Save" }).click();
await expect(lpModal).not.toBeVisible();
await expectModalHidden(lpModal);
// edit loadpoint
await page.getByTestId("loadpoint").nth(0).getByRole("button", { name: "edit" }).click();
await expect(lpModal).toBeVisible();
await expectModalVisible(lpModal);
await expect(lpModal).toContainText("No vehicles are configured.");
await lpModal.getByRole("button", { name: "Close" }).click();
@ -229,10 +230,10 @@ test.describe("loadpoint", async () => {
// set vehicle as default for loadpoint 1
await page.getByTestId("loadpoint").nth(0).getByRole("button", { name: "edit" }).click();
await expect(lpModal).toBeVisible();
await expectModalVisible(lpModal);
await lpModal.getByLabel("Default vehicle").selectOption(VEHICLE_1);
await lpModal.getByRole("button", { name: "Save" }).click();
await expect(lpModal).not.toBeVisible();
await expectModalHidden(lpModal);
// add second loadpoint
await newLoadpoint(page, LP_2);
@ -247,10 +248,10 @@ test.describe("loadpoint", async () => {
// 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 expect(lpModal).toBeVisible();
await expectModalVisible(lpModal);
await expect(lpModal.locator("#loadpointParamVehicle option:checked")).toHaveText(vehicle);
await lpModal.getByRole("button", { name: "Close" }).click();
await expect(lpModal).not.toBeVisible();
await expectModalHidden(lpModal);
}
});
@ -265,7 +266,7 @@ test.describe("loadpoint", async () => {
await meterModal.getByLabel("Manufacturer").selectOption("Demo meter");
await meterModal.getByLabel("Power").fill("-1000");
await meterModal.getByRole("button", { name: "Save" }).click();
await expect(meterModal).not.toBeVisible();
await expectModalHidden(meterModal);
// add a loadpoint with dummy charger,
const lpModal = page.getByTestId("loadpoint-modal");
@ -273,7 +274,7 @@ test.describe("loadpoint", async () => {
await addDemoCharger(page);
await lpModal.getByLabel("Default mode").selectOption("---");
await lpModal.getByRole("button", { name: "Save" }).click();
await expect(lpModal).not.toBeVisible();
await expectModalHidden(lpModal);
await restart(CONFIG_EMPTY);
// change on main ui
@ -288,10 +289,10 @@ test.describe("loadpoint", async () => {
await page.goto("/#/config");
// open first loadpoint
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
await expect(lpModal).toBeVisible();
await expectModalVisible(lpModal);
await lpModal.getByLabel("Default mode").selectOption("Fast");
await lpModal.getByRole("button", { name: "Save" }).click();
await expect(lpModal).not.toBeVisible();
await expectModalHidden(lpModal);
await restart(CONFIG_EMPTY);
// check loadpoint mode
@ -312,13 +313,13 @@ test.describe("loadpoint", async () => {
const lpModal = page.getByTestId("loadpoint-modal");
await lpModal.getByLabel("Default vehicle").selectOption("Porsche");
await lpModal.getByRole("button", { name: "Save" }).click();
await expect(lpModal).not.toBeVisible();
await expectModalHidden(lpModal);
// delete vehicle
await page.getByTestId("vehicle").nth(0).getByRole("button", { name: "edit" }).click();
const vehicleModal = page.getByTestId("vehicle-modal");
await vehicleModal.getByRole("button", { name: "Delete" }).click();
await expect(vehicleModal).not.toBeVisible();
await expectModalHidden(vehicleModal);
// restart
await restart(CONFIG_EMPTY);
@ -326,7 +327,7 @@ test.describe("loadpoint", async () => {
// check loadpoint default vehicle
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
await expect(lpModal).toBeVisible();
await expectModalVisible(lpModal);
await expect(lpModal.getByLabel("Default vehicle")).toHaveValue("");
});
@ -340,15 +341,16 @@ test.describe("loadpoint", async () => {
await addDemoCharger(page);
const lpModal = page.getByTestId("loadpoint-modal");
await lpModal.getByRole("button", { name: "Save" }).click();
await expect(lpModal).not.toBeVisible();
await expectModalHidden(lpModal);
// delete charger
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
await expect(lpModal).toBeVisible();
await expectModalVisible(lpModal);
await lpModal.getByRole("textbox", { name: "Charger" }).click();
const chargerModal = page.getByTestId("charger-modal");
await expectModalVisible(chargerModal);
await chargerModal.getByRole("button", { name: "Delete" }).click();
await expect(chargerModal).not.toBeVisible();
await expectModalHidden(chargerModal);
// restart without saving loadpoint
await restart(CONFIG_EMPTY);
@ -356,7 +358,7 @@ test.describe("loadpoint", async () => {
// check loadpoint default vehicle
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
await expect(lpModal).toBeVisible();
await expectModalVisible(lpModal);
await expect(lpModal.getByRole("textbox", { name: "Title" })).toHaveValue("Garage");
await expect(lpModal).toContainText("Configuring a charger is required.");
});
@ -372,16 +374,16 @@ test.describe("loadpoint", async () => {
await addDemoMeter(page, "11000");
const lpModal = page.getByTestId("loadpoint-modal");
await lpModal.getByRole("button", { name: "Save" }).click();
await expect(lpModal).not.toBeVisible();
await expectModalHidden(lpModal);
await expect(page.getByTestId("loadpoint")).toContainText("11.0 kW");
// delete charger
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
await expect(lpModal).toBeVisible();
await expectModalVisible(lpModal);
await lpModal.getByRole("textbox", { name: "Meter" }).click();
const meterModal = page.getByTestId("meter-modal");
await meterModal.getByRole("button", { name: "Delete" }).click();
await expect(meterModal).not.toBeVisible();
await expectModalHidden(meterModal);
// restart without saving loadpoint
await restart(CONFIG_EMPTY);
@ -390,7 +392,7 @@ test.describe("loadpoint", async () => {
// check loadpoint default vehicle
await expect(page.getByTestId("loadpoint")).not.toContainText("11.0 kW");
await page.getByTestId("loadpoint").getByRole("button", { name: "edit" }).click();
await expect(lpModal).toBeVisible();
await expectModalVisible(lpModal);
await expect(lpModal.getByRole("textbox", { name: "Title" })).toHaveValue("Garage");
await expect(
lpModal.getByRole("button", { name: "Add dedicated charger meter" })

View file

@ -1,6 +1,6 @@
import { test, expect } from "@playwright/test";
import { start, stop, baseUrl } from "./evcc";
import { enableExperimental } from "./utils";
import { enableExperimental, expectModalHidden, expectModalVisible } from "./utils";
const CONFIG_GRID_ONLY = "config-grid-only.evcc.yaml";
@ -24,7 +24,7 @@ test.describe("messaging", async () => {
await page.getByTestId("messaging").getByRole("button", { name: "edit" }).click();
const modal = await page.getByTestId("messaging-modal");
await expect(modal).toBeVisible();
await expectModalVisible(modal);
await modal.locator(".monaco-editor .view-line").nth(0).click();
for (let i = 0; i < 4; i++) {
@ -33,12 +33,12 @@ test.describe("messaging", async () => {
}
await page.keyboard.type("# hello world");
await page.getByRole("button", { name: "Save" }).click();
await expect(modal).not.toBeVisible();
await expectModalHidden(modal);
page.reload();
await page.getByTestId("messaging").getByRole("button", { name: "edit" }).click();
await expect(modal).toBeVisible();
await expectModalVisible(modal);
await expect(modal).toContainText("# hello world");
});
});

View file

@ -1,6 +1,6 @@
import { test, expect } from "@playwright/test";
import { start, stop, restart, baseUrl } from "./evcc";
import { enableExperimental } from "./utils";
import { enableExperimental, expectModalHidden } from "./utils";
const CONFIG = "config-grid-only.evcc.yaml";
@ -42,7 +42,7 @@ test.describe("mqtt", async () => {
await modal.getByLabel("Password").fill(VALID_PASSWORD);
await page.getByRole("button", { name: "Save" }).click();
await expect(modal.getByTestId("error")).not.toBeVisible();
await expect(modal).not.toBeVisible();
await expectModalHidden(modal);
// restart button appears
const restartButton = await page

View file

@ -1,6 +1,6 @@
import { test, expect } from "@playwright/test";
import { start, stop, restart, baseUrl } from "./evcc";
import { enableExperimental } from "./utils";
import { enableExperimental, expectModalHidden, expectModalVisible } from "./utils";
const CONFIG = "config-empty.evcc.yaml";
@ -21,11 +21,11 @@ test.describe("onboarding", async () => {
// set admin password
const admin = page.getByTestId("password-modal");
await expect(admin).toBeVisible();
await expectModalVisible(admin);
await admin.getByLabel("New password").fill(PASSWORD);
await admin.getByLabel("Repeat password").fill(PASSWORD);
await admin.getByRole("button", { name: "Create Password" }).click();
await expect(admin).not.toBeVisible();
await expectModalHidden(admin);
// onboarding
await expect(page.locator("body")).toContainText("Hello aboard!");
@ -33,10 +33,10 @@ test.describe("onboarding", async () => {
// login
const login = page.getByTestId("login-modal");
await expect(login).toBeVisible();
await expectModalVisible(login);
await login.getByLabel("Password").fill(PASSWORD);
await login.getByRole("button", { name: "Login" }).click();
await expect(login).not.toBeVisible();
await expectModalHidden(login);
// config page
await expect(page.getByRole("heading", { name: "Configuration" })).toBeVisible();
@ -53,30 +53,30 @@ test.describe("onboarding", async () => {
await chargerModal.getByLabel("Charge status").selectOption("C");
await chargerModal.getByLabel("Power").fill("3000");
await chargerModal.getByRole("button", { name: "Save" }).click();
await expect(chargerModal).not.toBeVisible();
await expect(lpModal).toBeVisible();
await expectModalHidden(chargerModal);
await expectModalVisible(lpModal);
await lpModal.getByRole("button", { name: "Save" }).click();
await expect(lpModal).not.toBeVisible();
await expectModalHidden(lpModal);
// create grid meter
await page.getByRole("button", { name: "Add grid meter" }).click();
const gridModal = page.getByTestId("meter-modal");
await expect(gridModal).toBeVisible();
await expectModalVisible(gridModal);
await gridModal.getByLabel("Manufacturer").selectOption("Demo meter");
await gridModal.getByLabel("Power").fill("-2000");
await gridModal.getByRole("button", { name: "Save" }).click();
await expect(gridModal).not.toBeVisible();
await expectModalHidden(gridModal);
// create pv meter
await page.getByRole("button", { name: "Add solar or battery" }).click();
const pvModal = page.getByTestId("meter-modal");
await expect(gridModal).toBeVisible();
await expectModalVisible(pvModal);
await pvModal.getByRole("button", { name: "Add solar meter" }).click();
await pvModal.getByLabel("Title").fill("PV South");
await pvModal.getByLabel("Manufacturer").selectOption("Demo meter");
await pvModal.getByLabel("Power").fill("5000");
await pvModal.getByRole("button", { name: "Save" }).click();
await expect(pvModal).not.toBeVisible();
await expectModalHidden(pvModal);
// restart
const restartButton = await page

View file

@ -1,7 +1,7 @@
import { test, expect } from "@playwright/test";
import { start, stop, restart, baseUrl } from "./evcc";
import { startSimulator, stopSimulator, simulatorHost } from "./simulator";
import { enableExperimental } from "./utils";
import { enableExperimental, expectModalHidden, expectModalVisible } from "./utils";
const CONFIG_GRID_ONLY = "config-grid-only.evcc.yaml";
@ -33,16 +33,16 @@ test.describe("pv meter", async () => {
await meterModal.getByRole("link", { name: "validate" }).click();
await expect(meterModal.getByTestId("device-tag-power")).toContainText("5.0 kW");
await meterModal.getByRole("button", { name: "Save" }).click();
await expect(meterModal).not.toBeVisible();
await expectModalHidden(meterModal);
await expect(page.getByTestId("pv")).toBeVisible(1);
await expect(page.getByTestId("pv")).toContainText("PV North");
// edit #1
await page.getByTestId("pv").getByRole("button", { name: "edit" }).click();
await expect(meterModal).toBeVisible();
await expectModalVisible(meterModal);
await meterModal.getByLabel("Power (W)").fill("6000");
await meterModal.getByRole("button", { name: "Validate & save" }).click();
await expect(meterModal).not.toBeVisible();
await expectModalHidden(meterModal);
const pv = page.getByTestId("pv");
await expect(pv).toBeVisible(1);
@ -83,7 +83,7 @@ test.describe("pv meter", async () => {
await meterModal.getByLabel("Manufacturer").selectOption("shelly-1pm");
await meterModal.getByLabel("IP address or hostname").fill(simulatorHost());
await meterModal.getByRole("button", { name: "Validate & save" }).click();
await expect(meterModal).not.toBeVisible();
await expectModalHidden(meterModal);
await expect(page.getByTestId("pv")).toBeVisible(1);
await expect(page.getByTestId("pv")).toContainText("North Roof");

View file

@ -1,6 +1,6 @@
import { test, expect } from "@playwright/test";
import { start, stop, restart, baseUrl } from "./evcc";
import { enableExperimental } from "./utils";
import { enableExperimental, expectModalHidden, expectModalVisible } from "./utils";
const CONFIG_GRID_ONLY = "config-grid-only.evcc.yaml";
const CONFIG_WITH_TARIFFS = "config-with-tariffs.evcc.yaml";
@ -34,7 +34,7 @@ test.describe("tariffs", async () => {
await page.getByTestId("add-tariffs").click();
const modal = await page.getByTestId("tariffs-modal");
await expect(modal).toBeVisible();
await expectModalVisible(modal);
await page.waitForLoadState("networkidle");
// default content
@ -68,7 +68,7 @@ test.describe("tariffs", async () => {
await expect(modal.getByTestId("error")).not.toBeVisible();
// modal closes
await expect(modal).not.toBeVisible();
await expectModalHidden(modal);
// restart button appears
const restartButton = await page

View file

@ -1,6 +1,6 @@
import { test, expect } from "@playwright/test";
import { start, stop, baseUrl } from "./evcc";
import { enableExperimental } from "./utils";
import { enableExperimental, expectModalHidden, expectModalVisible } from "./utils";
const CONFIG_GRID_ONLY = "config-grid-only.evcc.yaml";
@ -40,19 +40,19 @@ test.describe("general", async () => {
await expect(page.getByTestId("generalconfig-title")).toContainText("Hello World");
await page.getByTestId("generalconfig-title").getByRole("button", { name: "edit" }).click();
const modal = page.getByTestId("title-modal");
await expect(modal).toBeVisible();
await expectModalVisible(modal);
await modal.getByLabel("Title").fill("Whoops World");
// close modal and ignore entry on cancel
await modal.getByRole("button", { name: "Cancel" }).click();
await expect(modal).not.toBeVisible();
await expectModalHidden(modal);
await expect(page.getByTestId("generalconfig-title")).toContainText("Hello World");
// change and save value
await page.getByTestId("generalconfig-title").getByRole("button", { name: "edit" }).click();
await modal.getByLabel("Title").fill("Ahoy World");
await modal.getByRole("button", { name: "Save" }).click();
await expect(modal).not.toBeVisible();
await expectModalHidden(modal);
await expect(page.getByTestId("generalconfig-title")).toContainText("Ahoy World");
// check changed value on main ui

View file

@ -7,3 +7,13 @@ export async function enableExperimental(page) {
await page.getByRole("button", { name: "Close" }).click();
await expect(page.locator(".modal-backdrop")).not.toBeVisible();
}
export async function expectModalVisible(modal) {
await expect(modal).toBeVisible();
await expect(modal).toHaveAttribute("aria-hidden", "false");
}
export async function expectModalHidden(modal) {
await expect(modal).not.toBeVisible();
await expect(modal).toHaveAttribute("aria-hidden", "true");
}