Skip to content

feat: drawer table scroll #2364

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jun 9, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore: add tests
  • Loading branch information
astandrik committed Jun 6, 2025
commit 1ba16df5390a85b83fe2c8c26e2c42c495feb64a
2 changes: 1 addition & 1 deletion src/components/FixedHeightQuery/FixedHeightQuery.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.kv-fixed-height-query {
.ydb-fixed-height-query {
position: relative;

overflow: hidden;
Expand Down
2 changes: 1 addition & 1 deletion src/components/FixedHeightQuery/FixedHeightQuery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {YDBSyntaxHighlighter} from '../SyntaxHighlighter/YDBSyntaxHighlighter';

import './FixedHeightQuery.scss';

const b = cn('kv-fixed-height-query');
const b = cn('ydb-fixed-height-query');

const FIXED_PADDING = 8;
const LINE_HEIGHT = 20;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ export const TopQueriesData = ({
() => ({
...TOP_QUERIES_TABLE_SETTINGS,
dynamicInnerRef: reactListRef,
// Using 'uniform' type - react-list automatically calculates size from first item
}),
[],
);
Expand Down
21 changes: 21 additions & 0 deletions tests/suites/tenant/diagnostics/Diagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,27 @@ export class Table {
});
return true;
}

async clickRow(row: number) {
const rowElement = this.table.locator(`tr.data-table__row:nth-child(${row})`);
await rowElement.click();
}

async getRowPosition(row: number) {
const rowElement = this.table.locator(`tr.data-table__row:nth-child(${row})`);
return await rowElement.boundingBox();
}

async isRowVisible(row: number) {
const rowElement = this.table.locator(`tr.data-table__row:nth-child(${row})`);
const boundingBox = await rowElement.boundingBox();
if (!boundingBox) {
return false;
}

const viewportHeight = await rowElement.page().evaluate(() => window.innerHeight);
return boundingBox.y >= 0 && boundingBox.y + boundingBox.height <= viewportHeight;
}
}

export enum QueriesSwitch {
Expand Down
133 changes: 133 additions & 0 deletions tests/suites/tenant/diagnostics/tabs/queries.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,137 @@ test.describe('Diagnostics Queries tab', async () => {
// Verify the view was updated back
expect(await diagnostics.getSelectedQueryPeriod()).toBe(QueryPeriod.PerHour);
});

test('FixedHeightQuery maintains consistent height and proper scrolling behavior', async ({
page,
}) => {
const pageQueryParams = {
schema: tenantName,
database: tenantName,
tenantPage: 'diagnostics',
diagnosticsTab: 'topQueries',
};
const tenantPage = new TenantPage(page);
await tenantPage.goto(pageQueryParams);

const diagnostics = new Diagnostics(page);
await expect(diagnostics.table.isVisible()).resolves.toBe(true);

// Verify we have enough rows to test scrolling
const rowCount = await diagnostics.table.getRowCount();
if (rowCount > 5) {
// Test scrolling behavior: click on a row that might not be fully visible
const targetRowIndex = Math.min(rowCount, 8); // Target a row further down

// Click on the target row to test scrolling
await diagnostics.table.clickRow(targetRowIndex);

// Wait for any scrolling animation
await page.waitForTimeout(500);

// Verify the row is now visible in the viewport
const isVisible = await diagnostics.table.isRowVisible(targetRowIndex);
expect(isVisible).toBe(true);
}
});

test('FixedHeightQuery components have consistent height across different query lengths', async ({
page,
}) => {
const pageQueryParams = {
schema: tenantName,
database: tenantName,
tenantPage: 'diagnostics',
diagnosticsTab: 'topQueries',
};
const tenantPage = new TenantPage(page);
await tenantPage.goto(pageQueryParams);

const diagnostics = new Diagnostics(page);
await expect(diagnostics.table.isVisible()).resolves.toBe(true);

// Check that FixedHeightQuery components have the expected fixed height
const fixedHeightElements = page.locator('.ydb-fixed-height-query');
const elementCount = await fixedHeightElements.count();

if (elementCount > 1) {
// Check that all FixedHeightQuery components have the same height
const heights = [];
for (let i = 0; i < Math.min(elementCount, 5); i++) {
const element = fixedHeightElements.nth(i);
const height = await element.evaluate((el) => {
return window.getComputedStyle(el).height;
});
heights.push(height);
}

// All heights should be the same (88px for 4 lines)
const firstHeight = heights[0];
expect(firstHeight).toBe('88px');

for (const height of heights) {
expect(height).toBe(firstHeight);
}
}
});

test.only('Scroll to row, get shareable link, navigate to URL and verify row is scrolled into view', async ({
page,
}) => {
const pageQueryParams = {
schema: tenantName,
database: tenantName,
tenantPage: 'diagnostics',
diagnosticsTab: 'topQueries',
};
const tenantPage = new TenantPage(page);
await tenantPage.goto(pageQueryParams);

const diagnostics = new Diagnostics(page);
await expect(diagnostics.table.isVisible()).resolves.toBe(true);

// Get the number of rows and select a row that requires scrolling
const rowCount = await diagnostics.table.getRowCount();
if (rowCount > 5) {
const targetRowIndex = Math.min(rowCount, 8); // Target a row further down

// Click on the target row to open the drawer
await diagnostics.table.clickRow(targetRowIndex);

// Wait for drawer to open
await page.waitForTimeout(500);

// Find and click the copy link button in the drawer
const copyLinkButton = page.locator('.ydb-copy-link-button__icon').first();
await expect(copyLinkButton).toBeVisible();
await copyLinkButton.click();

// Get the copied URL from clipboard
const clipboardText = await page.evaluate(() => navigator.clipboard.readText());
expect(clipboardText).toBeTruthy();
expect(clipboardText).toContain('/tenant');

// Navigate to the copied URL
await page.goto(clipboardText);
await page.waitForTimeout(1000);

// Verify the table is visible and the target row is scrolled into view
await expect(diagnostics.table.isVisible()).resolves.toBe(true);

// Check that the target row is visible in the viewport
const isRowVisible = await diagnostics.table.isRowVisible(targetRowIndex);
expect(isRowVisible).toBe(true);

// Verify the row is highlighted/selected (if applicable)
const rowElement = page.locator(`tr.data-table__row:nth-child(${targetRowIndex})`);
const hasActiveClass = await rowElement.evaluate((el: HTMLElement) => {
return (
el.classList.contains('kv-top-queries__row_active') ||
el.classList.contains('active') ||
el.getAttribute('aria-selected') === 'true'
);
});
expect(hasActiveClass).toBe(true);
}
});
});