Skip to content

Commit 0e5c356

Browse files
astandrikAnton Standrik
andauthored
chore: tests for disabled statistics (#1660)
Co-authored-by: Anton Standrik <astandrik@Antons-MacBook-Air.local>
1 parent e934bad commit 0e5c356

File tree

10 files changed

+195
-60
lines changed

10 files changed

+195
-60
lines changed

.github/workflows/ci.yml

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ jobs:
196196

197197
steps:
198198
- uses: actions/checkout@v4
199+
with:
200+
fetch-depth: 0
199201

200202
- name: Fetch gh-pages branch
201203
run: |
@@ -222,6 +224,34 @@ jobs:
222224
destination_dir: .
223225
force_orphan: true
224226

227+
- name: Count new tests
228+
id: count_tests
229+
run: |
230+
git fetch origin main:main
231+
new_tests=0
232+
233+
# Get list of changed test files
234+
for file in $(git diff --name-only main...HEAD | grep -E '^tests/suites/.*\.(spec|test)\.(ts|tsx|js|jsx)$'); do
235+
# Count tests in current version
236+
if git show HEAD:"$file" > /dev/null 2>&1; then
237+
current_tests=$(git show HEAD:"$file" | grep -E "test\([\'\"]" | wc -l)
238+
else
239+
current_tests=0
240+
fi
241+
242+
# Count tests in main version
243+
if git show main:"$file" > /dev/null 2>&1; then
244+
base_tests=$(git show main:"$file" | grep -E "test\([\'\"]" | wc -l)
245+
else
246+
base_tests=0
247+
fi
248+
249+
# Add difference to total
250+
((new_tests += current_tests - base_tests))
251+
done
252+
253+
echo "new_tests=$new_tests" >> $GITHUB_OUTPUT
254+
225255
- name: Update PR description
226256
uses: actions/github-script@v6
227257
with:
@@ -266,14 +296,17 @@ jobs:
266296
parseFloat(percent) > 0 ? '🔺' :
267297
parseFloat(percent) < 0 ? '🔽' : '✅';
268298
299+
const newTests = parseInt('${{ steps.count_tests.outputs.new_tests }}');
300+
const testsStatus = newTests > 0 ? '✨' : '➖';
301+
269302
const ciSection = `## CI Results
270303
271304
### Test Status: <span style="color: ${statusColor};">${status}</span>
272305
📊 [Full Report](${reportUrl})
273306
274-
| Total | Passed | Failed | Flaky | Skipped |
275-
|:-----:|:------:|:------:|:-----:|:-------:|
276-
| ${testResults.total} | ${testResults.passed} | ${testResults.failed} | ${testResults.flaky} | ${testResults.skipped} |
307+
| Total | Passed | Failed | Flaky | Skipped | New Tests |
308+
|:-----:|:------:|:------:|:-----:|:-------:|:---------:|
309+
| ${testResults.total} | ${testResults.passed} | ${testResults.failed} | ${testResults.flaky} | ${testResults.skipped} | ${testsStatus} ${newTests} |
277310
278311
### Bundle Size: ${bundleStatus}
279312
Current: ${formatSize(currentSize)} | Main: ${formatSize(mainSize)}
@@ -292,6 +325,7 @@ jobs:
292325
- Bundle size is measured for the entire 'dist' directory.
293326
- 📊 indicates links to detailed reports.
294327
- 🔺 indicates increase, 🔽 decrease, and ✅ no change in bundle size.
328+
- ${testsStatus} indicates ${newTests} new test cases added in this PR.
295329
</details>`;
296330
297331
const { data: pullRequest } = await github.rest.pulls.get({

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
});

0 commit comments

Comments
 (0)