import { test, expect } from '@playwright/test'; import { TEST_CREDENTIALS } from './helpers/auth'; import { epic, feature, severity, description } from './helpers/allure'; test.describe('Authentication Tests', () => { test.setTimeout(90000); test.beforeEach(async ({ page }) => { epic('User Authentication'); feature('Login'); // Retry the initial navigation in place - on a loaded local machine a // single headless navigation can occasionally stall well past one // timeout even though the server itself responds in ~1-3s. 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); // Switch to English by clicking the article element console.log('Checking for language switcher...'); await page.waitForTimeout(1000); 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(); console.log(`Found language button with text: "${text}"`); console.log('Clicking to switch language...'); await languageArticle.click(); await page.waitForTimeout(2000); console.log('✓ Language switched'); } else { console.log('Language button not found'); } }); test('should successfully login with valid credentials', async ({ page }) => { severity('critical'); description('Test successful login flow with valid user credentials'); console.log('Testing login with valid credentials...'); await test.step('Fill in username', async () => { await page.fill('input[type="email"], input[name="email"], input[placeholder*="email" i]', TEST_CREDENTIALS.username); }); await test.step('Fill in password', async () => { await page.fill('input[type="password"], input[name="password"]', TEST_CREDENTIALS.password); }); await test.step('Click login button', async () => { await page.click('button[type="submit"], button:has-text("Login"), button:has-text("Sign in")'); }); await test.step('Verify redirect to dashboard', async () => { await page.waitForURL('**/dashboard**', { timeout: 30000 }).catch(() => { console.log('Checking for successful navigation...'); }); await page.waitForLoadState('domcontentloaded').catch(() => {}); await page.waitForTimeout(2000); const currentUrl = page.url(); console.log('Current URL after login:', currentUrl); expect(currentUrl).toContain('dashboard'); }); console.log('Login successful'); }); test('should show error with invalid credentials', async ({ page }) => { severity('critical'); description('Verify error handling for invalid login credentials'); console.log('Testing login with invalid credentials...'); await test.step('Fill in invalid username', async () => { await page.fill('input[type="email"], input[name="email"], input[placeholder*="email" i]', 'invalid@example.com'); }); await test.step('Fill in invalid password', async () => { await page.fill('input[type="password"], input[name="password"]', 'wrongpassword'); }); await test.step('Click login button', async () => { await page.click('button[type="submit"], button:has-text("Login"), button:has-text("Sign in")'); }); await test.step('Verify error message appears', async () => { await page.waitForTimeout(2000); const errorMessage = await page.locator('text=/error|invalid|incorrect|failed/i').first().isVisible().catch(() => false); const stillOnLoginPage = page.url().includes('login'); console.log('Error message visible:', errorMessage); console.log('Still on login page:', stillOnLoginPage); expect(errorMessage || stillOnLoginPage).toBeTruthy(); }); console.log('Invalid credentials test completed'); }); test('should validate required fields', async ({ page }) => { severity('normal'); description('Verify that required field validation works correctly'); console.log('Testing required field validation...'); await test.step('Click login without filling fields', async () => { await page.click('button[type="submit"], button:has-text("Login"), button:has-text("Sign in")'); await page.waitForTimeout(1000); }); await test.step('Verify validation or staying on login page', async () => { const stillOnLoginPage = page.url().includes('login'); console.log('Still on login page:', stillOnLoginPage); expect(stillOnLoginPage).toBeTruthy(); }); console.log('Required field validation test completed'); }); test('should successfully logout', async ({ page }) => { test.setTimeout(90000); severity('critical'); description('Verify that clicking Logout redirects to login page and clears session'); // First login await test.step('Login first', async () => { await page.fill('input[type="email"], input[name="email"], input[placeholder*="email" i]', TEST_CREDENTIALS.username); await page.fill('input[type="password"], input[name="password"]', TEST_CREDENTIALS.password); await page.click('button[type="submit"], button:has-text("Login"), button:has-text("Sign in")'); await page.waitForURL('**/dashboard**', { timeout: 30000 }).catch(() => {}); await page.waitForLoadState('domcontentloaded').catch(() => {}); console.log('✓ Logged in, URL:', page.url()); }); await test.step('Click Logout', async () => { const logoutLink = page.locator('text=Logout').first(); if (!(await logoutLink.isVisible({ timeout: 2500 }).catch(() => false))) { // Mobile layout might hide logout under a menu; try opening it. const openMenu = page.locator('button[aria-label="Open menu"], button[aria-label="Open navigation"], button:has-text("Menu"), button:has-text("Open")'); if (await openMenu.isVisible({ timeout: 2500 }).catch(() => false)) { await openMenu.click(); await page.waitForTimeout(1000); } } await logoutLink.waitFor({ state: 'visible', timeout: 10000 }); await logoutLink.click(); await page.waitForTimeout(3000); console.log('✓ Logout clicked'); }); await test.step('Verify redirected to login page', async () => { await page.waitForURL('**/login**', { timeout: 10000 }).catch(() => {}); const currentUrl = page.url(); console.log('URL after logout:', currentUrl); expect(currentUrl).toContain('login'); }); console.log('✓ Logout test completed'); }); });