Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
39 lines
1.9 KiB
TypeScript
39 lines
1.9 KiB
TypeScript
import { expect, test } from '@playwright/test'
|
|
|
|
test.use({ viewport: { width: 390, height: 844 }, deviceScaleFactor: 2, isMobile: true })
|
|
|
|
test('public mobile route stays inside the lab Core Web Vitals budget', async ({ browserName, page }) => {
|
|
test.skip(browserName !== 'chromium', 'Chromium exposes the Event Timing/LCP observers used by this lab budget')
|
|
await page.addInitScript(() => {
|
|
const values = { cls: 0, inp: 0, lcp: 0 }
|
|
|
|
Object.assign(window, { __labVitals: values })
|
|
new PerformanceObserver((list) => {
|
|
const latest = list.getEntries().at(-1)
|
|
|
|
if (latest) values.lcp = latest.startTime
|
|
}).observe({ type: 'largest-contentful-paint', buffered: true })
|
|
new PerformanceObserver((list) => {
|
|
for (const entry of list.getEntries() as (PerformanceEntry & { hadRecentInput?: boolean; value?: number })[]) {
|
|
if (!entry.hadRecentInput) values.cls += entry.value ?? 0
|
|
}
|
|
}).observe({ type: 'layout-shift', buffered: true })
|
|
new PerformanceObserver((list) => {
|
|
for (const entry of list.getEntries() as (PerformanceEntry & { duration: number; interactionId?: number })[]) {
|
|
if (entry.interactionId) values.inp = Math.max(values.inp, entry.duration)
|
|
}
|
|
}).observe({ type: 'event', buffered: true, durationThreshold: 16 } as PerformanceObserverInit)
|
|
})
|
|
await page.route('**/api/v1/**', (route) => route.fulfill({ json: { success: true, data: { items: [], meta: {} } } }))
|
|
await page.goto('/')
|
|
await page.getByRole('tab', { name: 'دستهبندی' }).click()
|
|
await page.waitForTimeout(500)
|
|
|
|
const vitals = await page.evaluate(() => (window as unknown as { __labVitals: { cls: number; inp: number; lcp: number } }).__labVitals)
|
|
|
|
expect(vitals.lcp).toBeGreaterThan(0)
|
|
expect(vitals.lcp).toBeLessThanOrEqual(2500)
|
|
expect(vitals.cls).toBeLessThanOrEqual(0.1)
|
|
expect(vitals.inp).toBeLessThanOrEqual(200)
|
|
})
|