Skip to content

Commit 885d310

Browse files
Merge pull request #120 from RedisInsight/feature/e2e
e2e - Command results at Workbench
2 parents 331150e + 9a27bc7 commit 885d310

File tree

10 files changed

+134
-17
lines changed

10 files changed

+134
-17
lines changed

redisinsight/ui/src/components/query-card/QueryCardCliPlugin/QueryCardCliPlugin.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ const QueryCardCliPlugin = (props: Props) => {
147147
ref={pluginIframeRef}
148148
referrerPolicy="no-referrer"
149149
sandbox="allow-same-origin allow-scripts"
150+
data-testid="pluginIframe"
150151
/>
151152
{!!error && (
152153
<div className={styles.container}>

tests/e2e/helpers/database.ts

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
1-
import { t } from 'testcafe'
2-
import { MyRedisDatabasePage } from '../pageObjects/my-redis-databases-page'
3-
import { AddNewDatabaseParameters, SentinelParameters, AddRedisDatabasePage, OSSClusterParameters } from '../pageObjects/add-redis-database-page'
4-
import { DiscoverMasterGroupsPage } from '../pageObjects/sentinel/discovered-sentinel-master-groups-page'
5-
import { AutoDiscoverREDatabases } from '../pageObjects/auto-discover-redis-enterprise-databases'
6-
import { BrowserPage } from '../pageObjects/browser-page'
1+
import { t } from 'testcafe';
2+
import { MyRedisDatabasePage } from '../pageObjects/my-redis-databases-page';
3+
import { AddNewDatabaseParameters, SentinelParameters, AddRedisDatabasePage, OSSClusterParameters } from '../pageObjects/add-redis-database-page';
4+
import { DiscoverMasterGroupsPage } from '../pageObjects/sentinel/discovered-sentinel-master-groups-page';
5+
import { AutoDiscoverREDatabases } from '../pageObjects/auto-discover-redis-enterprise-databases';
6+
import { BrowserPage } from '../pageObjects/browser-page';
7+
import { UserAgreementPage } from '../pageObjects';
78

8-
const myRedisDatabasPage = new MyRedisDatabasePage
9-
const addRedisDatabasePage = new AddRedisDatabasePage
10-
const discoverMasterGroupsPage = new DiscoverMasterGroupsPage
9+
const myRedisDatabasePage = new MyRedisDatabasePage;
10+
const addRedisDatabasePage = new AddRedisDatabasePage;
11+
const discoverMasterGroupsPage = new DiscoverMasterGroupsPage;
1112
const autoDiscoverREDatabases = new AutoDiscoverREDatabases;
1213
const browserPage = new BrowserPage;
14+
const userAgreementPage = new UserAgreementPage;
1315

1416
/**
1517
* Add a new database manually using host and port
@@ -21,7 +23,7 @@ export async function addNewStandaloneDatabase(databaseParameters: AddNewDatabas
2123
//Click for saving
2224
await t.click(addRedisDatabasePage.addRedisDatabaseButton);
2325
//Wait for database to be exist
24-
await t.expect(myRedisDatabasPage.dbNameList.withExactText(databaseParameters.databaseName).exists).ok('The existence of the database', { timeout: 60000 });
26+
await t.expect(myRedisDatabasePage.dbNameList.withExactText(databaseParameters.databaseName).exists).ok('The existence of the database', { timeout: 60000 });
2527
}
2628

2729
/**
@@ -68,9 +70,9 @@ export async function addOSSClusterDatabase(databaseParameters: OSSClusterParame
6870
//Click for saving
6971
await t.click(addRedisDatabasePage.addRedisDatabaseButton);
7072
//Check for info message that DB was added
71-
await t.expect(myRedisDatabasPage.databaseInfoMessage.exists).ok('Check that info message exists', { timeout: 60000 });
73+
await t.expect(myRedisDatabasePage.databaseInfoMessage.exists).ok('Check that info message exists', { timeout: 60000 });
7274
//Wait for database to be exist
73-
await t.expect(myRedisDatabasPage.dbNameList.withExactText(databaseParameters.ossClusterDatabaseName).exists).ok('The existence of the database', { timeout: 60000 });
75+
await t.expect(myRedisDatabasePage.dbNameList.withExactText(databaseParameters.ossClusterDatabaseName).exists).ok('The existence of the database', { timeout: 60000 });
7476
}
7577

7678
/**
@@ -91,6 +93,20 @@ export async function addNewRECloudDatabase(cloudAPIAccessKey: string, cloudAPIS
9193
await t.click(autoDiscoverREDatabases.addSelectedDatabases);
9294
//Wait for database to be exist in the My redis databases list
9395
await t.click(autoDiscoverREDatabases.viewDatabasesButton);
94-
await t.expect(myRedisDatabasPage.dbNameList.withExactText(databaseName).exists).ok('The existence of the database', { timeout: 60000 });
96+
await t.expect(myRedisDatabasePage.dbNameList.withExactText(databaseName).exists).ok('The existence of the database', { timeout: 60000 });
9597
return databaseName;
9698
}
99+
100+
/**
101+
* Accept License terms and add database
102+
* @param databaseParameters The database parameters
103+
* @param databaseName The database name
104+
*/
105+
export async function acceptLicenseTermsAndAddDatabase(databaseParameters: AddNewDatabaseParameters, databaseName: string): Promise<void> {
106+
await t.maximizeWindow();
107+
await userAgreementPage.acceptLicenseTerms();
108+
await t.expect(addRedisDatabasePage.addDatabaseButton.exists).ok('The add redis database view', {timeout: 20000});
109+
await addNewStandaloneDatabase(databaseParameters);
110+
//Connect to DB
111+
await myRedisDatabasePage.clickOnDBByName(databaseName);
112+
}

tests/e2e/pageObjects/my-redis-databases-page.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export class MyRedisDatabasePage {
6060

6161
//Delete all the databases from the list
6262
async deleteAllDatabases(): Promise<void> {
63+
await t.click(this.myRedisDBButton);
6364
const dbNames = this.tableRowContent;
6465
const count = await dbNames.count;
6566
if(count > 1) {

tests/e2e/pageObjects/workbench-page.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export class WorkbenchPage {
88
cssDeleteCommandButton: string
99
cssQueryCardOutputResponceSuccess: string
1010
cssTableViewTypeOption: string
11+
cssQueryTextResult: string
12+
cssQueryTableResult: string
1113
//------------------------------------------------------------------------------------------
1214
//DECLARATION OF TYPES: DOM ELEMENTS and UI COMPONENTS
1315
//*Assign the 'Selector' type to any element/component nested within the constructor.
@@ -45,6 +47,7 @@ export class WorkbenchPage {
4547
internalLinkWorkingWithHashes: Selector
4648
preselectExactSearch: Selector
4749
preselectGroupBy: Selector
50+
tableViewTypeOption: Selector
4851
preselectArea: Selector
4952
expandArea: Selector
5053
monacoHintWithArguments: Selector
@@ -61,6 +64,8 @@ export class WorkbenchPage {
6164
this.cssDeleteCommandButton = '[data-testid=delete-command]';
6265
this.cssQueryCardOutputResponceSuccess = '[data-testid=query-card-output-response-success]';
6366
this.cssTableViewTypeOption = '[data-testid=view-type-selected-Plugin-redisearch__redisearch]';
67+
this.cssQueryTextResult = '[data-testid=query-cli-result]';
68+
this.cssQueryTableResult = '[data-testid^=query-table-result-]';
6469
//-------------------------------------------------------------------------------------------
6570
//DECLARATION OF SELECTORS
6671
//*Declare all elements/components of the relevant page.
@@ -75,7 +80,8 @@ export class WorkbenchPage {
7580
this.paginationButtonPrevious = Selector(this.cssSelectorPaginationButtonPrevious);
7681
this.paginationButtonNext = Selector(this.cssSelectorPaginationButtonNext);
7782
this.selectViewType = Selector('[data-testid=select-view-type]');
78-
this.textViewTypeOption = Selector('[data-test-subj=view-type-option-Text]');
83+
this.textViewTypeOption = Selector('[data-test-subj^=view-type-option-Text]');
84+
this.tableViewTypeOption = Selector('[data-test-subj^=view-type-option-Plugin]');
7985
this.preselectList = Selector('[data-testid*=preselect-List]');
8086
this.preselectIndexInfo = Selector('[data-testid*=preselect-Index]');
8187
this.preselectSearch = Selector('[data-testid=preselect-Search]');
@@ -91,7 +97,7 @@ export class WorkbenchPage {
9197
this.queryCardContainer = Selector('[data-testid^=query-card-container]');
9298
this.queryCardCommand = Selector('[data-testid=query-card-command]');
9399
this.queryTableResult = Selector('[data-testid^=query-table-result-]');
94-
this.queryTextResult = Selector('[data-testid=query-cli-result]');
100+
this.queryTextResult = Selector(this.cssQueryTextResult);
95101
this.queryColumns = Selector('[data-testid*=query-column-]');
96102
this.queryInputScriptArea = Selector('[data-testid=query-input-container] .view-line');
97103
this.overviewTotalKeys = Selector('[data-test-subj=overview-total-keys]');
@@ -101,7 +107,7 @@ export class WorkbenchPage {
101107
this.monacoCommandDetails = Selector('div.suggest-details-container');
102108
this.monacoCloseCommandDetails = Selector('span.codicon-close');
103109
this.monacoSuggestion = Selector('span.monaco-icon-name-container');
104-
this.iframe = Selector('.pluginIframe', { timeout: 90000 });
110+
this.iframe = Selector('[data-testid=pluginIframe]', { timeout: 60000 });
105111
this.monacoHintWithArguments = Selector('[widgetid="editor.widget.parameterHintsWidget"]');
106112
this.noCommandHistorySection = Selector('[data-testid=wb_no-results]');
107113
this.preselectArea = Selector('[data-testid=enablementArea]');
@@ -125,6 +131,12 @@ export class WorkbenchPage {
125131
await t.click(this.textViewTypeOption);
126132
}
127133

134+
//Select Table view option in Workbench results
135+
async selectViewTypeTable(): Promise<void>{
136+
await t.click(this.selectViewType);
137+
await t.click(this.tableViewTypeOption);
138+
}
139+
128140
/**
129141
* Send a command in Workbench
130142
* @param command The command
@@ -134,4 +146,14 @@ export class WorkbenchPage {
134146
await t.typeText(this.queryInput, command, { replace: true, speed: speed});
135147
await t.click(this.submitCommandButton);
136148
}
149+
150+
/**
151+
* Send commands array in Workbench page
152+
* @param commands The array of commands to send
153+
*/
154+
async sendCommandsArrayInWorkbench(commands: string[]): Promise<void> {
155+
for(let command of commands) {
156+
await this.sendCommandInWorkbench(command);
157+
}
158+
}
137159
}

tests/e2e/tests/critical-path/browser/database-overview.e2e.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ fixture `Database overview`
3838
await t.pressKey('enter');
3939
await t.click(cliPage.cliCollapseButton);
4040
//Delete all databases
41-
await t.click(myRedisDatabasePage.myRedisDBButton);
4241
await myRedisDatabasePage.deleteAllDatabases();
4342
})
4443
test('Verify that user can see the list of Modules updated each time when he connects to the database', async t => {

tests/e2e/tests/critical-path/workbench/default-scripts-area.e2e.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ test.skip('Verify that user can edit and run automatically added "FT._LIST" and
5454
await t.pressKey('ctrl+a delete');
5555
await workbenchPage.sendCommandInWorkbench(addedScript);
5656
//Check the FT.INFO result
57+
await t.switchToIframe(workbenchPage.iframe);
5758
await t.expect(workbenchPage.queryColumns.textContent).contains('name', 'The result of the FT.INFO command');
59+
await t.switchToMainWindow();
5860
});
5961
//skipped due the inaccessibility of the iframe
6062
test.skip('Verify that user can edit and run automatically added "Search" script in Workbench and see the results', async t => {
@@ -72,10 +74,12 @@ test.skip('Verify that user can edit and run automatically added "Search" script
7274
await t.pressKey('ctrl+a delete');
7375
await workbenchPage.sendCommandInWorkbench(searchCommand);
7476
//Check the FT.SEARCH result
77+
await t.switchToIframe(workbenchPage.iframe);
7578
const key = workbenchPage.queryTableResult.withText('product:1');
7679
const name = workbenchPage.queryTableResult.withText('Apple Juice');
7780
await t.expect(key.exists).ok('The added key is in the Search result');
7881
await t.expect(name.exists).ok('The added key name field is in the Search result');
82+
await t.switchToMainWindow();
7983
});
8084
//skipped due the inaccessibility of the iframe
8185
test.skip('Verify that user can edit and run automatically added "Aggregate" script in Workbench and see the results', async t => {
@@ -94,8 +98,10 @@ test.skip('Verify that user can edit and run automatically added "Aggregate" scr
9498
await t.pressKey('ctrl+a delete');
9599
await workbenchPage.sendCommandInWorkbench(searchCommand);
96100
//Check the FT.Aggregate result
101+
await t.switchToIframe(workbenchPage.iframe);
97102
await t.expect(workbenchPage.queryTableResult.textContent).contains(aggregationResultField, 'The aggregation field name is in the Search result');
98103
await t.expect(workbenchPage.queryTableResult.textContent).contains('100', 'The aggregation max value is in the Search result');
104+
await t.switchToMainWindow();
99105
});
100106
test('Verify that when the “Manual” option clicked, user can see the Editor is automatically prepopulated with the information', async t => {
101107
const information = [

tests/e2e/tests/critical-path/workbench/index-schema.e2e.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ test.skip('Verify that user can open results in Text and Table views for FT.INFO
4949
await t.switchToIframe(workbenchPage.iframe);
5050
await t.expect(workbenchPage.queryTableResult.exists).ok('The result is displayed in Table view');
5151
//Select Text view type
52+
await t.switchToMainWindow();
5253
await workbenchPage.selectViewTypeText();
5354
//Check that result is displayed in Text view
5455
await t.expect(workbenchPage.queryTextResult.exists).ok('The result is displayed in Text view');
@@ -65,8 +66,10 @@ test.skip('Verify that user can open results in Text and Table views for FT.INFO
6566
//Send search command
6667
await workbenchPage.sendCommandInWorkbench(searchCommand);
6768
//Check that result is displayed in Table view
69+
await t.switchToIframe(workbenchPage.iframe);
6870
await t.expect(workbenchPage.queryTableResult.exists).ok('The result is displayed in Table view');
6971
//Select Text view type
72+
await t.switchToMainWindow();
7073
await workbenchPage.selectViewTypeText();
7174
//Check that result is displayed in Text view
7275
await t.expect(workbenchPage.queryTextResult.exists).ok('The result is displayed in Text view');

tests/e2e/tests/critical-path/workbench/json-workbench.e2e.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@ test.skip('Verify that user can see result in Table and Text view for JSON data
4747
//Send search command
4848
await workbenchPage.sendCommandInWorkbench(searchCommand);
4949
//Check that result is displayed in Table view
50+
await t.switchToIframe(workbenchPage.iframe);
5051
await t.expect(workbenchPage.queryTableResult.exists).ok('The result is displayed in Table view');
5152
//Select Text view type
53+
await t.switchToMainWindow();
5254
await workbenchPage.selectViewTypeText();
5355
//Check that result is displayed in Text view
5456
await t.expect(workbenchPage.queryTextResult.exists).ok('The result is displayed in Text view');

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,13 @@ test.skip('Verify that user when he have more than 10 results can request to vie
8080
//Get needed container
8181
const containerOfCommand = await workbenchPage.getCardContainerByCommand(searchCommand);
8282
//Verify that we have pagination buttons
83+
await t.switchToIframe(workbenchPage.iframe);
8384
await t.expect(containerOfCommand.find(workbenchPage.cssSelectorPaginationButtonPrevious).exists)
8485
.ok('Pagination previous button exists');
8586
await t.expect(containerOfCommand.find(workbenchPage.cssSelectorPaginationButtonNext).exists)
8687
.ok('Pagination next button exists');
8788
//Drop index and documents
89+
await t.switchToMainWindow();
8890
await workbenchPage.sendCommandInWorkbench('FT.DROPINDEX products DD');
8991
});
9092
//skipped due the inaccessibility of the iframe
@@ -105,8 +107,10 @@ test.skip
105107
//Send search command
106108
await workbenchPage.sendCommandInWorkbench(searchCommand);
107109
//Check that result is displayed in Table view
110+
await t.switchToIframe(workbenchPage.iframe);
108111
await t.expect(workbenchPage.queryTableResult.exists).ok('The result is displayed in Table view');
109112
//Select Text view type
113+
await t.switchToMainWindow();
110114
await workbenchPage.selectViewTypeText();
111115
//Check that result is displayed in Text view
112116
await t.expect(workbenchPage.queryTextResult.exists).ok('The result is displayed in Text view');
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { acceptLicenseTermsAndAddDatabase } from '../../../helpers/database';
2+
import { WorkbenchPage } from '../../../pageObjects/workbench-page';
3+
import { MyRedisDatabasePage } from '../../../pageObjects';
4+
import {
5+
commonUrl,
6+
ossStandaloneConfig
7+
} from '../../../helpers/conf';
8+
9+
const myRedisDatabasePage = new MyRedisDatabasePage();
10+
const workbenchPage = new WorkbenchPage();
11+
12+
const indexName = 'idx';
13+
const commandsForIndex = [
14+
`FT.CREATE ${indexName} ON HASH PREFIX 1 product: SCHEMA price NUMERIC SORTABLE`,
15+
'HMSET product:1 price 20',
16+
'HMSET product:2 price 100'
17+
];
18+
19+
//skipped due the inaccessibility of the iframe
20+
fixture.skip `Command results at Workbench`
21+
.meta({type: 'regression'})
22+
.page(commonUrl)
23+
.beforeEach(async t => {
24+
await acceptLicenseTermsAndAddDatabase(ossStandaloneConfig, ossStandaloneConfig.databaseName);
25+
//Add index and data
26+
await t.click(myRedisDatabasePage.workbenchButton);
27+
await workbenchPage.sendCommandsArrayInWorkbench(commandsForIndex);
28+
})
29+
.afterEach(async() => {
30+
//Drop index and dbs
31+
await workbenchPage.sendCommandInWorkbench('FT.DROPINDEX products DD');
32+
await myRedisDatabasePage.deleteAllDatabases();
33+
})
34+
test('Verify that user can switches between Table and Text for FT.INFO and see results corresponding to their views', async t => {
35+
const infoCommand = `FT.INFO ${indexName}`;
36+
//Send FT.INFO and switch to Text view
37+
await workbenchPage.sendCommandInWorkbench(infoCommand);
38+
await workbenchPage.selectViewTypeText();
39+
await t.expect(await workbenchPage.queryCardContainer.nth(0).find(workbenchPage.cssQueryTextResult).exists).ok(`The text view is switched for command FT.INFO`);
40+
//Switch to Table view and check result
41+
await workbenchPage.selectViewTypeTable();
42+
await t.expect(await workbenchPage.queryCardContainer.nth(0).find(workbenchPage.cssQueryTableResult).exists).ok(`The table view is switched for command FT.INFO`);
43+
});
44+
test('Verify that user can switches between Table and Text for FT.SEARCH and see results corresponding to their views', async t => {
45+
const searchCommand = `FT.SEARCH ${indexName} *`;
46+
//Send FT.SEARCH and switch to Text view
47+
await workbenchPage.sendCommandInWorkbench(searchCommand);
48+
await workbenchPage.selectViewTypeText();
49+
await t.expect(await workbenchPage.queryCardContainer.nth(0).find(workbenchPage.cssQueryTextResult).visible).ok(`The text view is switched for command FT.SEARCH`);
50+
//Switch to Table view and check result
51+
await workbenchPage.selectViewTypeTable();
52+
await t.expect(await workbenchPage.queryCardContainer.nth(0).find(workbenchPage.cssQueryTableResult).exists).ok(`The table view is switched for command FT.SEARCH`);
53+
});
54+
test('Verify that user can switches between Table and Text for FT.AGGREGATE and see results corresponding to their views', async t => {
55+
const aggregateCommand = `FT.Aggregate ${indexName} * GROUPBY 0 REDUCE MAX 1 @price AS max_price`;
56+
//Send FT.AGGREGATE and switch to Text view
57+
await workbenchPage.sendCommandInWorkbench(aggregateCommand);
58+
await workbenchPage.selectViewTypeText();
59+
await t.expect(await workbenchPage.queryCardContainer.nth(0).find(workbenchPage.cssQueryTextResult).visible).ok(`The text view is switched for command FT.AGGREGATE`);
60+
//Switch to Table view and check result
61+
await workbenchPage.selectViewTypeTable();
62+
await t.expect(await workbenchPage.queryCardContainer.nth(0).find(workbenchPage.cssQueryTableResult).exists).ok(`The table view is switched for command FT.AGGREGATE`);
63+
});

0 commit comments

Comments
 (0)