chore: improve playwright monaco stability (#21845)

This commit is contained in:
Michael Geers 2025-06-14 20:26:20 +02:00 • committed by GitHub
parent 8b562d7f8e
commit 4fd924317d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 117 additions and 110 deletions

View file

@ -15,6 +15,7 @@ export default defineConfig({
trace: "on-first-retry",
video: "on-first-retry",
screenshot: "only-on-failure",
permissions: ["clipboard-write"],
},
projects: [
{

View file

@ -2,7 +2,7 @@ import { test, expect } from "@playwright/test";
import { start, stop, restart, baseUrl } from "./evcc";
import {
editorClear,
editorType,
editorPaste,
enableExperimental,
expectModalHidden,
expectModalVisible,
@ -81,16 +81,16 @@ test.describe("aux meter", async () => {
await expect(editor).toContainText("power: # current power");
await editorClear(editor);
await editorType(editor, [
// prettier-ignore
"power:",
" source: const",
"value: 3000 # W",
"Shift+Tab",
"energy:",
" source: const",
"value: 42.0 # kWh",
]);
await editorPaste(
editor,
page,
`power:
source: const
value: 3000 # W
energy:
source: const
value: 42.0 # kWh`
);
const restResult = modal.getByTestId("test-result");
await expect(restResult).toContainText("Status: unknown");
@ -122,16 +122,16 @@ test.describe("aux meter", async () => {
// update
await modal.getByLabel("Title").fill("Small heater");
await editorClear(editor);
await editorType(editor, [
// prettier-ignore
"power:",
" source: const",
"value: 300 # W",
"Shift+Tab",
"energy:",
" source: const",
"value: 4.2 # kWh",
]);
await editorPaste(
editor,
page,
`power:
source: const
value: 300 # W
energy:
source: const
value: 4.2 # kWh`
);
await expect(restResult).toContainText("Status: unknown");
await restResult.getByRole("link", { name: "validate" }).click();
await expect(restResult).toContainText("Status: successful");
@ -175,11 +175,12 @@ test.describe("aux meter", async () => {
// yaml syntax error
await editorClear(editor);
await editorType(editor, [
// prettier-ignore
"hello: world",
" foo: bar",
]);
await editorPaste(
editor,
page,
`hello: world
foo: bar`
);
// no errors
await expect(editor.locator(".line-numbers.error")).toHaveCount(0);
@ -194,12 +195,13 @@ test.describe("aux meter", async () => {
// invalid field error
await editorClear(editor);
await editorType(editor, [
// prettier-ignore
"apower:",
" source: const",
"value: 3000 # W",
]);
await editorPaste(
editor,
page,
`apower:
source: const
value: 3000 # W`
);
await expect(restResult).toContainText("Status: unknown");
await restResult.getByRole("link", { name: "validate" }).click();
await expect(restResult).toContainText("Status: failed");
@ -208,12 +210,13 @@ test.describe("aux meter", async () => {
// unknown source error
await editorClear(editor);
await editorType(editor, [
// prettier-ignore
"power:",
" source: unknown",
"value: 3000 # W",
]);
await editorPaste(
editor,
page,
`power:
source: unknown
value: 3000 # W`
);
await expect(restResult).toContainText("Status: unknown");
await restResult.getByRole("link", { name: "validate" }).click();
await expect(restResult).toContainText("Status: failed");
@ -222,12 +225,13 @@ test.describe("aux meter", async () => {
// missing required field error
await editorClear(editor);
await editorType(editor, [
// prettier-ignore
"energy:",
" source: const",
"value: 300 # kWh",
]);
await editorPaste(
editor,
page,
`energy:
source: const
value: 300 # kWh`
);
await expect(restResult).toContainText("Status: unknown");
await restResult.getByRole("link", { name: "validate" }).click();
await expect(restResult).toContainText("Status: failed");

View file

@ -5,7 +5,7 @@ import {
expectModalVisible,
expectModalHidden,
editorClear,
editorType,
editorPaste,
} from "./utils";
const CONFIG_YAML = "config-circuit.evcc.yaml";
@ -86,22 +86,21 @@ test.describe("circuit", async () => {
const editor = circuitsModal.getByTestId("yaml-editor");
await editorClear(editor);
await editorType(editor, [
// prettier-ignore
"- name: main",
" meter: db:1",
"maxcurrent: 16",
"Shift+Tab",
"- name: house",
" title: House",
"maxcurrent: 10",
"parent: main",
"Shift+Tab",
"- name: garage",
" title: Garage",
"maxcurrent: 8",
"parent: main",
]);
await editorPaste(
editor,
page,
`- name: main
meter: db:1
maxcurrent: 16
- name: house
title: House
maxcurrent: 10
parent: main
- name: garage
title: Garage
maxcurrent: 8
parent: main`
);
await circuitsModal.getByRole("button", { name: "Save" }).click();
await expectModalHidden(circuitsModal);

View file

@ -1,6 +1,6 @@
import { test, expect } from "@playwright/test";
import { start, stop, restart, baseUrl } from "./evcc";
import { expectModalVisible, expectModalHidden, editorClear, editorType } from "./utils";
import { expectModalVisible, expectModalHidden, editorClear, editorPaste } from "./utils";
const CONFIG_EMPTY = "config-empty.evcc.yaml";
const CONFIG_ONE_LP = "config-one-lp.evcc.yaml";
@ -436,18 +436,25 @@ test.describe("loadpoint", async () => {
await expect(editor).toContainText("status: # charger status [A..F]");
await editorClear(editor, 10);
await editorType(editor, [
// prettier-ignore
"status:\n source: const\nvalue: 'C'",
"Shift+Tab",
"enabled:\n source: const\nvalue: true",
"Shift+Tab",
"enable:\n source: js\nscript: console.log(enable)",
"Shift+Tab",
"maxcurrent:\n source: js\nscript: console.log(maxcurrent)",
"Shift+Tab",
"power:\n source: const\nvalue: 11000",
]);
await editorPaste(
editor,
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 restResult = chargerModal.getByTestId("test-result");
await expect(restResult).toContainText("Status: unknown");

View file

@ -5,7 +5,7 @@ import {
expectModalHidden,
expectModalVisible,
editorClear,
editorType,
editorPaste,
} from "./utils";
const CONFIG_GRID_ONLY = "config-grid-only.evcc.yaml";
@ -47,19 +47,20 @@ test.describe("tariffs", async () => {
// clear and enter invalid yaml
await editorClear(editor);
await editorType(editor, "foo: bar");
await editorPaste(editor, page, "foo: bar");
await page.getByRole("button", { name: "Save" }).click();
await expect(modal.getByTestId("error")).toContainText("invalid keys: foo");
// clear and enter valid yaml
await editorClear(editor);
await editorType(editor, [
// prettier-ignore
"currency: CHF",
"grid:",
" type: fixed",
"price: 0.123",
]);
await editorPaste(
editor,
page,
`currency: CHF
grid:
type: fixed
price: 0.123`
);
await page.getByRole("button", { name: "Save" }).click();
await expect(modal.getByTestId("error")).not.toBeVisible();

View file

@ -2,7 +2,7 @@ import { test, expect } from "@playwright/test";
import { start, stop, restart, baseUrl } from "./evcc";
import {
editorClear,
editorType,
editorPaste,
enableExperimental,
expectModalHidden,
expectModalVisible,
@ -213,14 +213,15 @@ test.describe("vehicles", async () => {
await expect(editor).toContainText("title: green Honda");
await editorClear(editor);
await editorType(editor, [
// prettier-ignore
"title: blue Honda",
"capacity: 12.3",
"soc:",
" source: const",
"value: 42",
]);
await editorPaste(
editor,
page,
`title: blue Honda
capacity: 12.3
soc:
source: const
value: 42`
);
const restResult = modal.getByTestId("test-result");
await expect(restResult).toContainText("Status: unknown");
@ -247,14 +248,15 @@ test.describe("vehicles", async () => {
// update
await editorClear(editor);
await editorType(editor, [
// prettier-ignore
"title: pink Honda",
"capacity: 23.4",
"soc:",
" source: const",
"value: 32",
]);
await editorPaste(
editor,
page,
`title: pink Honda
capacity: 23.4
soc:
source: const
value: 32`
);
await expect(restResult).toContainText("Status: unknown");
await restResult.getByRole("link", { name: "validate" }).click();
await expect(restResult).toContainText("Status: successful");

View file

@ -26,15 +26,8 @@ export async function editorClear(editor: Locator, iterations = 6): Promise<void
}
}
export async function editorType(editor: Locator, text: string | string[]): Promise<void> {
const instructions = ["Shift+Tab"];
export async function editorPaste(editor: Locator, page: Page, text: string): Promise<void> {
await editor.locator(".view-line").nth(0).click();
const lines = Array.isArray(text) ? text : [text];
for (const line of lines) {
if (instructions.includes(line)) {
await editor.page().keyboard.press(line);
} else {
await editor.page().keyboard.type(line + "\n");
}
}
await page.evaluate((text) => navigator.clipboard.writeText(text), text);
await page.keyboard.press("ControlOrMeta+KeyV", { delay: 50 });
}