Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion tests/e2e/helpers/api/api-database.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { t } from 'testcafe';
import * as request from 'supertest';
import { asyncFilter, doAsyncStuff } from '../async-helper';
import { AddNewDatabaseParameters, OSSClusterParameters, databaseParameters, SentinelParameters } from '../../pageObjects/add-redis-database-page';
import { AddNewDatabaseParameters, OSSClusterParameters, databaseParameters, SentinelParameters, ClusterNodes } from '../../pageObjects/add-redis-database-page';
import { Common } from '../common';

const common = new Common();
Expand Down Expand Up @@ -195,3 +195,18 @@ export async function deleteStandaloneDatabasesApi(databasesParameters: AddNewDa
});
}
}

/**
* Get OSS Cluster nodes
* @param databaseParameters The database parameters
*/
export async function getClusterNodesApi(databaseParameters: OSSClusterParameters): Promise<string[]> {
const databaseId = await getDatabaseByName(databaseParameters.ossClusterDatabaseName);
const response = await request(endpoint)
.get(`/instance/${databaseId}/cluster-details`)
.set('Accept', 'application/json')
.expect(200);
let nodes = await response.body.nodes;
let nodeNames = await nodes.map((node: ClusterNodes) => (node.host + ':' + node.port));
return nodeNames;
}
10 changes: 10 additions & 0 deletions tests/e2e/pageObjects/add-redis-database-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,13 @@ export type databaseParameters = {
connectionType?: string,
lastConnection?: string
};

/**
* Nodes in OSS Cluster parameters
* @param host The host of the node
* @param port The port of the node
*/
export type ClusterNodes = {
host: string,
port: string

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be also a number

};
2 changes: 2 additions & 0 deletions tests/e2e/pageObjects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { DatabaseOverviewPage } from './database-overview-page';
import { HelpCenterPage } from './help-center-page';
import { ShortcutsPage } from './shortcuts-page';
import { MonitorPage } from './monitor-page';
import { OverviewPage } from './overview-page';
import { PubSubPage } from './pub-sub-page';
import { SlowLogPage } from './slow-log-page';
import { NotificationPage } from './notification-page';
Expand All @@ -29,6 +30,7 @@ export {
HelpCenterPage,
ShortcutsPage,
MonitorPage,
OverviewPage,
PubSubPage,
SlowLogPage,
NotificationPage
Expand Down
1 change: 1 addition & 0 deletions tests/e2e/pageObjects/my-redis-databases-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export class MyRedisDatabasePage {
//BUTTONS
settingsButton = Selector('[data-testid=settings-page-btn]');
workbenchButton = Selector('[data-testid=workbench-page-btn]');
analysisPageButton = Selector('[data-testid=analytics-page-btn]');
helpCenterButton = Selector('[data-testid=help-menu-button]');
githubButton = Selector('[data-testid=github-repo-icon]');
browserButton = Selector('[data-testid=browser-page-btn]');
Expand Down
66 changes: 66 additions & 0 deletions tests/e2e/pageObjects/overview-page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Selector } from 'testcafe';

export class OverviewPage {
//CSS Selectors
cssTableRow = 'tr[class=euiTableRow]';
//-------------------------------------------------------------------------------------------
//DECLARATION OF SELECTORS
//*Declare all elements/components of the relevant page.
//*Target any element/component via data-id, if possible!
//*The following categories are ordered alphabetically (Alerts, Buttons, Checkboxes, etc.).
//-------------------------------------------------------------------------------------------
//BUTTONS
overviewTab = Selector('[data-testid=analytics-tab-ClusterDetails]');
// COMPONENTS
clusterDetailsUptime = Selector('[data-testid=cluster-details-uptime]');
//TABLE COMPONENTS
tableHeaderCell = Selector('[data-test-subj^=tableHeaderCell]');
primaryNodesTable = Selector('[data-testid=primary-nodes-table]');
tableRow = Selector('tr[class=euiTableRow]');
connectedClientsValue = Selector('[data-testid^=connectedClients-value]');
totalKeysValue = Selector('[data-testid^=totalKeys-value]');
networkInputValue = Selector('[data-testid^=networkInKbps-value]');
networkOutputValue = Selector('[data-testid^=networkOutKbps-value]');

/**
* Get Primary nodes count in table
*/
async getPrimaryNodesCount(): Promise<number> {
return await this.primaryNodesTable.find(this.cssTableRow).count;
}

/**
* Get total value from all rows in column
* @param column The column name
*/
async getTotalValueByColumnName(column: string): Promise<number> {
let totalNumber = 0;
let columnInSelector = '';
switch (column) {
case 'Commands/s':
columnInSelector = 'opsPerSecond';
break;
case 'Clients':
columnInSelector = 'connectedClients';
break;
case 'Total Keys':
columnInSelector = 'totalKeys';
break;
case 'Network Input':
columnInSelector = 'networkInKbps';
break;
case 'Network Output':
columnInSelector = 'networkOutKbps';
break;
case 'Total Memory':
columnInSelector = 'usedMemory';
break;
default: columnInSelector = '';
}
const rowSelector = Selector(`[data-testid^=${columnInSelector}-value]`);
for (let i = 0; i < await rowSelector.count; i++) {
totalNumber += Number(await rowSelector.nth(i).textContent);
}
return totalNumber;
}
}
1 change: 0 additions & 1 deletion tests/e2e/pageObjects/slow-log-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ export class SlowLogPage {
//CSS Selectors
cssSelectorDurationValue = '[data-testid=duration-value]';
//BUTTONS
slowLogPageButton = Selector('[data-testid=slowlog-page-btn]');
slowLogSortByTimestamp = Selector('[data-testid=header-sorting-button]');
slowLogNumberOfCommandsDropdown = Selector('[data-testid=count-select]');
slowLogConfigureButton = Selector('[data-testid=configure-btn]');
Expand Down
86 changes: 86 additions & 0 deletions tests/e2e/tests/critical-path/overview/overview.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { Selector } from 'testcafe';
import { MyRedisDatabasePage, CliPage, OverviewPage, WorkbenchPage } from '../../../pageObjects';
import { rte } from '../../../helpers/constants';
import { acceptLicenseTermsAndAddOSSClusterDatabase } from '../../../helpers/database';
import { commonUrl, ossClusterConfig } from '../../../helpers/conf';
import { deleteOSSClusterDatabaseApi, getClusterNodesApi } from '../../../helpers/api/api-database';
import { Common } from '../../../helpers/common';

const overviewPage = new OverviewPage();
const myRedisDatabasePage = new MyRedisDatabasePage();
const common = new Common();
const cliPage = new CliPage();
const workbenchPage = new WorkbenchPage();

const headerColumns = {
'Type': 'OSS Cluster',
'Version': '7.0.0',
'User': 'Default'
};
const keyName = common.generateWord(10);
const commandToAddKey = `set ${keyName} test`;

fixture `Overview`
.meta({ type: 'critical_path', rte: rte.ossCluster })
.page(commonUrl)
.beforeEach(async t => {
await acceptLicenseTermsAndAddOSSClusterDatabase(ossClusterConfig, ossClusterConfig.ossClusterDatabaseName);
// Go to Analysis Tools page
await t.click(myRedisDatabasePage.analysisPageButton);
})
.afterEach(async() => {
await deleteOSSClusterDatabaseApi(ossClusterConfig);
});
test('Overview tab header for OSS Cluster', async t => {
const uptime = /[1-9][0-9]\s|[0-9]\smin|[1-9][0-9]\smin|[0-9]\sh/;
// Verify that user see "Overview" tab by default for OSS Cluster
await t.expect(overviewPage.overviewTab.withAttribute('aria-selected', 'true').exists).ok('The Overview tab not opened');
// Verify that user see "Overview" header with OSS Cluster info
for (const key in headerColumns) {
const columnSelector = Selector(`[data-testid=cluster-details-item-${key}]`);
await t.expect(columnSelector.textContent).contains(`${headerColumns[key]}`, `Cluster detail ${key} is incorrect`);
}
// Verify that Uptime is displayed as time in seconds or minutes from start
await t.expect(overviewPage.clusterDetailsUptime.textContent).match(uptime, 'Uptime value is not correct');
});
test
.after(async() => {
//Clear database and delete
await cliPage.sendCommandInCli(`DEL ${keyName}`);
await cliPage.sendCommandInCli('FT.DROPINDEX idx:schools DD');
await deleteOSSClusterDatabaseApi(ossClusterConfig);
})('Primary node statistics table displaying', async t => {
// Remember initial table values
const initialValues: number[] = [];
const nodes = (await getClusterNodesApi(ossClusterConfig)).sort();
const columns = ['Commands/s', 'Clients', 'Total Keys', 'Network Input', 'Network Output', 'Total Memory'];
for (const column in columns) {
initialValues.push(await overviewPage.getTotalValueByColumnName(column));
}
const nodesNumberInHeader = parseInt((await overviewPage.tableHeaderCell.nth(0).textContent).match(/\d+/)![0]);

// Add key from CLI
await t.click(cliPage.cliExpandButton);
await t.typeText(cliPage.cliCommandInput, commandToAddKey);
await t.pressKey('enter');
await t.click(cliPage.cliCollapseButton);
// Verify nodes in header column equal to rows
await t.expect(await overviewPage.getPrimaryNodesCount()).eql(nodesNumberInHeader, 'Primary nodes in table are not displayed');
// Verify that all nodes from BE response are displayed in table
for (const node of nodes) {
await t.expect(overviewPage.tableRow.nth(nodes.indexOf(node)).textContent).contains(node, `Node ${node} is not displayed in table`);
}
// Go to Workbench page
await t.click(myRedisDatabasePage.workbenchButton);
//Run Create hash index command to load network and memory
await t.click(workbenchPage.documentButtonInQuickGuides);
await t.click(workbenchPage.internalLinkWorkingWithHashes);
await t.click(workbenchPage.preselectCreateHashIndex);
await t.click(workbenchPage.submitCommandButton);
// Go to Analysis Tools page
await t.click(myRedisDatabasePage.analysisPageButton);
// Verify that values in table are dynamic
for (const column in columns) {
await t.expect(await overviewPage.getTotalValueByColumnName(column)).notEql(initialValues[columns.indexOf(column)], `${column} not dynamic`);
}
});
11 changes: 7 additions & 4 deletions tests/e2e/tests/critical-path/slow-log/slow-log.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SlowLogPage, MyRedisDatabasePage, BrowserPage, CliPage } from '../../../pageObjects';
import { SlowLogPage, MyRedisDatabasePage, BrowserPage, CliPage, OverviewPage } from '../../../pageObjects';
import { rte } from '../../../helpers/constants';
import { acceptLicenseTermsAndAddDatabaseApi } from '../../../helpers/database';
import { commonUrl, ossStandaloneBigConfig } from '../../../helpers/conf';
Expand All @@ -8,6 +8,7 @@ const slowLogPage = new SlowLogPage();
const myRedisDatabasePage = new MyRedisDatabasePage();
const browserPage = new BrowserPage();
const cliPage = new CliPage();
const overviewPage = new OverviewPage();
const slowerThanParameter = 1;
let maxCommandLength = 50;
let command = `slowlog get ${maxCommandLength}`;
Expand All @@ -17,13 +18,15 @@ fixture `Slow Log`
.page(commonUrl)
.beforeEach(async t => {
await acceptLicenseTermsAndAddDatabaseApi(ossStandaloneBigConfig, ossStandaloneBigConfig.databaseName);
await t.click(slowLogPage.slowLogPageButton);
await t.click(myRedisDatabasePage.analysisPageButton);
})
.afterEach(async() => {
await slowLogPage.resetToDefaultConfig();
await deleteStandaloneDatabaseApi(ossStandaloneBigConfig);
});
test('Verify that user can open new Slow Log page using new icon on left app panel', async t => {
// Verify that user see "Slow Log" page by default for non OSS Cluster
await t.expect(overviewPage.overviewTab.withAttribute('aria-selected', 'true').exists).notOk('The Overview tab is displayed for non OSS Cluster db');
// Verify that user can configure slowlog-max-len for Slow Log and see whole set of commands according to the setting
await slowLogPage.changeSlowerThanParameter(slowerThanParameter);
await cliPage.sendCommandInCli(command);
Expand All @@ -49,7 +52,7 @@ test('Verify that user can see "No Slow Logs found" message when slowlog-max-len
// Go to Browser page to scan keys and turn back
await t.click(myRedisDatabasePage.browserButton);
await t.click(browserPage.refreshKeysButton);
await t.click(slowLogPage.slowLogPageButton);
await t.click(myRedisDatabasePage.analysisPageButton);
// Compare number of logged commands with maxLength
await t.expect(slowLogPage.slowLogCommandStatistics.withText(`${maxCommandLength} entries`).exists).ok('Number of displayed commands is less than ');
});
Expand All @@ -73,7 +76,7 @@ test('Verify that users can specify number of commands that they want to display
// Go to Browser page to scan keys and turn back
await t.click(myRedisDatabasePage.browserButton);
await t.click(browserPage.refreshKeysButton);
await t.click(slowLogPage.slowLogPageButton);
await t.click(myRedisDatabasePage.analysisPageButton);
for (let i = 0; i < numberOfCommandsArray.length; i++) {
await slowLogPage.changeDisplayUpToParameter(numberOfCommandsArray[i]);
if (i === numberOfCommandsArray.length - 1) {
Expand Down