Skip to content

Commit d850620

Browse files
authored
Merge pull request #1564 from RedisInsight/e2e/feature/RI-2409-change_database_index
E2e/feature/ri 2409 change database index
2 parents fded78d + c699491 commit d850620

File tree

17 files changed

+230
-16
lines changed

17 files changed

+230
-16
lines changed

tests/e2e/helpers/keys.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,4 +234,13 @@ export async function verifyKeysNotDisplayedInTheList(keyNames: string[]): Promi
234234
for (const keyName of keyNames) {
235235
await t.expect(await browserPage.isKeyIsDisplayedInTheList(keyName)).notOk(`The key ${keyName} found`);
236236
}
237-
}
237+
}
238+
239+
/**
240+
* Verify search/filter value
241+
* @param value The value in search/filter input
242+
*/
243+
244+
export async function verifySearchFilterValue(value: string): Promise<void> {
245+
await t.expect(browserPage.filterByPatterSearchInput.withAttribute('value', value).exists).ok(`Filter per key name ${value} is not applied/correct`);
246+
}

tests/e2e/pageObjects/browser-page.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1043,6 +1043,14 @@ export class BrowserPage {
10431043
Selector(`[data-testid="${base}keys:keys:"]`).visible)
10441044
.ok("Folder is not selected");
10451045
}
1046+
1047+
/**
1048+
* Verify that database has no keys
1049+
*/
1050+
async verifyNoKeysInDatabase(): Promise<void> {
1051+
await t.expect(this.keyListMessage.exists).ok('Database not empty')
1052+
.expect(this.keysSummary.exists).notOk('Total value is displayed for empty database');
1053+
}
10461054
}
10471055

10481056
/**
Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Selector } from 'testcafe';
1+
import { Selector, t } from 'testcafe';
22

33
export class DatabaseOverviewPage {
44
//-------------------------------------------------------------------------------------------
@@ -7,14 +7,37 @@ export class DatabaseOverviewPage {
77
//*Target any element/component via data-id, if possible!
88
//*The following categories are ordered alphabetically (Alerts, Buttons, Checkboxes, etc.).
99
//-------------------------------------------------------------------------------------------
10-
//TEXT ELEMENTS
10+
// TEXT ELEMENTS
1111
overviewTotalKeys = Selector('[data-test-subj=overview-total-keys]');
1212
overviewTotalMemory = Selector('[data-test-subj=overview-total-memory]');
1313
databaseModules = Selector('[data-testid$=module]');
1414
overviewTooltipStatTitle = Selector('[data-testid=overview-db-stat-title]');
15-
//BUTTONS
15+
// BUTTONS
1616
overviewRedisStackLogo = Selector('[data-testid=redis-stack-logo]');
1717
overviewMoreInfo = Selector('[data-testid=overview-more-info-button]');
18-
//Panel
18+
changeIndexBtn = Selector('[data-testid=change-index-btn]');
19+
applyButton = Selector('[data-testid=apply-btn]');
20+
// PANEL
1921
overviewTooltip = Selector('[data-testid=overview-more-info-tooltip]');
22+
// INPUTS
23+
changeIndexInput = Selector('[data-testid=change-index-input]');
24+
25+
/**
26+
* Change database index
27+
* @param dbIndex The index of logical database
28+
*/
29+
async changeDbIndex(dbIndex: number): Promise<void> {
30+
await t.click(this.changeIndexBtn)
31+
.typeText(this.changeIndexInput, dbIndex.toString(), { replace: true, paste: true })
32+
.click(this.applyButton)
33+
.expect(this.changeIndexBtn.textContent).contains(dbIndex.toString());
34+
}
35+
36+
/**
37+
* Verify that definite database index selected
38+
* @param dbIndex The index of logical database
39+
*/
40+
async verifyDbIndexSelected(dbIndex: number): Promise<void> {
41+
await t.expect(this.changeIndexBtn.textContent).contains(dbIndex.toString());
42+
}
2043
}

tests/e2e/tests/critical-path/browser/context.e2e.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { commonUrl, ossStandaloneBigConfig, ossStandaloneConfig } from '../../..
88
import { Common } from '../../../helpers/common';
99
import { KeyTypesTexts, rte } from '../../../helpers/constants';
1010
import { deleteStandaloneDatabaseApi } from '../../../helpers/api/api-database';
11+
import { verifySearchFilterValue } from '../../../helpers/keys';
1112

1213
const myRedisDatabasePage = new MyRedisDatabasePage();
1314
const browserPage = new BrowserPage();
@@ -70,7 +71,7 @@ test('Verify that user can see saved filter per key type applied when he returns
7071
// Return back to Browser and check filter applied
7172
await t.click(myRedisDatabasePage.browserButton);
7273
// Verify that user can see saved input entered into the filter per Key name when he returns back to Browser page
73-
await t.expect(browserPage.filterByPatterSearchInput.withAttribute('value', keyName).exists).ok('Filter per key name is still applied');
74+
await verifySearchFilterValue(keyName);
7475
});
7576
test('Verify that user can see saved executed commands in CLI on Browser page when he returns back to Browser page', async t => {
7677
const commands = [

tests/e2e/tests/critical-path/browser/search-capabilities.e2e.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ async function verifyContext(): Promise<void> {
4343
.expect(browserPage.keyNameFormDetails.withExactText(keyName).exists).ok('Key details not opened');
4444
}
4545

46-
fixture`Search capabilities in Browser`
46+
fixture `Search capabilities in Browser`
4747
.meta({ type: 'critical_path', rte: rte.standalone })
4848
.page(commonUrl);
4949
test
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
import { acceptLicenseTermsAndAddDatabaseApi } from '../../../helpers/database';
2+
import { KeyTypesTexts, rte } from '../../../helpers/constants';
3+
import { Common } from '../../../helpers/common';
4+
import {
5+
MyRedisDatabasePage,
6+
BrowserPage,
7+
CliPage,
8+
DatabaseOverviewPage,
9+
WorkbenchPage,
10+
MemoryEfficiencyPage
11+
} from '../../../pageObjects';
12+
import {
13+
commonUrl,
14+
ossStandaloneConfig
15+
} from '../../../helpers/conf';
16+
import { deleteStandaloneDatabaseApi } from '../../../helpers/api/api-database';
17+
import { verifyKeysDisplayedInTheList, verifyKeysNotDisplayedInTheList, verifySearchFilterValue } from '../../../helpers/keys';
18+
19+
const myRedisDatabasePage = new MyRedisDatabasePage();
20+
const browserPage = new BrowserPage();
21+
const cliPage = new CliPage();
22+
const databaseOverviewPage = new DatabaseOverviewPage();
23+
const common = new Common();
24+
const workbenchPage = new WorkbenchPage();
25+
const memoryEfficiencyPage = new MemoryEfficiencyPage();
26+
27+
const keyName = common.generateWord(10);
28+
const indexName = `idx:${keyName}`;
29+
const keyNames = [`${keyName}:1`, `${keyName}:2`];
30+
const commands = [
31+
`HSET ${keyNames[0]} "name" "Hall School" "description" " Spanning 10 states" "class" "independent" "type" "traditional" "address_city" "London" "address_street" "Manor Street" "students" 342 "location" "51.445417, -0.258352"`,
32+
`HSET ${keyNames[1]} "name" "Garden School" "description" "Garden School is a new outdoor" "class" "state" "type" "forest; montessori;" "address_city" "London" "address_street" "Gordon Street" "students" 1452 "location" "51.402926, -0.321523"`,
33+
`FT.CREATE ${indexName} ON HASH PREFIX 1 "${keyName}:" SCHEMA name TEXT NOSTEM description TEXT class TAG type TAG SEPARATOR ";" address_city AS city TAG address_street AS address TEXT NOSTEM students NUMERIC SORTABLE location GEO`
34+
];
35+
const keyNameForSearchInLogicalDb = 'keyForSearch';
36+
const logicalDbKey = `${keyName}:3`;
37+
38+
fixture `Allow to change database index`
39+
.meta({ type: 'critical_path', rte: rte.standalone })
40+
.page(commonUrl)
41+
.beforeEach(async() => {
42+
await acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig, ossStandaloneConfig.databaseName);
43+
// Create 3 keys and index
44+
await cliPage.sendCommandsInCli(commands);
45+
})
46+
.afterEach(async() => {
47+
// Delete keys in logical database
48+
await databaseOverviewPage.changeDbIndex(1);
49+
await cliPage.sendCommandsInCli([`DEL ${keyNameForSearchInLogicalDb}`, `DEL ${logicalDbKey}`]);
50+
// Delete and clear database
51+
await databaseOverviewPage.changeDbIndex(0);
52+
await cliPage.sendCommandsInCli([`DEL ${keyNames.join(' ')}`, `DEL ${keyName}`, `FT.DROPINDEX ${indexName}`]);
53+
await deleteStandaloneDatabaseApi(ossStandaloneConfig);
54+
});
55+
test('Switching between indexed databases', async t => {
56+
const command = `HSET ${logicalDbKey} "name" "Gillford School" "description" "Gillford School is a centre" "class" "private" "type" "democratic; waldorf" "address_city" "Goudhurst" "address_street" "Goudhurst" "students" 721 "location" "51.112685, 0.451076"`;
57+
const rememberedConnectedClients = await browserPage.overviewConnectedClients.textContent;
58+
59+
// Change index to logical db
60+
// Verify that database index switcher displayed for Standalone db
61+
await databaseOverviewPage.changeDbIndex(1);
62+
// Verify that the same client connections are used after changing index
63+
const logicalDbConnectedClients = await browserPage.overviewConnectedClients.textContent;
64+
await t.expect(rememberedConnectedClients).eql(logicalDbConnectedClients);
65+
66+
// Verify that data changed for indexed db on Browser view
67+
await browserPage.verifyNoKeysInDatabase();
68+
69+
// Verify that logical db not changed after reloading page
70+
await common.reloadPage();
71+
await databaseOverviewPage.verifyDbIndexSelected(1);
72+
await browserPage.verifyNoKeysInDatabase();
73+
74+
// Add key to logical (index=1) database
75+
await browserPage.addHashKey(keyNameForSearchInLogicalDb);
76+
// Verify that data changed for indexed db on Tree view
77+
await t.click(browserPage.treeViewButton);
78+
await verifyKeysDisplayedInTheList([keyNameForSearchInLogicalDb]);
79+
await verifyKeysNotDisplayedInTheList(keyNames);
80+
81+
// Filter by Hash keys and search by key name
82+
await browserPage.selectFilterGroupType(KeyTypesTexts.Hash);
83+
await browserPage.searchByKeyName(keyNameForSearchInLogicalDb);
84+
// Return to default database
85+
await databaseOverviewPage.changeDbIndex(0);
86+
87+
// Verify that search/filter saved after switching index in Browser
88+
await verifySearchFilterValue(keyNameForSearchInLogicalDb);
89+
await verifyKeysNotDisplayedInTheList([keyNameForSearchInLogicalDb]);
90+
await t.click(browserPage.browserViewButton);
91+
// Change index to logical db
92+
await databaseOverviewPage.changeDbIndex(1);
93+
await verifySearchFilterValue(keyNameForSearchInLogicalDb);
94+
await verifyKeysDisplayedInTheList([keyNameForSearchInLogicalDb]);
95+
96+
// Return to default database and open search capability
97+
await databaseOverviewPage.changeDbIndex(0);
98+
await t.click(browserPage.redisearchModeBtn);
99+
await browserPage.selectIndexByName(indexName);
100+
await verifyKeysDisplayedInTheList(keyNames);
101+
// Change index to logical db
102+
await databaseOverviewPage.changeDbIndex(1);
103+
// Search by value and return to default database
104+
await browserPage.searchByKeyName('Hall School');
105+
await databaseOverviewPage.changeDbIndex(0);
106+
// Verify that data changed for indexed db on Search capability page
107+
await verifyKeysDisplayedInTheList([keyNames[0]]);
108+
// Change index to logical db
109+
await databaseOverviewPage.changeDbIndex(1);
110+
// Verify that search/filter saved after switching index in Search capability
111+
await verifySearchFilterValue('Hall School');
112+
113+
// Open Workbench page
114+
await t.click(myRedisDatabasePage.workbenchButton);
115+
await workbenchPage.sendCommandInWorkbench(command);
116+
// Open Browser page
117+
await t.click(myRedisDatabasePage.browserButton);
118+
// Clear filter
119+
await t.click(browserPage.clearFilterButton);
120+
// Verify that data changed for indexed db on Workbench page (on Search capability page)
121+
await verifyKeysDisplayedInTheList([logicalDbKey]);
122+
await t.click(browserPage.patternModeBtn);
123+
// Clear filter
124+
await t.click(browserPage.clearFilterButton);
125+
// Verify that data changed for indexed db on Workbench page
126+
await verifyKeysDisplayedInTheList([keyNameForSearchInLogicalDb, logicalDbKey]);
127+
await databaseOverviewPage.changeDbIndex(0);
128+
await verifyKeysNotDisplayedInTheList([logicalDbKey]);
129+
130+
// Go to Analysis Tools page and create new report
131+
await t.click(myRedisDatabasePage.analysisPageButton);
132+
await t.click(memoryEfficiencyPage.newReportBtn);
133+
134+
// Verify that data changed for indexed db on Database analysis page
135+
await t.expect(memoryEfficiencyPage.topKeysKeyName.withExactText(keyNames[0]).exists).ok('Keys from current db index not displayed in report');
136+
await t.expect(memoryEfficiencyPage.topKeysKeyName.withExactText(logicalDbKey).exists).notOk('Keys from other db index displayed in report');
137+
// Change index to logical db
138+
await databaseOverviewPage.changeDbIndex(1);
139+
await t.click(memoryEfficiencyPage.newReportBtn);
140+
await t.expect(memoryEfficiencyPage.topKeysKeyName.withExactText(logicalDbKey).exists).ok('Keys from current db index not displayed in report');
141+
await t.expect(memoryEfficiencyPage.topKeysKeyName.withExactText(keyNames[0]).exists).notOk('Keys from other db index displayed in report');
142+
});
File renamed without changes.

tests/e2e/tests/critical-path/database/logical-databases.e2e.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ test('Verify that user can add DB with logical index via host and port from Add
2424
// Enter logical index
2525
await t.click(addRedisDatabasePage.databaseIndexCheckbox);
2626
await t.typeText(addRedisDatabasePage.databaseIndexInput, index, { replace: true, paste: true });
27-
// Verify that user when users select DB index they can see info message how to work with DB index in add DB screen
28-
await t.expect(addRedisDatabasePage.databaseIndexMessage.exists).ok('Index message not displayed')
29-
.expect(addRedisDatabasePage.databaseIndexMessage.innerText).eql(indexDbMessage)
27+
// *** - outdated - Verify that user when users select DB index they can see info message how to work with DB index in add DB screen
28+
// Verify that logical db message not displayed in add database form
29+
await t.expect(addRedisDatabasePage.databaseIndexMessage.exists).notOk('Index message is still displayed')
3030
.expect(addRedisDatabasePage.databaseIndexCheckbox.parent().withExactText('Select Logical Database').exists).ok('Checkbox text not displayed');
3131
// Click for saving
3232
await t.click(addRedisDatabasePage.addRedisDatabaseButton);

tests/e2e/tests/critical-path/memory-efficiency/memory-efficiency.e2e.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { acceptLicenseTermsAndAddDatabaseApi } from '../../../helpers/database';
55
import { commonUrl, ossStandaloneConfig } from '../../../helpers/conf';
66
import { deleteStandaloneDatabaseApi } from '../../../helpers/api/api-database';
77
import { Common } from '../../../helpers/common';
8+
import { verifySearchFilterValue } from '../../../helpers/keys';
89

910
const memoryEfficiencyPage = new MemoryEfficiencyPage();
1011
const myRedisDatabasePage = new MyRedisDatabasePage();
@@ -95,7 +96,7 @@ test
9596
// Verify filter by data type applied
9697
await t.expect(browserPage.filteringLabel.textContent).eql('Stream', 'Key type lable is not displayed in search input');
9798
// Verify keyname in search input prepopulated
98-
await t.expect(browserPage.filterByPatterSearchInput.withAttribute('value', keySpaces[0]).exists).ok('Filter per key name is not applied');
99+
await verifySearchFilterValue(keySpaces[0]);
99100
// Verify key is displayed
100101
await t.click(browserPage.browserViewButton);
101102
await t.expect(await browserPage.isKeyIsDisplayedInTheList(streamKeyName)).ok('Key is not found');

tests/e2e/tests/critical-path/tree-view/tree-view.e2e.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
import { rte, KeyTypesTexts } from '../../../helpers/constants';
88
import { deleteStandaloneDatabaseApi } from '../../../helpers/api/api-database';
99
import { Common } from '../../../helpers/common';
10+
import { verifySearchFilterValue } from '../../../helpers/keys';
1011

1112
const browserPage = new BrowserPage();
1213
const common = new Common();
@@ -62,7 +63,7 @@ test('Verify that when user switched from Tree View to Browser and goes back sta
6263
await t.click(browserPage.browserViewButton);
6364
await t.click(browserPage.treeViewButton);
6465
// Verify that state of filer by key name is saved
65-
await t.expect(browserPage.filterByPatterSearchInput.withAttribute('value', keyName).exists).ok('Filter per key name is not applied');
66+
await verifySearchFilterValue(keyName);
6667
await t.click(browserPage.treeViewButton);
6768
// Set filter by key type
6869
await browserPage.selectFilterGroupType(KeyTypesTexts.String);

0 commit comments

Comments
 (0)