Some checks failed
E2E Tests / test (push) Has been cancelled
Copies the Playwright end-to-end suite out of the PassDashboard app repo so it can be run and deployed independently. Nothing was removed from the app repo - this is a copy. Carried over verbatim: tests/ (10 spec files, 4 helper modules, README) plus playwright.config.ts and .env.test.example. The suite drives the deployed app over HTTP and imports nothing from src/, which is what makes it standalone. New for this repo: - package.json with only the deps the suite actually uses (@playwright/test, allure-playwright, xlsx, typescript, @types/node) and the e2e scripts. - tsconfig.json covering tests/ - the app repo's tsconfig.app.json only included src/, so these files were never typechecked before. - .gitea/workflows/e2e-tests.yml for Gitea Actions. The app repo derived ENV from github.ref_name; that doesn't apply here since this repo has no per-environment branches, so the target is an explicit workflow_dispatch input and scheduled/push runs default to develop. Reports are uploaded as artifacts rather than deleted. - .gitignore and README covering local setup and the required CI secrets. The Jest unit tests under src/__tests__/ were deliberately left in the app repo: they import application source directly (AuthContext, ProtectedRoute, cryptoUtils, api) and cannot run without it. Verified: npx tsc --noEmit is clean and playwright collects all 43 tests across all 10 spec files. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
173 lines
4.2 KiB
TypeScript
173 lines
4.2 KiB
TypeScript
import { Page } from '@playwright/test';
|
|
|
|
/**
|
|
* Navigation helper that tries multiple methods to reach a page
|
|
* 1. Try clicking navigation link
|
|
* 2. Fall back to direct URL navigation
|
|
*/
|
|
|
|
export async function navigateToPage(
|
|
page: Page,
|
|
linkSelectors: string[],
|
|
urlPath: string,
|
|
pageName: string
|
|
): Promise<void> {
|
|
console.log(`Navigating to ${pageName}...`);
|
|
|
|
// Try clicking navigation links first
|
|
for (const selector of linkSelectors) {
|
|
const link = page.locator(selector).first();
|
|
const isVisible = await link.isVisible({ timeout: 3000 }).catch(() => false);
|
|
|
|
if (isVisible) {
|
|
console.log(`Found ${pageName} link, clicking...`);
|
|
await link.click();
|
|
await page.waitForLoadState('domcontentloaded', { timeout: 10000 }).catch(() => {});
|
|
await page.waitForTimeout(1000);
|
|
|
|
// Verify we're on the right page
|
|
if (page.url().toLowerCase().includes(urlPath.toLowerCase())) {
|
|
console.log(`Successfully navigated to ${pageName} via link`);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Fall back to direct URL navigation
|
|
console.log(`${pageName} link not found, using direct URL navigation...`);
|
|
try {
|
|
await page.goto(urlPath, { timeout: 15000, waitUntil: 'domcontentloaded' });
|
|
await page.waitForTimeout(2000);
|
|
console.log(`Successfully navigated to ${pageName} via URL`);
|
|
} catch (error) {
|
|
console.log(`Failed to navigate to ${urlPath}:`, error);
|
|
// Try with base URL
|
|
const baseUrl = page.context().browser()?.contexts()[0]?.pages()[0]?.url() || 'https://devpro.babinnovations.com';
|
|
const fullUrl = new URL(urlPath, baseUrl).href;
|
|
console.log(`Retrying with full URL: ${fullUrl}`);
|
|
await page.goto(fullUrl, { timeout: 15000, waitUntil: 'domcontentloaded' });
|
|
await page.waitForTimeout(2000);
|
|
console.log(`Successfully navigated to ${pageName} via full URL`);
|
|
}
|
|
}
|
|
|
|
export async function navigateToTransactions(page: Page): Promise<void> {
|
|
await navigateToPage(
|
|
page,
|
|
[
|
|
'a:has-text("Transaction")',
|
|
'a:has-text("Transactions")',
|
|
'[href*="transaction" i]',
|
|
'nav a:has-text("Trans")',
|
|
],
|
|
'/transactions',
|
|
'Transactions'
|
|
);
|
|
}
|
|
|
|
export async function navigateToTerminals(page: Page): Promise<void> {
|
|
await navigateToPage(
|
|
page,
|
|
[
|
|
'a:has-text("Terminal")',
|
|
'a:has-text("Terminals")',
|
|
'[href*="terminal" i]',
|
|
'nav a:has-text("Term")',
|
|
],
|
|
'/terminals',
|
|
'Terminals'
|
|
);
|
|
}
|
|
|
|
export async function navigateToRefunds(page: Page): Promise<void> {
|
|
await navigateToPage(
|
|
page,
|
|
[
|
|
'a:has-text("Refund")',
|
|
'a:has-text("Refunds")',
|
|
'[href*="refund" i]',
|
|
'nav a:has-text("Ref")',
|
|
],
|
|
'/refunds',
|
|
'Refunds'
|
|
);
|
|
}
|
|
|
|
export async function navigateToReconciliation(page: Page): Promise<void> {
|
|
await navigateToPage(
|
|
page,
|
|
[
|
|
'a:has-text("Reconcil")',
|
|
'a:has-text("Reconciliation")',
|
|
'[href*="reconcil" i]',
|
|
],
|
|
'/reconciliation',
|
|
'Reconciliation'
|
|
);
|
|
}
|
|
|
|
export async function navigateToManagement(page: Page): Promise<void> {
|
|
await navigateToPage(
|
|
page,
|
|
[
|
|
'a:has-text("Manage")',
|
|
'a:has-text("Management")',
|
|
'[href*="manage" i]',
|
|
],
|
|
'/management',
|
|
'Management'
|
|
);
|
|
}
|
|
|
|
export async function navigateToAdmin(page: Page): Promise<void> {
|
|
await navigateToPage(
|
|
page,
|
|
[
|
|
'a:has-text("Admin")',
|
|
'[href*="admin" i]',
|
|
],
|
|
'/admin',
|
|
'Admin'
|
|
);
|
|
}
|
|
|
|
export async function navigateToSettlement(page: Page): Promise<void> {
|
|
await navigateToPage(
|
|
page,
|
|
[
|
|
'a:has-text("Settlement")',
|
|
'[href*="settlement" i]',
|
|
'nav a:has-text("Settle")',
|
|
],
|
|
'/settlement',
|
|
'Settlement'
|
|
);
|
|
}
|
|
|
|
export async function navigateToDiscounts(page: Page): Promise<void> {
|
|
await navigateToPage(
|
|
page,
|
|
[
|
|
'a:has-text("Discount")',
|
|
'a:has-text("Discounts")',
|
|
'[href*="discount" i]',
|
|
'nav a:has-text("Disc")',
|
|
],
|
|
'/discounts',
|
|
'Discounts & Fees'
|
|
);
|
|
}
|
|
|
|
export async function navigateToSettings(page: Page): Promise<void> {
|
|
await navigateToPage(
|
|
page,
|
|
[
|
|
'a:has-text("Settings")',
|
|
'[href*="settings" i]',
|
|
'nav a:has-text("Setting")',
|
|
],
|
|
'/settings',
|
|
'Settings'
|
|
);
|
|
}
|