Files
bruno/tests/devtools/network/network-log-details-scroll.spec.ts
Sid 222ac80f5e fix(devtools): network tab panel inner scroll (#8329)
* fix: ui overflow for the network tab

* test(e2e): scroller behaviour for network tab
2026-06-22 19:32:29 +05:30

102 lines
4.0 KiB
TypeScript

import { test, expect, type Locator } from '../../../playwright';
import { openCollection, openRequest, sendRequest } from '../../utils/page';
const COLLECTION_NAME = 'network-log-scroll';
const REQUEST_NAME = 'network-log-scroll';
const isEntryVisibleInScroller = async (scroller: Locator, entry: Locator) => {
const entryHandle = await entry.elementHandle();
if (!entryHandle) {
return false;
}
return scroller.evaluate((container, entryEl) => {
const containerRect = container.getBoundingClientRect();
const entryRect = entryEl.getBoundingClientRect();
return (
entryRect.height > 0
&& entryRect.top >= containerRect.top - 1
&& entryRect.bottom <= containerRect.bottom + 1
);
}, entryHandle);
};
test.describe('DevTools Network Log Details Scroll', () => {
test('last network log lines are visible and scrollable in request details panel', async ({ pageWithUserData: page }) => {
await page.locator('[data-app-state="loaded"]').waitFor({ timeout: 30000 });
await test.step('Open fixture request and send it', async () => {
await openCollection(page, COLLECTION_NAME);
await openRequest(page, COLLECTION_NAME, REQUEST_NAME);
await sendRequest(page, 200);
});
await test.step('Open DevTools Network tab and select the request', async () => {
await page.locator('button[data-trigger="dev-tools"]').click();
await expect(page.locator('.console-header')).toBeVisible();
const networkTab = page.locator('.console-tab').filter({ hasText: 'Network' });
await expect(networkTab).toBeVisible();
await networkTab.click();
await expect(networkTab).toHaveClass(/active/);
const requestRow = page.getByTestId('network-request-row').first();
await expect(requestRow).toBeVisible();
await requestRow.click();
});
const panel = page.locator('.details-panel-wrapper');
const outerScroller = panel.locator('.panel-content');
const innerScroller = panel.locator('.network-logs-wrapper .network-logs-container');
const lastEntry = innerScroller.locator('.network-logs-entry').last();
await test.step('Open Network sub-tab in request details panel', async () => {
await expect(panel.getByText('Request Details')).toBeVisible();
const networkSubTab = panel.locator('.tab-button').filter({ hasText: 'Network' });
await expect(networkSubTab).toBeVisible();
await networkSubTab.click();
await expect(networkSubTab).toHaveClass(/active/);
await expect(innerScroller).toBeVisible();
});
await test.step('Verify nested inner scroller overflows', async () => {
const innerOverflows = await innerScroller.evaluate((el) => el.scrollHeight > el.clientHeight);
expect(innerOverflows).toBe(true);
await expect(lastEntry).toContainText(/Request completed in/);
});
await test.step('Outer panel scroll alone does not reveal the last log line', async () => {
const initialOuterScrollTop = await outerScroller.evaluate((el) => el.scrollTop);
expect(initialOuterScrollTop).toBe(0);
await outerScroller.evaluate((el) => {
el.scrollTop = el.scrollHeight;
});
await expect.poll(() => isEntryVisibleInScroller(innerScroller, lastEntry)).toBe(false);
await outerScroller.evaluate((el) => {
el.scrollTop = 0;
});
});
await test.step('Scroll nested inner container and verify last log line is visible in viewport', async () => {
await expect(async () => {
await innerScroller.evaluate((el) => {
el.scrollTop = el.scrollHeight;
});
const scrollTop = await innerScroller.evaluate((el) => el.scrollTop);
expect(scrollTop).toBeGreaterThan(0);
await expect(lastEntry).toBeVisible({ timeout: 1000 });
expect(await isEntryVisibleInScroller(innerScroller, lastEntry)).toBe(true);
}).toPass({ timeout: 10000 });
const outerScrollTop = await outerScroller.evaluate((el) => el.scrollTop);
expect(outerScrollTop).toBe(0);
});
});
});