Files
Frontend_automation/tests/helpers/navigation.ts

173 lines
4.2 KiB
TypeScript
Raw Normal View History

Extract PassDashboard Playwright e2e suite into standalone repo 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>
2026-08-03 15:50:50 +03:00
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'
);
}