Skip to content

Commit b5df0d6

Browse files
authored
fix(QueryHistory): query history not saving (#1111)
1 parent cc51b20 commit b5df0d6

File tree

5 files changed

+128
-7
lines changed

5 files changed

+128
-7
lines changed

src/containers/Tenant/Query/QueryEditor/QueryEditor.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ function QueryEditor(props: QueryEditorProps) {
150150

151151
const schema = useMultiSchema ? 'multi' : 'modern';
152152

153-
const query = text && typeof text === 'string' ? text : input;
153+
const query = text ?? input;
154154

155155
setLastUsedQueryAction(QUERY_ACTIONS.execute);
156156
if (!isEqual(lastQueryExecutionSettings, querySettings)) {
@@ -312,10 +312,10 @@ function QueryEditor(props: QueryEditorProps) {
312312
const renderControls = () => {
313313
return (
314314
<QueryEditorControls
315-
onRunButtonClick={handleSendExecuteClick}
315+
handleSendExecuteClick={handleSendExecuteClick}
316316
onSettingsButtonClick={handleSettingsClick}
317317
runIsLoading={executeQueryResult.isLoading}
318-
onExplainButtonClick={handleGetExplainQueryClick}
318+
handleGetExplainQueryClick={handleGetExplainQueryClick}
319319
explainIsLoading={explainQueryResult.isLoading}
320320
disabled={!executeQuery.input}
321321
highlightedAction={lastUsedQueryAction}

src/containers/Tenant/Query/QueryEditorControls/QueryEditorControls.tsx

+12-4
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,20 @@ const SettingsButton = ({onClick, runIsLoading}: SettingsButtonProps) => {
5454
};
5555

5656
interface QueryEditorControlsProps {
57-
onRunButtonClick: () => void;
57+
handleSendExecuteClick: () => void;
5858
onSettingsButtonClick: () => void;
5959
runIsLoading: boolean;
60-
onExplainButtonClick: () => void;
60+
handleGetExplainQueryClick: () => void;
6161
explainIsLoading: boolean;
6262
disabled: boolean;
6363
highlightedAction: QueryAction;
6464
}
6565

6666
export const QueryEditorControls = ({
67-
onRunButtonClick,
67+
handleSendExecuteClick,
6868
onSettingsButtonClick,
6969
runIsLoading,
70-
onExplainButtonClick,
70+
handleGetExplainQueryClick,
7171
explainIsLoading,
7272
disabled,
7373
highlightedAction,
@@ -76,6 +76,14 @@ export const QueryEditorControls = ({
7676
const explainView: ButtonView | undefined =
7777
highlightedAction === 'explain' ? 'action' : undefined;
7878

79+
const onRunButtonClick = () => {
80+
handleSendExecuteClick();
81+
};
82+
83+
const onExplainButtonClick = () => {
84+
handleGetExplainQueryClick();
85+
};
86+
7987
return (
8088
<div className={b()}>
8189
<div className={b('left')}>

tests/suites/tenant/queryEditor/QueryEditor.ts

+4
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ export class QueryEditor {
169169
}
170170
}
171171

172+
async focusEditor() {
173+
await this.editorTextArea.focus();
174+
}
175+
172176
async clickGearButton() {
173177
await this.gearButton.waitFor({state: 'visible', timeout: VISIBILITY_TIMEOUT});
174178
await this.gearButton.click();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import {expect, test} from '@playwright/test';
2+
3+
import {tenantName} from '../../../utils/constants';
4+
import {TenantPage} from '../TenantPage';
5+
import {QueryEditor, QueryMode} from '../queryEditor/QueryEditor';
6+
7+
import executeQueryWithKeybinding from './utils';
8+
9+
export const VISIBILITY_TIMEOUT = 5000;
10+
11+
test.describe('Query History', () => {
12+
let tenantPage: TenantPage;
13+
let queryEditor: QueryEditor;
14+
15+
test.beforeEach(async ({page}) => {
16+
const pageQueryParams = {
17+
schema: tenantName,
18+
name: tenantName,
19+
general: 'query',
20+
};
21+
22+
tenantPage = new TenantPage(page);
23+
await tenantPage.goto(pageQueryParams);
24+
queryEditor = new QueryEditor(page);
25+
});
26+
27+
test('New query appears in history after execution', async ({page}) => {
28+
const testQuery = 'SELECT 1 AS test_column;';
29+
30+
// Execute the query
31+
await queryEditor.run(testQuery, QueryMode.YQLScript);
32+
33+
// Navigate to the history tab
34+
await page.click('text=History');
35+
36+
// Check if the query appears in the history
37+
const historyTable = page.locator('.ydb-queries-history table');
38+
await expect(historyTable.locator(`text="${testQuery}"`)).toBeVisible({
39+
timeout: VISIBILITY_TIMEOUT,
40+
});
41+
});
42+
43+
test('Multiple queries appear in correct order in history', async ({page}) => {
44+
const queries = [
45+
'SELECT 1 AS first_query;',
46+
'SELECT 2 AS second_query;',
47+
'SELECT 3 AS third_query;',
48+
];
49+
50+
// Execute multiple queries
51+
for (const query of queries) {
52+
await queryEditor.run(query, QueryMode.YQLScript);
53+
}
54+
55+
// Navigate to the history tab
56+
await page.click('text=History');
57+
58+
// Check if queries appear in reverse order (most recent first)
59+
const historyTable = page.locator('.ydb-queries-history table');
60+
const rows = historyTable.locator('tbody tr');
61+
62+
await expect(rows).toHaveCount(queries.length);
63+
64+
for (let i = 0; i < queries.length; i++) {
65+
await expect(rows.nth(i)).toContainText(queries[queries.length - 1 - i]);
66+
}
67+
});
68+
69+
test('Query executed with keybinding is saved in history', async ({page, browserName}) => {
70+
const testQuery = 'SELECT 1 AS keybinding_test;';
71+
72+
// Focus on the query editor
73+
await queryEditor.focusEditor();
74+
75+
// Type the query
76+
await page.keyboard.type(testQuery);
77+
78+
// Use the keybinding to execute the query
79+
await executeQueryWithKeybinding(page, browserName);
80+
81+
// Wait for the query to be executed
82+
await page.waitForSelector('.ydb-query-execute-result__result', {timeout: 10000});
83+
84+
// Navigate to the history tab
85+
await page.click('text=History');
86+
87+
// Check if the query appears in the history
88+
const historyTable = page.locator('.ydb-queries-history table');
89+
await expect(historyTable.locator(`text="${testQuery}"`)).toBeVisible();
90+
});
91+
});
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type {Page} from '@playwright/test';
2+
3+
// eslint-disable-next-line no-implicit-globals
4+
export default async function executeQueryWithKeybinding(page: Page, browserName: string) {
5+
const isMac = process.platform === 'darwin';
6+
const modifierKey = browserName === 'webkit' ? 'Meta' : 'Control';
7+
8+
if (browserName !== 'webkit' || isMac) {
9+
await page.keyboard.down(modifierKey);
10+
await page.keyboard.press('Enter');
11+
await page.keyboard.up(modifierKey);
12+
} else {
13+
await page.keyboard.press('Meta+Enter');
14+
}
15+
16+
// Add a small delay to ensure the event is processed
17+
await page.waitForTimeout(1000);
18+
}

0 commit comments

Comments
 (0)