chore: alle Panels zu den selben Position bringen
This commit is contained in:
@@ -23,4 +23,4 @@ NEXT_PUBLIC_USE_MOCKS=true
|
|||||||
# z.B. http://10.10.0.13/xyz/index.aspx -> basePath in config.json auf /xyz setzen
|
# z.B. http://10.10.0.13/xyz/index.aspx -> basePath in config.json auf /xyz setzen
|
||||||
# basePath wird jetzt in public/config.json gepflegt
|
# basePath wird jetzt in public/config.json gepflegt
|
||||||
# App-Versionsnummer
|
# App-Versionsnummer
|
||||||
NEXT_PUBLIC_APP_VERSION=1.1.367
|
NEXT_PUBLIC_APP_VERSION=1.1.368
|
||||||
|
|||||||
@@ -24,4 +24,4 @@ NEXT_PUBLIC_USE_MOCKS=false
|
|||||||
# basePath wird jetzt in public/config.json gepflegt
|
# basePath wird jetzt in public/config.json gepflegt
|
||||||
|
|
||||||
# App-Versionsnummer
|
# App-Versionsnummer
|
||||||
NEXT_PUBLIC_APP_VERSION=1.1.367
|
NEXT_PUBLIC_APP_VERSION=1.1.368
|
||||||
|
|||||||
@@ -165,7 +165,14 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
|||||||
const [showVersionInfoModal, setShowVersionInfoModal] = useState(false);
|
const [showVersionInfoModal, setShowVersionInfoModal] = useState(false);
|
||||||
const [poiTypMap, setPoiTypMap] = useState(new Map());
|
const [poiTypMap, setPoiTypMap] = useState(new Map());
|
||||||
const [showPopup, setShowPopup] = useState(false);
|
const [showPopup, setShowPopup] = useState(false);
|
||||||
const [showAreaDropdown, setShowAreaDropdown] = useState(false);
|
const [showAreaDropdown, setShowAreaDropdown] = useState(() => {
|
||||||
|
try {
|
||||||
|
const v = localStorage.getItem("showAreaDropdown");
|
||||||
|
return v === null ? false : v === "true";
|
||||||
|
} catch (_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
const poiLayerRef = useRef(null); // Referenz auf die Layer-Gruppe für Datenbank-Marker
|
const poiLayerRef = useRef(null); // Referenz auf die Layer-Gruppe für Datenbank-Marker
|
||||||
const mapRef = useRef(null); // Referenz auf das DIV-Element der Karte
|
const mapRef = useRef(null); // Referenz auf das DIV-Element der Karte
|
||||||
const [map, setMap] = useState(null); // Zustand der Karteninstanz
|
const [map, setMap] = useState(null); // Zustand der Karteninstanz
|
||||||
@@ -199,6 +206,29 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Zentrale Steuerung: Nur ein Overlay gleichzeitig
|
||||||
|
// Mögliche Werte: null | 'area' | 'layers' | 'coord' | 'info'
|
||||||
|
const [overlay, setOverlay] = useState(null);
|
||||||
|
|
||||||
|
// Initiale Bestimmung des aktiven Overlays basierend auf bestehenden Flags
|
||||||
|
useEffect(() => {
|
||||||
|
if (showAreaDropdown) setOverlay("area");
|
||||||
|
else if (showLayersPanel) setOverlay("layers");
|
||||||
|
else if (showCoordinateInput) setOverlay("coord");
|
||||||
|
else if (showAppInfoCard) setOverlay("info");
|
||||||
|
else setOverlay(null);
|
||||||
|
// nur beim Mount ausführen
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Flags mit Overlay-State synchronisieren (persistiert weiterhin in bestehenden Effects)
|
||||||
|
useEffect(() => {
|
||||||
|
setShowAreaDropdown(overlay === "area");
|
||||||
|
setShowLayersPanel(overlay === "layers");
|
||||||
|
setShowCoordinateInput(overlay === "coord");
|
||||||
|
setShowAppInfoCard(overlay === "info");
|
||||||
|
}, [overlay]);
|
||||||
|
|
||||||
// Flag, ob Nutzer die Polyline-Checkbox manuell betätigt hat
|
// Flag, ob Nutzer die Polyline-Checkbox manuell betätigt hat
|
||||||
// Nutzer-Flag global auf window, damit auch Redux darauf zugreifen kann
|
// Nutzer-Flag global auf window, damit auch Redux darauf zugreifen kann
|
||||||
if (typeof window !== "undefined" && window.userToggledPolyline === undefined) {
|
if (typeof window !== "undefined" && window.userToggledPolyline === undefined) {
|
||||||
@@ -270,6 +300,12 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
|||||||
localStorage.setItem("showAppInfoCard", String(showAppInfoCard));
|
localStorage.setItem("showAppInfoCard", String(showAppInfoCard));
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}, [showAppInfoCard]);
|
}, [showAppInfoCard]);
|
||||||
|
// Persistiere Sichtbarkeit des Area-Dropdowns (Marker-Overlay)
|
||||||
|
useEffect(() => {
|
||||||
|
try {
|
||||||
|
localStorage.setItem("showAreaDropdown", String(showAreaDropdown));
|
||||||
|
} catch (_) {}
|
||||||
|
}, [showAreaDropdown]);
|
||||||
// Persistiere Sichtbarkeit des Layer-Panels
|
// Persistiere Sichtbarkeit des Layer-Panels
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
try {
|
try {
|
||||||
@@ -1160,23 +1196,17 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
|||||||
)}
|
)}
|
||||||
{/* Marker-Icon (line-md) */}
|
{/* Marker-Icon (line-md) */}
|
||||||
<button
|
<button
|
||||||
onClick={() =>
|
onClick={() => setOverlay(prev => (prev === "area" ? null : "area"))}
|
||||||
setShowAreaDropdown(v => {
|
|
||||||
const next = !v;
|
|
||||||
if (next) setShowLayersPanel(false); // Dropdown öffnen -> Panel schließen
|
|
||||||
return next;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
aria-label="Marker"
|
aria-label="Marker"
|
||||||
className="rounded-full bg-white/90 hover:bg-white shadow p-1"
|
className="rounded-full bg-white/90 hover:bg-white shadow p-1"
|
||||||
title="Marker"
|
title="Marker"
|
||||||
>
|
>
|
||||||
<MapMarkerIcon className="h-8 w-8" />
|
<MapMarkerIcon className="h-8 w-8" />
|
||||||
</button>
|
</button>
|
||||||
{showAreaDropdown && <AreaDropdown onClose={() => setShowAreaDropdown(false)} />}
|
{overlay === "area" && <AreaDropdown onClose={() => setOverlay(null)} />}
|
||||||
{/*Lupe: Koordinatensuche ein-/ausblenden */}
|
{/*Lupe: Koordinatensuche ein-/ausblenden */}
|
||||||
<button
|
<button
|
||||||
onClick={() => setShowCoordinateInput(v => !v)}
|
onClick={() => setOverlay(prev => (prev === "coord" ? null : "coord"))}
|
||||||
aria-label={
|
aria-label={
|
||||||
showCoordinateInput ? "Koordinatensuche ausblenden" : "Koordinatensuche einblenden"
|
showCoordinateInput ? "Koordinatensuche ausblenden" : "Koordinatensuche einblenden"
|
||||||
}
|
}
|
||||||
@@ -1217,13 +1247,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
|||||||
</button>
|
</button>
|
||||||
{/* Lupe: Koordinaten-Suche ein-/ausblenden */}
|
{/* Lupe: Koordinaten-Suche ein-/ausblenden */}
|
||||||
<button
|
<button
|
||||||
onClick={() =>
|
onClick={() => setOverlay(prev => (prev === "layers" ? null : "layers"))}
|
||||||
setShowLayersPanel(v => {
|
|
||||||
const next = !v;
|
|
||||||
if (next) setShowAreaDropdown(false); // Panel öffnen -> Dropdown schließen
|
|
||||||
return next;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
aria-label={showLayersPanel ? "Layer-Panel ausblenden" : "Layer-Panel einblenden"}
|
aria-label={showLayersPanel ? "Layer-Panel ausblenden" : "Layer-Panel einblenden"}
|
||||||
className="rounded-full bg-white/90 hover:bg-white shadow p-1"
|
className="rounded-full bg-white/90 hover:bg-white shadow p-1"
|
||||||
title={showLayersPanel ? "Layer-Panel ausblenden" : "Layer-Panel einblenden"}
|
title={showLayersPanel ? "Layer-Panel ausblenden" : "Layer-Panel einblenden"}
|
||||||
@@ -1232,7 +1256,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={() => setShowAppInfoCard(v => !v)}
|
onClick={() => setOverlay(prev => (prev === "info" ? null : "info"))}
|
||||||
aria-label={showAppInfoCard ? "Info ausblenden" : "Info einblenden"}
|
aria-label={showAppInfoCard ? "Info ausblenden" : "Info einblenden"}
|
||||||
className="rounded-full bg-white/90 hover:bg-white shadow p-1"
|
className="rounded-full bg-white/90 hover:bg-white shadow p-1"
|
||||||
title={showAppInfoCard ? "Info ausblenden" : "Info einblenden"}
|
title={showAppInfoCard ? "Info ausblenden" : "Info einblenden"}
|
||||||
@@ -1247,7 +1271,7 @@ const MapComponent = ({ locations, onLocationUpdate, lineCoordinates }) => {
|
|||||||
<CoordinatePopup isOpen={isPopupOpen} coordinates={currentCoordinates} onClose={closePopup} />
|
<CoordinatePopup isOpen={isPopupOpen} coordinates={currentCoordinates} onClose={closePopup} />
|
||||||
|
|
||||||
{showAppInfoCard && (
|
{showAppInfoCard && (
|
||||||
<div className="absolute bottom-3 left-3 w-72 p-4 bg-white rounded-lg shadow-md z-50">
|
<div className="absolute top-16 right-3 w-72 p-4 bg-white rounded-lg shadow-md z-50">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<div>
|
<div>
|
||||||
<span className="text-black text-lg font-semibold"> TALAS.Map </span>
|
<span className="text-black text-lg font-semibold"> TALAS.Map </span>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ const CoordinateInput = ({ onCoordinatesSubmit }) => {
|
|||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
className="fixed top-5 left-5 z-50 bg-white shadow-lg rounded-lg p-4 w-72"
|
className="absolute top-16 right-3 z-50 bg-white rounded-lg shadow-md p-4 w-72"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "nodemap",
|
"name": "nodemap",
|
||||||
"version": "1.1.367",
|
"version": "1.1.368",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "nodemap",
|
"name": "nodemap",
|
||||||
"version": "1.1.367",
|
"version": "1.1.368",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.13.3",
|
"@emotion/react": "^11.13.3",
|
||||||
"@emotion/styled": "^11.13.0",
|
"@emotion/styled": "^11.13.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "nodemap",
|
"name": "nodemap",
|
||||||
"version": "1.1.367",
|
"version": "1.1.368",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.13.3",
|
"@emotion/react": "^11.13.3",
|
||||||
"@emotion/styled": "^11.13.0",
|
"@emotion/styled": "^11.13.0",
|
||||||
@@ -45,6 +45,8 @@
|
|||||||
"start": "cross-env NODE_ENV=production node server.js",
|
"start": "cross-env NODE_ENV=production node server.js",
|
||||||
"export": "next export",
|
"export": "next export",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
|
"test:e2e": "playwright test",
|
||||||
|
"test:e2e:ui": "playwright test --ui",
|
||||||
"prepare": "husky",
|
"prepare": "husky",
|
||||||
"bump-version": "node ./scripts/bumpVersion.js"
|
"bump-version": "node ./scripts/bumpVersion.js"
|
||||||
},
|
},
|
||||||
|
|||||||
33
playwright.config.js
Normal file
33
playwright.config.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
// Playwright test configuration for the NodeMap project
|
||||||
|
// Starts the local Next.js custom server (server.js) and runs tests against http://localhost:3000
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
const { defineConfig, devices } = require("@playwright/test");
|
||||||
|
|
||||||
|
module.exports = defineConfig({
|
||||||
|
testDir: "./playwright/tests",
|
||||||
|
timeout: 60_000,
|
||||||
|
expect: { timeout: 10_000 },
|
||||||
|
fullyParallel: true,
|
||||||
|
retries: process.env.CI ? 2 : 0,
|
||||||
|
reporter: [["list"], ["junit", { outputFile: "reports/junit/playwright.xml" }]],
|
||||||
|
use: {
|
||||||
|
baseURL: "http://localhost:3000",
|
||||||
|
trace: "on-first-retry",
|
||||||
|
video: "retain-on-failure",
|
||||||
|
screenshot: "only-on-failure",
|
||||||
|
headless: true,
|
||||||
|
},
|
||||||
|
projects: [
|
||||||
|
{
|
||||||
|
name: "chromium",
|
||||||
|
use: { ...devices["Desktop Chrome"] },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
webServer: {
|
||||||
|
command: "node server.js",
|
||||||
|
port: 3000,
|
||||||
|
reuseExistingServer: !process.env.CI,
|
||||||
|
timeout: 120_000,
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
// example.spec.js
|
|
||||||
const { test, expect } = require("@playwright/test");
|
|
||||||
|
|
||||||
test("simple test", async ({ page }) => {
|
|
||||||
await page.goto("https://playwright.dev");
|
|
||||||
await expect(page).toHaveTitle(/Playwright/);
|
|
||||||
});
|
|
||||||
129
playwright/tests/mapcomponent.spec.js
Normal file
129
playwright/tests/mapcomponent.spec.js
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
import { test, expect } from "@playwright/test";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper: Pan the Leaflet map by simulating a mouse drag and wait until
|
||||||
|
* mapCenter in localStorage changes (MapComponent persists center on move/zoom).
|
||||||
|
*
|
||||||
|
* Note for codegen: The recorder oft erfasst Klicks statt Drag. Ersetze
|
||||||
|
* die aufgenommenen Klicks nachträglich durch diesen Helper für verlässliches Panning.
|
||||||
|
*/
|
||||||
|
async function panMap(page, deltaY = -200) {
|
||||||
|
const map = page.locator("#map");
|
||||||
|
await map.waitFor({ state: "visible" });
|
||||||
|
// Wait until Leaflet initializes the container class
|
||||||
|
await page.locator("#map.leaflet-container").waitFor({ state: "visible", timeout: 20_000 });
|
||||||
|
|
||||||
|
const centerBefore = await page.evaluate(() => {
|
||||||
|
try {
|
||||||
|
const v = localStorage.getItem("mapCenter");
|
||||||
|
return v ? JSON.parse(v) : null;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const box = await map.boundingBox();
|
||||||
|
if (!box) throw new Error("Map bounding box not found");
|
||||||
|
const startX = box.x + box.width / 2;
|
||||||
|
const startY = box.y + box.height / 2;
|
||||||
|
|
||||||
|
await page.mouse.move(startX, startY);
|
||||||
|
await page.mouse.down();
|
||||||
|
await page.mouse.move(startX, startY + deltaY, { steps: 12 });
|
||||||
|
await page.mouse.up();
|
||||||
|
|
||||||
|
await page.waitForFunction(
|
||||||
|
prev => {
|
||||||
|
try {
|
||||||
|
const v = localStorage.getItem("mapCenter");
|
||||||
|
if (!v) return false;
|
||||||
|
if (!prev) return true; // previously null -> now set
|
||||||
|
const c = JSON.parse(v);
|
||||||
|
const dLat = Math.abs(c[0] - prev[0]);
|
||||||
|
const dLng = Math.abs(c[1] - prev[1]);
|
||||||
|
return dLat > 0.0005 || dLng > 0.0005;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
centerBefore,
|
||||||
|
{ timeout: 15_000 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
test("MapComponent", async ({ page }) => {
|
||||||
|
await page.goto("http://localhost:3000/?m=12&u=484");
|
||||||
|
// 10 Sekunden warten, bis die Karte sichtbar ist
|
||||||
|
await page.locator("#map").waitFor({ state: "visible", timeout: 10_000 });
|
||||||
|
// Set your keys before the page loads (from your screenshot)
|
||||||
|
await page.addInitScript(() => {
|
||||||
|
localStorage.setItem("editMode", "false");
|
||||||
|
localStorage.setItem("polylineVisible_m12_u484", "true");
|
||||||
|
localStorage.setItem("currentMapId", "12");
|
||||||
|
localStorage.setItem("currentUserId", "484");
|
||||||
|
localStorage.setItem("mapZoom", "13");
|
||||||
|
localStorage.setItem("kabelstreckenVisible", "false"); // legacy, not used for init
|
||||||
|
localStorage.setItem("showBaseMapPanel", "false");
|
||||||
|
localStorage.setItem("mapLayersVisibility_m12_u484", {
|
||||||
|
"system-1": true,
|
||||||
|
"system-2": false,
|
||||||
|
"system-3": false,
|
||||||
|
"system-5": false,
|
||||||
|
"system-6": false,
|
||||||
|
"system-7": false,
|
||||||
|
"system-8": false,
|
||||||
|
"system-9": false,
|
||||||
|
"system-10": false,
|
||||||
|
"system-11": false,
|
||||||
|
"system-13": false,
|
||||||
|
"system-30": false,
|
||||||
|
"system-100": false,
|
||||||
|
"system-110": false,
|
||||||
|
"system-111": false,
|
||||||
|
"system-200": false,
|
||||||
|
});
|
||||||
|
localStorage.setItem("mapCenter", [53.23938294961826, 8.21434020996094]);
|
||||||
|
localStorage.setItem("markerLink", "undefined");
|
||||||
|
localStorage.setItem("lastElementType", "marker");
|
||||||
|
localStorage.setItem("polylineVisible", "false"); // global legacy
|
||||||
|
localStorage.setItem("showAppInfoCard", "false");
|
||||||
|
localStorage.setItem("showCoordinateInput", "false");
|
||||||
|
localStorage.setItem("showLayersPanel", "false");
|
||||||
|
});
|
||||||
|
|
||||||
|
// test steps
|
||||||
|
await expect(
|
||||||
|
page.locator("div").filter({ hasText: "TALASKabelstreckenULAFGSM" }).nth(3)
|
||||||
|
).toBeVisible();
|
||||||
|
await page.getByRole("button", { name: "Layer-Panel ausblenden" }).click();
|
||||||
|
await page.getByRole("button", { name: "Layer-Panel einblenden" }).click();
|
||||||
|
await expect(
|
||||||
|
page.locator("div").filter({ hasText: "TALASKabelstreckenULAFGSM" }).nth(3)
|
||||||
|
).toBeVisible();
|
||||||
|
await page.getByRole("button", { name: "Layer-Panel ausblenden" }).click();
|
||||||
|
await expect(page.getByRole("button", { name: "Info ausblenden" })).toBeVisible();
|
||||||
|
await page.getByRole("button", { name: "Info ausblenden" }).click();
|
||||||
|
await page.getByRole("button", { name: "Info einblenden" }).click();
|
||||||
|
await expect(page.locator("div").filter({ hasText: "TALAS.Map Version" }).nth(3)).toBeVisible();
|
||||||
|
await page.getByRole("button", { name: "Info ausblenden" }).click();
|
||||||
|
// Warten, bis der Button-Text wechselt, bevor erneut geklickt wird
|
||||||
|
await expect(page.getByRole("button", { name: "Info einblenden" })).toBeVisible({
|
||||||
|
timeout: 10000,
|
||||||
|
});
|
||||||
|
await page.getByRole("button", { name: "Info einblenden" }).click();
|
||||||
|
await expect(page.locator("div").filter({ hasText: "TALAS.Map Version" }).nth(3)).toBeVisible();
|
||||||
|
await page.getByRole("button", { name: "Koordinatensuche einblenden" }).click();
|
||||||
|
await expect(page.locator("form")).toBeVisible();
|
||||||
|
await page.getByRole("button", { name: "Koordinatensuche ausblenden" }).click();
|
||||||
|
await page.getByRole("button", { name: "Info ausblenden" }).click();
|
||||||
|
await page.getByLabel("Marker").click();
|
||||||
|
await expect(page.getByText("Station wählenBitte wählen…")).toBeVisible();
|
||||||
|
await page.getByRole("combobox").selectOption("50977");
|
||||||
|
await page.getByLabel("Marker").click();
|
||||||
|
await page.getByRole("combobox").selectOption("50986");
|
||||||
|
await page.getByLabel("Marker").click();
|
||||||
|
await page.getByLabel("Marker").click();
|
||||||
|
await page.getByLabel("Marker").click();
|
||||||
|
await page.getByRole("combobox").selectOption("50977");
|
||||||
|
await page.getByRole("button", { name: "Karte auf Standardansicht" }).click();
|
||||||
|
});
|
||||||
@@ -5,77 +5,7 @@
|
|||||||
"zoomOutCenter: Zielkoordinaten für Herauszoomen (lat, lng)",
|
"zoomOutCenter: Zielkoordinaten für Herauszoomen (lat, lng)",
|
||||||
"minZoom/maxZoom: erlaubte Zoomstufen pro Quelle"
|
"minZoom/maxZoom: erlaubte Zoomstufen pro Quelle"
|
||||||
],
|
],
|
||||||
"tileSources": {
|
|
||||||
"local": {
|
|
||||||
"url": "http://localhost/talas5/TileMap/mapTiles/{z}/{x}/{y}.png",
|
|
||||||
"_comment": "Offline-Kartenquelle (lokal)",
|
|
||||||
"minZoom": 5,
|
|
||||||
"maxZoom": 15
|
|
||||||
},
|
|
||||||
"osm": {
|
|
||||||
"url": "/tiles/{z}/{x}/{y}.png",
|
|
||||||
"_comment": "OpenStreetMap Online-Kartenquelle über Server-Proxy (relativ)",
|
|
||||||
"minZoom": 0,
|
|
||||||
"maxZoom": 19
|
|
||||||
},
|
|
||||||
"osm-standard": {
|
|
||||||
"name": "Standard",
|
|
||||||
"url": "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
||||||
"attribution": "© OpenStreetMap contributors",
|
|
||||||
"subdomains": "abc",
|
|
||||||
"minZoom": 0,
|
|
||||||
"maxZoom": 19
|
|
||||||
},
|
|
||||||
"osm-humanitarian": {
|
|
||||||
"name": "Humanitarian",
|
|
||||||
"url": "https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png",
|
|
||||||
"attribution": "© OpenStreetMap contributors, Humanitarian OpenStreetMap Team",
|
|
||||||
"subdomains": "abc",
|
|
||||||
"minZoom": 0,
|
|
||||||
"maxZoom": 19
|
|
||||||
},
|
|
||||||
"cyclosm": {
|
|
||||||
"name": "CyclOSM",
|
|
||||||
"url": "https://{s}.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png",
|
|
||||||
"attribution": "© OpenStreetMap contributors, CyclOSM",
|
|
||||||
"subdomains": "abc",
|
|
||||||
"minZoom": 0,
|
|
||||||
"maxZoom": 20
|
|
||||||
},
|
|
||||||
"carto-light": {
|
|
||||||
"name": "Carto Light",
|
|
||||||
"url": "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",
|
|
||||||
"attribution": "© OpenStreetMap contributors, © CARTO",
|
|
||||||
"subdomains": "abcd",
|
|
||||||
"minZoom": 0,
|
|
||||||
"maxZoom": 20
|
|
||||||
},
|
|
||||||
"thunderforest-cycle": {
|
|
||||||
"name": "Cycle Map (Thunderforest)",
|
|
||||||
"url": "https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=YOUR_THUNDERFOREST_API_KEY",
|
|
||||||
"attribution": "© OpenStreetMap contributors, © Thunderforest",
|
|
||||||
"subdomains": "abc",
|
|
||||||
"minZoom": 0,
|
|
||||||
"maxZoom": 22
|
|
||||||
},
|
|
||||||
"thunderforest-transport": {
|
|
||||||
"name": "Transport Map (Thunderforest)",
|
|
||||||
"url": "https://{s}.tile.thunderforest.com/transport/{z}/{x}/{y}.png?apikey=YOUR_THUNDERFOREST_API_KEY",
|
|
||||||
"attribution": "© OpenStreetMap contributors, © Thunderforest",
|
|
||||||
"subdomains": "abc",
|
|
||||||
"minZoom": 0,
|
|
||||||
"maxZoom": 22
|
|
||||||
},
|
|
||||||
"tracestrack-topo": {
|
|
||||||
"name": "Tracestrack Topo",
|
|
||||||
"url": "https://tile.tracestrack.com/topo__/{z}/{x}/{y}.webp?key=YOUR_TRACESTRACK_KEY",
|
|
||||||
"attribution": "© OpenStreetMap contributors, © Tracestrack",
|
|
||||||
"minZoom": 0,
|
|
||||||
"maxZoom": 19
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"active": "osm",
|
|
||||||
"_comment_active": "Aktive Kartenquelle: 'local' oder 'osm'",
|
|
||||||
"center": [53.111111, 8.4625],
|
"center": [53.111111, 8.4625],
|
||||||
"_comment_center": "Startmittelpunkt der Karte (lat, lng)",
|
"_comment_center": "Startmittelpunkt der Karte (lat, lng)",
|
||||||
|
|
||||||
|
|||||||
11
reports/junit/playwright.xml
Normal file
11
reports/junit/playwright.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<testsuites id="" name="" tests="1" failures="0" skipped="0" errors="0" time="10.898770000000018">
|
||||||
|
<testsuite name="mapcomponent.spec.js" timestamp="2025-09-16T08:19:23.460Z" hostname="chromium" tests="1" failures="0" skipped="0" time="7.415" errors="0">
|
||||||
|
<testcase name="MapComponent" classname="mapcomponent.spec.js" time="7.415">
|
||||||
|
<system-out>
|
||||||
|
<![CDATA[
|
||||||
|
[[ATTACHMENT|..\..\test-results\mapcomponent-MapComponent-chromium\trace.zip]]
|
||||||
|
]]>
|
||||||
|
</system-out>
|
||||||
|
</testcase>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"status": "passed",
|
|
||||||
"failedTests": []
|
|
||||||
}
|
|
||||||
BIN
test-results/mapcomponent-MapComponent-chromium/trace.zip
Normal file
BIN
test-results/mapcomponent-MapComponent-chromium/trace.zip
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
test-results/mapcomponent-test-chromium/trace.zip
Normal file
BIN
test-results/mapcomponent-test-chromium/trace.zip
Normal file
Binary file not shown.
Reference in New Issue
Block a user