Skip to content

Commit

Permalink
chore: playwright test stability (evcc-io#14849)
Browse files Browse the repository at this point in the history
  • Loading branch information
naltatis authored Jul 12, 2024
1 parent 3fa2c33 commit 77eb720
Show file tree
Hide file tree
Showing 9 changed files with 37 additions and 27 deletions.
2 changes: 1 addition & 1 deletion playwright.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { defineConfig, devices } from "@playwright/test";
export default defineConfig({
testDir: "./tests",
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
retries: process.env.CI ? 3 : 0,
timeout: 15000, // 15s (default 30s)
workers: process.env.CI ? 3 : 4,
reporter: "html",
Expand Down
2 changes: 1 addition & 1 deletion tests/config-battery.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ const CONFIG_GRID_ONLY = "config-grid-only.evcc.yaml";
test.use({ baseURL: baseUrl() });

test.beforeAll(async () => {
await start(CONFIG_GRID_ONLY, "password.sql");
await startSimulator();
await start(CONFIG_GRID_ONLY, "password.sql");
});
test.afterAll(async () => {
await stop();
Expand Down
2 changes: 1 addition & 1 deletion tests/config-grid.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ const CONFIG_EMPTY = "config-empty.evcc.yaml";
test.use({ baseURL: baseUrl() });

test.beforeAll(async () => {
await start(CONFIG_EMPTY, "password.sql");
await startSimulator();
await start(CONFIG_EMPTY, "password.sql");
});
test.afterAll(async () => {
await stop();
Expand Down
4 changes: 2 additions & 2 deletions tests/config-messaging.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ test.describe("messaging", async () => {

await modal.locator(".monaco-editor .view-line").nth(0).click();
for (let i = 0; i < 4; i++) {
await page.keyboard.press(SELECT_ALL);
await page.keyboard.press("Backspace");
await page.keyboard.press(SELECT_ALL, { delay: 10 });
await page.keyboard.press("Backspace", { delay: 10 });
}
await page.keyboard.type("# hello world");
await page.getByRole("button", { name: "Save" }).click();
Expand Down
18 changes: 12 additions & 6 deletions tests/config-tariffs.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,30 @@ test.describe("tariffs", async () => {
await page.getByTestId("tariffs").getByRole("button", { name: "edit" }).click();
const modal = await page.getByTestId("tariffs-modal");
await expect(modal).toBeVisible();
await page.waitForLoadState("networkidle");

// default content
await expect(modal).toContainText("# currency: EUR");

// clear and enter invalid yaml
await modal.locator(".monaco-editor .view-line").nth(0).click();
await page.keyboard.press(SELECT_ALL);
await page.keyboard.press("Backspace");
await page.keyboard.press(SELECT_ALL);
await page.keyboard.press("Backspace");

for (let i = 0; i < 4; i++) {
await page.keyboard.press(SELECT_ALL, { delay: 10 });
await page.keyboard.press("Backspace", { delay: 10 });
}

await page.keyboard.type("foo: bar\n");
await page.getByRole("button", { name: "Save" }).click();
await expect(modal.getByTestId("error")).toContainText("invalid keys: foo");

// clear and enter valid yaml
await modal.locator(".monaco-editor .view-line").nth(0).click();
await page.keyboard.press(SELECT_ALL);
await page.keyboard.press("Backspace");
for (let i = 0; i < 4; i++) {
await page.keyboard.press(SELECT_ALL, { delay: 10 });
await page.keyboard.press("Backspace", { delay: 10 });
}

await page.keyboard.type("currency: CHF\n");
await page.keyboard.type("grid:\n");
await page.keyboard.type(" type: fixed\n");
Expand Down
4 changes: 2 additions & 2 deletions tests/modals.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,13 @@ test.describe("Basics", async () => {

test.describe("Advanced", async () => {
test.beforeAll(async () => {
await start(simulatorConfig(), "password.sql");
await startSimulator();
await start(simulatorConfig(), "password.sql");
});

test.afterAll(async () => {
await stopSimulator();
await stop();
await stopSimulator();
});

test("Menu options. All available.", async ({ page }) => {
Expand Down
20 changes: 12 additions & 8 deletions tests/simulator.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import waitOn from "wait-on";
import axios from "axios";
import { exec } from "child_process";

function port() {
const index = process.env.TEST_PARALLEL_INDEX * 1;
function workerPort() {
const index = process.env.TEST_WORKER_INDEX * 1;
return 12000 + index;
}

export function simulatorHost() {
return `localhost:${port()}`;
return `localhost:${workerPort()}`;
}

export function simulatorUrl() {
Expand All @@ -29,9 +29,11 @@ export function simulatorConfig() {
}

export async function startSimulator() {
console.log("starting simulator");
const instance = exec(`npm run simulator -- --port ${port()}`);
console.log("exec end");
const port = workerPort();
console.log("starting simulator", { port });
console.log(`wait until port ${port} is available`);
await waitOn({ resources: [`tcp:localhost:${port}`], reverse: true });
const instance = exec(`npm run simulator -- --port ${port}`);
instance.stdout.pipe(process.stdout);
instance.stderr.pipe(process.stderr);

Expand All @@ -40,11 +42,13 @@ export async function startSimulator() {
throw new Error("simulator terminated", code);
}
});
console.log("waiton");
await waitOn({ resources: [`${simulatorUrl()}/api/state`], log: true });
}

export async function stopSimulator() {
console.log("shutting down simulator");
const port = workerPort();
console.log("shutting down simulator", { port });
await axios.post(`${simulatorUrl()}/api/shutdown`);
console.log(`wait until port ${port} is closed`);
await waitOn({ resources: [`tcp:localhost:${port}`], reverse: true });
}
8 changes: 4 additions & 4 deletions tests/simulator/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ let state = {

const stateApiMiddleware = (req, res, next) => {
if (req.method === "POST" && req.originalUrl === "/api/state") {
console.log("POST /api/state", req.body);
console.log("[simulator] POST /api/state", req.body);
state = req.body;
res.end();
} else if (req.method === "POST" && req.originalUrl === "/api/shutdown") {
console.log("POST /api/shutdown", req.body);
console.log("[simulator] POST /api/shutdown", req.body);
res.end();
process.exit();
} else if (req.originalUrl === "/api/state") {
Expand All @@ -35,7 +35,7 @@ const openemsMiddleware = (req, res, next) => {
};
const endpoint = endpoints[req.originalUrl];
if (req.method === "GET" && endpoint) {
console.log("GET", req.originalUrl, endpoint);
console.log("[simulator] GET", req.originalUrl, endpoint);
res.end(JSON.stringify(endpoint));
} else {
next();
Expand All @@ -46,7 +46,7 @@ export default () => ({
name: "api",
enforce: "pre",
configureServer(server) {
console.log("configureServer");
console.log("[simulator] configured");
return () => {
server.middlewares.use(bodyParser.json());
server.middlewares.use(stateApiMiddleware);
Expand Down
4 changes: 2 additions & 2 deletions tests/smart-cost.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import { startSimulator, stopSimulator, simulatorUrl, simulatorConfig } from "./
test.use({ baseURL: baseUrl() });

test.beforeAll(async () => {
await start(simulatorConfig(), "password.sql");
await startSimulator();
await start(simulatorConfig(), "password.sql");
});
test.afterAll(async () => {
await stopSimulator();
await stop();
await stopSimulator();
});

test.beforeEach(async ({ page }) => {
Expand Down

0 comments on commit 77eb720

Please sign in to comment.