Files
pos-system/apps/web-client-tpos-net/tests/WebClientTpos.E2ETests/helpers/auth.helper.ts
Ho Ngoc Hai dc1ea7c0d2 feat: Phase 2 W7-8 production readiness — QR menu, analytics, E2E tests, observability
- Public QR menu: BFF proxy endpoints (no auth), PosDataService public methods
- Revenue analytics + staff performance: Dapper queries, validators, BFF proxy
- Playwright E2E tests: 8 spec files covering auth, admin, 5 POS verticals, reports
- Observability: Grafana dashboard (HTTP metrics, infra, business), Prometheus alert rules
- Fixes: validator frozen-date bug (Must vs LessThanOrEqualTo), PublicMenuController logging + CancellationToken

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 19:51:37 +07:00

79 lines
2.8 KiB
TypeScript

import { type Page, expect } from '@playwright/test';
import { ADMIN_USER, MERCHANT_USER, ROUTES, BLAZOR_LOAD_TIMEOUT } from './test-data';
/**
* EN: Wait for Blazor WASM to finish loading (spinner disappears, interactive DOM ready).
* VI: Doi Blazor WASM tai xong (spinner bien mat, DOM tuong tac san sang).
*/
export async function waitForBlazor(page: Page): Promise<void> {
// Blazor WASM renders a loading placeholder; wait until the app root has content.
// MudBlazor injects a .mud- prefixed element once the framework boots.
await page.waitForLoadState('networkidle', { timeout: BLAZOR_LOAD_TIMEOUT });
// Wait for any MudBlazor rendered element, indicating the Blazor runtime is active.
await page.waitForSelector('.mud-layout, .mud-main-content, [class*="mud-"]', {
timeout: BLAZOR_LOAD_TIMEOUT,
state: 'attached',
});
}
/**
* EN: Log in as admin (owner/merchant) and wait for redirect to admin dashboard.
* VI: Dang nhap voi vai tro admin (owner/merchant) va doi redirect ve admin dashboard.
*/
export async function loginAsAdmin(
page: Page,
email = ADMIN_USER.email,
password = ADMIN_USER.password,
): Promise<void> {
await page.goto(ROUTES.LOGIN_ADMIN);
await waitForBlazor(page);
// Fill email
await page.locator('input[type="email"], input[autocomplete="email"]').first().fill(email);
// Fill password
await page.locator('input[type="password"]').first().fill(password);
// Submit
await page.locator('button[type="submit"]').first().click();
// Wait for navigation to admin area
await page.waitForURL('**/admin**', { timeout: 15_000 });
await waitForBlazor(page);
}
/**
* EN: Log in as merchant and wait for redirect to admin dashboard.
* VI: Dang nhap voi vai tro merchant va doi redirect ve admin dashboard.
*/
export async function loginAsMerchant(
page: Page,
email = MERCHANT_USER.email,
password = MERCHANT_USER.password,
): Promise<void> {
await loginAsAdmin(page, email, password);
}
/**
* EN: Verify the user is logged in by checking for user-profile or avatar elements.
* VI: Xac nhan nguoi dung da dang nhap bang cach kiem tra phan tu user-profile hoac avatar.
*/
export async function expectLoggedIn(page: Page): Promise<void> {
// The admin layout should render a sidebar or user menu once authenticated.
await expect(
page.locator('.mud-navmenu, .mud-drawer, [class*="sidebar"], [class*="user-menu"]').first(),
).toBeVisible({ timeout: 10_000 });
}
/**
* EN: Log out by navigating to profile and clicking logout, or clearing localStorage token.
* VI: Dang xuat bang cach vao profile va nhan logout, hoac xoa token trong localStorage.
*/
export async function logout(page: Page): Promise<void> {
// Clear the JWT token from localStorage (key: aPOS_token)
await page.evaluate(() => {
localStorage.removeItem('aPOS_token');
});
await page.goto(ROUTES.LOGIN);
await waitForBlazor(page);
}