All checks were successful
Queue Release Build / prepare (push) Successful in 23s
Deploy Web Apps / deploy (push) Successful in 6m5s
Queue Release Build / build-windows (push) Successful in 17m1s
Queue Release Build / build-linux (push) Successful in 29m15s
Queue Release Build / finalize (push) Successful in 38s
169 lines
5.0 KiB
TypeScript
169 lines
5.0 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: readonly 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;
|
|
const currentUserId = storage.getItem('metoyou_currentUserId')?.trim() || null;
|
|
const generalSettings = JSON.stringify({
|
|
reopenLastViewedChat: false
|
|
});
|
|
|
|
storage.setItem(storageState.key, JSON.stringify(storageState.endpoints));
|
|
storage.setItem(storageState.removedKey, JSON.stringify([
|
|
'default',
|
|
'toju-primary',
|
|
'toju-sweden'
|
|
]));
|
|
storage.setItem('metoyou_general_settings', generalSettings);
|
|
|
|
if (currentUserId) {
|
|
storage.setItem(`metoyou_general_settings__${encodeURIComponent(currentUserId)}`, generalSettings);
|
|
}
|
|
|
|
const keysToRemove: string[] = [];
|
|
|
|
for (let index = 0; index < storage.length; index += 1) {
|
|
const key = storage.key(index);
|
|
|
|
if (key === 'metoyou_lastViewedChat' || key?.startsWith('metoyou_lastViewedChat__')) {
|
|
keysToRemove.push(key);
|
|
}
|
|
}
|
|
|
|
for (const key of keysToRemove) {
|
|
storage.removeItem(key);
|
|
}
|
|
} catch {
|
|
// about:blank and some Playwright UI pages deny localStorage access.
|
|
}
|
|
}
|
|
|
|
export async function disableLastViewedChatResume(page: Page): Promise<void> {
|
|
await page.evaluate(() => {
|
|
const currentUserId = localStorage.getItem('metoyou_currentUserId')?.trim() || null;
|
|
const generalSettings = JSON.stringify({ reopenLastViewedChat: false });
|
|
const keysToRemove: string[] = [];
|
|
|
|
localStorage.setItem('metoyou_general_settings', generalSettings);
|
|
|
|
if (currentUserId) {
|
|
localStorage.setItem(`metoyou_general_settings__${encodeURIComponent(currentUserId)}`, generalSettings);
|
|
}
|
|
|
|
for (let index = 0; index < localStorage.length; index += 1) {
|
|
const key = localStorage.key(index);
|
|
|
|
if (key === 'metoyou_lastViewedChat' || key?.startsWith('metoyou_lastViewedChat__')) {
|
|
keysToRemove.push(key);
|
|
}
|
|
}
|
|
|
|
for (const key of keysToRemove) {
|
|
localStorage.removeItem(key);
|
|
}
|
|
});
|
|
}
|
|
|
|
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: readonly 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: readonly SeededEndpointInput[]
|
|
): Promise<void> {
|
|
const storageState = buildSeededEndpointStorageState(endpoints);
|
|
|
|
await page.evaluate(applySeededEndpointStorageState, storageState);
|
|
}
|