From 16d7d9fc7f053aee7b184c4e24ff8b1dc646549f Mon Sep 17 00:00:00 2001 From: Elena Naboko Date: Thu, 10 Mar 2022 23:46:22 +0300 Subject: [PATCH 1/2] [E2E] Module tests are added --- .../pageObjects/add-redis-database-page.ts | 414 ++++++++++-------- .../pageObjects/my-redis-databases-page.ts | 246 ++++++----- .../critical-path/database/modules.e2e.ts | 52 +++ 3 files changed, 432 insertions(+), 280 deletions(-) create mode 100644 tests/e2e/tests/critical-path/database/modules.e2e.ts diff --git a/tests/e2e/pageObjects/add-redis-database-page.ts b/tests/e2e/pageObjects/add-redis-database-page.ts index 86291b7bd8..6d61a3b1c7 100644 --- a/tests/e2e/pageObjects/add-redis-database-page.ts +++ b/tests/e2e/pageObjects/add-redis-database-page.ts @@ -1,4 +1,4 @@ -import { t, Selector } from 'testcafe'; +import {t, Selector} from 'testcafe'; export class AddRedisDatabasePage { @@ -7,176 +7,242 @@ export class AddRedisDatabasePage { //*Assign the 'Selector' type to any element/component nested within the constructor. //------------------------------------------------------------------------------------------ - addDatabaseButton: Selector - addDatabaseManually: Selector - addAutoDiscoverDatabase: Selector - redisClusterType: Selector - redisCloudProType: Selector - redisSentinelType: Selector - databaseName: Selector - hostInput: Selector - portInput: Selector - databaseAliasInput: Selector - passwordInput: Selector - usernameInput: Selector - addRedisDatabaseButton: Selector - discoverSentinelDatabaseButton: Selector - accessKeyInput: Selector - showDatabasesButton: Selector - selectAllCheckbox: Selector - welcomePageTitle: Selector - databaseIndexCheckbox: Selector - databaseIndexInput: Selector - errorMessage: Selector - secretKeyInput: Selector; + addDatabaseButton: Selector + addDatabaseManually: Selector + addAutoDiscoverDatabase: Selector + redisClusterType: Selector + redisCloudProType: Selector + redisSentinelType: Selector + databaseName: Selector + hostInput: Selector + portInput: Selector + databaseAliasInput: Selector + passwordInput: Selector + usernameInput: Selector + addRedisDatabaseButton: Selector + discoverSentinelDatabaseButton: Selector + accessKeyInput: Selector + showDatabasesButton: Selector + selectAllCheckbox: Selector + welcomePageTitle: Selector + databaseIndexCheckbox: Selector + databaseIndexInput: Selector + errorMessage: Selector + secretKeyInput: Selector; - constructor() { - //------------------------------------------------------------------------------------------- - //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 - this.addDatabaseButton = Selector('[data-testid=add-redis-database]'); - this.addRedisDatabaseButton = Selector('[data-testid=btn-submit]'); - this.addDatabaseManually = Selector('[data-testid=add-manual]'); - this.addAutoDiscoverDatabase = Selector('[data-testid=add-auto]'); - this.redisClusterType = Selector('[data-test-subj=radio-btn-enterprise-cluster]'); - this.redisCloudProType = Selector('[data-test-subj=radio-btn-cloud-pro]'); - this.redisSentinelType = Selector('[data-test-subj=radio-btn-sentinel]'); - this.showDatabasesButton = Selector('[data-testid=btn-show-databases]'); - this.databaseName = Selector('.euiTableCellContent.column_name'); - this.selectAllCheckbox = Selector('[data-test-subj=checkboxSelectAll]'); - this.databaseIndexCheckbox = Selector('[data-testid=showDb]~div'); - //TEXT INPUTS (also referred to as 'Text fields') - this.hostInput = Selector('[data-testid=host]'); - this.portInput = Selector('[data-testid=port]'); - this.databaseAliasInput = Selector('[data-testid=name]'); - this.passwordInput = Selector('[data-testid=password]'); - this.usernameInput = Selector('[data-testid=username]'); - this.discoverSentinelDatabaseButton = Selector('[data-testid=btn-submit]'); - this.accessKeyInput = Selector('[data-testid=access-key]'); - this.secretKeyInput = Selector('[data-testid=secret-key]'); - this.welcomePageTitle = Selector('[data-testid=welcome-page-title]'); - this.databaseIndexInput = Selector('[data-testid=db]'); - this.errorMessage = Selector('[data-test-subj=toast-error]'); - } - - /** - * Adding a new redis database - * @param parameters the parameters of the database - */ - async addRedisDataBase(parameters: AddNewDatabaseParameters): Promise { - await t - .click(this.addDatabaseButton) - .click(this.addDatabaseManually) - await t - .typeText(this.hostInput, parameters.host, { replace: true, paste: true }) - .typeText(this.portInput, parameters.port, { replace: true, paste: true }) - .typeText(this.databaseAliasInput, parameters.databaseName, { replace: true, paste: true }) - if (!!parameters.databaseUsername) { - await t.typeText(this.usernameInput, parameters.databaseUsername, { replace: true, paste: true }) - } - if (!!parameters.databasePassword) { - await t.typeText(this.passwordInput, parameters.databasePassword, { replace: true, paste: true }) - } - } + constructor() { + //------------------------------------------------------------------------------------------- + //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 + this.addDatabaseButton = Selector('[data-testid=add-redis-database]'); + this.addRedisDatabaseButton = Selector('[data-testid=btn-submit]'); + this.addDatabaseManually = Selector('[data-testid=add-manual]'); + this.addAutoDiscoverDatabase = Selector('[data-testid=add-auto]'); + this.redisClusterType = Selector('[data-test-subj=radio-btn-enterprise-cluster]'); + this.redisCloudProType = Selector('[data-test-subj=radio-btn-cloud-pro]'); + this.redisSentinelType = Selector('[data-test-subj=radio-btn-sentinel]'); + this.showDatabasesButton = Selector('[data-testid=btn-show-databases]'); + this.databaseName = Selector('.euiTableCellContent.column_name'); + this.selectAllCheckbox = Selector('[data-test-subj=checkboxSelectAll]'); + this.databaseIndexCheckbox = Selector('[data-testid=showDb]~div'); + //TEXT INPUTS (also referred to as 'Text fields') + this.hostInput = Selector('[data-testid=host]'); + this.portInput = Selector('[data-testid=port]'); + this.databaseAliasInput = Selector('[data-testid=name]'); + this.passwordInput = Selector('[data-testid=password]'); + this.usernameInput = Selector('[data-testid=username]'); + this.discoverSentinelDatabaseButton = Selector('[data-testid=btn-submit]'); + this.accessKeyInput = Selector('[data-testid=access-key]'); + this.secretKeyInput = Selector('[data-testid=secret-key]'); + this.welcomePageTitle = Selector('[data-testid=welcome-page-title]'); + this.databaseIndexInput = Selector('[data-testid=db]'); + this.errorMessage = Selector('[data-test-subj=toast-error]'); + } - /** - * Adding a new redis database with index - * @param parameters the parameters of the database - * @param index the logical index of database - */ - async addLogicalRedisDatabase(parameters: AddNewDatabaseParameters, index: string): Promise { - await t - .click(this.addDatabaseButton) - .click(this.addDatabaseManually) - await t - .typeText(this.hostInput, parameters.host, { replace: true, paste: true }) - .typeText(this.portInput, parameters.port, { replace: true, paste: true }) - .typeText(this.databaseAliasInput, parameters.databaseName, { replace: true, paste: true }) - if (!!parameters.databaseUsername) { - await t.typeText(this.usernameInput, parameters.databaseUsername, { replace: true, paste: true }) + /** + * Adding a new redis database + * @param parameters the parameters of the database + */ + async addRedisDataBase(parameters: AddNewDatabaseParameters): Promise { + await t + .click(this.addDatabaseButton) + .click(this.addDatabaseManually) + await t + .typeText(this.hostInput, parameters.host, { + replace: true, + paste: true + }) + .typeText(this.portInput, parameters.port, { + replace: true, + paste: true + }) + .typeText(this.databaseAliasInput, parameters.databaseName, { + replace: true, + paste: true + }) + if (!!parameters.databaseUsername) { + await t.typeText(this.usernameInput, parameters.databaseUsername, { + replace: true, + paste: true + }) + } + if (!!parameters.databasePassword) { + await t.typeText(this.passwordInput, parameters.databasePassword, { + replace: true, + paste: true + }) + } } - if (!!parameters.databasePassword) { - await t.typeText(this.passwordInput, parameters.databasePassword, { replace: true, paste: true }) + + /** + * Adding a new redis database with index + * @param parameters the parameters of the database + * @param index the logical index of database + */ + async addLogicalRedisDatabase(parameters: AddNewDatabaseParameters, index: string): Promise { + await t + .click(this.addDatabaseButton) + .click(this.addDatabaseManually) + await t + .typeText(this.hostInput, parameters.host, { + replace: true, + paste: true + }) + .typeText(this.portInput, parameters.port, { + replace: true, + paste: true + }) + .typeText(this.databaseAliasInput, parameters.databaseName, { + replace: true, + paste: true + }) + if (!!parameters.databaseUsername) { + await t.typeText(this.usernameInput, parameters.databaseUsername, { + replace: true, + paste: true + }) + } + if (!!parameters.databasePassword) { + await t.typeText(this.passwordInput, parameters.databasePassword, { + replace: true, + paste: true + }) + } + //Enter logical index + await t.click(this.databaseIndexCheckbox); + await t.typeText(this.databaseIndexInput, index, {paste: true}); + //Click for saving + await t.click(this.addRedisDatabaseButton); } - //Enter logical index - await t.click(this.databaseIndexCheckbox); - await t.typeText(this.databaseIndexInput, index, { paste: true }); - //Click for saving - await t.click(this.addRedisDatabaseButton); -} - /** - * Auto-discover Master Groups from Sentinel - * @param parameters - Parameters of Sentinel: host, port and Sentinel password - */ - async discoverSentinelDatabases(parameters: SentinelParameters): Promise { - await t - .click(this.addDatabaseButton) - .click(this.addAutoDiscoverDatabase) - .click(this.redisSentinelType) - if (!!parameters.sentinelHost) { - await t.typeText(this.hostInput, parameters.sentinelHost, { replace: true, paste: true }) - } - if (!!parameters.sentinelPort) { - await t.typeText(this.portInput, parameters.sentinelPort, { replace: true, paste: true }) - } - if (!!parameters.sentinelPassword) { - await t.typeText(this.passwordInput, parameters.sentinelPassword, { replace: true, paste: true }) - } - } + /** + * Auto-discover Master Groups from Sentinel + * @param parameters - Parameters of Sentinel: host, port and Sentinel password + */ + async discoverSentinelDatabases(parameters: SentinelParameters): Promise { + await t + .click(this.addDatabaseButton) + .click(this.addAutoDiscoverDatabase) + .click(this.redisSentinelType) + if (!!parameters.sentinelHost) { + await t.typeText(this.hostInput, parameters.sentinelHost, { + replace: true, + paste: true + }) + } + if (!!parameters.sentinelPort) { + await t.typeText(this.portInput, parameters.sentinelPort, { + replace: true, + paste: true + }) + } + if (!!parameters.sentinelPassword) { + await t.typeText(this.passwordInput, parameters.sentinelPassword, { + replace: true, + paste: true + }) + } + } - /** - * Adding a new database from RE Cluster via auto-discover flow - * @param prameters the parameters of the database - */ - async addAutodiscoverREClucterDatabase(parameters: AddNewDatabaseParameters): Promise { - await t - .click(this.addDatabaseButton) - .click(this.addAutoDiscoverDatabase) - .click(this.redisClusterType) - await t - .typeText(this.hostInput, parameters.host, { replace: true, paste: true }) - .typeText(this.portInput, parameters.port, { replace: true, paste: true }) - .typeText(this.usernameInput, parameters.databaseUsername, { replace: true, paste: true }) - .typeText(this.passwordInput, parameters.databasePassword, { replace: true, paste: true }) - } + /** + * Adding a new database from RE Cluster via auto-discover flow + * @param prameters the parameters of the database + */ + async addAutodiscoverREClucterDatabase(parameters: AddNewDatabaseParameters): Promise { + await t + .click(this.addDatabaseButton) + .click(this.addAutoDiscoverDatabase) + .click(this.redisClusterType) + await t + .typeText(this.hostInput, parameters.host, { + replace: true, + paste: true + }) + .typeText(this.portInput, parameters.port, { + replace: true, + paste: true + }) + .typeText(this.usernameInput, parameters.databaseUsername, { + replace: true, + paste: true + }) + .typeText(this.passwordInput, parameters.databasePassword, { + replace: true, + paste: true + }) + } - /** - * Adding a new database from RE Cloud via auto-discover flow - * @param parameters the parameters of the database - */ - async addAutodiscoverRECloudDatabase(cloudAPIAccessKey: string, cloudAPISecretKey: string): Promise { - await t - .click(this.addDatabaseButton) - .click(this.addAutoDiscoverDatabase) - .click(this.redisCloudProType) - await t - .typeText(this.accessKeyInput, cloudAPIAccessKey, { replace: true, paste: true }) - .typeText(this.secretKeyInput, cloudAPISecretKey, { replace: true, paste: true }) - } + /** + * Adding a new database from RE Cloud via auto-discover flow + * @param parameters the parameters of the database + */ + async addAutodiscoverRECloudDatabase(cloudAPIAccessKey: string, cloudAPISecretKey: string): Promise { + await t + .click(this.addDatabaseButton) + .click(this.addAutoDiscoverDatabase) + .click(this.redisCloudProType) + await t + .typeText(this.accessKeyInput, cloudAPIAccessKey, { + replace: true, + paste: true + }) + .typeText(this.secretKeyInput, cloudAPISecretKey, { + replace: true, + paste: true + }) + } - /** - * Auto-discover Master Groups from Sentinel - * @param parameters - Parameters of Sentinel: host, port and Sentinel password - */ - async addOssClusterDatabase(parameters: OSSClusterParameters): Promise { - await t - .click(this.addDatabaseButton) - .click(this.addDatabaseManually) - if (!!parameters.ossClusterHost) { - await t.typeText(this.hostInput, parameters.ossClusterHost, { replace: true, paste: true }) - } - if (!!parameters.ossClusterPort) { - await t.typeText(this.portInput, parameters.ossClusterPort, { replace: true, paste: true }) - } - if (!!parameters.ossClusterDatabaseName) { - await t.typeText(this.databaseAliasInput, parameters.ossClusterDatabaseName, { replace: true, paste: true }) - } - } + /** + * Auto-discover Master Groups from Sentinel + * @param parameters - Parameters of Sentinel: host, port and Sentinel password + */ + async addOssClusterDatabase(parameters: OSSClusterParameters): Promise { + await t + .click(this.addDatabaseButton) + .click(this.addDatabaseManually) + if (!!parameters.ossClusterHost) { + await t.typeText(this.hostInput, parameters.ossClusterHost, { + replace: true, + paste: true + }) + } + if (!!parameters.ossClusterPort) { + await t.typeText(this.portInput, parameters.ossClusterPort, { + replace: true, + paste: true + }) + } + if (!!parameters.ossClusterDatabaseName) { + await t.typeText(this.databaseAliasInput, parameters.ossClusterDatabaseName, { + replace: true, + paste: true + }) + } + } } /** @@ -188,11 +254,11 @@ export class AddRedisDatabasePage { * @param databasePassword The password of the database */ export type AddNewDatabaseParameters = { - host: string, - port: string, - databaseName?: string, - databaseUsername?: string, - databasePassword?: string + host: string, + port: string, + databaseName?: string, + databaseUsername?: string, + databasePassword?: string } /** @@ -202,9 +268,9 @@ export type AddNewDatabaseParameters = { * @param sentinelPassword The password of sentinel */ export type SentinelParameters = { - sentinelHost: string, - sentinelPort: string, - sentinelPassword?: string + sentinelHost: string, + sentinelPort: string, + sentinelPassword?: string } /** @@ -215,7 +281,7 @@ export type SentinelParameters = { */ export type OSSClusterParameters = { - ossClusterHost: string, - ossClusterPort: string, - ossClusterDatabaseName: string + ossClusterHost: string, + ossClusterPort: string, + ossClusterDatabaseName: string } diff --git a/tests/e2e/pageObjects/my-redis-databases-page.ts b/tests/e2e/pageObjects/my-redis-databases-page.ts index 6c27a31624..f15af68bcc 100644 --- a/tests/e2e/pageObjects/my-redis-databases-page.ts +++ b/tests/e2e/pageObjects/my-redis-databases-page.ts @@ -1,4 +1,4 @@ -import { t, Selector } from 'testcafe'; +import {t, Selector} from 'testcafe'; export class MyRedisDatabasePage { @@ -7,117 +7,151 @@ export class MyRedisDatabasePage { //*Assign the 'Selector' type to any element/component nested within the constructor. //------------------------------------------------------------------------------------------ - dbNameList: Selector - settingsButton: Selector - workbenchButton: Selector - helpCenterButton: Selector - myRedisDBButton: Selector - toastCloseButton: Selector - deleteDatabaseButton: Selector - confirmDeleteButton: Selector - tableRowContent: Selector - hostPort: Selector - selectAllCheckbox: Selector - deleteButtonInPopover: Selector - confirmDeleteAllDbButton: Selector - browserButton: Selector - editDatabaseButton: Selector - editAliasButton: Selector - aliasInput: Selector - applyButton: Selector - submitChangesButton: Selector - databaseInfoMessage: Selector; + dbNameList: Selector + settingsButton: Selector + workbenchButton: Selector + helpCenterButton: Selector + myRedisDBButton: Selector + toastCloseButton: Selector + deleteDatabaseButton: Selector + confirmDeleteButton: Selector + tableRowContent: Selector + hostPort: Selector + selectAllCheckbox: Selector + deleteButtonInPopover: Selector + confirmDeleteAllDbButton: Selector + browserButton: Selector + editDatabaseButton: Selector + editAliasButton: Selector + aliasInput: Selector + applyButton: Selector + submitChangesButton: Selector + databaseInfoMessage: Selector + moduleColumn: Selector + moduleSearchIcon: Selector + moduleGraphIcon: Selector + moduleJSONIcon: Selector + moduleTimeseriesIcon: Selector + moduleBloomIcon: Selector + moduleAIIcon: Selector + moduleGearsIcon: Selector + moduleTooltip: Selector + moduleQuantifier: Selector + allModules: Selector + modulesOnEditPage: Selector - constructor() { - //------------------------------------------------------------------------------------------- - //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 - this.settingsButton = Selector('[data-testid=settings-page-btn]'); - this.workbenchButton = Selector('[data-testid=workbench-page-btn]'); - this.helpCenterButton = Selector('[data-testid=help-menu-button]'); - this.browserButton = Selector('[data-testid=browser-page-btn]'); - this.myRedisDBButton = Selector('[data-test-subj=home-page-btn]'); - this.deleteDatabaseButton = Selector('[data-testid^=delete-instance-]'); - this.confirmDeleteButton = Selector('[data-testid^=delete-instance-confirm]'); - this.toastCloseButton = Selector('[data-test-subj=toastCloseButton]'); - this.selectAllCheckbox = Selector('[data-test-subj=checkboxSelectAll]'); - this.deleteButtonInPopover = Selector('#deletePopover button'); - this.confirmDeleteAllDbButton = Selector('[data-testid=delete-selected-dbs]'); - this.editDatabaseButton = Selector('[data-testid^=edit-instance]'); - this.editAliasButton = Selector('[data-testid=edit-alias-btn]'); - this.applyButton = Selector('[data-testid=apply-btn]'); - this.submitChangesButton = Selector('[data-testid=btn-submit]'); - // TEXT INPUTS (also referred to as 'Text fields') - this.dbNameList = Selector('[data-testid^=instance-name]'); - this.tableRowContent = Selector('[data-test-subj=database-alias-column]'); - this.databaseInfoMessage = Selector('[data-test-subj=euiToastHeader]'); - this.hostPort = Selector('[data-testid=host-port]'); - this.aliasInput = Selector('[data-testid=alias-input]'); - } + constructor() { + //------------------------------------------------------------------------------------------- + //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 + this.settingsButton = Selector('[data-testid=settings-page-btn]'); + this.workbenchButton = Selector('[data-testid=workbench-page-btn]'); + this.helpCenterButton = Selector('[data-testid=help-menu-button]'); + this.browserButton = Selector('[data-testid=browser-page-btn]'); + this.myRedisDBButton = Selector('[data-test-subj=home-page-btn]'); + this.deleteDatabaseButton = Selector('[data-testid^=delete-instance-]'); + this.confirmDeleteButton = Selector('[data-testid^=delete-instance-confirm]'); + this.toastCloseButton = Selector('[data-test-subj=toastCloseButton]'); + this.selectAllCheckbox = Selector('[data-test-subj=checkboxSelectAll]'); + this.deleteButtonInPopover = Selector('#deletePopover button'); + this.confirmDeleteAllDbButton = Selector('[data-testid=delete-selected-dbs]'); + this.editDatabaseButton = Selector('[data-testid^=edit-instance]'); + this.editAliasButton = Selector('[data-testid=edit-alias-btn]'); + this.applyButton = Selector('[data-testid=apply-btn]'); + this.submitChangesButton = Selector('[data-testid=btn-submit]'); + this.moduleColumn = Selector('[data-test-subj=tableHeaderCell_modules_3]'); + this.moduleSearchIcon = Selector('[data-testid^=RediSearch]'); + this.moduleGraphIcon = Selector('[data-testid^=RedisGraph]'); + this.moduleJSONIcon = Selector('[data-testid^=RedisJSON]'); + this.moduleTimeseriesIcon = Selector('[data-testid^=RedisTimeSeries]'); + this.moduleBloomIcon = Selector('[data-testid^=RedisBloom]'); + this.moduleAIIcon = Selector('[data-testid^=RedisAI]'); + this.moduleGearsIcon = Selector('[data-testid^=RedisGears]'); + this.moduleTooltip = Selector('.euiToolTipPopover'); + this.moduleQuantifier = Selector('[data-testid=_module]'); + this.allModules = Selector('.euiToolTipAnchor'); + this.modulesOnEditPage = Selector('[]'); + // TEXT INPUTS (also referred to as 'Text fields') + this.dbNameList = Selector('[data-testid^=instance-name]'); + this.tableRowContent = Selector('[data-test-subj=database-alias-column]'); + this.databaseInfoMessage = Selector('[data-test-subj=euiToastHeader]'); + this.hostPort = Selector('[data-testid=host-port]'); + this.aliasInput = Selector('[data-testid=alias-input]'); + } + + /** + * Click on the database by name + * @param dbName The name of the database to be opened + */ + async clickOnDBByName(dbName: string): Promise { + if (await this.toastCloseButton.exists) { + await t.click(this.toastCloseButton); + } + const db = this.dbNameList.withExactText(dbName.trim()); + await t.expect(db.exists) + .ok('The database exists', {timeout: 60000}); + await t.click(db); + } - /** - * Click on the database by name - * @param dbName The name of the database to be opened - */ - async clickOnDBByName(dbName: string): Promise{ - if (await this.toastCloseButton.exists) { - await t.click(this.toastCloseButton); - } - const db = this.dbNameList.withExactText(dbName.trim()); - await t.expect(db.exists).ok('The database exists', {timeout: 60000}); - await t.click(db); - } + //Delete all the databases from the list + async deleteAllDatabases(): Promise { + await t.click(this.myRedisDBButton); + const dbNames = this.tableRowContent; + const count = await dbNames.count; + if (count > 1) { + await t.click(this.selectAllCheckbox); + await t.click(this.deleteButtonInPopover); + await t.click(this.confirmDeleteAllDbButton); + } else if (count === 1) { + await t.click(this.deleteDatabaseButton); + await t.click(this.confirmDeleteButton); + } + if (await this.toastCloseButton.exists) { + await t.click(this.toastCloseButton); + } + } - //Delete all the databases from the list - async deleteAllDatabases(): Promise { - await t.click(this.myRedisDBButton); - const dbNames = this.tableRowContent; - const count = await dbNames.count; - if(count > 1) { - await t.click(this.selectAllCheckbox); - await t.click(this.deleteButtonInPopover); - await t.click(this.confirmDeleteAllDbButton); - } - else if (count === 1) { - await t.click(this.deleteDatabaseButton); - await t.click(this.confirmDeleteButton); - } - if (await this.toastCloseButton.exists) { - await t.click(this.toastCloseButton); - } - } + //Delete database by Name + async deleteDatabaseByName(dbName: string): Promise { + const dbNames = this.tableRowContent; + const count = await dbNames.count; - //Delete database by Name - async deleteDatabaseByName(dbName: string): Promise { - const dbNames = this.tableRowContent; - const count = await dbNames.count; + for (let i = 0; i < count; i++) { + if ((await dbNames.nth(i).innerText || '').includes(dbName)) { + await t.click(this.deleteDatabaseButton.nth(i)); + await t.click(this.confirmDeleteButton); + break; + } + } + } - for(let i = 0; i < count; i++) { - if((await dbNames.nth(i).innerText || '').includes(dbName)) { - await t.click(this.deleteDatabaseButton.nth(i)); - await t.click(this.confirmDeleteButton); - break; - } - } - } + /** + * Click on the edit database button by name + * @param databaseName The name of the database to be edited + */ + async clickOnEditDBByName(databaseName: string): Promise { + const dbNames = this.tableRowContent; + const count = await dbNames.count; - /** - * Click on the edit database button by name - * @param databaseName The name of the database to be edited - */ - async clickOnEditDBByName(databaseName: string): Promise{ - const dbNames = this.tableRowContent; - const count = await dbNames.count; + for (let i = 0; i < count; i++) { + if ((await dbNames.nth(i).innerText || '').includes(databaseName)) { + await t.click(this.editDatabaseButton.nth(i)); + break; + } + } + } - for(let i = 0; i < count; i++) { - if((await dbNames.nth(i).innerText || '').includes(databaseName)) { - await t.click(this.editDatabaseButton.nth(i)); - break; - } - } + /** + * Check module inside of tooltip + * @param moduleList Array with modules list + */ + async checkModulesInTooltip(moduleList: Array): Promise { + for (const item of moduleList) { + await t.expect(this.moduleTooltip.find('span').withText(`${item} v.`).exists).ok(item) + } } } diff --git a/tests/e2e/tests/critical-path/database/modules.e2e.ts b/tests/e2e/tests/critical-path/database/modules.e2e.ts new file mode 100644 index 0000000000..f4c27b8eea --- /dev/null +++ b/tests/e2e/tests/critical-path/database/modules.e2e.ts @@ -0,0 +1,52 @@ +import { rte } from '../../../helpers/constants'; +import { + acceptLicenseTerms, + addNewStandaloneDatabase, + deleteDatabase +} from '../../../helpers/database'; +import { MyRedisDatabasePage } from '../../../pageObjects'; +import {commonUrl, ossStandaloneRedisearch} from '../../../helpers/conf'; + +const myRedisDatabasePage = new MyRedisDatabasePage(); +const moduleList = ['RediSearch', 'RedisGraph', 'RedisBloom', 'RedisJSON', 'RedisAI', 'RedisTimeSeries', 'RedisGears']; + +fixture `Modules` + .meta({ type: 'critical_path' }) + .page(commonUrl) + .beforeEach(async() => { + await acceptLicenseTerms(); + await addNewStandaloneDatabase(ossStandaloneRedisearch); + }) + .afterEach(async() => { + //Delete database + await deleteDatabase(ossStandaloneRedisearch.databaseName); + }) +test + .meta({ rte: rte.standalone }) + ('Verify that user can see DB modules on DB list page for Standalone DB', async t => { + //Check module column on DB list page + await t.expect(myRedisDatabasePage.moduleColumn.exists).ok('Module column'); + //Check that module icons are displayed + await t.expect(myRedisDatabasePage.moduleGraphIcon.exists).ok('Graph icon'); + await t.expect(myRedisDatabasePage.moduleBloomIcon.exists).ok('Bloom icon'); + await t.expect(myRedisDatabasePage.moduleJSONIcon.exists).ok('JSON icon'); + //Verify that user can see +N icon (where N>1) on DB list page when modules icons don't fit the Module column width + await t.expect(myRedisDatabasePage.moduleQuantifier.textContent).eql('+4'); + await t.expect(myRedisDatabasePage.moduleQuantifier.exists).ok('Quantifier icon'); + //Verify that user can hover over the module icons and see tooltip with all modules name + await t.hover(myRedisDatabasePage.moduleQuantifier); + await t.expect(myRedisDatabasePage.moduleTooltip.visible).ok('Module tooltip'); + //Verify that user can hover over the module icons and see tooltip with version. + await myRedisDatabasePage.checkModulesInTooltip(moduleList); + }); +test.skip + .meta({ rte: rte.standalone }) + ('Verify that user can see full module list in the Edit mode', async t => { + //Verify that modules are displayed + await t.expect(myRedisDatabasePage.allModules.exists).ok('Visible module icons'); + //Open Edit mode + await t.click(myRedisDatabasePage.editDatabaseButton); + await t.expect(myRedisDatabasePage.allModules.exists).notOk('Not visible module icons'); + //Verify modules in Edit mode + await t.expect(myRedisDatabasePage.modulesOnEditPage.exists).ok('Edit modules'); + }); From 0c521c987cfb4638980468be0767b14bd0ec14d6 Mon Sep 17 00:00:00 2001 From: Elena Naboko Date: Tue, 15 Mar 2022 14:04:46 +0300 Subject: [PATCH 2/2] [E2E] Modules for Edit DB form is added, fixes for moudles test added --- tests/e2e/helpers/database.ts | 18 +-- .../pageObjects/add-redis-database-page.ts | 110 ++++-------------- .../pageObjects/my-redis-databases-page.ts | 22 +++- .../critical-path/database/modules.e2e.ts | 28 +++-- 4 files changed, 64 insertions(+), 114 deletions(-) diff --git a/tests/e2e/helpers/database.ts b/tests/e2e/helpers/database.ts index c6d068c96e..18717c7d63 100644 --- a/tests/e2e/helpers/database.ts +++ b/tests/e2e/helpers/database.ts @@ -28,7 +28,9 @@ export async function addNewStandaloneDatabase(databaseParameters: AddNewDatabas //Click for saving await t.click(addRedisDatabasePage.addRedisDatabaseButton); //Wait for database to be exist - await t.expect(myRedisDatabasePage.dbNameList.withExactText(databaseParameters.databaseName).exists).ok('The existence of the database', { timeout: 60000 }); + await t.expect(myRedisDatabasePage.dbNameList.withExactText(databaseParameters.databaseName).exists).ok('The existence of the database', { timeout: 10000 }); + //Close message + await t.click(myRedisDatabasePage.toastCloseButton); } /** @@ -102,6 +104,13 @@ export async function addNewRECloudDatabase(cloudAPIAccessKey: string, cloudAPIS return databaseName; } +//Accept License terms +export async function acceptLicenseTerms(): Promise { + await t.maximizeWindow(); + await userAgreementPage.acceptLicenseTerms(); + await t.expect(addRedisDatabasePage.addDatabaseButton.exists).ok('The add redis database view', {timeout: 20000}); +} + /** * Accept License terms and add database * @param databaseParameters The database parameters @@ -126,13 +135,6 @@ export async function acceptLicenseTermsAndAddOSSClusterDatabase(databaseParamet await myRedisDatabasePage.clickOnDBByName(databaseName); } -//Accept License terms -export async function acceptLicenseTerms(): Promise { - await t.maximizeWindow(); - await userAgreementPage.acceptLicenseTerms(); - await t.expect(addRedisDatabasePage.addDatabaseButton.exists).ok('The add redis database view', {timeout: 20000}); -} - //Clear database data export async function clearDatabaseInCli(): Promise { if (await cliPage.cliCollapseButton.exists === false) { diff --git a/tests/e2e/pageObjects/add-redis-database-page.ts b/tests/e2e/pageObjects/add-redis-database-page.ts index 6d61a3b1c7..db469fe7a0 100644 --- a/tests/e2e/pageObjects/add-redis-database-page.ts +++ b/tests/e2e/pageObjects/add-redis-database-page.ts @@ -72,29 +72,14 @@ export class AddRedisDatabasePage { .click(this.addDatabaseButton) .click(this.addDatabaseManually) await t - .typeText(this.hostInput, parameters.host, { - replace: true, - paste: true - }) - .typeText(this.portInput, parameters.port, { - replace: true, - paste: true - }) - .typeText(this.databaseAliasInput, parameters.databaseName, { - replace: true, - paste: true - }) + .typeText(this.hostInput, parameters.host, { replace: true, paste: true }) + .typeText(this.portInput, parameters.port, { replace: true, paste: true }) + .typeText(this.databaseAliasInput, parameters.databaseName, { replace: true, paste: true }) if (!!parameters.databaseUsername) { - await t.typeText(this.usernameInput, parameters.databaseUsername, { - replace: true, - paste: true - }) + await t.typeText(this.usernameInput, parameters.databaseUsername, { replace: true, paste: true }) } if (!!parameters.databasePassword) { - await t.typeText(this.passwordInput, parameters.databasePassword, { - replace: true, - paste: true - }) + await t.typeText(this.passwordInput, parameters.databasePassword, { replace: true, paste: true }) } } @@ -108,29 +93,14 @@ export class AddRedisDatabasePage { .click(this.addDatabaseButton) .click(this.addDatabaseManually) await t - .typeText(this.hostInput, parameters.host, { - replace: true, - paste: true - }) - .typeText(this.portInput, parameters.port, { - replace: true, - paste: true - }) - .typeText(this.databaseAliasInput, parameters.databaseName, { - replace: true, - paste: true - }) + .typeText(this.hostInput, parameters.host, { replace: true, paste: true }) + .typeText(this.portInput, parameters.port, { replace: true, paste: true }) + .typeText(this.databaseAliasInput, parameters.databaseName, { replace: true, paste: true }) if (!!parameters.databaseUsername) { - await t.typeText(this.usernameInput, parameters.databaseUsername, { - replace: true, - paste: true - }) + await t.typeText(this.usernameInput, parameters.databaseUsername, { replace: true, paste: true }) } if (!!parameters.databasePassword) { - await t.typeText(this.passwordInput, parameters.databasePassword, { - replace: true, - paste: true - }) + await t.typeText(this.passwordInput, parameters.databasePassword, { replace: true, paste: true }) } //Enter logical index await t.click(this.databaseIndexCheckbox); @@ -149,22 +119,13 @@ export class AddRedisDatabasePage { .click(this.addAutoDiscoverDatabase) .click(this.redisSentinelType) if (!!parameters.sentinelHost) { - await t.typeText(this.hostInput, parameters.sentinelHost, { - replace: true, - paste: true - }) + await t.typeText(this.hostInput, parameters.sentinelHost, { replace: true, paste: true }) } if (!!parameters.sentinelPort) { - await t.typeText(this.portInput, parameters.sentinelPort, { - replace: true, - paste: true - }) + await t.typeText(this.portInput, parameters.sentinelPort, { replace: true, paste: true }) } if (!!parameters.sentinelPassword) { - await t.typeText(this.passwordInput, parameters.sentinelPassword, { - replace: true, - paste: true - }) + await t.typeText(this.passwordInput, parameters.sentinelPassword, { replace: true, paste: true }) } } @@ -178,22 +139,10 @@ export class AddRedisDatabasePage { .click(this.addAutoDiscoverDatabase) .click(this.redisClusterType) await t - .typeText(this.hostInput, parameters.host, { - replace: true, - paste: true - }) - .typeText(this.portInput, parameters.port, { - replace: true, - paste: true - }) - .typeText(this.usernameInput, parameters.databaseUsername, { - replace: true, - paste: true - }) - .typeText(this.passwordInput, parameters.databasePassword, { - replace: true, - paste: true - }) + .typeText(this.hostInput, parameters.host, { replace: true, paste: true }) + .typeText(this.portInput, parameters.port, { replace: true, paste: true }) + .typeText(this.usernameInput, parameters.databaseUsername, { replace: true, paste: true }) + .typeText(this.passwordInput, parameters.databasePassword, { replace: true, paste: true }) } /** @@ -206,14 +155,8 @@ export class AddRedisDatabasePage { .click(this.addAutoDiscoverDatabase) .click(this.redisCloudProType) await t - .typeText(this.accessKeyInput, cloudAPIAccessKey, { - replace: true, - paste: true - }) - .typeText(this.secretKeyInput, cloudAPISecretKey, { - replace: true, - paste: true - }) + .typeText(this.accessKeyInput, cloudAPIAccessKey, { replace: true, paste: true }) + .typeText(this.secretKeyInput, cloudAPISecretKey, { replace: true, paste: true }) } /** @@ -225,22 +168,13 @@ export class AddRedisDatabasePage { .click(this.addDatabaseButton) .click(this.addDatabaseManually) if (!!parameters.ossClusterHost) { - await t.typeText(this.hostInput, parameters.ossClusterHost, { - replace: true, - paste: true - }) + await t.typeText(this.hostInput, parameters.ossClusterHost, { replace: true, paste: true }) } if (!!parameters.ossClusterPort) { - await t.typeText(this.portInput, parameters.ossClusterPort, { - replace: true, - paste: true - }) + await t.typeText(this.portInput, parameters.ossClusterPort, { replace: true, paste: true }) } if (!!parameters.ossClusterDatabaseName) { - await t.typeText(this.databaseAliasInput, parameters.ossClusterDatabaseName, { - replace: true, - paste: true - }) + await t.typeText(this.databaseAliasInput, parameters.ossClusterDatabaseName, { replace: true, paste: true }) } } } diff --git a/tests/e2e/pageObjects/my-redis-databases-page.ts b/tests/e2e/pageObjects/my-redis-databases-page.ts index f15af68bcc..3881455936 100644 --- a/tests/e2e/pageObjects/my-redis-databases-page.ts +++ b/tests/e2e/pageObjects/my-redis-databases-page.ts @@ -37,7 +37,6 @@ export class MyRedisDatabasePage { moduleGearsIcon: Selector moduleTooltip: Selector moduleQuantifier: Selector - allModules: Selector modulesOnEditPage: Selector constructor() { @@ -73,8 +72,6 @@ export class MyRedisDatabasePage { this.moduleGearsIcon = Selector('[data-testid^=RedisGears]'); this.moduleTooltip = Selector('.euiToolTipPopover'); this.moduleQuantifier = Selector('[data-testid=_module]'); - this.allModules = Selector('.euiToolTipAnchor'); - this.modulesOnEditPage = Selector('[]'); // TEXT INPUTS (also referred to as 'Text fields') this.dbNameList = Selector('[data-testid^=instance-name]'); this.tableRowContent = Selector('[data-test-subj=database-alias-column]'); @@ -115,7 +112,10 @@ export class MyRedisDatabasePage { } } - //Delete database by Name + /** + * Delete DB by name + * @param dbName The name of the database to be deleted + */ async deleteDatabaseByName(dbName: string): Promise { const dbNames = this.tableRowContent; const count = await dbNames.count; @@ -147,11 +147,21 @@ export class MyRedisDatabasePage { /** * Check module inside of tooltip + * @param moduleNameList Array with modules list + */ + async checkModulesInTooltip(moduleNameList: Array): Promise { + for (const item of moduleNameList) { + await t.expect(this.moduleTooltip.find('span').withText(`${item} v.`).exists).ok(item) + } + } + + /** + * Check module icons on the page * @param moduleList Array with modules list */ - async checkModulesInTooltip(moduleList: Array): Promise { + async checkModulesOnPage(moduleList: Array): Promise { for (const item of moduleList) { - await t.expect(this.moduleTooltip.find('span').withText(`${item} v.`).exists).ok(item) + await t.expect(item.visible).ok(`${item} icon`) } } } diff --git a/tests/e2e/tests/critical-path/database/modules.e2e.ts b/tests/e2e/tests/critical-path/database/modules.e2e.ts index f4c27b8eea..e4fa1315f2 100644 --- a/tests/e2e/tests/critical-path/database/modules.e2e.ts +++ b/tests/e2e/tests/critical-path/database/modules.e2e.ts @@ -8,9 +8,12 @@ import { MyRedisDatabasePage } from '../../../pageObjects'; import {commonUrl, ossStandaloneRedisearch} from '../../../helpers/conf'; const myRedisDatabasePage = new MyRedisDatabasePage(); -const moduleList = ['RediSearch', 'RedisGraph', 'RedisBloom', 'RedisJSON', 'RedisAI', 'RedisTimeSeries', 'RedisGears']; +const moduleNameList = ['RediSearch', 'RedisGraph', 'RedisBloom', 'RedisJSON', 'RedisAI', 'RedisTimeSeries', 'RedisGears']; +const moduleList = [myRedisDatabasePage.moduleJSONIcon, myRedisDatabasePage.moduleSearchIcon, + myRedisDatabasePage.moduleTimeseriesIcon, myRedisDatabasePage.moduleBloomIcon, myRedisDatabasePage.moduleGraphIcon, + myRedisDatabasePage.moduleAIIcon, myRedisDatabasePage.moduleGearsIcon]; -fixture `Modules` +fixture `Database modules` .meta({ type: 'critical_path' }) .page(commonUrl) .beforeEach(async() => { @@ -27,26 +30,27 @@ test //Check module column on DB list page await t.expect(myRedisDatabasePage.moduleColumn.exists).ok('Module column'); //Check that module icons are displayed - await t.expect(myRedisDatabasePage.moduleGraphIcon.exists).ok('Graph icon'); - await t.expect(myRedisDatabasePage.moduleBloomIcon.exists).ok('Bloom icon'); - await t.expect(myRedisDatabasePage.moduleJSONIcon.exists).ok('JSON icon'); + await myRedisDatabasePage.checkModulesOnPage(moduleList); + //Minimize the window to check quantifier + await t.resizeWindow(1000, 700); //Verify that user can see +N icon (where N>1) on DB list page when modules icons don't fit the Module column width - await t.expect(myRedisDatabasePage.moduleQuantifier.textContent).eql('+4'); + await t.expect(myRedisDatabasePage.moduleQuantifier.textContent).eql('+3'); await t.expect(myRedisDatabasePage.moduleQuantifier.exists).ok('Quantifier icon'); //Verify that user can hover over the module icons and see tooltip with all modules name await t.hover(myRedisDatabasePage.moduleQuantifier); await t.expect(myRedisDatabasePage.moduleTooltip.visible).ok('Module tooltip'); //Verify that user can hover over the module icons and see tooltip with version. - await myRedisDatabasePage.checkModulesInTooltip(moduleList); + await myRedisDatabasePage.checkModulesInTooltip(moduleNameList); }); -test.skip +test .meta({ rte: rte.standalone }) ('Verify that user can see full module list in the Edit mode', async t => { - //Verify that modules are displayed - await t.expect(myRedisDatabasePage.allModules.exists).ok('Visible module icons'); + //Verify that module column is displayed + await t.expect(myRedisDatabasePage.moduleColumn.visible).ok('Module column'); //Open Edit mode await t.click(myRedisDatabasePage.editDatabaseButton); - await t.expect(myRedisDatabasePage.allModules.exists).notOk('Not visible module icons'); + //Verify that module column is not displayed + await t.expect(myRedisDatabasePage.moduleColumn.visible).notOk('Module column'); //Verify modules in Edit mode - await t.expect(myRedisDatabasePage.modulesOnEditPage.exists).ok('Edit modules'); + await myRedisDatabasePage.checkModulesOnPage(moduleList); });