Skip to content

Commit b25d33f

Browse files
authored
Merge pull request #3953 from RedisInsight/e2e/feature/RI-6151_add-autocompletion-to-workbench
E2e/feature/ri 6151 add autocompletion to workbench
2 parents 78b9df9 + 6c02859 commit b25d33f

File tree

10 files changed

+62
-46
lines changed

10 files changed

+62
-46
lines changed

tests/e2e/pageObjects/workbench-page.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ export class WorkbenchPage extends InstancePage {
113113
for (const command of commands) {
114114
await t
115115
.typeText(this.queryInput, command, { replace: false, speed: 1, paste: true })
116+
.pressKey('esc')
116117
.pressKey('enter');
117118
}
118119
await t.click(this.submitCommandButton);
@@ -195,6 +196,7 @@ export class WorkbenchPage extends InstancePage {
195196
await t.typeText(this.queryInput, value, { replace: false });
196197
// Select query option into autosuggest and go out of quotes
197198
await t.pressKey('tab');
199+
await t.pressKey('tab');
198200
await t.pressKey('right');
199201
await t.pressKey('space');
200202
}

tests/e2e/tests/web/critical-path/workbench/autocomplete.e2e.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ test('Verify that when user have selected a command (via “Enter” from the li
3636
await t.pressKey('enter');
3737
const script = await workbenchPage.queryInputScriptArea.textContent;
3838
// Verify that user can select a command from the list with auto-suggestions when type in any character in the Editor
39-
await t.expect(script.replace(/\s/g, ' ')).contains('LINDEX ', 'Result of sent command exists');
39+
await t.expect(script.replace(/\s/g, ' ')).eql('LINDEX ', 'Result of sent command not exists');
4040

41-
// Check the required arguments inserted
41+
// Check the required arguments suggested
4242
for (const argument of commandArguments) {
43-
await t.expect(script).contains(argument, `The required argument ${argument} is inserted`);
43+
await t.expect(workbenchPage.MonacoEditor.monacoHintWithArguments.textContent).contains(argument, `The required argument ${argument} is not suggested`);
4444
}
4545
});
4646
test('Verify that user can change any required argument inserted', async t => {
47-
const command = 'HMGET';
47+
const command = 'HMGE';
4848
const commandArguments = [
4949
'key',
5050
'field'
@@ -54,7 +54,7 @@ test('Verify that user can change any required argument inserted', async t => {
5454
'secondArgument'
5555
];
5656

57-
// Select command via Enter
57+
// Select HMGET command via Enter
5858
await t.typeText(workbenchPage.queryInput, command, { replace: true });
5959
await t.pressKey('enter');
6060
// Change required arguments
@@ -68,15 +68,18 @@ test('Verify that user can change any required argument inserted', async t => {
6868
await t.expect(scriptAfterEdit).notContains(commandArguments[0], `The argument ${commandArguments[0]} is not changed`);
6969
});
7070
test('Verify that the list of optional arguments will not be inserted with autocomplete', async t => {
71-
const command = 'ZPOPMAX';
71+
const command = 'ZPOPMA';
7272
const commandRequiredArgument = 'key';
73-
const commandOptionalArgument = 'count';
73+
const commandOptionalArgument = '[count]';
7474

75-
// Select command via Enter
75+
// Select ZPOPMAX command via Enter
7676
await t.typeText(workbenchPage.queryInput, command, { replace: true });
7777
await t.pressKey('enter');
7878
// Verify the command arguments inserted
7979
const script = await workbenchPage.queryInputScriptArea.textContent;
80-
await t.expect(script).contains(commandRequiredArgument, 'The required argument is inserted');
81-
await t.expect(script).notContains(commandOptionalArgument, 'The optional argument is not inserted');
80+
await t.expect(script.replace(/\s/g, ' ')).eql('ZPOPMAX ', 'Result of sent command not exists');
81+
82+
// Check the required and optional arguments suggested
83+
await t.expect(workbenchPage.MonacoEditor.monacoHintWithArguments.textContent).contains(commandRequiredArgument, `The required argument is not suggested`);
84+
await t.expect(workbenchPage.MonacoEditor.monacoHintWithArguments.textContent).contains(commandOptionalArgument, `The optional argument is not suggested in blocks`);
8285
});

tests/e2e/tests/web/critical-path/workbench/command-results.e2e.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ test
175175
await t
176176
.click(workbenchPage.queryInput)
177177
.pressKey('ctrl+a')
178-
.pressKey('delete');
178+
.pressKey('delete')
179+
.pressKey('esc');
179180
// Verify the quick access to command history by up button
180181
for (const command of commands.reverse()) {
181182
await t.pressKey('up');

tests/e2e/tests/web/critical-path/workbench/scripting-area.e2e.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,9 @@ test('Verify that user can run one command in multiple lines in Workbench page',
112112
'ON HASH PREFIX 1 product:',
113113
'SCHEMA price NUMERIC SORTABLE'
114114
];
115-
//Send command in multiple lines
115+
// Send command in multiple lines
116116
await workbenchPage.sendCommandInWorkbench(multipleLinesCommand.join('\n\t'), 0.5);
117-
//Check the result
117+
// Check the result
118118
const resultCommand = await workbenchPage.queryCardCommand.nth(0).textContent;
119119
for(const commandPart of multipleLinesCommand) {
120120
await t.expect(resultCommand).contains(commandPart, 'The multiple lines command is in the result');
@@ -126,12 +126,12 @@ test('Verify that user can use one indent to indicate command in several lines i
126126
`FT.CREATE ${indexName}`,
127127
'ON HASH PREFIX 1 product: SCHEMA price NUMERIC SORTABLE'
128128
];
129-
//Send command in multiple lines
129+
// Send command in multiple lines
130130
await t.typeText(workbenchPage.queryInput, multipleLinesCommand[0]);
131-
await t.pressKey('enter tab');
131+
await t.pressKey('enter esc tab');
132132
await t.typeText(workbenchPage.queryInput, multipleLinesCommand[1]);
133133
await t.click(workbenchPage.submitCommandButton);
134-
//Check the result
134+
// Check the result
135135
const resultCommand = await workbenchPage.queryCardCommand.nth(0).textContent;
136136
for(const commandPart of multipleLinesCommand) {
137137
await t.expect(resultCommand).contains(commandPart, 'The multiple lines command is in the result');

tests/e2e/tests/web/regression/insights/live-recommendations.e2e.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ test
246246
//Verify that user is navigated to DB Analysis page via Analyze button and new report is generated
247247
await t.click(memoryEfficiencyPage.selectedReport);
248248
await t.expect(memoryEfficiencyPage.reportItem.visible).ok('Database analysis page not opened');
249-
await t.click(memoryEfficiencyPage.NavigationPanel.workbenchButton);
249+
await t.click(memoryEfficiencyPage.NavigationPanel.browserButton);
250250
await workbenchPage.NavigationHeader.togglePanel(true);
251251
tab = await browserPage.InsightsPanel.setActiveTab(ExploreTabs.Tips);
252252
await t.click(tab.analyzeDatabaseLink);

tests/e2e/tests/web/regression/search-and-query/no-indexes-suggestions.e2e.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ test
2424
})('Verify suggestions when there are no indexes', async t => {
2525

2626
await t.click(browserPage.NavigationPanel.workbenchButton);
27-
await t.pressKey('ctrl+space');
2827

2928
await t.typeText(workbenchPage.queryInput, 'FT.SE', { replace: true });
3029
await t.pressKey('tab');

tests/e2e/tests/web/regression/search-and-query/search-and-query-tab.e2e.ts

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ fixture `Autocomplete for entered commands in search and query`
3737
// Create 3 keys and index
3838
await browserPage.Cli.sendCommandsInCli(commands);
3939
await t.click(browserPage.NavigationPanel.workbenchButton);
40-
await t.pressKey('ctrl+space');
4140
})
4241
.afterEach(async() => {
4342
// Clear and delete database
@@ -51,7 +50,7 @@ test('Verify that tutorials can be opened from Workbench', async t => {
5150
await t.click(workbenchPage.getTutorialLinkLocator('sq-intro'));
5251
await t.expect(workbenchPage.InsightsPanel.sidePanel.exists).ok('Insight panel is not opened');
5352
const tab = await browserPage.InsightsPanel.setActiveTab(ExploreTabs.Tutorials);
54-
await t.expect(tab.preselectArea.textContent).contains('EXACT MATCH', 'the tutorial page is incorrect');
53+
await t.expect(tab.preselectArea.textContent).contains('INTRODUCTION', 'the tutorial page is incorrect');
5554
});
5655
test('Verify that user can use show more to see command fully in 2nd tooltip', async t => {
5756
const commandDetails = [
@@ -92,12 +91,13 @@ test('Verify full commands suggestions with index and query for FT.AGGREGATE', a
9291
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.withText('FT.AGGREGATE').exists).ok('FT.AGGREGATE auto-suggestions are not displayed');
9392

9493
// Select command and check result
94+
await t.typeText(workbenchPage.queryInput, '.AG', { replace: false });
9595
await t.pressKey('enter');
9696
let script = await workbenchPage.queryInputScriptArea.textContent;
9797
await t.expect(script.replace(/\s/g, ' ')).contains('FT.AGGREGATE ', 'Result of sent command exists');
9898

9999
// Verify that user can see the list of all the indexes in database when put a space after only FT.SEARCH and FT.AGGREGATE commands
100-
await t.expect(script.replace(/\s/g, ' ')).contains(`"${indexName1}" "" `, 'Index not suggested into input');
100+
await t.expect(script.replace(/\s/g, ' ')).contains(`'${indexName1}' 'query to search' `, 'Index not suggested into input');
101101
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.withExactText(indexName1).exists).ok('Index not auto-suggested');
102102
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.withExactText(indexName2).exists).ok('All indexes not auto-suggested');
103103

@@ -115,10 +115,12 @@ test('Verify full commands suggestions with index and query for FT.AGGREGATE', a
115115
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.withExactText('city').exists).ok('Index field not auto-suggested after starting typing');
116116
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.count).eql(1, 'Wrong index fields suggested after typing first letter');
117117

118-
// Verify contextual suggestions after typing letters for commands
118+
// Go out of index field
119+
await t.pressKey('tab');
119120
await t.pressKey('tab');
120121
await t.pressKey('right');
121122
await t.pressKey('space');
123+
// Verify contextual suggestions after typing letters for commands
122124
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.withExactText('APPLY').exists).ok('FT.AGGREGATE arguments not suggested');
123125
await t.typeText(workbenchPage.queryInput, 'g', { replace: false });
124126
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.nth(0).textContent).contains('GROUPBY', 'Argument not suggested after typing first letters');
@@ -141,23 +143,22 @@ test('Verify full commands suggestions with index and query for FT.AGGREGATE', a
141143
await t.typeText(workbenchPage.queryInput, 'stud', { replace: false });
142144

143145
await t.pressKey('space');
144-
await t.debug();
145146
// Verify multiple argument option suggestions
146147
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.nth(0).textContent).contains('REDUCE', 'Incorrect order of suggested arguments');
147148
// Verify complex command sequences like nargs and properties are suggested accurately for GROUPBY
148-
const expectedText = `FT.AGGREGATE "${indexName1}" "@city" GROUPBY 1 "London" REDUCE SUM 1 @students AS stud REDUCE`.trim().replace(/\s+/g, ' ');
149+
const expectedText = `FT.AGGREGATE '${indexName1}' '@city:{tag} ' GROUPBY 1 "London" REDUCE SUM 1 @students AS stud REDUCE`.trim().replace(/\s+/g, ' ');
149150
await t.expect((await workbenchPage.queryInputForText.innerText).trim().replace(/\s+/g, ' ')).contains(expectedText, 'Incorrect order of entered arguments');
150151
});
151152
test('Verify full commands suggestions with index and query for FT.SEARCH', async t => {
152-
await t.typeText(workbenchPage.queryInput, 'FT.SE', { replace: true });
153+
await t.typeText(workbenchPage.queryInput, 'FT.SEA', { replace: true });
153154
// Select command and check result
154155
await t.pressKey('enter');
155156
const script = await workbenchPage.queryInputScriptArea.textContent;
156157
await t.expect(script.replace(/\s/g, ' ')).contains('FT.SEARCH ', 'Result of sent command exists');
157158

158-
await t.pressKey('tab');
159+
await t.pressKey('tab')
159160
// Select '@city' field
160-
await workbenchPage.selectFieldUsingAutosuggest('city');
161+
await workbenchPage.selectFieldUsingAutosuggest('city')
161162
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.withExactText('DIALECT').exists).ok('FT.SEARCH arguments not suggested');
162163
await t.typeText(workbenchPage.queryInput, 'n', { replace: false });
163164
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.nth(0).textContent).contains('NOCONTENT', 'Argument not suggested after typing first letters');
@@ -199,7 +200,7 @@ test('Verify full commands suggestions with index and query for FT.PROFILE(SEARC
199200
await workbenchPage.selectFieldUsingAutosuggest('city');
200201
// Verify that there are no more suggestions
201202
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.exists).notOk('Additional invalid commands suggested');
202-
const expectedText = `FT.PROFILE "${indexName1}" SEARCH QUERY "@city"`.trim().replace(/\s+/g, ' ');
203+
const expectedText = `FT.PROFILE '${indexName1}' SEARCH QUERY '@city:{tag} '`.trim().replace(/\s+/g, ' ');
203204
// Verify command entered correctly
204205
await t.expect((await workbenchPage.queryInputForText.innerText).trim().replace(/\s+/g, ' ')).contains(expectedText, 'Incorrect order of entered arguments');
205206
});
@@ -220,7 +221,7 @@ test('Verify full commands suggestions with index and query for FT.PROFILE(AGGRE
220221
await workbenchPage.selectFieldUsingAutosuggest('city');
221222
// Verify that there are no more suggestions
222223
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.exists).notOk('Additional invalid commands suggested');
223-
const expectedText = `FT.PROFILE "${indexName1}" AGGREGATE QUERY "@city"`.trim().replace(/\s+/g, ' ');
224+
const expectedText = `FT.PROFILE '${indexName1}' AGGREGATE QUERY '@city:{tag} '`.trim().replace(/\s+/g, ' ');
224225
// Verify command entered correctly
225226
await t.expect((await workbenchPage.queryInputForText.innerText).trim().replace(/\s+/g, ' ')).contains(expectedText, 'Incorrect order of entered arguments');
226227
});
@@ -238,7 +239,7 @@ test('Verify full commands suggestions with index and query for FT.EXPLAIN', asy
238239
// Verify that there are no more suggestions
239240
await t.pressKey('space');
240241
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.exists).notOk('Additional invalid commands suggested');
241-
const expectedText = `FT.EXPLAIN "${indexName1}" "@city" DIALECT dialectTest`.trim().replace(/\s+/g, ' ');
242+
const expectedText = `FT.EXPLAIN '${indexName1}' '@city:{tag} ' DIALECT dialectTest`.trim().replace(/\s+/g, ' ');
242243
// Verify command entered correctly
243244
await t.expect((await workbenchPage.queryInputForText.innerText).trim().replace(/\s+/g, ' ')).contains(expectedText, 'Incorrect order of entered arguments');
244245
});
@@ -259,11 +260,12 @@ test('Verify commands suggestions for APPLY and FILTER', async t => {
259260
await t.typeText(workbenchPage.queryInput, '@', { replace: false });
260261
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.visible).ok('Suggestions not displayed');
261262
await t.typeText(workbenchPage.queryInput, 'location', { replace: false });
262-
await t.typeText(workbenchPage.queryInput, ', \'40.7128,-74.0060\'');
263+
await t.typeText(workbenchPage.queryInput, ', "40.7128,-74.0060"');
263264
for (let i = 0; i < 3; i++) {
264265
await t.pressKey('right');
265266
}
266267
await t.pressKey('space');
268+
await t.typeText(workbenchPage.queryInput, 'a');
267269
await t.pressKey('tab');
268270
await t.typeText(workbenchPage.queryInput, 'apply_key', { replace: false });
269271

@@ -277,7 +279,6 @@ test('Verify commands suggestions for APPLY and FILTER', async t => {
277279
await t.pressKey('space');
278280
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.withExactText('GROUPBY').exists).ok('query can not be prolong');
279281
});
280-
281282
test('Verify REDUCE commands', async t => {
282283
await t.typeText(workbenchPage.queryInput, `FT.AGGREGATE ${indexName1} "*" GROUPBY 1 @location`, { replace: true });
283284
await t.pressKey('space');
@@ -288,6 +289,7 @@ test('Verify REDUCE commands', async t => {
288289

289290
// set value of reduce
290291
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.visible).ok('Suggestions not displayed');
292+
// Select COUNT
291293
await t.typeText(workbenchPage.queryInput, 'CO');
292294
await t.pressKey('enter');
293295
await t.typeText(workbenchPage.queryInput, '0');
@@ -325,7 +327,7 @@ test('Verify suggestions for fields', async t => {
325327
// verify suggestions for geo
326328
await t.typeText(workbenchPage.queryInput, 'l');
327329
await t.pressKey('tab');
328-
await t.expect((await workbenchPage.MonacoEditor.getTextFromMonaco()).trim()).eql(`FT.AGGREGATE "${indexName1}" "@location:[lon lat radius unit]"`);
330+
await t.expect((await workbenchPage.MonacoEditor.getTextFromMonaco()).trim()).eql(`FT.AGGREGATE '${indexName1}' '@location:[lon lat radius unit] '`);
329331

330332
// verify for numeric
331333
await t.typeText(workbenchPage.queryInput, 'FT.AGGREGATE ', { replace: true });
@@ -336,10 +338,10 @@ test('Verify suggestions for fields', async t => {
336338
await t.typeText(workbenchPage.queryInput, '@');
337339
await t.typeText(workbenchPage.queryInput, 's');
338340
await t.pressKey('tab');
339-
await t.expect((await workbenchPage.MonacoEditor.getTextFromMonaco()).trim()).eql(`FT.AGGREGATE "${indexName1}" "@students:[range]"`);
341+
await t.expect((await workbenchPage.MonacoEditor.getTextFromMonaco()).trim()).eql(`FT.AGGREGATE '${indexName1}' '@students:[range] '`);
340342
});
341-
342-
test
343+
// Unskip after fixing https://redislabs.atlassian.net/browse/RI-6212
344+
test.skip
343345
.after(async() => {
344346
// Clear and delete database
345347
await apiKeyRequests.deleteKeyByNameApi(keyName, ossStandaloneConfig.databaseName);
@@ -349,7 +351,6 @@ test
349351
await databaseAPIRequests.deleteStandaloneDatabaseApi(ossStandaloneConfig);
350352
})('Verify commands suggestions for CREATE', async t => {
351353
await t.typeText(workbenchPage.queryInput, 'FT.CREATE ', { replace: true });
352-
await t.pressKey('enter');
353354
// Verify that indexes are not suggested for FT.CREATE
354355
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.exists).notOk('Existing index suggested');
355356

@@ -376,5 +377,15 @@ test
376377
// Select SORTABLE
377378
await t.typeText(workbenchPage.queryInput, 'so', { replace: false });
378379
await t.pressKey('tab');
379-
await t.expect((await workbenchPage.MonacoEditor.getTextFromMonaco()).trim()).eql(`FT.CREATE ${indexName3} FILTER filterNew SCHEMA field_name TEXT SORTABLE`);
380+
381+
// Enter second field to SCHEMA
382+
await t.typeText(workbenchPage.queryInput, 'field2_num', { replace: false });
383+
await t.pressKey('space');
384+
await t.expect(workbenchPage.MonacoEditor.monacoSuggestion.withExactText('NUMERIC').exists).ok('query can not be prolong');
385+
386+
// Select NUMERIC keyword
387+
await t.typeText(workbenchPage.queryInput, 'so', { replace: false });
388+
await t.pressKey('tab');
389+
390+
await t.expect((await workbenchPage.MonacoEditor.getTextFromMonaco()).trim()).eql(`FT.CREATE ${indexName3} FILTER filterNew SCHEMA field_name TEXT SORTABLE field2_num NUMERIC`);
380391
});

0 commit comments

Comments
 (0)