Skip to content

Commit 1bb449c

Browse files
Anton StandrikAnton Standrik
authored andcommitted
chore: tests for disabled statistics
1 parent e934bad commit 1bb449c

File tree

9 files changed

+158
-57
lines changed

9 files changed

+158
-57
lines changed

src/containers/Tenant/Query/QuerySettingsDialog/QuerySettingsDialog.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ function QuerySettingsForm({initialValues, onSubmit, onClose}: QuerySettingsForm
182182
{QUERY_SETTINGS_FIELD_SETTINGS.statisticsMode.title}
183183
</label>
184184
<Tooltip
185+
className={b('statistics-mode-tooltip')}
185186
disabled={!useShowPlanToSvg}
186187
openDelay={0}
187188
content={i18n('tooltip_plan-to-svg-statistics')}

src/containers/Tenant/Query/QuerySettingsDialog/QuerySettingsSelect.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export function QuerySettingsSelect<T extends SelectType>(props: QuerySettingsSe
4444
getOptionHeight={getOptionHeight}
4545
popupClassName={b('popup')}
4646
renderOption={(option: QuerySettingSelectOption<T>) => (
47-
<div className={b('item')}>
47+
<div className={b('item', {type: option.value})}>
4848
<div className={b('item-title')}>
4949
{option.content}
5050
{option.isDefault ? i18n('description.default') : ''}

tests/suites/tenant/queryEditor/models/QueryEditor.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,13 @@
11
import type {Locator, Page} from '@playwright/test';
22

3+
import type {QUERY_MODES} from '../../../../../src/utils/query';
34
import {VISIBILITY_TIMEOUT} from '../../TenantPage';
45

56
import {QueryTabsNavigation} from './QueryTabsNavigation';
67
import {PaneWrapper, ResultTable} from './ResultTable';
78
import {SavedQueriesTable} from './SavedQueriesTable';
89
import {SettingsDialog} from './SettingsDialog';
910

10-
export enum QueryMode {
11-
YQLScript = 'YQL Script',
12-
Data = 'DML',
13-
Scan = 'Scan',
14-
}
15-
1611
export enum ExplainResultType {
1712
Schema = 'Schema',
1813
JSON = 'JSON',
@@ -85,15 +80,15 @@ export class QueryEditor {
8580
this.savedQueries = new SavedQueriesTable(page);
8681
}
8782

88-
async run(query: string, mode: QueryMode) {
83+
async run(query: string, mode: keyof typeof QUERY_MODES) {
8984
await this.clickGearButton();
9085
await this.settingsDialog.changeQueryMode(mode);
9186
await this.settingsDialog.clickButton(ButtonNames.Save);
9287
await this.setQuery(query);
9388
await this.clickRunButton();
9489
}
9590

96-
async explain(query: string, mode: QueryMode) {
91+
async explain(query: string, mode: keyof typeof QUERY_MODES) {
9792
await this.clickGearButton();
9893
await this.settingsDialog.changeQueryMode(mode);
9994
await this.settingsDialog.clickButton(ButtonNames.Save);
Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,81 @@
11
import type {Locator, Page} from '@playwright/test';
22

3+
import type {
4+
QUERY_MODES,
5+
STATISTICS_MODES,
6+
TRANSACTION_MODES,
7+
} from '../../../../../src/utils/query';
38
import {VISIBILITY_TIMEOUT} from '../../TenantPage';
49

5-
import type {ButtonNames, QueryMode} from './QueryEditor';
10+
import type {ButtonNames} from './QueryEditor';
611

712
export class SettingsDialog {
813
private dialog: Locator;
914
private page: Page;
15+
private selectPopup: Locator;
16+
private limitRowsInput: Locator;
17+
18+
private queryModeSelect: Locator;
19+
private transactionModeSelect: Locator;
20+
private statisticsModeSelect: Locator;
21+
private statisticsModeTooltip: Locator;
1022

1123
constructor(page: Page) {
1224
this.page = page;
1325
this.dialog = page.locator('.ydb-query-settings-dialog');
14-
}
1526

16-
async changeQueryMode(mode: QueryMode) {
17-
const dropdown = this.dialog.locator(
27+
this.limitRowsInput = this.dialog.locator('.ydb-query-settings-dialog__limit-rows input');
28+
this.selectPopup = page.locator('.ydb-query-settings-select__popup');
29+
30+
// Define distinct locators for selects
31+
this.queryModeSelect = this.dialog.locator(
1832
'.ydb-query-settings-dialog__control-wrapper_queryMode',
1933
);
20-
await dropdown.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
21-
await dropdown.click();
22-
const popup = this.page.locator('.ydb-query-settings-select__popup');
23-
await popup.getByText(mode).first().click();
34+
this.transactionModeSelect = this.dialog.locator(
35+
'.ydb-query-settings-dialog__control-wrapper_transactionMode',
36+
);
37+
this.statisticsModeSelect = this.dialog.locator(
38+
'.ydb-query-settings-dialog__control-wrapper_statisticsMode',
39+
);
40+
this.statisticsModeTooltip = this.page.locator(
41+
'.ydb-query-settings-dialog__statistics-mode-tooltip',
42+
);
43+
}
44+
45+
async changeQueryMode(mode: (typeof QUERY_MODES)[keyof typeof QUERY_MODES]) {
46+
await this.queryModeSelect.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
47+
await this.queryModeSelect.click();
48+
await this.selectPopup.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
49+
await this.page.locator(`.ydb-query-settings-select__item_type_${mode}`).click();
2450
await this.page.waitForTimeout(1000);
2551
}
2652

27-
async changeTransactionMode(level: string) {
28-
const dropdown = this.dialog.locator(
29-
'.ydb-query-settings-dialog__control-wrapper_transactionMode',
30-
);
31-
await dropdown.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
32-
await dropdown.click();
33-
const popup = this.page.locator('.ydb-query-settings-select__popup');
34-
await popup.getByText(level).first().click();
53+
async changeTransactionMode(level: (typeof TRANSACTION_MODES)[keyof typeof TRANSACTION_MODES]) {
54+
await this.transactionModeSelect.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
55+
await this.transactionModeSelect.click();
56+
await this.selectPopup.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
57+
await this.page.locator(`.ydb-query-settings-select__item_type_${level}`).click();
3558
await this.page.waitForTimeout(1000);
3659
}
3760

38-
async changeStatsLevel(mode: string) {
39-
const dropdown = this.dialog.locator(
40-
'.ydb-query-settings-dialog__control-wrapper_statisticsMode',
41-
);
42-
await dropdown.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
43-
await dropdown.click();
44-
const popup = this.page.locator('.ydb-query-settings-select__popup');
45-
await popup.getByText(mode).first().click();
61+
async changeStatsLevel(mode: (typeof STATISTICS_MODES)[keyof typeof STATISTICS_MODES]) {
62+
await this.statisticsModeSelect.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
63+
await this.statisticsModeSelect.click();
64+
await this.selectPopup.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
65+
await this.page.locator(`.ydb-query-settings-select__item_type_${mode}`).click();
4666
await this.page.waitForTimeout(1000);
4767
}
4868

69+
async getStatsLevel() {
70+
await this.statisticsModeSelect.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
71+
const selectedText = await this.statisticsModeSelect
72+
.locator('.g-select-control__option-text')
73+
.textContent();
74+
return selectedText;
75+
}
76+
4977
async changeLimitRows(limitRows: number) {
50-
const limitRowsInput = this.dialog.locator('.ydb-query-settings-dialog__limit-rows input');
51-
await limitRowsInput.fill(limitRows.toString());
78+
await this.limitRowsInput.fill(limitRows.toString());
5279
await this.page.waitForTimeout(1000);
5380
}
5481

@@ -63,8 +90,23 @@ export class SettingsDialog {
6390
return true;
6491
}
6592

93+
async isStatsTooltipVisible() {
94+
await this.statisticsModeTooltip.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
95+
return true;
96+
}
97+
6698
async isHidden() {
6799
await this.dialog.waitFor({state: 'hidden', timeout: VISIBILITY_TIMEOUT});
68100
return true;
69101
}
102+
103+
async isStatisticsSelectDisabled() {
104+
await this.statisticsModeSelect.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
105+
return this.statisticsModeSelect.locator('.g-select-control_disabled').isVisible();
106+
}
107+
108+
async hoverStatisticsSelect() {
109+
await this.statisticsModeSelect.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
110+
await this.statisticsModeSelect.hover();
111+
}
70112
}

tests/suites/tenant/queryEditor/planToSvg.test.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import {expect, test} from '@playwright/test';
22

3+
import {STATISTICS_MODES} from '../../../../src/utils/query';
34
import {tenantName} from '../../../utils/constants';
45
import {toggleExperiment} from '../../../utils/toggleExperiment';
56
import {TenantPage} from '../TenantPage';
67

7-
import {QueryEditor} from './models/QueryEditor';
8+
import {ButtonNames, QueryEditor} from './models/QueryEditor';
89

910
test.describe('Test Plan to SVG functionality', async () => {
1011
const testQuery = 'SELECT 1;'; // Simple query that will generate a plan
@@ -46,4 +47,63 @@ test.describe('Test Plan to SVG functionality', async () => {
4647
const svgElement = page.locator('svg').first();
4748
await expect(svgElement).toBeVisible();
4849
});
50+
51+
test('Statistics setting becomes disabled when execution plan experiment is enabled', async ({
52+
page,
53+
}) => {
54+
const queryEditor = new QueryEditor(page);
55+
56+
// Open settings dialog
57+
await queryEditor.clickGearButton();
58+
59+
// Statistics is enabled
60+
await expect(queryEditor.settingsDialog.isStatisticsSelectDisabled()).resolves.toBe(false);
61+
62+
await queryEditor.settingsDialog.clickButton(ButtonNames.Cancel);
63+
64+
// Turn on execution plan experiment
65+
await toggleExperiment(page, 'on', 'Execution plan');
66+
67+
// Open settings dialog
68+
await queryEditor.clickGearButton();
69+
70+
// Verify statistics mode is disabled
71+
await expect(queryEditor.settingsDialog.isStatisticsSelectDisabled()).resolves.toBe(true);
72+
});
73+
74+
test('Statistics mode changes when toggling execution plan experiment', async ({page}) => {
75+
const queryEditor = new QueryEditor(page);
76+
77+
// Set initial state
78+
await queryEditor.clickGearButton();
79+
await queryEditor.settingsDialog.changeStatsLevel(STATISTICS_MODES.none);
80+
await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
81+
82+
// Turn on execution plan experiment
83+
await toggleExperiment(page, 'on', 'Execution plan');
84+
85+
// Verify statistics changed to Full
86+
await queryEditor.clickGearButton();
87+
await expect(queryEditor.settingsDialog.getStatsLevel()).resolves.toBe('Full');
88+
await queryEditor.settingsDialog.clickButton(ButtonNames.Cancel);
89+
90+
// Turn off execution plan experiment
91+
await toggleExperiment(page, 'off', 'Execution plan');
92+
93+
// Verify statistics returned to None
94+
await queryEditor.clickGearButton();
95+
await expect(queryEditor.settingsDialog.getStatsLevel()).resolves.toBe('None');
96+
await queryEditor.settingsDialog.clickButton(ButtonNames.Cancel);
97+
});
98+
99+
test('Statistics setting shows tooltip when disabled by execution plan experiment', async ({
100+
page,
101+
}) => {
102+
const queryEditor = new QueryEditor(page);
103+
104+
await toggleExperiment(page, 'on', 'Execution plan');
105+
await queryEditor.clickGearButton();
106+
await queryEditor.settingsDialog.hoverStatisticsSelect();
107+
await expect(queryEditor.settingsDialog.isStatsTooltipVisible()).resolves.toBe(true);
108+
});
49109
});

tests/suites/tenant/queryEditor/queryEditor.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {expect, test} from '@playwright/test';
22

3+
import {QUERY_MODES, STATISTICS_MODES} from '../../../../src/utils/query';
34
import {tenantName} from '../../../utils/constants';
45
import {NavigationTabs, TenantPage, VISIBILITY_TIMEOUT} from '../TenantPage';
56
import {createTableQuery, longRunningQuery, longTableSelect} from '../constants';
@@ -8,7 +9,6 @@ import {
89
ButtonNames,
910
ExplainResultType,
1011
QueryEditor,
11-
QueryMode,
1212
QueryTabs,
1313
ResultTabNames,
1414
} from './models/QueryEditor';
@@ -29,21 +29,21 @@ test.describe('Test Query Editor', async () => {
2929

3030
test('Run button executes YQL script', async ({page}) => {
3131
const queryEditor = new QueryEditor(page);
32-
await queryEditor.run(testQuery, QueryMode.YQLScript);
32+
await queryEditor.run(testQuery, QUERY_MODES.script);
3333

3434
await expect(queryEditor.resultTable.isVisible()).resolves.toBe(true);
3535
});
3636

3737
test('Run button executes Scan', async ({page}) => {
3838
const queryEditor = new QueryEditor(page);
39-
await queryEditor.run(testQuery, QueryMode.Scan);
39+
await queryEditor.run(testQuery, QUERY_MODES.scan);
4040

4141
await expect(queryEditor.resultTable.isVisible()).resolves.toBe(true);
4242
});
4343

4444
test('Explain button executes YQL script explanation', async ({page}) => {
4545
const queryEditor = new QueryEditor(page);
46-
await queryEditor.explain(testQuery, QueryMode.YQLScript);
46+
await queryEditor.explain(testQuery, QUERY_MODES.script);
4747

4848
const explainSchema = await queryEditor.getExplainResult(ExplainResultType.Schema);
4949
await expect(explainSchema).toBeVisible({timeout: VISIBILITY_TIMEOUT});
@@ -54,7 +54,7 @@ test.describe('Test Query Editor', async () => {
5454

5555
test('Explain button executes Scan explanation', async ({page}) => {
5656
const queryEditor = new QueryEditor(page);
57-
await queryEditor.explain(testQuery, QueryMode.Scan);
57+
await queryEditor.explain(testQuery, QUERY_MODES.scan);
5858

5959
const explainSchema = await queryEditor.getExplainResult(ExplainResultType.Schema);
6060
await expect(explainSchema).toBeVisible({timeout: VISIBILITY_TIMEOUT});
@@ -155,7 +155,7 @@ test.describe('Test Query Editor', async () => {
155155
// Test for Execute mode
156156
await queryEditor.setQuery(longRunningQuery);
157157
await queryEditor.clickGearButton();
158-
await queryEditor.settingsDialog.changeQueryMode(QueryMode.Data);
158+
await queryEditor.settingsDialog.changeQueryMode(QUERY_MODES.data);
159159
await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
160160

161161
// Test for Explain mode
@@ -170,7 +170,7 @@ test.describe('Test Query Editor', async () => {
170170
const queryEditor = new QueryEditor(page);
171171
await queryEditor.setQuery(testQuery);
172172
await queryEditor.clickGearButton();
173-
await queryEditor.settingsDialog.changeStatsLevel('Profile');
173+
await queryEditor.settingsDialog.changeStatsLevel(STATISTICS_MODES.profile);
174174
await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
175175
await queryEditor.clickRunButton();
176176
await expect(queryEditor.resultTable.isVisible()).resolves.toBe(true);
@@ -184,7 +184,7 @@ test.describe('Test Query Editor', async () => {
184184
const queryEditor = new QueryEditor(page);
185185
await queryEditor.setQuery(testQuery);
186186
await queryEditor.clickGearButton();
187-
await queryEditor.settingsDialog.changeStatsLevel('Profile');
187+
await queryEditor.settingsDialog.changeStatsLevel(STATISTICS_MODES.profile);
188188
await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
189189
await queryEditor.clickRunButton();
190190
await expect(queryEditor.resultTable.isVisible()).resolves.toBe(true);
@@ -199,7 +199,7 @@ test.describe('Test Query Editor', async () => {
199199
const tenantPage = new TenantPage(page);
200200
await queryEditor.setQuery(testQuery);
201201
await queryEditor.clickGearButton();
202-
await queryEditor.settingsDialog.changeStatsLevel('Profile');
202+
await queryEditor.settingsDialog.changeStatsLevel(STATISTICS_MODES.profile);
203203
await queryEditor.settingsDialog.clickButton(ButtonNames.Save);
204204
await queryEditor.clickRunButton();
205205
await expect(queryEditor.resultTable.isVisible()).resolves.toBe(true);

0 commit comments

Comments
 (0)