Skip to content

Commit 7041463

Browse files
authored
Merge pull request #1488 from RedisInsight/e2e/feature/RI-3892_treeViewImprovements
RI-3892 - Tree View Improvements
2 parents 0a50a0a + dbe0380 commit 7041463

File tree

3 files changed

+229
-2
lines changed

3 files changed

+229
-2
lines changed

tests/e2e/pageObjects/browser-page.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ export class BrowserPage {
2222
//*The following categories are ordered alphabetically (Alerts, Buttons, Checkboxes, etc.).
2323
//-------------------------------------------------------------------------------------------
2424
//BUTTONS
25+
hashDeleteButton = Selector('[data-testid=hash-delete-btn]');
26+
setDeleteButton = Selector('[data-testid=set-delete-btn]');
27+
streamDeleteButton = Selector('[data-testid=stream-delete-btn]');
2528
myRedisDbIcon = Selector('[data-testid=my-redis-db-icon]');
2629
deleteKeyButton = Selector('[data-testid=delete-key-btn]');
2730
confirmDeleteKeyButton = Selector('[data-testid=delete-key-confirm-btn]');
@@ -987,7 +990,7 @@ export class BrowserPage {
987990

988991
/**
989992
* Verify that keys can be scanned more and results increased
990-
*/
993+
*/
991994
async verifyScannningMore(): Promise<void> {
992995
for (let i = 10; i < 100; i += 10) {
993996
// Remember results value
@@ -1006,13 +1009,40 @@ export class BrowserPage {
10061009
/**
10071010
* Open Select Index droprown and select option
10081011
* @param index The name of format
1009-
*/
1012+
*/
10101013
async selectIndexByName(index: string): Promise<void> {
10111014
const option = Selector(`[data-test-subj="mode-option-type-${index}"]`);
10121015
await t
10131016
.click(this.selectIndexDdn)
10141017
.click(option);
10151018
}
1019+
1020+
/**
1021+
* Get text from first tree element
1022+
*/
1023+
async getTextFromNthTreeElement(number: number): Promise<string> {
1024+
return (await Selector(`[role="treeitem"]`).nth(number).find(`div`).textContent).replace(/\s/g, '');
1025+
}
1026+
1027+
/**
1028+
* Open tree folder with multiple level
1029+
* @param names folder names with sequence of subfolder
1030+
*/
1031+
async openTreeFolders(names: string[]): Promise<void> {
1032+
let base = `node-item_${names[0]}:`
1033+
await t.click(Selector(`[data-testid="${base}"]`));
1034+
if (names.length > 1) {
1035+
for (let i = 1; i < names.length; i++) {
1036+
base = base + `${names[i]}:`;
1037+
await t.click(Selector(`[data-testid="${base}"]`));
1038+
}
1039+
}
1040+
await t.click(Selector(`[data-testid="${base}keys:keys:"]`));
1041+
1042+
await t.expect(
1043+
Selector(`[data-testid="${base}keys:keys:"]`).visible)
1044+
.ok("Folder is not selected");
1045+
}
10161046
}
10171047

10181048
/**

tests/e2e/pageObjects/cli-page.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,4 +171,18 @@ export class CliPage {
171171
await t.click(this.readMoreButton);
172172
await t.expect(getPageUrl()).eql(url, 'The opened page not correct');
173173
}
174+
175+
/**
176+
* Create random index name with CLI and return
177+
*/
178+
179+
async createIndexwithCLI(prefix: string): Promise<string> {
180+
const word = common.generateWord(10);
181+
const index = `idx:${word}`;
182+
const commands = [
183+
`FT.CREATE ${index} ON HASH PREFIX 1 ${prefix} SCHEMA "name" TEXT`,
184+
];
185+
await this.sendCommandsInCli(commands);
186+
return index;
187+
}
174188
}
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
import { Selector, t } from 'testcafe';
2+
import { acceptLicenseTermsAndAddDatabaseApi } from '../../../helpers/database';
3+
import {
4+
BrowserPage, CliPage
5+
} from '../../../pageObjects';
6+
import {
7+
commonUrl,
8+
ossStandaloneBigConfig,
9+
ossStandaloneConfig
10+
} from '../../../helpers/conf';
11+
import { KeyTypesTexts, rte } from '../../../helpers/constants';
12+
import { deleteStandaloneDatabaseApi } from '../../../helpers/api/api-database';
13+
import { Common } from '../../../helpers/common';
14+
import { verifyKeysDisplayedInTheList, verifyKeysNotDisplayedInTheList } from '../../../helpers/keys';
15+
16+
const browserPage = new BrowserPage();
17+
const common = new Common();
18+
const cliPage = new CliPage();
19+
let keyNames: string[];
20+
let keyName1: string;
21+
let keyName2: string;
22+
let keynameSingle: string;
23+
let index: string;
24+
25+
fixture`Tree view navigations improvement tests`
26+
.meta({ type: 'critical_path', rte: rte.standalone })
27+
.page(commonUrl);
28+
test
29+
.before(async () => {
30+
await acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig, ossStandaloneConfig.databaseName);
31+
})
32+
.after(async () => {
33+
await t.click(browserPage.patternModeBtn);
34+
await browserPage.deleteKeysByNames(keyNames);
35+
await deleteStandaloneDatabaseApi(ossStandaloneConfig);
36+
})('Tree view preselected folder', async t => {
37+
keyName1 = common.generateWord(10); // used to create index name
38+
keyName2 = common.generateWord(10); // used to create index name
39+
keynameSingle = common.generateWord(10);
40+
keyNames = [`${keyName1}:1`, `${keyName1}:2`, `${keyName2}:1`, `${keyName2}:2`, keynameSingle];
41+
42+
const commands = [
43+
`HSET ${keyNames[0]} field value`,
44+
`HSET ${keyNames[1]} field value`,
45+
`HSET ${keyNames[2]} field value`,
46+
`HSET ${keyNames[3]} field value`,
47+
`SADD ${keyNames[4]} value`
48+
];
49+
50+
// Create 5 keys
51+
await cliPage.sendCommandsInCli(commands);
52+
await t.click(browserPage.treeViewButton);
53+
// The folder without any patterns selected and the list of keys is displayed when there is a folder without any patterns
54+
await verifyKeysDisplayedInTheList([keynameSingle]);
55+
56+
await browserPage.openTreeFolders([await browserPage.getTextFromNthTreeElement(1)]);
57+
await browserPage.selectFilterGroupType(KeyTypesTexts.Set);
58+
// The folder without any namespaces is selected (if exists) when folder does not exist after search/filter
59+
await verifyKeysDisplayedInTheList([keynameSingle]);
60+
61+
await t.click(browserPage.setDeleteButton);
62+
// The folder without any patterns selected and the list of keys is displayed when there is a folder without any patterns
63+
await verifyKeysDisplayedInTheList([keynameSingle]);
64+
await verifyKeysNotDisplayedInTheList([`${keyNames[0]}:1`, `${keyNames[2]}:2`]);
65+
66+
// switch between browser view and tree view
67+
await t.click(browserPage.browserViewButton)
68+
.click(browserPage.treeViewButton);
69+
await browserPage.deleteKeyByName(keyNames[4]);
70+
await t.click(browserPage.clearFilterButton);
71+
// get first folder name
72+
const firstTreeItemText = await browserPage.getTextFromNthTreeElement(0);
73+
const firstTreeItemKeys = Selector(`[data-testid="node-item_${firstTreeItemText}:keys:keys:"]`); // keys after node item opened
74+
// The first folder with namespaces is expanded and selected when there is no folder without any patterns
75+
await t.expect(firstTreeItemKeys.visible)
76+
.ok('First folder is not expanded');
77+
await verifyKeysDisplayedInTheList([`${firstTreeItemText}:1`, `${firstTreeItemText}:2`]);
78+
79+
const commands1 = [
80+
`HSET ${keyNames[4]} field value`
81+
];
82+
83+
await cliPage.sendCommandsInCli(commands1);
84+
await t.click(browserPage.refreshKeysButton);
85+
// Refreshed Tree view preselected folder
86+
await t.expect(firstTreeItemKeys.visible)
87+
.ok('Folder is not selected');
88+
await verifyKeysDisplayedInTheList([`${firstTreeItemText}:1`, `${firstTreeItemText}:2`]);
89+
90+
await browserPage.selectFilterGroupType(KeyTypesTexts.Hash);
91+
await t.expect(firstTreeItemKeys.visible).ok('Folder is not selected after searching with HASH');
92+
// Filterred Tree view preselected folder
93+
await verifyKeysDisplayedInTheList([`${firstTreeItemText}:1`, `${firstTreeItemText}:2`]);
94+
95+
await browserPage.searchByKeyName('*');
96+
// Search capability Filterred Tree view preselected folder
97+
await t.expect(firstTreeItemKeys.visible).ok('Folder is not selected');
98+
await verifyKeysDisplayedInTheList([`${firstTreeItemText}:1`, `${firstTreeItemText}:2`]);
99+
100+
await t.click(browserPage.clearFilterButton);
101+
// Filterred Tree view preselected folder
102+
await t.expect(firstTreeItemKeys.visible).ok('Folder is not selected');
103+
await verifyKeysDisplayedInTheList([`${firstTreeItemText}:1`, `${firstTreeItemText}:2`]);
104+
105+
await browserPage.selectFilterGroupType(KeyTypesTexts.Stream);
106+
// Filterred Tree view preselected folder
107+
await t.expect(browserPage.keyListTable.textContent).contains('No results found.', 'Key is not found message not displayed');
108+
109+
await t.click(browserPage.streamDeleteButton); // clear stream from filter
110+
// Filterred Tree view preselected folder
111+
await t.expect(browserPage.keyListTable.textContent).notContains('No results found.', 'Key is not found message still displayed');
112+
await t.expect(
113+
firstTreeItemKeys.visible)
114+
.notOk('First folder is expanded');
115+
});
116+
117+
test
118+
.before(async () => {
119+
await acceptLicenseTermsAndAddDatabaseApi(ossStandaloneBigConfig, ossStandaloneBigConfig.databaseName);
120+
})
121+
.after(async () => {
122+
await cliPage.sendCommandInCli(`FT.DROPINDEX ${index}`);
123+
await deleteStandaloneDatabaseApi(ossStandaloneBigConfig);
124+
})('Verify tree view navigation for index based search', async t => {
125+
// generate index based on keyName
126+
const folders = ['mobile', '2014'];
127+
index = await cliPage.createIndexwithCLI(folders.join(':'));
128+
await t.click(browserPage.redisearchModeBtn); // click redisearch button
129+
await browserPage.selectIndexByName(index);
130+
await t.click(browserPage.treeViewButton);
131+
await t.click(Selector(`[data-testid="${`node-item_${folders[0]}:`}"]`)); // close folder
132+
await browserPage.openTreeFolders(folders);
133+
await t.click(browserPage.refreshKeysButton);
134+
// Refreshed Tree view preselected folder for index based search
135+
await t.expect(
136+
Selector(`[data-testid="node-item_${folders[0]}:${folders[1]}:keys:keys:"]`).visible)
137+
.ok('Folder is not selected');
138+
});
139+
140+
test
141+
.before(async () => {
142+
await acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig, ossStandaloneConfig.databaseName);
143+
})
144+
.after(async () => {
145+
await t.click(browserPage.patternModeBtn);
146+
await browserPage.deleteKeysByNames(keyNames.slice(1));
147+
await deleteStandaloneDatabaseApi(ossStandaloneConfig);
148+
})('Search capability Refreshed Tree view preselected folder', async t => {
149+
keyName1 = common.generateWord(10); // used to create index name
150+
keyName2 = common.generateWord(10); // used to create index name
151+
keynameSingle = common.generateWord(10);
152+
keyNames = [`${keyName1}:1`, `${keyName1}:2`, `${keyName2}:1`, `${keyName2}:2`, keynameSingle];
153+
const commands = [
154+
`HSET ${keyNames[0]} field value`,
155+
`HSET ${keyNames[1]} field value`,
156+
`RPUSH ${keyNames[2]} field`,
157+
`RPUSH ${keyNames[3]} field`,
158+
`SADD ${keyNames[4]} value`
159+
];
160+
await cliPage.sendCommandsInCli(commands);
161+
await t.click(browserPage.treeViewButton);
162+
// The folder without any patterns selected and the list of keys is displayed when there is a folder without any patterns
163+
await verifyKeysDisplayedInTheList([keynameSingle]);
164+
165+
await browserPage.openTreeFolders([keyName1]); // Type: hash
166+
await browserPage.openTreeFolders([keyName2]); // Type: list
167+
await browserPage.selectFilterGroupType(KeyTypesTexts.Hash);
168+
// The first folder with namespaces is expanded and selected when folder and folder without any namespaces does not exist after search/filter
169+
await verifyKeysDisplayedInTheList([keyNames[0], keyNames[1]]);
170+
171+
await t.click(browserPage.hashDeleteButton);
172+
await cliPage.sendCommandsInCli([`DEL ${keyNames[0]}`]);
173+
await t.click(browserPage.refreshKeysButton); // refresh keys
174+
// The previously selected folder is preselected when key does not exist after keys refresh
175+
await verifyKeysDisplayedInTheList([keyNames[1]]);
176+
await verifyKeysNotDisplayedInTheList([keyNames[0], keyNames[2], keyNames[3], keyNames[4]]);
177+
178+
await browserPage.searchByKeyName('*');
179+
await t.click(browserPage.refreshKeysButton);
180+
// Search capability Refreshed Tree view preselected folder
181+
await verifyKeysDisplayedInTheList([keyNames[1]]);
182+
await verifyKeysNotDisplayedInTheList([keyNames[0], keyNames[2], keyNames[3], keyNames[4]]);
183+
});

0 commit comments

Comments
 (0)