import { expect, test } from "@playwright/test"; test("docks the route planner beside the map and releases the full map when collapsed", async ({ page }) => { await page.goto("/"); const routePanel = page.getByRole("complementary", { name: "Routenplanung" }); const map = page.getByTestId("map-container"); const status = page.getByLabel("Navigationsstatus"); await expect(routePanel).toBeVisible(); await expect.poll(async () => (await map.boundingBox())?.x).toBe(400); const dockedPanelBox = await routePanel.boundingBox(); const dockedMapBox = await map.boundingBox(); const statusBox = await status.boundingBox(); expect(dockedPanelBox).not.toBeNull(); expect(dockedMapBox).not.toBeNull(); expect(statusBox).not.toBeNull(); expect(dockedPanelBox!.x).toBe(0); expect(dockedPanelBox!.width).toBe(400); expect(dockedPanelBox!.x + dockedPanelBox!.width).toBeLessThanOrEqual(dockedMapBox!.x); expect(dockedPanelBox!.y + dockedPanelBox!.height).toBeLessThanOrEqual(statusBox!.y + 1); await routePanel.getByRole("button", { name: "Routenfenster ausblenden" }).click(); await expect(routePanel).toBeHidden(); await expect.poll(async () => (await map.boundingBox())?.x).toBe(0); await expect.poll(async () => { return page.locator(".maplibregl-canvas").evaluate((node) => { const canvas = node as HTMLCanvasElement; return Math.abs(canvas.width / window.devicePixelRatio - canvas.clientWidth); }); }).toBeLessThan(2); await page.getByRole("button", { name: "Routenfenster einblenden" }).click(); await expect.poll(async () => (await map.boundingBox())?.x).toBe(400); }); test("switches from floating tablet panel to docked desktop sidebar at 1100 pixels", async ({ page }) => { await page.goto("/"); const routePanel = page.getByRole("complementary", { name: "Routenplanung" }); const map = page.getByTestId("map-container"); await page.setViewportSize({ width: 1099, height: 900 }); await expect.poll(async () => (await map.boundingBox())?.x).toBe(0); const floatingPanelBox = await routePanel.boundingBox(); expect(floatingPanelBox?.x).toBe(10); expect(floatingPanelBox?.width).toBe(360); await page.setViewportSize({ width: 1100, height: 900 }); await expect.poll(async () => (await map.boundingBox())?.x).toBe(400); const dockedPanelBox = await routePanel.boundingBox(); expect(dockedPanelBox?.x).toBe(0); expect(dockedPanelBox?.width).toBe(400); }); test("shows marine contact details as a right-hand desktop drawer", async ({ page, context }) => { await context.grantPermissions(["geolocation"]); await context.setGeolocation({ latitude: 54.18, longitude: 12.09 }); const requestedFeatureLayers: string[][] = []; await page.route("**/api/features**", async (route) => { const requestedLayers = new URL(route.request().url()).searchParams.get("layers")?.split(",") ?? []; requestedFeatureLayers.push(requestedLayers); await route.fulfill({ status: 200, contentType: "application/json", body: JSON.stringify({ type: "FeatureCollection", features: requestedLayers.includes("harbours") ? [ { type: "Feature", id: "e2e-test-harbour", geometry: { type: "Point", coordinates: [12.09, 54.18] }, properties: { layer: "harbours", name: "Testhafen Rostock", phone: "+49 381 123456", website: "https://example.com", vhf: "Kanal 12", source: "E2E" } } ] : [] }) }); }); await page.goto("/"); await expect(page.locator(".data-badge")).toHaveAttribute("data-ready", "true"); await page.getByRole("button", { name: "GPS starten" }).click(); await page.getByRole("button", { name: "Position zentrieren" }).click(); await expect.poll(() => requestedFeatureLayers.flat().sort().join(",")).toContain("harbours"); const featureButton = page.getByRole("button", { name: "Informationen zu Hafen Testhafen Rostock", includeHidden: true }); await expect(featureButton).toBeAttached({ timeout: 10_000 }); await featureButton.focus(); await featureButton.press("Enter"); const drawer = page.getByRole("dialog", { name: "Testhafen Rostock" }); await expect(drawer).toBeVisible(); await expect(drawer.getByRole("link", { name: /Testhafen Rostock anrufen/ })).toBeVisible(); const drawerBox = await drawer.boundingBox(); const statusBox = await page.getByLabel("Navigationsstatus").boundingBox(); expect(drawerBox).not.toBeNull(); expect(statusBox).not.toBeNull(); expect(drawerBox!.x + drawerBox!.width).toBeGreaterThanOrEqual(1426); expect(drawerBox!.y).toBeGreaterThanOrEqual(62); expect(drawerBox!.y + drawerBox!.height).toBeLessThanOrEqual(statusBox!.y); await page.keyboard.press("Escape"); await expect(drawer).toBeHidden(); await expect(featureButton).toBeFocused(); });