|
- import { captureScreenshot, expect, test } from './fixtures'
- import { loginAsAdmin } from './helpers'
-
- const navigationModes = [
- { label: '顶部一级 + 左侧二级', value: 'top-side' },
- { label: '左侧分组菜单', value: 'side' },
- { label: '顶部下拉菜单', value: 'top' },
- ] as const
-
- const waitForDashboard = async (page: import('@playwright/test').Page) => {
- await expect(page.locator('.platform-shell')).toBeVisible()
- await expect(page.getByRole('heading', { name: '前后端联调状态' })).toBeVisible()
- await expect(page.getByText('2/2', { exact: true })).toBeVisible({ timeout: 15_000 })
- await expect(page.locator('.dashboard-metrics article').first().locator('b')).not.toHaveText('0', { timeout: 15_000 })
- }
-
- const contrastRatio = (foreground: string, background: string) => {
- const channels = (value: string) => (value.match(/[\d.]+/g) ?? []).slice(0, 3).map(Number)
- const luminance = (value: string) => channels(value).reduce((sum, channel, index) => {
- const normalized = channel / 255
- const linear = normalized <= .03928 ? normalized / 12.92 : ((normalized + .055) / 1.055) ** 2.4
- return sum + linear * [.2126, .7152, .0722][index]!
- }, 0)
- const [lighter, darker] = [luminance(foreground), luminance(background)].sort((left, right) => right - left)
- return (lighter! + .05) / (darker! + .05)
- }
-
- test('三种导航模式与三种主题可以持久化', async ({ page }, testInfo) => {
- await page.emulateMedia({ colorScheme: 'dark' })
- await loginAsAdmin(page)
- await expect(page.locator('.platform-shell')).toHaveAttribute('data-navigation-mode', 'top-side')
- await expect(page.locator('html')).toHaveAttribute('data-theme', 'light')
- await expect(page.locator('.platform-header')).toHaveCSS('background-color', 'rgb(255, 255, 255)')
- expect(await page.locator('html').evaluate((element) => getComputedStyle(element).getPropertyValue('--primary').trim())).toBe('#0b7a70')
-
- for (const mode of navigationModes) {
- await test.step(`导航模式:${mode.label}`, async () => {
- await page.getByRole('button', { name: '界面与导航设置' }).click()
- const drawer = page.locator('.el-drawer:visible')
- await drawer.getByRole('button', { name: new RegExp(mode.label.replace('+', '\\+')) }).click()
- await expect(page.locator('.platform-shell')).toHaveAttribute('data-navigation-mode', mode.value)
- await page.keyboard.press('Escape')
- await page.reload()
- await expect(page.locator('.platform-shell')).toHaveAttribute('data-navigation-mode', mode.value)
- await waitForDashboard(page)
- await captureScreenshot(page, testInfo, `navigation-${mode.value}`)
- })
- }
-
- await test.step('桌面侧栏收起、刷新持久化与展开恢复', async () => {
- await page.getByRole('button', { name: '界面与导航设置' }).click()
- const drawer = page.locator('.el-drawer:visible')
- await drawer.getByRole('button', { name: /顶部一级 \+ 左侧二级/ }).click()
- await page.keyboard.press('Escape')
- await expect(drawer).toBeHidden()
-
- const shell = page.locator('.platform-shell')
- await expect(shell).toHaveAttribute('data-navigation-mode', 'top-side')
- const collapseButton = page.getByRole('button', { name: '收起左侧导航' })
- await expect(collapseButton).toBeVisible()
- await collapseButton.click()
- await expect(shell).toHaveClass(/sidebar-collapsed/)
- await expect(page.getByRole('button', { name: '展开左侧导航' })).toBeVisible()
- await captureScreenshot(page, testInfo, 'sidebar-collapsed')
-
- await page.reload()
- await waitForDashboard(page)
- await expect(shell).toHaveClass(/sidebar-collapsed/)
- const expandButton = page.getByRole('button', { name: '展开左侧导航' })
- await expect(expandButton).toBeVisible()
- await expandButton.click()
- await expect(shell).not.toHaveClass(/sidebar-collapsed/)
- await expect(page.getByRole('button', { name: '收起左侧导航' })).toBeVisible()
- await captureScreenshot(page, testInfo, 'sidebar-expanded')
-
- await page.reload()
- await waitForDashboard(page)
- await expect(shell).not.toHaveClass(/sidebar-collapsed/)
- })
-
- const themes = [
- { label: '明亮', value: 'light', expected: 'light' },
- { label: '暗黑', value: 'dark', expected: 'dark' },
- { label: '跟随系统', value: 'system', expected: 'dark' },
- ] as const
-
- for (const theme of themes) {
- await test.step(`主题模式:${theme.label}`, async () => {
- await page.getByRole('button', { name: '界面与导航设置' }).click()
- const drawer = page.locator('.el-drawer:visible')
- await drawer.getByRole('button', { name: new RegExp(theme.label) }).click()
- await expect(page.locator('html')).toHaveAttribute('data-theme', theme.expected)
- await page.keyboard.press('Escape')
- await page.reload()
- await expect(page.locator('html')).toHaveAttribute('data-theme', theme.expected)
- await waitForDashboard(page)
- if (theme.expected === 'dark') {
- const colors = await page.locator('.dashboard-metrics article').first().evaluate((element) => ({
- foreground: getComputedStyle(element).color,
- background: getComputedStyle(element).backgroundColor,
- }))
- expect(contrastRatio(colors.foreground, colors.background)).toBeGreaterThanOrEqual(4.5)
- expect(await page.locator('html').evaluate((element) => getComputedStyle(element).getPropertyValue('--primary').trim())).toBe('#55d0bd')
- }
- await captureScreenshot(page, testInfo, `theme-${theme.value}`)
- })
- }
-
- // 保持默认值,避免 headed 模式下人工继续检查时继承最后一次设置。
- await page.getByRole('button', { name: '界面与导航设置' }).click()
- const drawer = page.locator('.el-drawer:visible')
- await drawer.getByRole('button', { name: /明亮/ }).click()
- await drawer.getByRole('button', { name: /顶部一级 \+ 左侧二级/ }).click()
- })
|