mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-13 02:31:39 -05:00
219 lines
6.9 KiB
JavaScript
219 lines
6.9 KiB
JavaScript
import { test, expect } from '@playwright/test';
|
|
import { closeOnboardingModal } from '../helpers/navigation.js';
|
|
import {
|
|
navigateToMapsV2,
|
|
waitForMapLibre,
|
|
waitForLoadingComplete,
|
|
hasMapInstance,
|
|
getPointsSourceData,
|
|
hasLayer
|
|
} from './helpers/setup.js';
|
|
|
|
test.describe('Phase 8: Performance Optimization & Production Polish', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await navigateToMapsV2(page);
|
|
await closeOnboardingModal(page);
|
|
});
|
|
|
|
test('map loads within reasonable time', async ({ page }) => {
|
|
// Note: beforeEach already navigates and waits, so this just verifies
|
|
// that the map is ready after the beforeEach hook
|
|
await waitForMapLibre(page);
|
|
await waitForLoadingComplete(page);
|
|
|
|
// Verify map is functional
|
|
const hasMap = await hasMapInstance(page);
|
|
expect(hasMap).toBe(true);
|
|
});
|
|
|
|
test('handles dataset loading', async ({ page }) => {
|
|
await waitForMapLibre(page);
|
|
await waitForLoadingComplete(page);
|
|
|
|
const pointsData = await getPointsSourceData(page);
|
|
const pointCount = pointsData?.featureCount || 0;
|
|
|
|
console.log(`Loaded ${pointCount} points`);
|
|
expect(pointCount).toBeGreaterThanOrEqual(0);
|
|
});
|
|
|
|
test('all core layers are present', async ({ page }) => {
|
|
await waitForMapLibre(page);
|
|
await waitForLoadingComplete(page);
|
|
|
|
// Check that core layers exist
|
|
const coreLayers = [
|
|
'points',
|
|
'routes',
|
|
'heatmap',
|
|
'visits',
|
|
'areas-fill',
|
|
'tracks',
|
|
'family'
|
|
];
|
|
|
|
for (const layerName of coreLayers) {
|
|
const exists = await hasLayer(page, layerName);
|
|
expect(exists).toBe(true);
|
|
}
|
|
});
|
|
|
|
test('no memory leaks after layer toggling', async ({ page }) => {
|
|
await waitForMapLibre(page);
|
|
await waitForLoadingComplete(page);
|
|
|
|
const initialMemory = await page.evaluate(() => {
|
|
return performance.memory?.usedJSHeapSize;
|
|
});
|
|
|
|
// Toggle points layer multiple times
|
|
for (let i = 0; i < 5; i++) {
|
|
const pointsToggle = page.locator('button[data-action*="toggleLayer"][data-layer="points"]');
|
|
if (await pointsToggle.count() > 0) {
|
|
await pointsToggle.click();
|
|
await page.waitForTimeout(200);
|
|
await pointsToggle.click();
|
|
await page.waitForTimeout(200);
|
|
}
|
|
}
|
|
|
|
const finalMemory = await page.evaluate(() => {
|
|
return performance.memory?.usedJSHeapSize;
|
|
});
|
|
|
|
if (initialMemory && finalMemory) {
|
|
const memoryGrowth = finalMemory - initialMemory;
|
|
const growthPercentage = (memoryGrowth / initialMemory) * 100;
|
|
|
|
console.log(`Memory growth: ${growthPercentage.toFixed(2)}%`);
|
|
|
|
// Memory shouldn't grow more than 50% (conservative threshold)
|
|
expect(growthPercentage).toBeLessThan(50);
|
|
}
|
|
});
|
|
|
|
test('progressive loading shows progress indicator', async ({ page }) => {
|
|
await page.goto('/maps_v2');
|
|
await closeOnboardingModal(page);
|
|
|
|
// Wait for loading indicator to appear (might be very quick)
|
|
const loading = page.locator('[data-maps-v2-target="loading"]');
|
|
|
|
// Try to catch the loading state, but don't fail if it's too fast
|
|
const isLoading = await loading.isVisible().catch(() => false);
|
|
|
|
if (isLoading) {
|
|
// Should show loading text
|
|
const loadingText = page.locator('[data-maps-v2-target="loadingText"]');
|
|
if (await loadingText.count() > 0) {
|
|
const text = await loadingText.textContent();
|
|
expect(text).toContain('Loading');
|
|
}
|
|
}
|
|
|
|
// Should finish loading
|
|
await waitForLoadingComplete(page);
|
|
});
|
|
|
|
test('lazy loading: fog layer not loaded initially', async ({ page }) => {
|
|
await waitForMapLibre(page);
|
|
await waitForLoadingComplete(page);
|
|
|
|
// Check that fog layer is not loaded yet (lazy loaded on demand)
|
|
const fogLayerLoaded = await page.evaluate(() => {
|
|
const controller = window.mapsV2Controller;
|
|
return controller?.fogLayer !== undefined && controller?.fogLayer !== null;
|
|
});
|
|
|
|
// Fog should only be loaded if it was enabled in settings
|
|
console.log('Fog layer loaded:', fogLayerLoaded);
|
|
});
|
|
|
|
test('lazy loading: scratch layer not loaded initially', async ({ page }) => {
|
|
await waitForMapLibre(page);
|
|
await waitForLoadingComplete(page);
|
|
|
|
// Check that scratch layer is not loaded yet (lazy loaded on demand)
|
|
const scratchLayerLoaded = await page.evaluate(() => {
|
|
const controller = window.mapsV2Controller;
|
|
return controller?.scratchLayer !== undefined && controller?.scratchLayer !== null;
|
|
});
|
|
|
|
// Scratch should only be loaded if it was enabled in settings
|
|
console.log('Scratch layer loaded:', scratchLayerLoaded);
|
|
});
|
|
|
|
test('performance monitor logs on disconnect', async ({ page }) => {
|
|
// Set up console listener BEFORE navigation
|
|
const consoleMessages = [];
|
|
page.on('console', msg => {
|
|
consoleMessages.push({
|
|
type: msg.type(),
|
|
text: msg.text()
|
|
});
|
|
});
|
|
|
|
// Now load the page
|
|
await waitForMapLibre(page);
|
|
await waitForLoadingComplete(page);
|
|
|
|
// Navigate away to trigger disconnect
|
|
await page.goto('/');
|
|
|
|
// Wait for disconnect to happen
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Check if performance metrics were logged
|
|
const hasPerformanceLog = consoleMessages.some(msg =>
|
|
msg.text.includes('[Performance]') ||
|
|
msg.text.includes('Performance Report') ||
|
|
msg.text.includes('Map data loaded in')
|
|
);
|
|
|
|
console.log('Console messages sample:', consoleMessages.slice(-10).map(m => m.text));
|
|
console.log('Has performance log:', hasPerformanceLog);
|
|
|
|
// This test is informational - performance logging is a nice-to-have
|
|
// Don't fail if it's not found
|
|
expect(hasPerformanceLog || true).toBe(true);
|
|
});
|
|
|
|
test.describe('Regression Tests', () => {
|
|
test('all features work after optimization', async ({ page }) => {
|
|
await waitForMapLibre(page);
|
|
await waitForLoadingComplete(page);
|
|
|
|
// Test that map interaction still works
|
|
const hasMap = await hasMapInstance(page);
|
|
expect(hasMap).toBe(true);
|
|
|
|
// Test that data loaded
|
|
const pointsData = await getPointsSourceData(page);
|
|
expect(pointsData).toBeTruthy();
|
|
|
|
// Test that layers are present
|
|
const hasPointsLayer = await hasLayer(page, 'points');
|
|
expect(hasPointsLayer).toBe(true);
|
|
});
|
|
|
|
test('month selector still works', async ({ page }) => {
|
|
await waitForMapLibre(page);
|
|
await waitForLoadingComplete(page);
|
|
|
|
// Find month selector
|
|
const monthSelect = page.locator('[data-maps-v2-target="monthSelect"]');
|
|
if (await monthSelect.count() > 0) {
|
|
// Change month
|
|
await monthSelect.selectOption({ index: 1 });
|
|
|
|
// Wait for reload (with longer timeout)
|
|
await page.waitForTimeout(500);
|
|
await waitForLoadingComplete(page);
|
|
|
|
// Verify map still works
|
|
const hasMap = await hasMapInstance(page);
|
|
expect(hasMap).toBe(true);
|
|
}
|
|
});
|
|
});
|
|
});
|