Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
38 changes: 21 additions & 17 deletions src/containers/Tenant/Query/ExecuteResult/ExecuteResult.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,24 +119,28 @@ export function ExecuteResult({
/>
</div>
)}
<div className={b('result')}>
<div className={b('result-head')}>
<Text variant="subheader-3">
{currentResult?.truncated
? i18n('title.truncated')
: i18n('title.result')}
</Text>
<Text
color="secondary"
variant="body-2"
className={b('row-count')}
>{`(${currentResult?.result?.length})`}</Text>
{currentResult && (
<div className={b('result')}>
<div className={b('result-head')}>
<Text variant="subheader-3">
{currentResult?.truncated
? i18n('title.truncated')
: i18n('title.result')}
</Text>
{currentResult.result && (
<Text
color="secondary"
variant="body-2"
className={b('row-count')}
>{`(${currentResult.result.length})`}</Text>
)}
</div>
<QueryResultTable
data={currentResult.result}
columns={currentResult.columns}
/>
</div>
<QueryResultTable
data={currentResult?.result}
columns={currentResult?.columns}
/>
</div>
)}
</div>
);
};
Expand Down
35 changes: 34 additions & 1 deletion tests/suites/tenant/constants.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,40 @@
// Long running query for tests
// May cause Memory exceed on real database

const simpleQuery = 'SELECT 1;';
export const simpleQuery = 'SELECT 1;';
export const longTableSelect = 'SELECT * FROM `.sys/pg_class`';

// 400 is pretty enough
export const longRunningQuery = new Array(400).fill(simpleQuery).join('');

export const createTableQuery = `
CREATE TABLE \`/local/ydb_row_table\` (
category_id Uint64 NOT NULL,
id Uint64,
expire_at Datetime,
updated_on Datetime,
name Text,
\`binary-payload\` Bytes,
attributes JsonDocument,
-- uncomment to add a secondary index
-- INDEX idx_row_table_id GLOBAL SYNC ON ( id ) COVER ( name, attributes ), -- Secondary indexes docs https://ydb.tech/en/docs/yql/reference/syntax/create_table#secondary_index
PRIMARY KEY (category_id, id)
)
WITH (
AUTO_PARTITIONING_BY_SIZE = ENABLED,
AUTO_PARTITIONING_PARTITION_SIZE_MB = 2048,
AUTO_PARTITIONING_BY_LOAD = ENABLED,
AUTO_PARTITIONING_MIN_PARTITIONS_COUNT = 4,
AUTO_PARTITIONING_MAX_PARTITIONS_COUNT = 1024
-- uncomment to create a table with predefined partitions
-- , UNIFORM_PARTITIONS = 4 -- The number of partitions for uniform initial table partitioning.
-- The primary key's first column must have type Uint64 or Uint32.
-- A created table is immediately divided into the specified number of partitions
-- uncomment to launch read only replicas in every AZ
-- , READ_REPLICAS_SETTINGS = 'PER_AZ:1' -- Enable read replicas for stale read, launch one replica in every availability zone
-- uncomment to enable ttl
-- , TTL = Interval("PT1H") ON expire_at -- Enable background deletion of expired rows https://ydb.tech/en/docs/concepts/ttl
-- uncomment to create a table with a bloom filter
-- , KEY_BLOOM_FILTER = ENABLED -- With a Bloom filter, you can more efficiently determine
-- if some keys are missing in a table when making multiple single queries by the primary key.
)`;
18 changes: 18 additions & 0 deletions tests/suites/tenant/queryEditor/QueryEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ export class SettingsDialog {
await this.page.waitForTimeout(1000);
}

async changeLimitRows(limitRows: number) {
const limitRowsInput = this.dialog.locator('.ydb-query-settings-dialog__limit-rows input');
await limitRowsInput.fill(limitRows.toString());
await this.page.waitForTimeout(1000);
}

async clickButton(buttonName: ButtonNames) {
const button = this.dialog.getByRole('button', {name: buttonName});
await button.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
Expand Down Expand Up @@ -140,10 +146,12 @@ class PaneWrapper {
export class ResultTable {
private table: Locator;
private preview: Locator;
private resultHead: Locator;

constructor(selector: Locator) {
this.table = selector.locator('.ydb-query-execute-result__result');
this.preview = selector.locator('.kv-preview__result');
this.resultHead = selector.locator('.ydb-query-execute-result__result-head');
}

async isVisible() {
Expand Down Expand Up @@ -175,6 +183,16 @@ export class ResultTable {
const cell = this.table.locator(`tr:nth-child(${row}) td:nth-child(${col})`);
return cell.innerText();
}

async isResultHeaderHidden() {
await this.resultHead.waitFor({state: 'hidden', timeout: VISIBILITY_TIMEOUT});
return true;
}

async getResultHeadText() {
await this.resultHead.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
return this.resultHead.innerText();
}
}

export class QueryEditor {
Expand Down
27 changes: 26 additions & 1 deletion tests/suites/tenant/queryEditor/queryEditor.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {expect, test} from '@playwright/test';

import {tenantName} from '../../../utils/constants';
import {NavigationTabs, TenantPage, VISIBILITY_TIMEOUT} from '../TenantPage';
import {longRunningQuery} from '../constants';
import {createTableQuery, longRunningQuery, longTableSelect} from '../constants';

import {
ButtonNames,
Expand Down Expand Up @@ -377,4 +377,29 @@ test.describe('Test Query Editor', async () => {
await tenantPage.selectNavigationTab(NavigationTabs.Query);
await expect(queryEditor.resultTable.isVisible()).resolves.toBe(true);
});

test('Result head value is 1 for 1 row result', async ({page}) => {
const queryEditor = new QueryEditor(page);
await queryEditor.setQuery(testQuery);
await queryEditor.clickRunButton();
await expect(queryEditor.resultTable.getResultHeadText()).resolves.toBe('Result(1)');
});

test('No result head value for no result', async ({page}) => {
const queryEditor = new QueryEditor(page);
await queryEditor.setQuery(createTableQuery);
await queryEditor.clickRunButton();
await page.waitForTimeout(1000);
await expect(queryEditor.resultTable.isResultHeaderHidden()).resolves.toBe(true);
});

test('Truncated head value is 1 for 1 row truncated result', async ({page}) => {
const queryEditor = new QueryEditor(page);
await queryEditor.setQuery(longTableSelect);
await queryEditor.clickGearButton();
await queryEditor.settingsDialog.changeLimitRows(1);
await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
await queryEditor.clickRunButton();
await expect(queryEditor.resultTable.getResultHeadText()).resolves.toBe('Truncated(1)');
});
});
Loading