99 خطوط
4.2 KiB
TypeScript
99 خطوط
4.2 KiB
TypeScript
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!)
|
|
})
|