import { test, expect } from '@playwright/test'; test.describe('Sites Map', () => { test('can access sites map', async ({ page }) => { await page.goto('/sites-map'); await expect(page).toHaveURL(/\/sites-map/); await expect(page.locator('body')).toBeVisible(); }); test('shows geographic map', async ({ page }) => { await page.goto('/sites-map'); // Look for map container const mapContainer = page.locator( '[id*="map"], .leaflet-container, [class*="map"], canvas' ).first(); if (await mapContainer.isVisible({ timeout: 3000 }).catch(() => false)) { await expect(mapContainer).toBeVisible(); } }); test('shows site markers on map', async ({ page }) => { await page.goto('/sites-map'); // Look for map markers const marker = page.locator( '[data-marker], .leaflet-marker-icon, [class*="marker"], circle, path' ).first(); if (await marker.isVisible({ timeout: 3000 }).catch(() => false)) { await expect(marker).toBeVisible(); } }); test('can zoom in/out on map', async ({ page }) => { await page.goto('/sites-map'); // Look for zoom controls const zoomIn = page.locator( 'button[aria-label*="Zoom in"], .leaflet-control-zoom-in, button:has-text("+")' ).first(); if (await zoomIn.isVisible({ timeout: 2000 }).catch(() => false)) { await zoomIn.click(); await page.waitForTimeout(300); } }); test('can click on site marker', async ({ page }) => { await page.goto('/sites-map'); // Look for clickable markers const marker = page.locator( '[data-marker], .leaflet-marker-icon, circle, path' ).first(); if (await marker.isVisible({ timeout: 3000 }).catch(() => false)) { await marker.click(); await page.waitForTimeout(500); // Should show popup or tooltip const popup = page.locator( '.leaflet-popup, [role="tooltip"], [data-popup]' ).first(); if (await popup.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(popup).toBeVisible(); } } }); test('shows site details in popup', async ({ page }) => { await page.goto('/sites-map'); const marker = page.locator( '[data-marker], .leaflet-marker-icon, circle, path' ).first(); if (await marker.isVisible({ timeout: 3000 }).catch(() => false)) { await marker.click(); await page.waitForTimeout(500); // Look for site information const siteInfo = page.locator( ':has-text("Site"), :has-text("Devices"), a[href*="/sites/"]' ).first(); if (await siteInfo.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(siteInfo).toBeVisible(); } } }); test('can filter sites on map', async ({ page }) => { await page.goto('/sites-map'); // Look for filter controls const filterControl = page.locator( 'select, button:has-text("Filter"), input[type="search"]' ).first(); if (await filterControl.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(filterControl).toBeVisible(); } }); test('can pan around map', async ({ page }) => { await page.goto('/sites-map'); const mapContainer = page.locator( '[id*="map"], .leaflet-container, [class*="map"]' ).first(); if (await mapContainer.isVisible({ timeout: 3000 }).catch(() => false)) { // Map should be interactive (can't fully test panning without mouse events) await expect(mapContainer).toBeVisible(); } }); test('shows map legend', async ({ page }) => { await page.goto('/sites-map'); // Look for map legend const legend = page.locator( '.legend, [data-legend], :has-text("Online"), :has-text("Offline")' ).first(); if (await legend.isVisible({ timeout: 2000 }).catch(() => false)) { await expect(legend).toBeVisible(); } }); });