evcc-io/tests/navigation.spec.ts

104 lines
4.2 KiB
TypeScript

import { test, expect } from "@playwright/test";
import { start, stop, restart, baseUrl } from "./evcc";
import { expectModalHidden, expectModalVisible } from "./utils";
test.use({ baseURL: baseUrl() });
test.describe("bottom navigation", async () => {
test.afterAll(async () => {
await stop();
});
test("tabs, navigation, and forecast empty state", async ({ page }) => {
// start with blank install
await start();
await page.goto("/");
const bottomNav = page.getByTestId("bottom-tab-bar");
await expect(bottomNav).toBeVisible();
const tabCharge = bottomNav.getByRole("link", { name: "Charge" });
const tabBattery = bottomNav.getByRole("link", { name: "Battery" });
const tabForecast = bottomNav.getByRole("link", { name: "Forecast" });
const tabSessions = bottomNav.getByRole("link", { name: "Sessions" });
const tabMore = bottomNav.getByTestId("tab-more");
// verify bottom nav tabs (no battery)
await expect(tabCharge).toBeVisible();
await expect(tabForecast).toBeVisible();
await expect(tabSessions).toBeVisible();
await expect(tabMore).toBeVisible();
await expect(tabBattery).toHaveCount(0);
// more menu opens and closes on the same tab
const configLink = tabMore.getByRole("link", { name: "Configuration" });
await tabMore.click();
await expect(configLink).toBeVisible();
await tabMore.click();
await expect(configLink).not.toBeVisible();
// navigate to config via More menu
await tabMore.click();
await configLink.click();
await expect(page.getByRole("heading", { name: "Configuration" })).toBeVisible();
// create battery meter
await page.getByRole("button", { name: "Add solar or battery" }).click();
const meterModal = page.getByTestId("meter-modal");
await meterModal.getByRole("button", { name: "Add battery meter" }).click();
await meterModal.getByLabel("Title").fill("Demo Battery");
await meterModal.getByLabel("Manufacturer").selectOption("Demo battery");
await meterModal.getByLabel("Power").fill("1000");
await meterModal.getByLabel("Charge").fill("50");
await meterModal.getByRole("button", { name: "Save" }).click();
await expectModalHidden(meterModal);
await expect(page.getByTestId("battery")).toBeVisible();
// restart and verify battery tab appears
const restartButton = page
.getByTestId("bottom-banner")
.getByRole("button", { name: "Restart" });
await expect(restartButton).toBeVisible();
await restart();
await expect(restartButton).not.toBeVisible();
await page.goto("/");
await expect(tabBattery).toBeVisible();
// click all tabs, verify headlines
await tabCharge.click();
await expect(page.getByRole("heading", { name: "evcc" })).toBeVisible();
await tabBattery.click();
await expect(page.getByRole("heading", { name: "Home Battery" })).toBeVisible();
await tabForecast.click();
await expect(page.getByRole("heading", { name: "Forecast" })).toBeVisible();
await tabSessions.click();
await expect(page.getByRole("heading", { name: "Sessions" })).toBeVisible();
// forecast empty state → create solar forecast
await tabForecast.click();
await page.getByRole("link", { name: "Set up tariffs and forecasts" }).click();
await expect(page.getByRole("heading", { name: "Configuration" })).toBeVisible();
const tariffModal = page.getByTestId("tariff-modal");
await page.getByRole("button", { name: "Add forecast" }).click();
await expectModalVisible(tariffModal);
await tariffModal.getByRole("button", { name: "Add solar forecast" }).click();
await tariffModal.getByLabel("Title").fill("Demo Forecast");
await tariffModal.getByLabel("Provider").selectOption("Demo PV Forecast");
await tariffModal.getByRole("button", { name: "Validate & save" }).click();
await expectModalHidden(tariffModal);
await expect(page.getByTestId("tariff-solar")).toBeVisible();
// restart, navigate to forecast, verify headline
await expect(restartButton).toBeVisible();
await restart();
await expect(restartButton).not.toBeVisible();
await tabForecast.click();
await expect(page.getByRole("heading", { name: "Forecast" })).toBeVisible();
});
});