import { test, expect } from '@playwright/test'; import { login, TEST_ORG_SLUG, TEST_EMAIL, waitForHydration, navigateTo } from './helpers'; test('should log in and reach org dashboard', async ({ page }) => { await login(page); await expect(page).toHaveURL(new RegExp(`/${TEST_ORG_SLUG}`)); }); test.describe('Sidebar', () => { test.beforeEach(async ({ page }) => { await login(page); }); test('should display logo in sidebar', async ({ page }) => { const logo = page.locator('aside svg'); await expect(logo.first()).toBeVisible(); }); test('should display user avatar and email in sidebar', async ({ page }) => { const userMenu = page.locator('.user-menu-container'); await expect(userMenu).toBeVisible(); // Profile link and logout button should be visible await expect(userMenu.locator('button[aria-label="Sign Out"]')).toBeVisible(); await expect(userMenu.locator('a')).toBeVisible(); }); test('should show user profile link and logout button in sidebar', async ({ page }) => { const userMenu = page.locator('.user-menu-container'); // Profile link navigates to account settings const profileLink = userMenu.locator('a'); await expect(profileLink).toBeVisible(); // Logout button is visible const logoutBtn = userMenu.locator('button[aria-label="Sign Out"]'); await expect(logoutBtn).toBeVisible(); }); test('should show user name in sidebar profile area', async ({ page }) => { const userMenu = page.locator('.user-menu-container'); // Profile area shows a link with user info const profileLink = userMenu.locator('a'); await expect(profileLink).toBeVisible({ timeout: 5000 }); }); test('should navigate to account settings via profile link', async ({ page }) => { const profileLink = page.locator('.user-menu-container a').first(); await expect(profileLink).toBeVisible(); await profileLink.click(); await page.waitForURL(new RegExp(`/${TEST_ORG_SLUG}/account`), { timeout: 10000 }); }); test('sidebar nav items should be visible', async ({ page }) => { const aside = page.locator('aside'); await expect(aside).toBeVisible(); const navLinks = aside.locator('nav a'); const count = await navLinks.count(); expect(count).toBeGreaterThan(0); }); }); test.describe('Account Settings Page', () => { test.beforeEach(async ({ page }) => { await navigateTo(page, `/${TEST_ORG_SLUG}/account`); }); test('should display Profile section with all elements', async ({ page }) => { await expect(page.getByRole('heading', { name: 'Profile' })).toBeVisible({ timeout: 10000 }); await expect(page.getByText('Display Name')).toBeVisible(); await expect(page.getByText('Email').first()).toBeVisible(); await expect(page.getByRole('button', { name: 'Upload' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Sync Google' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Save Profile' }).first()).toBeVisible(); }); test('should display Appearance section with color picker', async ({ page }) => { await expect(page.getByRole('heading', { name: 'Appearance' })).toBeVisible(); await expect(page.getByText('Accent Color')).toBeVisible(); // Custom color picker label const colorPicker = page.locator('label[title="Custom color"]'); await expect(colorPicker).toBeVisible(); // Org theme toggle await expect(page.getByText('Use Organization Theme')).toBeVisible(); await expect(page.getByRole('button', { name: 'Save Preferences' })).toBeVisible(); }); test('should display Security & Sessions section', async ({ page }) => { await expect(page.getByRole('heading', { name: 'Security & Sessions' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Send Reset Email' })).toBeVisible(); await expect(page.getByRole('button', { name: 'Sign Out Other Sessions' })).toBeVisible(); }); test('accent color swatches should be clickable', async ({ page }) => { const swatches = page.locator('.flex.flex-wrap button[type="button"]'); const count = await swatches.count(); expect(count).toBeGreaterThanOrEqual(8); // Click the third swatch (Red) await swatches.nth(2).click(); await expect(swatches.nth(2)).toHaveClass(/border-white/); }); }); test.describe('Kanban Page - ContextMenu', () => { test.beforeEach(async ({ page }) => { await navigateTo(page, `/${TEST_ORG_SLUG}/kanban`); }); test('should load kanban page', async ({ page }) => { await expect(page.getByRole('heading', { name: 'Kanban' })).toBeVisible(); }); test('should have context menu button in header', async ({ page }) => { const moreBtn = page.getByRole('button', { name: 'More options' }); await expect(moreBtn).toBeVisible(); }); test('should open context menu on click', async ({ page }) => { const moreBtn = page.getByRole('button', { name: 'More options' }); await moreBtn.click(); await expect(moreBtn).toHaveAttribute('aria-expanded', 'true', { timeout: 3000 }); // Menu dropdown should be visible const menu = page.locator('.context-menu-container div.absolute'); await expect(menu).toBeVisible({ timeout: 3000 }); }); }); test.describe('Calendar Page - ContextMenu', () => { test.beforeEach(async ({ page }) => { await navigateTo(page, `/${TEST_ORG_SLUG}/calendar`); }); test('should load calendar page', async ({ page }) => { await expect(page.getByRole('heading', { name: 'Calendar' })).toBeVisible(); }); test('should have context menu button in header', async ({ page }) => { const moreBtn = page.getByRole('button', { name: 'More options' }); await expect(moreBtn).toBeVisible(); }); test('should show Refresh Events in context menu', async ({ page }) => { const moreBtn = page.getByRole('button', { name: 'More options' }); await moreBtn.click(); await expect(moreBtn).toHaveAttribute('aria-expanded', 'true', { timeout: 3000 }); await expect(page.getByText('Refresh Events')).toBeVisible({ timeout: 3000 }); }); });