Fix horizontal page overflow caused by wide tables
Wide tables stretched the whole page because the shell's main is a flex item without min-width:0 and no table had a scroll container, so the header and the summary tiles scrolled out of view. Every table now scrolls inside its own overflow-x-auto container, the sidebar no longer shrinks, and long CVE ids, versions, targets and image references are kept on one line or truncated with a title tooltip. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
61
frontend/e2e/layout.spec.ts
Normal file
61
frontend/e2e/layout.spec.ts
Normal file
@ -0,0 +1,61 @@
|
||||
import { test, expect, type Page } from '@playwright/test'
|
||||
|
||||
// Wide content (tables) must scroll inside its own container; the page itself must never
|
||||
// scroll horizontally, otherwise the header and the tiles get cut off.
|
||||
const PAGES = [
|
||||
'/',
|
||||
'/updates',
|
||||
'/cluster',
|
||||
'/vulnerabilities',
|
||||
'/backups',
|
||||
'/jobs',
|
||||
'/users',
|
||||
'/settings',
|
||||
]
|
||||
|
||||
async function login(page: Page) {
|
||||
await page.goto('/login')
|
||||
await page.getByLabel('Email').fill('admin@example.com')
|
||||
await page.getByLabel('Password').fill('admin-password-123')
|
||||
await page.getByRole('button', { name: 'Sign in' }).click()
|
||||
await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible()
|
||||
}
|
||||
|
||||
const pageOverflow = (page: Page) =>
|
||||
page.evaluate(() => document.documentElement.scrollWidth - document.documentElement.clientWidth)
|
||||
|
||||
test('no page scrolls horizontally, with data and on a narrow window', async ({ page }) => {
|
||||
await page.setViewportSize({ width: 1280, height: 800 })
|
||||
await login(page)
|
||||
|
||||
// fill the app with the data that makes the tables wide
|
||||
await page.goto('/updates')
|
||||
await page.getByRole('button', { name: 'Refresh inventory' }).click()
|
||||
await expect(page.getByTestId('os-name')).toContainText('Debian', { timeout: 15_000 })
|
||||
await page.goto('/vulnerabilities')
|
||||
await page.getByRole('button', { name: 'Scan now' }).click()
|
||||
await expect(page.getByTestId('count-critical')).not.toHaveText('0', { timeout: 20_000 })
|
||||
|
||||
for (const width of [1440, 1280, 1024, 900]) {
|
||||
await page.setViewportSize({ width, height: 800 })
|
||||
for (const path of PAGES) {
|
||||
await page.goto(path)
|
||||
await expect(page.getByRole('heading').first()).toBeVisible()
|
||||
expect(await pageOverflow(page), `${path} at ${width}px scrolls horizontally`).toBe(0)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test('the findings table scrolls inside its own container', async ({ page }) => {
|
||||
await page.setViewportSize({ width: 900, height: 800 })
|
||||
await login(page)
|
||||
await page.goto('/vulnerabilities')
|
||||
await page.getByRole('button', { name: 'Scan now' }).click()
|
||||
await expect(page.getByTestId('count-critical')).not.toHaveText('0', { timeout: 20_000 })
|
||||
|
||||
expect(await pageOverflow(page)).toBe(0)
|
||||
const scrollable = await page
|
||||
.getByTestId('findings-scroll')
|
||||
.evaluate((el) => el.scrollWidth > el.clientWidth && getComputedStyle(el).overflowX === 'auto')
|
||||
expect(scrollable).toBe(true)
|
||||
})
|
||||
Reference in New Issue
Block a user