Files
zpan/e2e/responsive-admin.spec.ts
T
2026-07-20 22:35:12 -04:00

99 lines
3.8 KiB
TypeScript

import { expect, test } from '@playwright/test'
import { signInAsAdmin } from './helpers'
// ---------------------------------------------------------------------------
// Admin sidebar
// ---------------------------------------------------------------------------
test.describe('Admin sidebar responsive', () => {
test('desktop: admin sidebar is visible @desktop', async ({ page }) => {
await signInAsAdmin(page)
const sidebar = page.locator('[data-slot="sidebar"]')
await expect(sidebar).toBeVisible()
const navLinks = await sidebar.locator('a').evaluateAll((links) => links.map((link) => link.getAttribute('href')))
expect(navLinks.indexOf('/admin/analytics')).toBe(navLinks.indexOf('/admin/audit') + 1)
})
test('mobile: admin sidebar opens via trigger @mobile', async ({ page }) => {
await signInAsAdmin(page)
const sidebar = page.locator('[data-slot="sidebar"]')
await expect(sidebar).not.toBeInViewport()
const trigger = page.locator('button[data-sidebar="trigger"]')
await expect(trigger).toBeVisible()
await trigger.click()
await expect(sidebar).toBeVisible()
})
})
// ---------------------------------------------------------------------------
// Admin overview dashboard
// ---------------------------------------------------------------------------
test.describe('Admin overview dashboard responsive', () => {
test('dashboard widgets stay inside the viewport @all', async ({ page }) => {
await signInAsAdmin(page)
await page.goto('/admin')
await page.waitForURL(/\/admin\/dashboard\/?$/, { timeout: 10000 })
const cards = page.locator('[data-slot="card"]')
await expect(cards).toHaveCount(12)
const hasHScroll = await page.evaluate(
() => document.documentElement.scrollWidth > document.documentElement.clientWidth,
)
expect(hasHScroll).toBe(false)
const viewport = page.viewportSize()
expect(viewport).not.toBeNull()
for (const card of await cards.all()) {
const box = await card.boundingBox()
expect(box).not.toBeNull()
expect(box?.x).toBeGreaterThanOrEqual(0)
expect((box?.x ?? 0) + (box?.width ?? 0)).toBeLessThanOrEqual((viewport?.width ?? 0) + 1)
}
})
})
// ---------------------------------------------------------------------------
// Admin storages page
// ---------------------------------------------------------------------------
test.describe('Admin storages page responsive', () => {
test('storages page has no horizontal overflow @all', async ({ page }) => {
await signInAsAdmin(page)
const hasHScroll = await page.evaluate(
() => document.documentElement.scrollWidth > document.documentElement.clientWidth,
)
expect(hasHScroll).toBe(false)
})
})
// ---------------------------------------------------------------------------
// Admin users page
// ---------------------------------------------------------------------------
test.describe('Admin users page responsive', () => {
test('mobile: users page has no horizontal overflow @mobile', async ({ page }) => {
await signInAsAdmin(page)
await page.goto('/admin/users')
await page.waitForURL(/admin\/users/, { timeout: 10000 })
const hasHScroll = await page.evaluate(
() => document.documentElement.scrollWidth > document.documentElement.clientWidth,
)
expect(hasHScroll).toBe(false)
})
test('mobile: secondary user columns are hidden @mobile', async ({ page }) => {
await signInAsAdmin(page)
await page.goto('/admin/users')
await page.waitForURL(/admin\/users/, { timeout: 10000 })
const table = page.locator('table')
await expect(table.locator('th', { hasText: /email/i })).not.toBeVisible()
await expect(table.locator('th', { hasText: /quota/i })).not.toBeVisible()
await expect(table.locator('th', { hasText: /created/i })).not.toBeVisible()
})
})