import { expect, test } from './fixtures' test.beforeEach(async ({ page }) => { await page.route('**/api/**', async (route) => { const url = new URL(route.request().url()) if (!url.pathname.startsWith('/api/')) return route.continue() if (url.pathname === '/api/auth/me') { return route.fulfill({ json: { data: { id: 1, name: 'مدیر تست', email: 'admin@example.test', roles: ['admin'], permissions: ['view_leads', 'create_calls', 'assign_leads'], is_active: true, } } }) } if (url.pathname === '/api/leads/1') { return route.fulfill({ json: { id: 1, company: 'شرکت تست چیدمان', first_name: 'مینا', last_name: 'احمدی', phone: '09120000000', notes: [], contacts: [], contactRelations: [], callLogs: [], call_attempts: 2, assignee: { id: 2, name: 'کارشناس تست' }, } }) } if (url.pathname === '/api/calls' || url.pathname === '/api/follow-ups') { return route.fulfill({ json: { data: [], meta: { current_page: 1, last_page: 1, per_page: 50, total: 0 } } }) } if (url.pathname === '/api/call-results') return route.fulfill({ json: [] }) if (url.pathname === '/api/timeline' || url.pathname === '/api/attachments') return route.fulfill({ json: { data: [] } }) if (url.pathname === '/api/users/referral-targets') return route.fulfill({ json: [] }) if (url.pathname === '/api/users') return route.fulfill({ json: { data: [] } }) if (url.pathname === '/api/notifications/unread-count') return route.fulfill({ json: { data: 0 } }) if (url.pathname === '/api/settings/public') return route.fulfill({ json: { data: {} } }) return route.fulfill({ json: { data: [] } }) }) }) test('lead header stays compact and does not cover content in a short desktop viewport', async ({ page }) => { await page.setViewportSize({ width: 1917, height: 375 }) await page.goto('/leads/1') const appHeader = page.getByTestId('app-header') const actionBar = page.getByTestId('lead-action-bar') const scrollContainer = page.getByTestId('app-scroll-container') const summaryLabel = page.getByText('مخاطب اصلی برای تماس بعدی') await expect(page.getByRole('heading', { name: 'شرکت تست چیدمان' })).toBeVisible() await actionBar.evaluate(async (element) => { const animations = element.parentElement?.getAnimations() ?? [] await Promise.all(animations.map((animation) => animation.finished)) }) const initialHeaderBox = await appHeader.boundingBox() const initialActionBox = await actionBar.boundingBox() const initialSummaryBox = await summaryLabel.boundingBox() expect(initialHeaderBox).not.toBeNull() expect(initialActionBox).not.toBeNull() expect(initialSummaryBox).not.toBeNull() expect(initialHeaderBox!.height).toBeLessThanOrEqual(65) expect(initialActionBox!.height).toBeLessThanOrEqual(65) expect(Math.abs(initialActionBox!.y - (initialHeaderBox!.y + initialHeaderBox!.height))).toBeLessThanOrEqual(1) expect(initialSummaryBox!.y).toBeGreaterThanOrEqual(initialActionBox!.y + initialActionBox!.height) await scrollContainer.evaluate((element) => { element.scrollTop = 320 }) await expect.poll(async () => (await actionBar.boundingBox())?.y).toBe(initialHeaderBox!.y + initialHeaderBox!.height) const stickyActionBox = await actionBar.boundingBox() const followupsBox = await page.getByTestId('lead-followups').boundingBox() expect(stickyActionBox).not.toBeNull() expect(followupsBox).not.toBeNull() expect(followupsBox!.y).toBeGreaterThanOrEqual(stickyActionBox!.y + stickyActionBox!.height + 15) }) test('lead actions remain in normal flow on mobile', async ({ page }) => { await page.setViewportSize({ width: 375, height: 812 }) await page.goto('/leads/1') const actionBar = page.getByTestId('lead-action-bar') const scrollContainer = page.getByTestId('app-scroll-container') const initialY = (await actionBar.boundingBox())?.y expect(initialY).toBeDefined() await scrollContainer.evaluate((element) => { element.scrollTop = 240 }) await expect.poll(async () => (await actionBar.boundingBox())?.y).toBeLessThan(initialY!) })