105 lines
3.2 KiB
JavaScript
105 lines
3.2 KiB
JavaScript
import { test, expect } from '@playwright/test';
|
|
|
|
// MapLibre GL requires WebGL which isn't available in headless Chromium.
|
|
// Intercept the module request and return a lightweight mock so React can render.
|
|
const MAPLIBRE_MOCK = `
|
|
class Map {
|
|
constructor(opts) {
|
|
this._listeners = {};
|
|
Promise.resolve().then(() => this._emit('style.load'));
|
|
}
|
|
_emit(event) {
|
|
(this._listeners[event] || []).forEach(fn => fn());
|
|
}
|
|
on(event, fn) {
|
|
if (!this._listeners[event]) this._listeners[event] = [];
|
|
this._listeners[event].push(fn);
|
|
return this;
|
|
}
|
|
off(event, fn) {
|
|
this._listeners[event] = (this._listeners[event] || []).filter(l => l !== fn);
|
|
return this;
|
|
}
|
|
remove() {}
|
|
getSource() { return null; }
|
|
getLayer() { return null; }
|
|
addSource() {}
|
|
addLayer() {}
|
|
removeLayer() {}
|
|
removeSource() {}
|
|
setSky() {}
|
|
setTerrain() {}
|
|
setLayoutProperty() {}
|
|
flyTo() {}
|
|
jumpTo() {}
|
|
setStyle() { Promise.resolve().then(() => this._emit('style.load')); }
|
|
getCanvas() { return document.createElement('canvas'); }
|
|
project() { return { x: 0, y: 0 }; }
|
|
unproject() { return { lng: 0, lat: 0 }; }
|
|
}
|
|
class Marker {
|
|
constructor(opts) {
|
|
this._el = (opts && opts.element) || document.createElement('div');
|
|
}
|
|
setLngLat() { return this; }
|
|
addTo() { return this; }
|
|
remove() {}
|
|
getLngLat() { return { lng: 0, lat: 0 }; }
|
|
getElement() { return this._el; }
|
|
}
|
|
class Popup {
|
|
setLngLat() { return this; }
|
|
setDOMContent() { return this; }
|
|
addTo() { return this; }
|
|
remove() {}
|
|
}
|
|
class LngLatBounds {
|
|
extend() { return this; }
|
|
}
|
|
export default { Map, Marker, Popup, LngLatBounds };
|
|
`;
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.route('**maplibre-gl.js*', async route => {
|
|
await route.fulfill({ contentType: 'application/javascript', body: MAPLIBRE_MOCK });
|
|
});
|
|
});
|
|
|
|
test.describe('Line of Sight Application', () => {
|
|
test('should load the home page and show settings', async ({ page }) => {
|
|
await page.goto('/');
|
|
await expect(page.locator('text=Line of Sight Settings')).toBeVisible();
|
|
await expect(page.locator('label:has-text("Direction")')).toBeVisible();
|
|
});
|
|
|
|
test('should be able to toggle map style', async ({ page }) => {
|
|
await page.goto('/');
|
|
await page.waitForSelector('h3:text("Line of Sight Settings")', { timeout: 10000 });
|
|
const darkButton = page.locator('button:text("Dark")');
|
|
await darkButton.click();
|
|
await expect(darkButton).toHaveClass(/active-style/);
|
|
});
|
|
|
|
test('should show results when clicking the search button', async ({ page }) => {
|
|
await page.goto('/');
|
|
await page.waitForSelector('h3:text("Line of Sight Settings")', { timeout: 10000 });
|
|
|
|
await page.route('**/api/line-of-sight*', async route => {
|
|
const json = {
|
|
success: true,
|
|
data: {
|
|
conurbations: [
|
|
{ id: 1, name: 'Test City', population: 100000, country: 'TS', lat: 0, lon: 0, distance_km: 10, off_line_km: 1 }
|
|
],
|
|
line_coordinates: [{ lat: 0, lon: 0 }, { lat: 1, lon: 1 }]
|
|
}
|
|
};
|
|
await route.fulfill({ json });
|
|
});
|
|
|
|
await page.click('button:text("Show Line of Sight")');
|
|
await expect(page.locator('text=Conurbations Found')).toBeVisible();
|
|
await expect(page.locator('text=Test City')).toBeVisible();
|
|
});
|
|
});
|