Files
tilbudgivern/tests/labor-reload.spec.js
2026-08-10 12:38:52 +02:00

107 lines
4.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const { test, expect } = require('@playwright/test');
const economics = {
model: 'standard_overhead_profit_v1',
materialTotal: 1000,
rentalTotal: 14000,
laborTotal: 44080,
subtotal: 59080,
overheadPercentage: 15,
overheadAmount: 8862,
subtotalWithOverhead: 67942,
profitPercentage: 20,
profitAmount: 13588.4,
totalExclVat: 81530.4,
vatPercentage: 25,
vatAmount: 20382.6,
totalInclVat: 101913
};
test('labor survives a full reload with the single-object API contract', async ({ page }) => {
let laborReads = 0;
await page.addInitScript(() => {
window.localStorage.setItem('accessToken', 'labor-reload-test-token');
window.localStorage.setItem('user', JSON.stringify({ username: 'labor-reload-test' }));
window.localStorage.setItem('tilbudgivern_current_view', 'projects');
});
await page.route('**/api/**', async route => {
const request = route.request();
const url = new URL(request.url());
const path = url.pathname;
const fulfill = body => route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(body) });
if (path.endsWith('/api/customer-projects/projects')) {
return fulfill({ success: true, projects: [{
id: 392,
project_name: 'Røsevangen 44 betontag',
customer_name: 'Testkunde',
customer_address: 'Røsevangen 44, 3520 Farum',
project_description: 'Udskiftning af betontag',
project_status: 'review_pending',
updated_at: '2026-08-10T10:00:00Z'
}] });
}
if (path.endsWith('/api/customer-projects/392')) {
return fulfill({ success: true, project: {
id: 392,
project_name: 'Røsevangen 44 betontag',
customer_name: 'Testkunde',
customer_address: 'Røsevangen 44, 3520 Farum',
project_description: 'Udskiftning af betontag',
project_status: 'review_pending'
} });
}
if (path.endsWith('/392/geometry')) {
return fulfill({ success: true, geometry: {
roof_type: 'skraat_tag', frontend_roof_type: 'sadeltag', width: 6, length: 10,
roof_pitch: 30, total_area: 60, roof_covering_area: 69.28
} });
}
if (path.endsWith('/392/labor')) {
laborReads += 1;
return fulfill({ success: true, labor: {
total_work_hours: '76.00', hourly_rate: '580.00', total_labor_cost: '44080.00',
work_breakdown: JSON.stringify([
{ task: 'Nedtagning', hours: 20, rate: 580, cost: 11600 },
{ task: 'Montering', hours: 56, rate: 580, cost: 32480 }
])
} });
}
if (path.endsWith('/392/materials')) {
return fulfill({ success: true, materials: [{ material_name: 'Betontagsten', quantity: 10, unit: 'stk', unit_price: 100 }] });
}
if (path.endsWith('/projects/392/rentals')) {
return fulfill({ success: true, rentals: [{ rental_name: 'Stillads', quantity: 1, unit: 'sum', unit_price: 14000 }] });
}
if (path.endsWith('/392/packages')) {
return fulfill({ success: true, packages: [{ id: 1, name: 'Betontag', materials: [] }] });
}
if (path.endsWith('/392/calculation')) return fulfill({ success: true, data: economics });
if (path.endsWith('/392/calculate')) return fulfill({ success: true, data: economics });
if (path.includes('/order-suggestions')) return fulfill({ success: true, matches: [] });
if (path.includes('/material-price-status')) return fulfill({ success: true, sources: [] });
return fulfill({ success: true, data: null });
});
const openFinalReview = async () => {
const projectLoaded = page.waitForResponse(response => response.url().endsWith('/api/customer-projects/392'));
await page.locator('.project-resume-panel button').click();
await projectLoaded;
await expect(page.getByRole('heading', { name: /Røsevangen 44 betontag/ })).toBeVisible();
await expect(page.locator('.loading-overlay')).toHaveCount(0);
await page.locator('.step').filter({ hasText: 'Final Review' }).click();
await expect(page.getByRole('heading', { name: /Timer & Opgaver \(2 opgaver\)/ })).toBeVisible();
await expect(page.getByText('76 timer', { exact: true })).toBeVisible();
await expect(page.getByText('44.080,00 kr', { exact: true }).first()).toBeVisible();
};
await page.goto('/', { waitUntil: 'domcontentloaded' });
await openFinalReview();
await page.evaluate(() => window.sessionStorage.clear());
await page.reload({ waitUntil: 'domcontentloaded' });
await openFinalReview();
expect(laborReads).toBeGreaterThanOrEqual(2);
});