test: npx playwright test erfolgreich
This commit is contained in:
@@ -6,6 +6,6 @@ NEXT_PUBLIC_USE_MOCK_BACKEND_LOOP_START=false
|
|||||||
NEXT_PUBLIC_EXPORT_STATIC=false
|
NEXT_PUBLIC_EXPORT_STATIC=false
|
||||||
NEXT_PUBLIC_USE_CGI=false
|
NEXT_PUBLIC_USE_CGI=false
|
||||||
# App-Versionsnummer
|
# App-Versionsnummer
|
||||||
NEXT_PUBLIC_APP_VERSION=1.6.831
|
NEXT_PUBLIC_APP_VERSION=1.6.832
|
||||||
NEXT_PUBLIC_CPL_MODE=json # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter)
|
NEXT_PUBLIC_CPL_MODE=json # json (Entwicklungsumgebung) oder jsSimulatedProd (CPL ->CGI-Interface-Simulator) oder production (CPL-> CGI-Interface Platzhalter)
|
||||||
|
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ NEXT_PUBLIC_CPL_API_PATH=/CPL
|
|||||||
NEXT_PUBLIC_EXPORT_STATIC=true
|
NEXT_PUBLIC_EXPORT_STATIC=true
|
||||||
NEXT_PUBLIC_USE_CGI=true
|
NEXT_PUBLIC_USE_CGI=true
|
||||||
# App-Versionsnummer
|
# App-Versionsnummer
|
||||||
NEXT_PUBLIC_APP_VERSION=1.6.831
|
NEXT_PUBLIC_APP_VERSION=1.6.832
|
||||||
NEXT_PUBLIC_CPL_MODE=production
|
NEXT_PUBLIC_CPL_MODE=production
|
||||||
@@ -1,3 +1,8 @@
|
|||||||
|
## [1.6.832] – 2025-09-03
|
||||||
|
|
||||||
|
- refactoring: test files
|
||||||
|
|
||||||
|
---
|
||||||
## [1.6.831] – 2025-09-03
|
## [1.6.831] – 2025-09-03
|
||||||
|
|
||||||
- fix: DigitalOutputsVies.tsx
|
- fix: DigitalOutputsVies.tsx
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"win_da_state": [
|
"win_da_state": [
|
||||||
0,
|
1,
|
||||||
0,
|
1,
|
||||||
0,
|
1,
|
||||||
0
|
1
|
||||||
],
|
],
|
||||||
"win_da_bezeichnung": [
|
"win_da_bezeichnung": [
|
||||||
"Ausgang1",
|
"Ausgang1",
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "cpl-v4",
|
"name": "cpl-v4",
|
||||||
"version": "1.6.831",
|
"version": "1.6.832",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "cpl-v4",
|
"name": "cpl-v4",
|
||||||
"version": "1.6.831",
|
"version": "1.6.832",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/roboto": "^5.1.0",
|
"@fontsource/roboto": "^5.1.0",
|
||||||
"@headlessui/react": "^2.2.4",
|
"@headlessui/react": "^2.2.4",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cpl-v4",
|
"name": "cpl-v4",
|
||||||
"version": "1.6.831",
|
"version": "1.6.832",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev -p 3000",
|
"dev": "next dev -p 3000",
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
"test:e2e:webkit": "playwright test --project=webkit",
|
"test:e2e:webkit": "playwright test --project=webkit",
|
||||||
"test:e2e:report": "playwright show-report playwright/report",
|
"test:e2e:report": "playwright show-report playwright/report",
|
||||||
"test:e2e:clean": "rimraf playwright/report playwright/test-results playwright/.cache blob-report test-results playwright-report",
|
"test:e2e:clean": "rimraf playwright/report playwright/test-results playwright/.cache blob-report test-results playwright-report",
|
||||||
|
"test:e2e:missing": "node ./scripts/find-missing-playwright-tests.mjs",
|
||||||
"prepare": "husky install",
|
"prepare": "husky install",
|
||||||
"bump-version": "node ./scripts/bumpVersion.js",
|
"bump-version": "node ./scripts/bumpVersion.js",
|
||||||
"mocks:cable": "node ./mocks/scripts/fetchCableData.mjs --insecure",
|
"mocks:cable": "node ./mocks/scripts/fetchCableData.mjs --insecure",
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { test, expect } from "@playwright/test";
|
||||||
|
import { highlightAndExpectVisible } from "@playwright/utils/highlight";
|
||||||
|
|
||||||
|
test("AnalogInputsChartModal opens after clicking chart button", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
await page.goto("/analogInputs");
|
||||||
|
// Öffne Modal via Chart-Button (📈)
|
||||||
|
await highlightAndExpectVisible(
|
||||||
|
page,
|
||||||
|
page.getByRole("button", { name: "Messkurve anzeigen" })
|
||||||
|
);
|
||||||
|
await page
|
||||||
|
.getByRole("button", { name: "Messkurve anzeigen" })
|
||||||
|
.first()
|
||||||
|
.click();
|
||||||
|
await highlightAndExpectVisible(page, page.getByRole("dialog"));
|
||||||
|
await expect(page.getByRole("dialog")).toBeVisible();
|
||||||
|
});
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { test } from "@playwright/test";
|
||||||
|
import { highlightAndExpectVisible } from "@playwright/utils/highlight";
|
||||||
|
|
||||||
|
test("AnalogInputsDatePicker renders two inputs", async ({ page }) => {
|
||||||
|
await page.goto("/analogInputs");
|
||||||
|
// Öffne erst die Chart-Ansicht (enthält den DatePicker)
|
||||||
|
const chartBtn = page
|
||||||
|
.getByRole("button", { name: "Messkurve anzeigen" })
|
||||||
|
.first();
|
||||||
|
await highlightAndExpectVisible(page, chartBtn);
|
||||||
|
await chartBtn.click();
|
||||||
|
await highlightAndExpectVisible(page, page.getByRole("dialog"));
|
||||||
|
await highlightAndExpectVisible(page, page.getByText("Von"));
|
||||||
|
await highlightAndExpectVisible(page, page.getByText("Bis"));
|
||||||
|
});
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { test } from "@playwright/test";
|
||||||
|
import { highlightAndExpectVisible } from "@playwright/utils/highlight";
|
||||||
|
|
||||||
|
test("AnalogInputsSettingsModal opens after clicking settings", async ({
|
||||||
|
page,
|
||||||
|
}) => {
|
||||||
|
await page.goto("/analogInputs");
|
||||||
|
// Wähle die erste Tabellenzeile und in der 5. Spalte (Einstellungen) den Button
|
||||||
|
const firstRow = page.locator("table tbody tr").first();
|
||||||
|
const settingsButton = firstRow.locator("td").nth(4).locator("button");
|
||||||
|
await highlightAndExpectVisible(page, settingsButton);
|
||||||
|
await settingsButton.click();
|
||||||
|
await highlightAndExpectVisible(
|
||||||
|
page,
|
||||||
|
page.getByRole("button", { name: "Modal schließen" })
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { test } from "@playwright/test";
|
||||||
|
import { highlightAndExpectVisible } from "@playwright/utils/highlight";
|
||||||
|
|
||||||
|
test("AnalogInputsTable renders rows", async ({ page }) => {
|
||||||
|
await page.goto("/analogInputs");
|
||||||
|
await highlightAndExpectVisible(page, page.getByRole("table"));
|
||||||
|
// Mindestens eine Tabellenzeile sichtbar
|
||||||
|
await highlightAndExpectVisible(page, page.locator("tbody tr").first());
|
||||||
|
});
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { test, expect } from "@playwright/test";
|
||||||
|
import { highlightAndExpectVisible } from "@playwright/utils/highlight";
|
||||||
|
|
||||||
|
test("AnalogInputsView shows heading and table", async ({ page }) => {
|
||||||
|
await page.goto("/analogInputs");
|
||||||
|
await highlightAndExpectVisible(
|
||||||
|
page,
|
||||||
|
page.getByRole("heading", { name: "Messwerteingänge" })
|
||||||
|
);
|
||||||
|
await highlightAndExpectVisible(page, page.getByRole("table"));
|
||||||
|
await expect(page.getByRole("table")).toBeVisible();
|
||||||
|
});
|
||||||
5
playwright/components/main/analogInputs/xioPMTest.ts
Normal file
5
playwright/components/main/analogInputs/xioPMTest.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { test } from "@playwright/test";
|
||||||
|
|
||||||
|
test.fixme("XioPM visual presence", async ({ page }) => {
|
||||||
|
await page.goto("/analogInputs");
|
||||||
|
});
|
||||||
6
playwright/pages/analogInputsTest.ts
Normal file
6
playwright/pages/analogInputsTest.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { test } from "@playwright/test";
|
||||||
|
import { runAnalogInputsTest } from "../tests/pages/analogInputs/analogInputsTest";
|
||||||
|
|
||||||
|
test("analog inputs page", async ({ page }) => {
|
||||||
|
await runAnalogInputsTest(page);
|
||||||
|
});
|
||||||
6
playwright/pages/dashboardTest.ts
Normal file
6
playwright/pages/dashboardTest.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { test } from "@playwright/test";
|
||||||
|
import { runDashboardTest } from "../tests/pages/dashboard/dashboardTest";
|
||||||
|
|
||||||
|
test("dashboard page", async ({ page }) => {
|
||||||
|
await runDashboardTest(page);
|
||||||
|
});
|
||||||
6
playwright/pages/digitalInputsTest.ts
Normal file
6
playwright/pages/digitalInputsTest.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { test } from "@playwright/test";
|
||||||
|
import { runDigitalInputsTest } from "../tests/pages/digitalInputs/digitalInputsTest";
|
||||||
|
|
||||||
|
test("digital inputs page", async ({ page }) => {
|
||||||
|
await runDigitalInputsTest(page);
|
||||||
|
});
|
||||||
6
playwright/pages/digitalOutputsTest.ts
Normal file
6
playwright/pages/digitalOutputsTest.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { test } from "@playwright/test";
|
||||||
|
import { runDigitalOutputsTest } from "../tests/pages/digitalOutputs/digitalOutputsTest";
|
||||||
|
|
||||||
|
test("digital outputs page", async ({ page }) => {
|
||||||
|
await runDigitalOutputsTest(page);
|
||||||
|
});
|
||||||
6
playwright/pages/einstellungenTest.ts
Normal file
6
playwright/pages/einstellungenTest.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { test } from "@playwright/test";
|
||||||
|
import { runSettingsPageTest } from "../tests/pages/settingsPage/settingsPageTest";
|
||||||
|
|
||||||
|
test("einstellungen page", async ({ page }) => {
|
||||||
|
await runSettingsPageTest(page);
|
||||||
|
});
|
||||||
5
playwright/pages/indexTest.ts
Normal file
5
playwright/pages/indexTest.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { test } from "@playwright/test";
|
||||||
|
|
||||||
|
test("index page", async ({ page }) => {
|
||||||
|
await page.goto("/");
|
||||||
|
});
|
||||||
6
playwright/pages/kabelueberwachungTest.ts
Normal file
6
playwright/pages/kabelueberwachungTest.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { test } from "@playwright/test";
|
||||||
|
import { runCableMonitoringTest } from "../tests/pages/kabelueberwachung/kabelueberwachungTest";
|
||||||
|
|
||||||
|
test("kabelueberwachung page", async ({ page }) => {
|
||||||
|
await runCableMonitoringTest(page);
|
||||||
|
});
|
||||||
6
playwright/pages/meldungenTest.ts
Normal file
6
playwright/pages/meldungenTest.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { test } from "@playwright/test";
|
||||||
|
import { runMeldungenTest } from "../tests/pages/meldungen/meldungenTest";
|
||||||
|
|
||||||
|
test("meldungen page", async ({ page }) => {
|
||||||
|
await runMeldungenTest(page);
|
||||||
|
});
|
||||||
6
playwright/pages/systemTest.ts
Normal file
6
playwright/pages/systemTest.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { test } from "@playwright/test";
|
||||||
|
import { runSystemTest } from "../tests/pages/system/systemTest";
|
||||||
|
|
||||||
|
test("system page", async ({ page }) => {
|
||||||
|
await runSystemTest(page);
|
||||||
|
});
|
||||||
5
playwright/pages/zutrittskontrolleTest.ts
Normal file
5
playwright/pages/zutrittskontrolleTest.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { test } from "@playwright/test";
|
||||||
|
|
||||||
|
test("zutrittskontrolle page", async ({ page }) => {
|
||||||
|
await page.goto("/zutrittskontrolle");
|
||||||
|
});
|
||||||
84
scripts/find-missing-playwright-tests.cjs
Normal file
84
scripts/find-missing-playwright-tests.cjs
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/*
|
||||||
|
Scan TSX sources and report missing Playwright tests following the convention:
|
||||||
|
- For file: <root>/(components|pages|...)/path/Foo.tsx
|
||||||
|
- Expect test at: playwright/<same-subtree>/path/fooTest.ts
|
||||||
|
(lowerCamel + 'Test.ts' or same baseName + 'Test.ts').
|
||||||
|
|
||||||
|
You can adjust the mapping rules below to your preference.
|
||||||
|
*/
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const projectRoot = process.cwd();
|
||||||
|
const srcRoots = ["components", "pages", "redux", "services"];
|
||||||
|
const testsRoot = path.join(projectRoot, "playwright");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map a TSX file to a desired Playwright test path.
|
||||||
|
* Current rule:
|
||||||
|
* <root>/<subdirs>/<Name>.tsx -> playwright/<root>/<subdirs>/<name>Test.ts
|
||||||
|
* where name = baseName with first letter lowercased.
|
||||||
|
*/
|
||||||
|
function mapToTest(tsxAbs) {
|
||||||
|
const rel = path.relative(projectRoot, tsxAbs).replace(/\\/g, "/");
|
||||||
|
const parts = rel.split("/");
|
||||||
|
const top = parts.shift();
|
||||||
|
if (!srcRoots.includes(top)) return null; // ignore non-mapped roots
|
||||||
|
const file = parts.pop();
|
||||||
|
if (!file) return null;
|
||||||
|
const base = file.replace(/\.tsx?$/, "");
|
||||||
|
// lowerCamel for test file base name
|
||||||
|
const lowerCamel = base.charAt(0).toLowerCase() + base.slice(1);
|
||||||
|
const testRel = path
|
||||||
|
.join("playwright", top, ...parts, `${lowerCamel}Test.ts`)
|
||||||
|
.replace(/\\/g, "/");
|
||||||
|
return path.join(projectRoot, testRel);
|
||||||
|
}
|
||||||
|
|
||||||
|
function walk(dir, files = []) {
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
||||||
|
const p = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) walk(p, files);
|
||||||
|
else files.push(p);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
const tsxFiles = [];
|
||||||
|
for (const root of srcRoots) {
|
||||||
|
const abs = path.join(projectRoot, root);
|
||||||
|
if (!fs.existsSync(abs)) continue;
|
||||||
|
tsxFiles.push(...walk(abs).filter((f) => /\.tsx$/.test(f)));
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = [];
|
||||||
|
for (const tsx of tsxFiles) {
|
||||||
|
const testPath = mapToTest(tsx);
|
||||||
|
if (!testPath) continue;
|
||||||
|
if (!fs.existsSync(testPath)) {
|
||||||
|
results.push({ tsx, testPath });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.length === 0) {
|
||||||
|
console.log(
|
||||||
|
"✅ Alle TSX-Dateien haben entsprechende Playwright-Tests nach der Konvention."
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("❌ Fehlende Playwright-Tests gefunden (Vorschlagspfade):");
|
||||||
|
for (const r of results) {
|
||||||
|
const relSrc = path.relative(projectRoot, r.tsx).replace(/\\/g, "/");
|
||||||
|
const relTest = path.relative(projectRoot, r.testPath).replace(/\\/g, "/");
|
||||||
|
console.log(`- ${relSrc} -> ${relTest}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit non-zero to make it CI-enforceable
|
||||||
|
process.exitCode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
74
scripts/find-missing-playwright-tests.mjs
Normal file
74
scripts/find-missing-playwright-tests.mjs
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
/*
|
||||||
|
Scan TSX sources and report missing Playwright tests following the convention:
|
||||||
|
- For file: <root>/(components|pages|redux|services)/path/Foo.tsx
|
||||||
|
- Expect test at: playwright/<root>/path/fooTest.ts
|
||||||
|
|
||||||
|
Adjust srcRoots to your needs.
|
||||||
|
*/
|
||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
const projectRoot = process.cwd();
|
||||||
|
const srcRoots = ["components", "pages", "redux", "services"];
|
||||||
|
|
||||||
|
function mapToTest(tsxAbs) {
|
||||||
|
const rel = path.relative(projectRoot, tsxAbs).replace(/\\/g, "/");
|
||||||
|
const parts = rel.split("/");
|
||||||
|
const top = parts.shift();
|
||||||
|
if (!srcRoots.includes(top)) return null;
|
||||||
|
const file = parts.pop();
|
||||||
|
if (!file) return null;
|
||||||
|
const base = file.replace(/\.tsx?$/, "");
|
||||||
|
const lowerCamel = base.charAt(0).toLowerCase() + base.slice(1);
|
||||||
|
const testRel = path
|
||||||
|
.join("playwright", top, ...parts, `${lowerCamel}Test.ts`)
|
||||||
|
.replace(/\\/g, "/");
|
||||||
|
return path.join(projectRoot, testRel);
|
||||||
|
}
|
||||||
|
|
||||||
|
function walk(dir, files = []) {
|
||||||
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
||||||
|
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
||||||
|
const p = path.join(dir, entry.name);
|
||||||
|
if (entry.isDirectory()) walk(p, files);
|
||||||
|
else files.push(p);
|
||||||
|
}
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
const tsxFiles = [];
|
||||||
|
for (const root of srcRoots) {
|
||||||
|
const abs = path.join(projectRoot, root);
|
||||||
|
if (!fs.existsSync(abs)) continue;
|
||||||
|
tsxFiles.push(...walk(abs).filter((f) => /\.tsx$/.test(f)));
|
||||||
|
}
|
||||||
|
|
||||||
|
const results = [];
|
||||||
|
for (const tsx of tsxFiles) {
|
||||||
|
const testPath = mapToTest(tsx);
|
||||||
|
if (!testPath) continue;
|
||||||
|
if (!fs.existsSync(testPath)) {
|
||||||
|
results.push({ tsx, testPath });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.length === 0) {
|
||||||
|
console.log(
|
||||||
|
"✅ Alle TSX-Dateien haben entsprechende Playwright-Tests nach der Konvention."
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("❌ Fehlende Playwright-Tests gefunden (Vorschlagspfade):");
|
||||||
|
for (const r of results) {
|
||||||
|
const relSrc = path.relative(projectRoot, r.tsx).replace(/\\/g, "/");
|
||||||
|
const relTest = path.relative(projectRoot, r.testPath).replace(/\\/g, "/");
|
||||||
|
console.log(`- ${relSrc} -> ${relTest}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
process.exitCode = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
Reference in New Issue
Block a user