import type { Page, Route } from '@playwright/test'; import { E2E_LOGIN } from './credentials'; import { createFakeJwt } from './fake-jwt'; const APP_HOSTS = new Set(['127.0.0.1', 'localhost']); const APP_PORT = Number(process.env.E2E_PORT ?? 4173); const EMPTY_LIST = { data: [], meta: { currentPage: 1, itemsPerPage: 10, totalItems: 0, totalPages: 0, itemCount: 0, }, }; const E2E_USER = { id: 'e2e-user-id', username: E2E_LOGIN.username, isSuperadmin: true, privilege: null, permissions: {}, }; export type LoginApiOutcome = 'success' | 'unauthorized'; export async function mockBackend(page: Page, login: LoginApiOutcome = 'success'): Promise { await page.route('**/*', async (route) => { const requestUrl = new URL(route.request().url()); if (isAppRequest(requestUrl)) { await route.continue(); return; } await fulfillBackend(route, login); }); } function isAppRequest(requestUrl: URL): boolean { const port = Number(requestUrl.port || (requestUrl.protocol === 'https:' ? 443 : 80)); return APP_HOSTS.has(requestUrl.hostname) && port === APP_PORT; } async function fulfillBackend(route: Route, login: LoginApiOutcome): Promise { const request = route.request(); const pathname = new URL(request.url()).pathname.replace(/\/$/, ''); if (pathname.endsWith('/auth/login') && request.method() === 'POST') { if (login === 'unauthorized') { await route.fulfill({ status: 401, contentType: 'application/json', body: JSON.stringify({ statusCode: 401, message: 'Unauthorized' }), }); return; } await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify({ accessToken: createFakeJwt(), refreshToken: createFakeJwt(86_400), }), }); return; } if (pathname.endsWith('/auth/me') && request.method() === 'GET') { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(E2E_USER), }); return; } const resourceType = request.resourceType(); if (resourceType === 'xhr' || resourceType === 'fetch') { await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(EMPTY_LIST), }); return; } await route.abort(); }