import { observedTrafficFixturePayload } from "./traffic-observation-fixture" import { test, expect, type Page } from '@playwright/test' const longName = 'customer-with-a-very-long-unbroken-identifier-12345678901234567890' async function setup(page: Page, empty = false) { const metrics = { rxNow: 2, txNow: 3, rxPeak: 4, txPeak: 5, rxTotal: 100, txTotal: 200, rxSeries: [1, 2], txSeries: [2, 3] } const iface = { ...metrics, id: 'i1', bindingId: 'b1', userId: 'u1', userLogin: longName, userName: longName, interfaceName: longName, interfaceType: 'gre', comment: longName, serverId: '1', serverName: longName, serverSite: 'TEST', serverCountry: 'RU', status: 'online' } const user = { ...metrics, id: 'u1', login: longName, displayName: longName, role: 'viewer', interfaces: [iface] } await page.route('**/health', r => r.fulfill({ json: observedTrafficFixturePayload({ ok: true }) })) await page.route('**/api/**', route => { const path = new URL(route.request().url()).pathname const json = path === '/api/auth/config' ? { required: false } : path === '/api/traffic/servers' ? { servers: [] } : path === '/api/traffic/users' ? { users: empty ? [] : [user] } : path === '/api/traffic/bound-interfaces' ? { interfaces: empty ? [] : [iface] } : path.endsWith('/interfaces') ? { interfaces: [] } : path === '/api/servers' ? [] : {} return route.fulfill({ json: observedTrafficFixturePayload(json) }) }) await page.goto('/traffic') } for (const width of [320, 390]) { for (const mode of ['Клиенты', 'Интерфейсы']) { test(`Трафик: ${mode}, длинные значения, ${width}px`, async ({ page }) => { await page.setViewportSize({ width, height: 900 }) await setup(page) await page.getByRole('button', { name: mode, exact: true }).click() const heading = page.getByRole('heading', { name: longName, exact: true }) await expect(heading).toBeVisible() const box = await heading.boundingBox() expect(box!.x + box!.width).toBeLessThanOrEqual(width + 1) await page.getByRole('button', { name: '24ч', exact: true }).click() await expect(heading).toBeVisible() const overflow = await page.evaluate(() => [...document.querySelectorAll('main *')].filter(el => { const r = el.getBoundingClientRect() return r.width > 0 && r.right > innerWidth + 1 && getComputedStyle(el).position !== 'fixed' && !el.closest('[aria-label="Разделы трафика"]') }).map(el => el.tagName + '.' + el.className)) expect(overflow).toEqual([]) await page.screenshot({ path: `test-results/traffic-${mode}-${width}.png`, fullPage: true }) }) } } test('Трафик: пустой список клиентов имеет объяснение', async ({ page }) => { await setup(page, true) await page.getByRole('button', { name: 'Клиенты', exact: true }).click() await expect(page.getByText('Нет клиентов с данными трафика', { exact: true })).toBeVisible() }) test('Трафик: поиск без совпадений сохраняет данные при очистке', async ({ page }) => { await setup(page) await page.getByRole('button', { name: 'Клиенты', exact: true }).click() await expect(page.getByRole('heading', { name: longName, exact: true })).toBeVisible() await page.getByPlaceholder('Поиск…').fill('отсутствующий-клиент') await expect(page.getByText('По вашему запросу ничего не найдено', { exact: true })).toBeVisible() await expect(page.getByText('Нет клиентов с данными трафика', { exact: true })).toHaveCount(0) await page.getByPlaceholder('Поиск…').fill('') await expect(page.getByText('По вашему запросу ничего не найдено', { exact: true })).toHaveCount(0) await expect(page.getByRole('button').filter({ hasText: longName })).toHaveCount(1) })