import 'dotenv/config'; import { test as base, expect, Page, APIRequestContext } from '@playwright/test'; export type TenantCredentials = { email: string; password: string; }; export type TenantAdminFixtures = { tenantAdminCredentials: TenantCredentials | null; signInTenantAdmin: () => Promise; }; const tenantAdminEmail = process.env.E2E_TENANT_EMAIL ?? 'hello@lumen-moments.demo'; const tenantAdminPassword = process.env.E2E_TENANT_PASSWORD ?? 'Demo1234!'; export const test = base.extend({ tenantAdminCredentials: async ({}, use) => { if (!tenantAdminEmail || !tenantAdminPassword) { await use(null); return; } await use({ email: tenantAdminEmail, password: tenantAdminPassword, }); }, signInTenantAdmin: async ({ page, tenantAdminCredentials }, use) => { if (!tenantAdminCredentials) { await use(async () => { throw new Error('Tenant admin credentials missing. Provide E2E_TENANT_EMAIL and E2E_TENANT_PASSWORD.'); }); return; } await use(async () => { await performTenantSignIn(page, tenantAdminCredentials); }); }, }); export const expectFixture = expect; async function performTenantSignIn(page: Page, credentials: TenantCredentials) { const token = await exchangeToken(page.request, credentials); await page.addInitScript(({ stored }) => { localStorage.setItem('tenant_admin.token.v1', JSON.stringify(stored)); sessionStorage.setItem('tenant_admin.token.session.v1', JSON.stringify(stored)); }, { stored: token }); await page.goto('/event-admin'); await page.waitForLoadState('domcontentloaded'); } type StoredTokenPayload = { accessToken: string; abilities: string[]; issuedAt: number; }; async function exchangeToken(request: APIRequestContext, credentials: TenantCredentials): Promise { const response = await request.post('/api/v1/tenant-auth/login', { data: { login: credentials.email, password: credentials.password, }, }); if (!response.ok()) { throw new Error(`Tenant PAT login failed: ${response.status()} ${await response.text()}`); } const body = await response.json(); return { accessToken: body.token, abilities: Array.isArray(body.abilities) ? body.abilities : [], issuedAt: Date.now(), }; }