{option.content}
{option.isDefault ? i18n('description.default') : ''}
diff --git a/tests/suites/tenant/queryEditor/models/QueryEditor.ts b/tests/suites/tenant/queryEditor/models/QueryEditor.ts
index aec62a2ab..cae3c8ce9 100644
--- a/tests/suites/tenant/queryEditor/models/QueryEditor.ts
+++ b/tests/suites/tenant/queryEditor/models/QueryEditor.ts
@@ -1,5 +1,6 @@
import type {Locator, Page} from '@playwright/test';
+import type {QUERY_MODES} from '../../../../../src/utils/query';
import {VISIBILITY_TIMEOUT} from '../../TenantPage';
import {QueryTabsNavigation} from './QueryTabsNavigation';
@@ -7,12 +8,6 @@ import {PaneWrapper, ResultTable} from './ResultTable';
import {SavedQueriesTable} from './SavedQueriesTable';
import {SettingsDialog} from './SettingsDialog';
-export enum QueryMode {
- YQLScript = 'YQL Script',
- Data = 'DML',
- Scan = 'Scan',
-}
-
export enum ExplainResultType {
Schema = 'Schema',
JSON = 'JSON',
@@ -85,7 +80,7 @@ export class QueryEditor {
this.savedQueries = new SavedQueriesTable(page);
}
- async run(query: string, mode: QueryMode) {
+ async run(query: string, mode: keyof typeof QUERY_MODES) {
await this.clickGearButton();
await this.settingsDialog.changeQueryMode(mode);
await this.settingsDialog.clickButton(ButtonNames.Save);
@@ -93,7 +88,7 @@ export class QueryEditor {
await this.clickRunButton();
}
- async explain(query: string, mode: QueryMode) {
+ async explain(query: string, mode: keyof typeof QUERY_MODES) {
await this.clickGearButton();
await this.settingsDialog.changeQueryMode(mode);
await this.settingsDialog.clickButton(ButtonNames.Save);
diff --git a/tests/suites/tenant/queryEditor/models/SettingsDialog.ts b/tests/suites/tenant/queryEditor/models/SettingsDialog.ts
index 4aacf4321..e428e9129 100644
--- a/tests/suites/tenant/queryEditor/models/SettingsDialog.ts
+++ b/tests/suites/tenant/queryEditor/models/SettingsDialog.ts
@@ -1,54 +1,81 @@
import type {Locator, Page} from '@playwright/test';
+import type {
+ QUERY_MODES,
+ STATISTICS_MODES,
+ TRANSACTION_MODES,
+} from '../../../../../src/utils/query';
import {VISIBILITY_TIMEOUT} from '../../TenantPage';
-import type {ButtonNames, QueryMode} from './QueryEditor';
+import type {ButtonNames} from './QueryEditor';
export class SettingsDialog {
private dialog: Locator;
private page: Page;
+ private selectPopup: Locator;
+ private limitRowsInput: Locator;
+
+ private queryModeSelect: Locator;
+ private transactionModeSelect: Locator;
+ private statisticsModeSelect: Locator;
+ private statisticsModeTooltip: Locator;
constructor(page: Page) {
this.page = page;
this.dialog = page.locator('.ydb-query-settings-dialog');
- }
- async changeQueryMode(mode: QueryMode) {
- const dropdown = this.dialog.locator(
+ this.limitRowsInput = this.dialog.locator('.ydb-query-settings-dialog__limit-rows input');
+ this.selectPopup = page.locator('.ydb-query-settings-select__popup');
+
+ // Define distinct locators for selects
+ this.queryModeSelect = this.dialog.locator(
'.ydb-query-settings-dialog__control-wrapper_queryMode',
);
- await dropdown.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
- await dropdown.click();
- const popup = this.page.locator('.ydb-query-settings-select__popup');
- await popup.getByText(mode).first().click();
+ this.transactionModeSelect = this.dialog.locator(
+ '.ydb-query-settings-dialog__control-wrapper_transactionMode',
+ );
+ this.statisticsModeSelect = this.dialog.locator(
+ '.ydb-query-settings-dialog__control-wrapper_statisticsMode',
+ );
+ this.statisticsModeTooltip = this.page.locator(
+ '.ydb-query-settings-dialog__statistics-mode-tooltip',
+ );
+ }
+
+ async changeQueryMode(mode: (typeof QUERY_MODES)[keyof typeof QUERY_MODES]) {
+ await this.queryModeSelect.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
+ await this.queryModeSelect.click();
+ await this.selectPopup.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
+ await this.page.locator(`.ydb-query-settings-select__item_type_${mode}`).click();
await this.page.waitForTimeout(1000);
}
- async changeTransactionMode(level: string) {
- const dropdown = this.dialog.locator(
- '.ydb-query-settings-dialog__control-wrapper_transactionMode',
- );
- await dropdown.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
- await dropdown.click();
- const popup = this.page.locator('.ydb-query-settings-select__popup');
- await popup.getByText(level).first().click();
+ async changeTransactionMode(level: (typeof TRANSACTION_MODES)[keyof typeof TRANSACTION_MODES]) {
+ await this.transactionModeSelect.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
+ await this.transactionModeSelect.click();
+ await this.selectPopup.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
+ await this.page.locator(`.ydb-query-settings-select__item_type_${level}`).click();
await this.page.waitForTimeout(1000);
}
- async changeStatsLevel(mode: string) {
- const dropdown = this.dialog.locator(
- '.ydb-query-settings-dialog__control-wrapper_statisticsMode',
- );
- await dropdown.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
- await dropdown.click();
- const popup = this.page.locator('.ydb-query-settings-select__popup');
- await popup.getByText(mode).first().click();
+ async changeStatsLevel(mode: (typeof STATISTICS_MODES)[keyof typeof STATISTICS_MODES]) {
+ await this.statisticsModeSelect.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
+ await this.statisticsModeSelect.click();
+ await this.selectPopup.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
+ await this.page.locator(`.ydb-query-settings-select__item_type_${mode}`).click();
await this.page.waitForTimeout(1000);
}
+ async getStatsLevel() {
+ await this.statisticsModeSelect.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
+ const selectedText = await this.statisticsModeSelect
+ .locator('.g-select-control__option-text')
+ .textContent();
+ return selectedText;
+ }
+
async changeLimitRows(limitRows: number) {
- const limitRowsInput = this.dialog.locator('.ydb-query-settings-dialog__limit-rows input');
- await limitRowsInput.fill(limitRows.toString());
+ await this.limitRowsInput.fill(limitRows.toString());
await this.page.waitForTimeout(1000);
}
@@ -63,8 +90,23 @@ export class SettingsDialog {
return true;
}
+ async isStatsTooltipVisible() {
+ await this.statisticsModeTooltip.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
+ return true;
+ }
+
async isHidden() {
await this.dialog.waitFor({state: 'hidden', timeout: VISIBILITY_TIMEOUT});
return true;
}
+
+ async isStatisticsSelectDisabled() {
+ await this.statisticsModeSelect.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
+ return this.statisticsModeSelect.locator('.g-select-control_disabled').isVisible();
+ }
+
+ async hoverStatisticsSelect() {
+ await this.statisticsModeSelect.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
+ await this.statisticsModeSelect.hover();
+ }
}
diff --git a/tests/suites/tenant/queryEditor/planToSvg.test.ts b/tests/suites/tenant/queryEditor/planToSvg.test.ts
index 94cba5b13..e6752deee 100644
--- a/tests/suites/tenant/queryEditor/planToSvg.test.ts
+++ b/tests/suites/tenant/queryEditor/planToSvg.test.ts
@@ -1,10 +1,11 @@
import {expect, test} from '@playwright/test';
+import {STATISTICS_MODES} from '../../../../src/utils/query';
import {tenantName} from '../../../utils/constants';
import {toggleExperiment} from '../../../utils/toggleExperiment';
import {TenantPage} from '../TenantPage';
-import {QueryEditor} from './models/QueryEditor';
+import {ButtonNames, QueryEditor} from './models/QueryEditor';
test.describe('Test Plan to SVG functionality', async () => {
const testQuery = 'SELECT 1;'; // Simple query that will generate a plan
@@ -46,4 +47,63 @@ test.describe('Test Plan to SVG functionality', async () => {
const svgElement = page.locator('svg').first();
await expect(svgElement).toBeVisible();
});
+
+ test('Statistics setting becomes disabled when execution plan experiment is enabled', async ({
+ page,
+ }) => {
+ const queryEditor = new QueryEditor(page);
+
+ // Open settings dialog
+ await queryEditor.clickGearButton();
+
+ // Statistics is enabled
+ await expect(queryEditor.settingsDialog.isStatisticsSelectDisabled()).resolves.toBe(false);
+
+ await queryEditor.settingsDialog.clickButton(ButtonNames.Cancel);
+
+ // Turn on execution plan experiment
+ await toggleExperiment(page, 'on', 'Execution plan');
+
+ // Open settings dialog
+ await queryEditor.clickGearButton();
+
+ // Verify statistics mode is disabled
+ await expect(queryEditor.settingsDialog.isStatisticsSelectDisabled()).resolves.toBe(true);
+ });
+
+ test('Statistics mode changes when toggling execution plan experiment', async ({page}) => {
+ const queryEditor = new QueryEditor(page);
+
+ // Set initial state
+ await queryEditor.clickGearButton();
+ await queryEditor.settingsDialog.changeStatsLevel(STATISTICS_MODES.none);
+ await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
+
+ // Turn on execution plan experiment
+ await toggleExperiment(page, 'on', 'Execution plan');
+
+ // Verify statistics changed to Full
+ await queryEditor.clickGearButton();
+ await expect(queryEditor.settingsDialog.getStatsLevel()).resolves.toBe('Full');
+ await queryEditor.settingsDialog.clickButton(ButtonNames.Cancel);
+
+ // Turn off execution plan experiment
+ await toggleExperiment(page, 'off', 'Execution plan');
+
+ // Verify statistics returned to None
+ await queryEditor.clickGearButton();
+ await expect(queryEditor.settingsDialog.getStatsLevel()).resolves.toBe('None');
+ await queryEditor.settingsDialog.clickButton(ButtonNames.Cancel);
+ });
+
+ test('Statistics setting shows tooltip when disabled by execution plan experiment', async ({
+ page,
+ }) => {
+ const queryEditor = new QueryEditor(page);
+
+ await toggleExperiment(page, 'on', 'Execution plan');
+ await queryEditor.clickGearButton();
+ await queryEditor.settingsDialog.hoverStatisticsSelect();
+ await expect(queryEditor.settingsDialog.isStatsTooltipVisible()).resolves.toBe(true);
+ });
});
diff --git a/tests/suites/tenant/queryEditor/queryEditor.test.ts b/tests/suites/tenant/queryEditor/queryEditor.test.ts
index 73724606b..2d14840fd 100644
--- a/tests/suites/tenant/queryEditor/queryEditor.test.ts
+++ b/tests/suites/tenant/queryEditor/queryEditor.test.ts
@@ -1,5 +1,6 @@
import {expect, test} from '@playwright/test';
+import {QUERY_MODES, STATISTICS_MODES} from '../../../../src/utils/query';
import {tenantName} from '../../../utils/constants';
import {NavigationTabs, TenantPage, VISIBILITY_TIMEOUT} from '../TenantPage';
import {createTableQuery, longRunningQuery, longTableSelect} from '../constants';
@@ -8,7 +9,6 @@ import {
ButtonNames,
ExplainResultType,
QueryEditor,
- QueryMode,
QueryTabs,
ResultTabNames,
} from './models/QueryEditor';
@@ -29,21 +29,21 @@ test.describe('Test Query Editor', async () => {
test('Run button executes YQL script', async ({page}) => {
const queryEditor = new QueryEditor(page);
- await queryEditor.run(testQuery, QueryMode.YQLScript);
+ await queryEditor.run(testQuery, QUERY_MODES.script);
await expect(queryEditor.resultTable.isVisible()).resolves.toBe(true);
});
test('Run button executes Scan', async ({page}) => {
const queryEditor = new QueryEditor(page);
- await queryEditor.run(testQuery, QueryMode.Scan);
+ await queryEditor.run(testQuery, QUERY_MODES.scan);
await expect(queryEditor.resultTable.isVisible()).resolves.toBe(true);
});
test('Explain button executes YQL script explanation', async ({page}) => {
const queryEditor = new QueryEditor(page);
- await queryEditor.explain(testQuery, QueryMode.YQLScript);
+ await queryEditor.explain(testQuery, QUERY_MODES.script);
const explainSchema = await queryEditor.getExplainResult(ExplainResultType.Schema);
await expect(explainSchema).toBeVisible({timeout: VISIBILITY_TIMEOUT});
@@ -54,7 +54,7 @@ test.describe('Test Query Editor', async () => {
test('Explain button executes Scan explanation', async ({page}) => {
const queryEditor = new QueryEditor(page);
- await queryEditor.explain(testQuery, QueryMode.Scan);
+ await queryEditor.explain(testQuery, QUERY_MODES.scan);
const explainSchema = await queryEditor.getExplainResult(ExplainResultType.Schema);
await expect(explainSchema).toBeVisible({timeout: VISIBILITY_TIMEOUT});
@@ -155,7 +155,7 @@ test.describe('Test Query Editor', async () => {
// Test for Execute mode
await queryEditor.setQuery(longRunningQuery);
await queryEditor.clickGearButton();
- await queryEditor.settingsDialog.changeQueryMode(QueryMode.Data);
+ await queryEditor.settingsDialog.changeQueryMode(QUERY_MODES.data);
await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
// Test for Explain mode
@@ -170,7 +170,7 @@ test.describe('Test Query Editor', async () => {
const queryEditor = new QueryEditor(page);
await queryEditor.setQuery(testQuery);
await queryEditor.clickGearButton();
- await queryEditor.settingsDialog.changeStatsLevel('Profile');
+ await queryEditor.settingsDialog.changeStatsLevel(STATISTICS_MODES.profile);
await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
await queryEditor.clickRunButton();
await expect(queryEditor.resultTable.isVisible()).resolves.toBe(true);
@@ -184,7 +184,7 @@ test.describe('Test Query Editor', async () => {
const queryEditor = new QueryEditor(page);
await queryEditor.setQuery(testQuery);
await queryEditor.clickGearButton();
- await queryEditor.settingsDialog.changeStatsLevel('Profile');
+ await queryEditor.settingsDialog.changeStatsLevel(STATISTICS_MODES.profile);
await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
await queryEditor.clickRunButton();
await expect(queryEditor.resultTable.isVisible()).resolves.toBe(true);
@@ -199,7 +199,7 @@ test.describe('Test Query Editor', async () => {
const tenantPage = new TenantPage(page);
await queryEditor.setQuery(testQuery);
await queryEditor.clickGearButton();
- await queryEditor.settingsDialog.changeStatsLevel('Profile');
+ await queryEditor.settingsDialog.changeStatsLevel(STATISTICS_MODES.profile);
await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
await queryEditor.clickRunButton();
await expect(queryEditor.resultTable.isVisible()).resolves.toBe(true);
diff --git a/tests/suites/tenant/queryEditor/querySettings.test.ts b/tests/suites/tenant/queryEditor/querySettings.test.ts
index 816463685..abcb1c945 100644
--- a/tests/suites/tenant/queryEditor/querySettings.test.ts
+++ b/tests/suites/tenant/queryEditor/querySettings.test.ts
@@ -1,10 +1,11 @@
import {expect, test} from '@playwright/test';
+import {QUERY_MODES, TRANSACTION_MODES} from '../../../../src/utils/query';
import {tenantName} from '../../../utils/constants';
import {TenantPage, VISIBILITY_TIMEOUT} from '../TenantPage';
import {longRunningQuery} from '../constants';
-import {ButtonNames, QueryEditor, QueryMode} from './models/QueryEditor';
+import {ButtonNames, QueryEditor} from './models/QueryEditor';
test.describe('Test Query Settings', async () => {
const testQuery = 'SELECT 1, 2, 3, 4, 5;';
@@ -34,7 +35,7 @@ test.describe('Test Query Settings', async () => {
const queryEditor = new QueryEditor(page);
await queryEditor.clickGearButton();
- await queryEditor.settingsDialog.changeQueryMode(QueryMode.Scan);
+ await queryEditor.settingsDialog.changeQueryMode(QUERY_MODES.scan);
await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
await expect(async () => {
@@ -48,7 +49,7 @@ test.describe('Test Query Settings', async () => {
// Change a setting
await queryEditor.clickGearButton();
- await queryEditor.settingsDialog.changeQueryMode(QueryMode.Scan);
+ await queryEditor.settingsDialog.changeQueryMode(QUERY_MODES.scan);
await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
// Execute a script
@@ -64,7 +65,7 @@ test.describe('Test Query Settings', async () => {
// Change a setting
await queryEditor.clickGearButton();
- await queryEditor.settingsDialog.changeQueryMode(QueryMode.Scan);
+ await queryEditor.settingsDialog.changeQueryMode(QUERY_MODES.scan);
await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
// Execute a script
@@ -81,7 +82,7 @@ test.describe('Test Query Settings', async () => {
// Change a setting
await queryEditor.clickGearButton();
- await queryEditor.settingsDialog.changeQueryMode(QueryMode.Scan);
+ await queryEditor.settingsDialog.changeQueryMode(QUERY_MODES.scan);
await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
// Execute a script to make the banner appear
@@ -99,7 +100,7 @@ test.describe('Test Query Settings', async () => {
// Change a setting
await queryEditor.clickGearButton();
- await queryEditor.settingsDialog.changeTransactionMode('Snapshot');
+ await queryEditor.settingsDialog.changeTransactionMode(TRANSACTION_MODES.snapshot);
await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
// Execute a script to make the banner appear
@@ -119,8 +120,8 @@ test.describe('Test Query Settings', async () => {
const queryEditor = new QueryEditor(page);
await queryEditor.clickGearButton();
- await queryEditor.settingsDialog.changeQueryMode(QueryMode.Scan);
- await queryEditor.settingsDialog.changeTransactionMode('Snapshot');
+ await queryEditor.settingsDialog.changeQueryMode(QUERY_MODES.scan);
+ await queryEditor.settingsDialog.changeTransactionMode(TRANSACTION_MODES.snapshot);
await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
await expect(async () => {
diff --git a/tests/suites/tenant/queryEditor/queryStatus.test.ts b/tests/suites/tenant/queryEditor/queryStatus.test.ts
index ea27ada9b..02eb1a89d 100644
--- a/tests/suites/tenant/queryEditor/queryStatus.test.ts
+++ b/tests/suites/tenant/queryEditor/queryStatus.test.ts
@@ -1,5 +1,6 @@
import {expect, test} from '@playwright/test';
+import {STATISTICS_MODES} from '../../../../src/utils/query';
import {tenantName} from '../../../utils/constants';
import {TenantPage} from '../TenantPage';
import {longRunningQuery} from '../constants';
@@ -26,7 +27,7 @@ test.describe('Test Query Execution Status', async () => {
// Ensure page is loaded
await queryEditor.setQuery(longRunningQuery);
await queryEditor.clickGearButton();
- await queryEditor.settingsDialog.changeStatsLevel('Profile');
+ await queryEditor.settingsDialog.changeStatsLevel(STATISTICS_MODES.profile);
await expect(queryEditor.isResultsControlsHidden()).resolves.toBe(true);
});
diff --git a/tests/suites/tenant/queryHistory/queryHistory.test.ts b/tests/suites/tenant/queryHistory/queryHistory.test.ts
index 78919fab2..5eb971068 100644
--- a/tests/suites/tenant/queryHistory/queryHistory.test.ts
+++ b/tests/suites/tenant/queryHistory/queryHistory.test.ts
@@ -1,8 +1,9 @@
import {expect, test} from '@playwright/test';
+import {QUERY_MODES} from '../../../../src/utils/query';
import {tenantName} from '../../../utils/constants';
import {TenantPage, VISIBILITY_TIMEOUT} from '../TenantPage';
-import {QueryEditor, QueryMode} from '../queryEditor/models/QueryEditor';
+import {QueryEditor} from '../queryEditor/models/QueryEditor';
import executeQueryWithKeybinding from './utils';
@@ -26,7 +27,7 @@ test.describe('Query History', () => {
const testQuery = 'SELECT 1 AS test_column;';
// Execute the query
- await queryEditor.run(testQuery, QueryMode.YQLScript);
+ await queryEditor.run(testQuery, QUERY_MODES.script);
// Navigate to the history tab
await page.click('text=History');
@@ -47,7 +48,7 @@ test.describe('Query History', () => {
// Execute multiple queries
for (const query of queries) {
- await queryEditor.run(query, QueryMode.YQLScript);
+ await queryEditor.run(query, QUERY_MODES.script);
}
// Navigate to the history tab