120 lines
3.5 KiB
TypeScript
120 lines
3.5 KiB
TypeScript
import { type BrowserContext, type Page } from '@playwright/test';
|
|
|
|
const SERVER_ENDPOINTS_STORAGE_KEY = 'metoyou_server_endpoints';
|
|
const REMOVED_DEFAULT_KEYS_STORAGE_KEY = 'metoyou_removed_default_server_keys';
|
|
|
|
export interface SeededEndpointInput {
|
|
id: string;
|
|
name: string;
|
|
url: string;
|
|
isActive?: boolean;
|
|
isDefault?: boolean;
|
|
status?: string;
|
|
}
|
|
|
|
interface SeededEndpointStorageState {
|
|
key: string;
|
|
removedKey: string;
|
|
endpoints: {
|
|
id: string;
|
|
name: string;
|
|
url: string;
|
|
isActive: boolean;
|
|
isDefault: boolean;
|
|
status: string;
|
|
}[];
|
|
}
|
|
|
|
function buildSeededEndpointStorageState(
|
|
endpointsOrPort: ReadonlyArray<SeededEndpointInput> | number = Number(process.env.TEST_SERVER_PORT) || 3099
|
|
): SeededEndpointStorageState {
|
|
const endpoints = Array.isArray(endpointsOrPort)
|
|
? endpointsOrPort.map((endpoint) => ({
|
|
id: endpoint.id,
|
|
name: endpoint.name,
|
|
url: endpoint.url,
|
|
isActive: endpoint.isActive ?? true,
|
|
isDefault: endpoint.isDefault ?? false,
|
|
status: endpoint.status ?? 'unknown'
|
|
}))
|
|
: [
|
|
{
|
|
id: 'e2e-test-server',
|
|
name: 'E2E Test Server',
|
|
url: `http://localhost:${endpointsOrPort}`,
|
|
isActive: true,
|
|
isDefault: false,
|
|
status: 'unknown'
|
|
}
|
|
];
|
|
|
|
return {
|
|
key: SERVER_ENDPOINTS_STORAGE_KEY,
|
|
removedKey: REMOVED_DEFAULT_KEYS_STORAGE_KEY,
|
|
endpoints
|
|
};
|
|
}
|
|
|
|
function applySeededEndpointStorageState(storageState: SeededEndpointStorageState): void {
|
|
try {
|
|
const storage = window.localStorage;
|
|
|
|
storage.setItem(storageState.key, JSON.stringify(storageState.endpoints));
|
|
storage.setItem(storageState.removedKey, JSON.stringify([
|
|
'default',
|
|
'toju-primary',
|
|
'toju-sweden'
|
|
]));
|
|
} catch {
|
|
// about:blank and some Playwright UI pages deny localStorage access.
|
|
}
|
|
}
|
|
|
|
export async function installTestServerEndpoint(
|
|
context: BrowserContext,
|
|
port: number = Number(process.env.TEST_SERVER_PORT) || 3099
|
|
): Promise<void> {
|
|
const storageState = buildSeededEndpointStorageState(port);
|
|
|
|
await context.addInitScript(applySeededEndpointStorageState, storageState);
|
|
}
|
|
|
|
export async function installTestServerEndpoints(
|
|
context: BrowserContext,
|
|
endpoints: ReadonlyArray<SeededEndpointInput>
|
|
): Promise<void> {
|
|
const storageState = buildSeededEndpointStorageState(endpoints);
|
|
|
|
await context.addInitScript(applySeededEndpointStorageState, storageState);
|
|
}
|
|
|
|
/**
|
|
* Seed localStorage with a single signal endpoint pointing at the test server.
|
|
* Must be called AFTER navigating to the app origin (localStorage is per-origin)
|
|
* but BEFORE the app reads from storage (i.e. before the Angular bootstrap is
|
|
* relied upon - calling it in the first goto() landing page is fine since the
|
|
* page will re-read on next navigation/reload).
|
|
*
|
|
* Typical usage:
|
|
* await page.goto('/');
|
|
* await seedTestServerEndpoint(page);
|
|
* await page.reload(); // App now picks up the test endpoint
|
|
*/
|
|
export async function seedTestServerEndpoint(
|
|
page: Page,
|
|
port: number = Number(process.env.TEST_SERVER_PORT) || 3099
|
|
): Promise<void> {
|
|
const storageState = buildSeededEndpointStorageState(port);
|
|
|
|
await page.evaluate(applySeededEndpointStorageState, storageState);
|
|
}
|
|
|
|
export async function seedTestServerEndpoints(
|
|
page: Page,
|
|
endpoints: ReadonlyArray<SeededEndpointInput>
|
|
): Promise<void> {
|
|
const storageState = buildSeededEndpointStorageState(endpoints);
|
|
|
|
await page.evaluate(applySeededEndpointStorageState, storageState);
|
|
}
|