leaflet_svelte/tests/e2e/fixtures.ts

74 lines
2.4 KiB
TypeScript

import {
test as base,
expect,
type Page,
type BrowserContext,
} from '@playwright/test';
/**
* Shared fixtures and helpers.
*
* Works against either the mock plugin (VITE_USE_MOCK_API=true) or the real
* Django backend (stratoflights). Mock accepts any credentials; Django
* expects demo/demo and enforces CSRF.
*
* The `TEST_USERNAME` / `TEST_PASSWORD` envs let CI override the default.
*
* Critical detail: login/logout must go through `page.context().request` so
* cookies are shared between API calls and the page. Using the plain
* `request` fixture gives you a separate cookie jar.
*/
const USERNAME = process.env.TEST_USERNAME ?? 'demo';
const PASSWORD = process.env.TEST_PASSWORD ?? 'demo';
export async function login(context: BrowserContext): Promise<void> {
const request = context.request;
await request.get('/api/csrf/');
const state = await context.storageState();
const csrf = state.cookies.find((c) => c.name === 'csrftoken')?.value ?? '';
const res = await request.post('/api/login/', {
data: { username: USERNAME, password: PASSWORD },
headers: { 'X-CSRFToken': csrf, 'Content-Type': 'application/json' },
});
if (!res.ok()) {
throw new Error(
`Login failed: ${res.status()} ${await res.text()}. Is stratoflights running on :8000 with a user "${USERNAME}" / "${PASSWORD}"?`,
);
}
}
export async function logout(context: BrowserContext): Promise<void> {
const state = await context.storageState();
const csrf = state.cookies.find((c) => c.name === 'csrftoken')?.value ?? '';
await context.request.post('/api/logout/', {
headers: { 'X-CSRFToken': csrf, 'Content-Type': 'application/json' },
});
// Clear cookies so the page navigator is fully anonymous next goto.
await context.clearCookies();
}
export const test = base.extend({
page: async ({ page }, use) => {
const hardErrors: string[] = [];
page.on('pageerror', (e) => hardErrors.push(`[pageerror] ${e.message}`));
page.on('console', (msg) => {
if (msg.type() === 'error') {
// eslint-disable-next-line no-console
console.log(' [page console.error]', msg.text());
}
});
await use(page);
if (hardErrors.length > 0) throw new Error('Page errors:\n' + hardErrors.join('\n'));
},
});
export { expect };
export async function openPredict(page: Page) {
await page.goto('/predict');
await page
.locator('.map-container canvas')
.first()
.waitFor({ state: 'attached', timeout: 15_000 });
}