import { Page } from '@playwright/test'; import { getEnvironmentConfig } from './environment'; const env = getEnvironmentConfig(); export const TEST_CREDENTIALS = { username: env.username, password: env.password, loginPath: process.env.TEST_LOGIN_PATH || '/neopaas/portal/login', dashboardPath: '/dashboard', }; export async function loginAs(page: Page, identifier: string, password: string): Promise { console.log('Starting login process...'); // The initial navigation is the most failure-prone step on a loaded local // machine (headless browser launch/navigation can occasionally stall well // past a single timeout even though the server itself responds in ~1-3s) - // retry it in place rather than letting one slow navigation fail the whole // test and force an expensive full test-level retry. let lastError: unknown; for (let attempt = 1; attempt <= 3; attempt++) { try { await page.goto(TEST_CREDENTIALS.loginPath, { waitUntil: 'domcontentloaded' }); lastError = undefined; break; } catch (error) { lastError = error; console.log(`Login page navigation attempt ${attempt} failed, retrying...`); } } if (lastError) throw lastError; await page.waitForTimeout(2000); // The button's own text is the language you'd switch TO, not the current // one - so it reads "English" while the page is in Arabic (click to go to // English), and "العربية" once already in English. The language preference // persists across logout/login (e.g. via localStorage), so on a second // login within the same test the page may already be in English - only // click when the button would actually switch TO English. console.log('Checking for language switcher...'); const languageArticle = page.locator('article.ant-typography.font-poppins-500.css-1kfsfla').first(); const isVisible = await languageArticle.isVisible({ timeout: 2000 }).catch(() => false); if (isVisible) { const text = (await languageArticle.textContent())?.trim(); console.log(`Found language button with text: "${text}"`); if (text === 'English') { console.log('Clicking to switch language to English...'); await languageArticle.click(); await page.waitForTimeout(2000); console.log('✓ Language switched'); } else { console.log('Already in English - no switch needed'); } } console.log('Filling username...'); await page.fill('input[type="email"], input[type="text"], input[name="email"], input[name="username"], input[placeholder*="email" i], input[placeholder*="username" i]', identifier); console.log('Filling password...'); await page.fill('input[type="password"], input[name="password"]', password); console.log('Clicking login button...'); await page.click('button[type="submit"], button:has-text("Login"), button:has-text("Sign in")'); console.log('Waiting for redirect...'); await page.waitForURL(/\/(dashboard|terminals)/, { timeout: 30000 }).catch(() => { console.log('Post-login URL not detected, checking for navigation...'); }); await page.waitForLoadState('domcontentloaded').catch(() => {}); await page.waitForTimeout(2000); console.log('Login completed successfully'); } export async function login(page: Page): Promise { await loginAs(page, TEST_CREDENTIALS.username, TEST_CREDENTIALS.password); }