/** * Profile Management E2E Tests * * Critical flows tested: * 1. Profile page loads correctly * 2. Edit profile navigation * 3. Profile settings access * 4. Logout functionality * 5. Notification settings * 6. Language settings * 7. Help and About pages */ import { test, expect } from '@playwright/test'; import { LoginPage, OtpPage, ProfilePage, } from '../helpers/page-objects'; import { enableConsoleLogging, TEST_CREDENTIALS, BASE_URL, } from '../helpers/test-helpers'; // Run tests serially test.describe.configure({ mode: 'serial' }); test.describe('Profile Page', () => { test.beforeEach(async ({ page }) => { enableConsoleLogging(page); // Login const loginPage = new LoginPage(page); await loginPage.goto(); const isOnLogin = await loginPage.welcomeText.isVisible({ timeout: 2000 }).catch(() => false); if (isOnLogin) { await loginPage.loginWithEmail(TEST_CREDENTIALS.existingUser.email); const otpPage = new OtpPage(page); await otpPage.expectLoaded(); await otpPage.enterCode(TEST_CREDENTIALS.existingUser.bypassOtp); await page.waitForTimeout(3000); } }); test('1. Profile page loads correctly', async ({ page }) => { await page.goto(BASE_URL); await page.waitForLoadState('networkidle'); await page.waitForTimeout(3000); // Navigate to profile (bottom tab or menu) const profileTab = page.getByText('Profile').first(); if (await profileTab.isVisible({ timeout: 3000 })) { await profileTab.click(); await page.waitForTimeout(2000); const profilePage = new ProfilePage(page); await profilePage.expectLoaded(); console.log('✅ Profile page loaded'); } else { // Try menu icon const menuIcon = page.locator('[data-testid="profile-menu"]'); if (await menuIcon.isVisible({ timeout: 2000 })) { await menuIcon.click(); await page.waitForTimeout(2000); } } }); test('2. Profile shows user information', async ({ page }) => { await page.goto(BASE_URL); await page.waitForLoadState('networkidle'); await page.waitForTimeout(3000); const profileTab = page.getByText('Profile').first(); if (await profileTab.isVisible({ timeout: 3000 })) { await profileTab.click(); await page.waitForTimeout(2000); // Check for user info display const hasEmail = await page.getByText(/@/).isVisible({ timeout: 2000 }).catch(() => false); const hasEditOption = await page.getByText(/Edit/i).isVisible({ timeout: 2000 }).catch(() => false); console.log(`Email visible: ${hasEmail}, Edit visible: ${hasEditOption}`); console.log('✅ Profile info displayed'); } }); test('3. Edit profile navigation works', async ({ page }) => { await page.goto(BASE_URL); await page.waitForLoadState('networkidle'); await page.waitForTimeout(3000); const profileTab = page.getByText('Profile').first(); if (await profileTab.isVisible({ timeout: 3000 })) { await profileTab.click(); await page.waitForTimeout(2000); const profilePage = new ProfilePage(page); if (await profilePage.editButton.isVisible({ timeout: 2000 })) { await profilePage.editProfile(); await page.waitForTimeout(2000); // Should be on edit profile page const hasNameInput = await page.getByPlaceholder(/name/i).isVisible({ timeout: 3000 }).catch(() => false); const hasPhoneInput = await page.getByPlaceholder(/phone/i).isVisible({ timeout: 3000 }).catch(() => false); expect(hasNameInput || hasPhoneInput).toBe(true); console.log('✅ Edit profile page loaded'); } else { console.log('⚠️ Edit button not visible'); } } }); test('4. Notification settings accessible', async ({ page }) => { await page.goto(BASE_URL); await page.waitForLoadState('networkidle'); await page.waitForTimeout(3000); const profileTab = page.getByText('Profile').first(); if (await profileTab.isVisible({ timeout: 3000 })) { await profileTab.click(); await page.waitForTimeout(2000); const profilePage = new ProfilePage(page); if (await profilePage.notificationsItem.isVisible({ timeout: 2000 })) { await profilePage.goToNotifications(); await page.waitForTimeout(2000); // Should be on notifications settings const hasToggle = await page.locator('input[type="checkbox"], [role="switch"]').isVisible({ timeout: 2000 }).catch(() => false); const hasNotificationText = await page.getByText(/notification|push|alert/i).isVisible({ timeout: 2000 }).catch(() => false); console.log(`Toggle: ${hasToggle}, Text: ${hasNotificationText}`); console.log('✅ Notifications settings accessible'); } else { console.log('⚠️ Notifications item not visible'); } } }); test('5. Language settings accessible', async ({ page }) => { await page.goto(BASE_URL); await page.waitForLoadState('networkidle'); await page.waitForTimeout(3000); const profileTab = page.getByText('Profile').first(); if (await profileTab.isVisible({ timeout: 3000 })) { await profileTab.click(); await page.waitForTimeout(2000); const profilePage = new ProfilePage(page); if (await profilePage.languageItem.isVisible({ timeout: 2000 })) { await profilePage.goToLanguage(); await page.waitForTimeout(2000); // Should be on language settings const hasLanguageOptions = await page.getByText(/English|Русский|Spanish/i).isVisible({ timeout: 2000 }).catch(() => false); console.log(`Language options: ${hasLanguageOptions}`); console.log('✅ Language settings accessible'); } else { console.log('⚠️ Language item not visible'); } } }); test('6. Help page accessible', async ({ page }) => { await page.goto(BASE_URL); await page.waitForLoadState('networkidle'); await page.waitForTimeout(3000); const profileTab = page.getByText('Profile').first(); if (await profileTab.isVisible({ timeout: 3000 })) { await profileTab.click(); await page.waitForTimeout(2000); const profilePage = new ProfilePage(page); if (await profilePage.helpItem.isVisible({ timeout: 2000 })) { await profilePage.goToHelp(); await page.waitForTimeout(2000); // Should be on help page const hasHelpContent = await page.getByText(/FAQ|Support|Contact|Help/i).isVisible({ timeout: 2000 }).catch(() => false); console.log(`Help content: ${hasHelpContent}`); console.log('✅ Help page accessible'); } else { console.log('⚠️ Help item not visible'); } } }); test('7. About page accessible', async ({ page }) => { await page.goto(BASE_URL); await page.waitForLoadState('networkidle'); await page.waitForTimeout(3000); const profileTab = page.getByText('Profile').first(); if (await profileTab.isVisible({ timeout: 3000 })) { await profileTab.click(); await page.waitForTimeout(2000); const profilePage = new ProfilePage(page); if (await profilePage.aboutItem.isVisible({ timeout: 2000 })) { await profilePage.goToAbout(); await page.waitForTimeout(2000); // Should be on about page const hasVersion = await page.getByText(/Version|WellNuo|About/i).isVisible({ timeout: 2000 }).catch(() => false); console.log(`Version info: ${hasVersion}`); console.log('✅ About page accessible'); } else { console.log('⚠️ About item not visible'); } } }); test('8. Logout button visible', async ({ page }) => { await page.goto(BASE_URL); await page.waitForLoadState('networkidle'); await page.waitForTimeout(3000); const profileTab = page.getByText('Profile').first(); if (await profileTab.isVisible({ timeout: 3000 })) { await profileTab.click(); await page.waitForTimeout(2000); const profilePage = new ProfilePage(page); // Scroll down to find logout button await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); await page.waitForTimeout(500); const hasLogout = await profilePage.logoutButton.isVisible({ timeout: 3000 }).catch(() => false); expect(hasLogout).toBe(true); console.log('✅ Logout button visible'); } }); }); test.describe('Logout Flow', () => { test.beforeEach(async ({ page }) => { enableConsoleLogging(page); const loginPage = new LoginPage(page); await loginPage.goto(); const isOnLogin = await loginPage.welcomeText.isVisible({ timeout: 2000 }).catch(() => false); if (isOnLogin) { await loginPage.loginWithEmail(TEST_CREDENTIALS.existingUser.email); const otpPage = new OtpPage(page); await otpPage.expectLoaded(); await otpPage.enterCode(TEST_CREDENTIALS.existingUser.bypassOtp); await page.waitForTimeout(3000); } }); test('Logout clears session and returns to login', async ({ page }) => { await page.goto(BASE_URL); await page.waitForLoadState('networkidle'); await page.waitForTimeout(3000); const profileTab = page.getByText('Profile').first(); if (await profileTab.isVisible({ timeout: 3000 })) { await profileTab.click(); await page.waitForTimeout(2000); const profilePage = new ProfilePage(page); // Scroll to logout await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight)); await page.waitForTimeout(500); if (await profilePage.logoutButton.isVisible({ timeout: 3000 })) { await profilePage.logout(); await page.waitForTimeout(3000); // Should be back on login page const loginPage = new LoginPage(page); await loginPage.expectLoaded(); console.log('✅ Logout successful, returned to login'); } else { console.log('⚠️ Logout button not found'); } } }); }); test.describe('Profile Edit Flow', () => { test.beforeEach(async ({ page }) => { enableConsoleLogging(page); const loginPage = new LoginPage(page); await loginPage.goto(); const isOnLogin = await loginPage.welcomeText.isVisible({ timeout: 2000 }).catch(() => false); if (isOnLogin) { await loginPage.loginWithEmail(TEST_CREDENTIALS.existingUser.email); const otpPage = new OtpPage(page); await otpPage.expectLoaded(); await otpPage.enterCode(TEST_CREDENTIALS.existingUser.bypassOtp); await page.waitForTimeout(3000); } }); test('Profile edit form has required fields', async ({ page }) => { await page.goto(BASE_URL); await page.waitForLoadState('networkidle'); await page.waitForTimeout(3000); const profileTab = page.getByText('Profile').first(); if (await profileTab.isVisible({ timeout: 3000 })) { await profileTab.click(); await page.waitForTimeout(2000); const editButton = page.getByText('Edit Profile'); if (await editButton.isVisible({ timeout: 2000 })) { await editButton.click(); await page.waitForTimeout(2000); // Check for form fields const hasFirstName = await page.getByPlaceholder(/first.*name/i).isVisible({ timeout: 2000 }).catch(() => false); const hasLastName = await page.getByPlaceholder(/last.*name/i).isVisible({ timeout: 2000 }).catch(() => false); const hasPhone = await page.getByPlaceholder(/phone/i).isVisible({ timeout: 2000 }).catch(() => false); const hasSaveButton = await page.getByText(/Save|Update/i).isVisible({ timeout: 2000 }).catch(() => false); console.log(`First: ${hasFirstName}, Last: ${hasLastName}, Phone: ${hasPhone}, Save: ${hasSaveButton}`); expect(hasFirstName || hasLastName || hasPhone).toBe(true); console.log('✅ Profile edit form has fields'); } } }); test('Profile edit validates input', async ({ page }) => { await page.goto(BASE_URL); await page.waitForLoadState('networkidle'); await page.waitForTimeout(3000); const profileTab = page.getByText('Profile').first(); if (await profileTab.isVisible({ timeout: 3000 })) { await profileTab.click(); await page.waitForTimeout(2000); const editButton = page.getByText('Edit Profile'); if (await editButton.isVisible({ timeout: 2000 })) { await editButton.click(); await page.waitForTimeout(2000); // Clear name field const nameInput = page.getByPlaceholder(/first.*name/i); if (await nameInput.isVisible({ timeout: 2000 })) { await nameInput.clear(); // Try to save const saveButton = page.getByText(/Save|Update/i); if (await saveButton.isVisible({ timeout: 2000 })) { await saveButton.click(); await page.waitForTimeout(1000); // Should show validation or stay on edit page const stillOnEdit = await nameInput.isVisible({ timeout: 2000 }); expect(stillOnEdit).toBe(true); console.log('✅ Profile edit validates input'); } } } } }); });