Publish curated ITWorx-Pulse source from 0e0633c8ac91cb71312a26837f791035a78d81b8
Public source validation / validate (push) Failing after 2m10s
Public source validation / validate (push) Failing after 2m10s
This commit is contained in:
1 parent
a4956c2af9
commit
db8093b608
88 files changed
+3685
-469
No files matched your search
@@ -0,0 +1,94 @@
|
||||
import AxeBuilder from '@axe-core/playwright';
|
||||
import { expect, test, type Page, type Route } from '@playwright/test';
|
||||
|
||||
type Dashboard = { id: string; slug: string; name: string; description: string; ownerId: string; scope: string; revision: number; currentVersion: number; archivedAt?: string };
|
||||
|
||||
const observedAt = new Date().toISOString();
|
||||
const initial: Dashboard = { id: 'dashboard-1', slug: 'operations', name: 'Operations', description: 'Dagelijkse operatie', ownerId: 'editor-1', scope: 'shared', revision: 1, currentVersion: 2 };
|
||||
|
||||
async function fulfill(route: Route, body: unknown, status = 200): Promise<void> {
|
||||
await route.fulfill({ status, contentType: status >= 400 ? 'application/problem+json' : 'application/json', body: JSON.stringify(body) });
|
||||
}
|
||||
|
||||
async function mockShell(page: Page, session: unknown): Promise<void> {
|
||||
await page.route('**/api/v1/system/status', (route) => fulfill(route, { version: '1.5.0', generatedAt: observedAt, overallState: 'healthy', components: [], backup: { state: 'disabled', reason: 'not_configured' }, sourceLag: [{ sourceId: 'test', state: 'healthy', reason: 'ok' }] }));
|
||||
await page.route('**/api/v1/session', (route) => fulfill(route, session));
|
||||
await page.route('**/api/v1/host', (route) => fulfill(route, { identity: { name: 'lifecycle-fixture' } }));
|
||||
await page.route('**/api/v1/alerts**', (route) => fulfill(route, { items: [] }));
|
||||
await page.route('**/api/v1/incidents**', (route) => fulfill(route, { items: [] }));
|
||||
}
|
||||
|
||||
test('editor completes the dashboard lifecycle with revision locks', async ({ page }, testInfo) => {
|
||||
test.skip(testInfo.project.name === 'wallboard-chromium', 'Dashboardbeheer is geen wallboardtaak.');
|
||||
const dashboards: Dashboard[] = [{ ...initial }];
|
||||
const revisionHeaders: string[] = [];
|
||||
await mockShell(page, { subject: 'editor-1', role: 'editor', environment: 'test', permissions: { view: true, operate: true, edit: true, admin: false } });
|
||||
await page.route('**/api/v1/dashboards**', async (route) => {
|
||||
const request = route.request();
|
||||
const url = new URL(request.url());
|
||||
const path = url.pathname;
|
||||
const method = request.method();
|
||||
if (path === '/api/v1/dashboards' && method === 'GET') return fulfill(route, { items: dashboards });
|
||||
if (path === '/api/v1/dashboards' && method === 'POST') {
|
||||
const document = request.postDataJSON() as { slug: string; name: string; description: string; scope: string };
|
||||
const created = { id: 'dashboard-created', slug: document.slug, name: document.name, description: document.description, ownerId: 'editor-1', scope: document.scope, revision: 1, currentVersion: 1 };
|
||||
dashboards.push(created); return fulfill(route, { dashboard: created }, 201);
|
||||
}
|
||||
const item = dashboards.find((candidate) => path.includes(candidate.id));
|
||||
if (!item) return fulfill(route, { code: 'NOT_FOUND' }, 404);
|
||||
if (path.endsWith('/versions') && method === 'GET') return fulfill(route, { items: [
|
||||
{ id: 'v2', dashboardId: item.id, number: 2, schemaVersion: 2, document: {}, changeSummary: 'metadata', createdBy: 'editor-1', createdAt: observedAt },
|
||||
{ id: 'v1', dashboardId: item.id, number: 1, schemaVersion: 2, document: {}, changeSummary: 'initial', createdBy: 'editor-1', createdAt: observedAt },
|
||||
] });
|
||||
if (path.endsWith('/restore/1') && method === 'POST') { revisionHeaders.push(request.headers()['if-match'] ?? ''); item.revision += 1; item.currentVersion += 1; return fulfill(route, { dashboard: item }); }
|
||||
if (path.endsWith('/clone') && method === 'POST') {
|
||||
const body = request.postDataJSON() as { slug: string; name: string };
|
||||
const clone = { ...item, id: 'dashboard-clone', slug: body.slug, name: body.name, revision: 1, currentVersion: 1 };
|
||||
dashboards.push(clone); return fulfill(route, { dashboard: clone }, 201);
|
||||
}
|
||||
if (method === 'PATCH') { revisionHeaders.push(request.headers()['if-match'] ?? ''); const body = request.postDataJSON() as { name: string; description: string }; Object.assign(item, body, { revision: item.revision + 1 }); return fulfill(route, { dashboard: item }); }
|
||||
if (method === 'DELETE') { revisionHeaders.push(request.headers()['if-match'] ?? ''); item.revision += 1; item.archivedAt = observedAt; return fulfill(route, { dashboard: item }); }
|
||||
return fulfill(route, { code: 'NOT_FOUND' }, 404);
|
||||
});
|
||||
|
||||
await page.goto('/dashboards');
|
||||
await expect(page.getByRole('heading', { level: 1, name: 'Dashboardbeheer' })).toBeVisible();
|
||||
await page.getByRole('button', { name: 'Nieuw dashboard' }).click();
|
||||
await page.getByLabel('Naam').fill('Nachtzicht');
|
||||
await page.getByLabel('Template').selectOption('blank');
|
||||
await page.getByRole('button', { name: 'Dashboard maken' }).click();
|
||||
await expect(page.locator('.dashboard-manager-row').filter({ has: page.getByText('Nachtzicht', { exact: true }) })).toBeVisible();
|
||||
|
||||
let row = page.locator('.dashboard-manager-row').filter({ hasText: 'Operations' });
|
||||
await row.getByRole('button', { name: 'Beheren' }).click();
|
||||
await row.getByLabel('Naam').fill('Operations EU');
|
||||
await row.getByRole('button', { name: 'Naam en beschrijving opslaan' }).click();
|
||||
row = page.locator('.dashboard-manager-row').filter({ has: page.getByText('Operations EU', { exact: true }) });
|
||||
await row.getByRole('button', { name: 'Beheren' }).click();
|
||||
await row.getByRole('button', { name: 'Dupliceren' }).click();
|
||||
await expect(page.getByText('Operations EU (kopie)', { exact: true })).toBeVisible();
|
||||
await row.getByRole('button', { name: 'Versies bekijken' }).click();
|
||||
await row.getByRole('button', { name: 'Herstellen als huidige versie' }).click();
|
||||
await row.getByRole('button', { name: 'Archiveren' }).click();
|
||||
await row.getByRole('button', { name: 'Ja, archiveren' }).click();
|
||||
await expect(page.getByText('Dashboard gearchiveerd.')).toBeVisible();
|
||||
expect(revisionHeaders).toEqual(['1', '2', '3']);
|
||||
expect(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth + 1)).toBe(true);
|
||||
const serious = (await new AxeBuilder({ page }).analyze()).violations.filter((violation) => violation.impact === 'critical' || violation.impact === 'serious');
|
||||
expect(serious).toEqual([]);
|
||||
});
|
||||
|
||||
test('viewer gets a read-only dashboard manager', async ({ page }, testInfo) => {
|
||||
test.skip(testInfo.project.name === 'wallboard-chromium', 'Dashboardbeheer is geen wallboardtaak.');
|
||||
await mockShell(page, { subject: 'viewer-1', role: 'viewer', environment: 'test', permissions: { view: true, operate: false, edit: false, admin: false } });
|
||||
await page.route('**/api/v1/dashboards**', (route) => new URL(route.request().url()).pathname === '/api/v1/dashboards/dashboard-1'
|
||||
? fulfill(route, { dashboard: initial, version: { document: { schemaVersion: 2, id: '00000000-0000-4000-8000-000000000001', slug: 'operations', name: 'Operations', scope: 'shared', variables: [], widgets: [], settings: { defaultTimeRange: '1h' } } } })
|
||||
: fulfill(route, { items: [initial] }));
|
||||
await page.goto('/dashboards');
|
||||
await expect(page.getByText('Alleen bekijken')).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'Nieuw dashboard' })).toHaveCount(0);
|
||||
await expect(page.getByRole('button', { name: 'Beheren' })).toHaveCount(0);
|
||||
await page.locator('.dashboard-manager-open').click();
|
||||
await expect(page.getByRole('heading', { level: 1, name: 'Operations' })).toBeVisible();
|
||||
await expect(page.getByRole('button', { name: 'Bewerken' })).toHaveCount(0);
|
||||
});
|
||||
Reference in new issue
Block a user