From 109bcc3a97f8e5f049c333d5cdd67348cf6c8481 Mon Sep 17 00:00:00 2001 From: nmammadli Date: Mon, 23 Jan 2023 11:46:30 +0100 Subject: [PATCH 1/6] Add upvote recommendations test and page object for recommendations --- tests/e2e/pageObjects/recommendations-page.ts | 34 ++++++++++++++ .../database-recommendations.e2e.ts | 44 +++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 tests/e2e/pageObjects/recommendations-page.ts create mode 100644 tests/e2e/tests/critical-path/database-overview/database-recommendations.e2e.ts diff --git a/tests/e2e/pageObjects/recommendations-page.ts b/tests/e2e/pageObjects/recommendations-page.ts new file mode 100644 index 0000000000..4027da79b3 --- /dev/null +++ b/tests/e2e/pageObjects/recommendations-page.ts @@ -0,0 +1,34 @@ +import {Selector, t} from 'testcafe'; + +export class RecommendationsPage { + //CSS Selectors + veryUsefulVoteBtn = Selector('[data-testid=very-useful-vote-btn]').nth(0); + usefulVoteBtn = Selector('[data-testid=useful-vote-btn]').nth(0); + notUsefulVoteBtn = Selector('[data-testid=not-useful-vote-btn]').nth(0); + recommendationsFeedbackBtn = Selector('[data-testid=recommendation-feedback-btn]'); + + async voteForVeryUsefulAndVerifyDisabled(): Promise { + await t.click(this.veryUsefulVoteBtn); + await this.verifyVoteDisabled(); + } + + async voteForUsefulAndVerifyDisabled(): Promise { + await t.click(this.usefulVoteBtn); + await this.verifyVoteDisabled(); + } + + async voteForNotUsefulAndVerifyDisabled(): Promise { + await t.click(this.notUsefulVoteBtn); + await this.verifyVoteDisabled(); + } + + async verifyVoteDisabled(): Promise{ + // Verify that user can rate recommendations with one of 3 existing types at the same time + await t.expect(this.veryUsefulVoteBtn.nth(0) + .hasAttribute('disabled')).ok(); + await t.expect(this.usefulVoteBtn.nth(0) + .hasAttribute('disabled')).ok(); + await t.expect(this.notUsefulVoteBtn.nth(0) + .hasAttribute('disabled')).ok(); + } +} diff --git a/tests/e2e/tests/critical-path/database-overview/database-recommendations.e2e.ts b/tests/e2e/tests/critical-path/database-overview/database-recommendations.e2e.ts new file mode 100644 index 0000000000..d4d169bfe9 --- /dev/null +++ b/tests/e2e/tests/critical-path/database-overview/database-recommendations.e2e.ts @@ -0,0 +1,44 @@ +import { acceptLicenseTermsAndAddDatabaseApi } from '../../../helpers/database'; +import { rte } from '../../../helpers/constants'; +import { + commonUrl, + ossStandaloneConfig +} from '../../../helpers/conf'; +import { deleteStandaloneDatabaseApi } from '../../../helpers/api/api-database'; +import {MemoryEfficiencyPage, MyRedisDatabasePage} from '../../../pageObjects'; +import {RecommendationsPage} from '../../../pageObjects/recommendations-page'; +import {Common} from '../../../helpers/common'; + +const myRedisDatabasePage = new MyRedisDatabasePage(); +const memoryEfficiencyPage = new MemoryEfficiencyPage(); +const recommendationPage = new RecommendationsPage(); +const common = new Common(); + +fixture `Upvote recommendations` + .meta({ type: 'critical_path', rte: rte.standalone }) + .page(commonUrl) + .beforeEach(async t => { + await acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig, ossStandaloneConfig.databaseName); + // Go to Analysis Tools page and create new report and open recommendations + await t.click(myRedisDatabasePage.analysisPageButton); + await t.click(memoryEfficiencyPage.newReportBtn); + await t.click(memoryEfficiencyPage.recommendationsTab); + }) + .afterEach(async() => { + await deleteStandaloneDatabaseApi(ossStandaloneConfig); + }); +test.only('Verify that user can upvote recommendations', async t => { + await recommendationPage.voteForVeryUsefulAndVerifyDisabled(); + // Verify that user can see previous votes when reload the page + await common.reloadPage(); + await t.click(memoryEfficiencyPage.recommendationsTab); + await recommendationPage.verifyVoteDisabled(); + + await t.click(memoryEfficiencyPage.newReportBtn); + await recommendationPage.voteForUsefulAndVerifyDisabled(); + + await t.click(memoryEfficiencyPage.newReportBtn); + await recommendationPage.voteForNotUsefulAndVerifyDisabled(); + // Verify that user can see the popup with link when he votes for “Not useful” + await t.expect(recommendationPage.recommendationsFeedbackBtn.visible).ok(); +}); From 0aabc97f885a69acd6bf46bb09bcd97aa0af9cd4 Mon Sep 17 00:00:00 2001 From: nmammadli Date: Mon, 23 Jan 2023 12:02:19 +0100 Subject: [PATCH 2/6] Update recommendations-page.ts Delete unused nth from verifyVoteDisabled --- tests/e2e/pageObjects/recommendations-page.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/e2e/pageObjects/recommendations-page.ts b/tests/e2e/pageObjects/recommendations-page.ts index 4027da79b3..9b5c850dee 100644 --- a/tests/e2e/pageObjects/recommendations-page.ts +++ b/tests/e2e/pageObjects/recommendations-page.ts @@ -1,7 +1,6 @@ import {Selector, t} from 'testcafe'; export class RecommendationsPage { - //CSS Selectors veryUsefulVoteBtn = Selector('[data-testid=very-useful-vote-btn]').nth(0); usefulVoteBtn = Selector('[data-testid=useful-vote-btn]').nth(0); notUsefulVoteBtn = Selector('[data-testid=not-useful-vote-btn]').nth(0); @@ -24,11 +23,11 @@ export class RecommendationsPage { async verifyVoteDisabled(): Promise{ // Verify that user can rate recommendations with one of 3 existing types at the same time - await t.expect(this.veryUsefulVoteBtn.nth(0) + await t.expect(this.veryUsefulVoteBtn .hasAttribute('disabled')).ok(); - await t.expect(this.usefulVoteBtn.nth(0) + await t.expect(this.usefulVoteBtn .hasAttribute('disabled')).ok(); - await t.expect(this.notUsefulVoteBtn.nth(0) + await t.expect(this.notUsefulVoteBtn .hasAttribute('disabled')).ok(); } } From d9c1d918c49f1cfce4aa38061621edd98d0f074c Mon Sep 17 00:00:00 2001 From: nmammadli Date: Mon, 23 Jan 2023 12:39:15 +0100 Subject: [PATCH 3/6] Update recommendations-page.ts Add assert message --- tests/e2e/pageObjects/recommendations-page.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e/pageObjects/recommendations-page.ts b/tests/e2e/pageObjects/recommendations-page.ts index 9b5c850dee..0be344b64c 100644 --- a/tests/e2e/pageObjects/recommendations-page.ts +++ b/tests/e2e/pageObjects/recommendations-page.ts @@ -24,10 +24,10 @@ export class RecommendationsPage { async verifyVoteDisabled(): Promise{ // Verify that user can rate recommendations with one of 3 existing types at the same time await t.expect(this.veryUsefulVoteBtn - .hasAttribute('disabled')).ok(); + .hasAttribute('disabled')).ok('very useful vote button is not disabled'); await t.expect(this.usefulVoteBtn - .hasAttribute('disabled')).ok(); + .hasAttribute('disabled')).ok('useful vote button is not disabled'); await t.expect(this.notUsefulVoteBtn - .hasAttribute('disabled')).ok(); + .hasAttribute('disabled')).ok('not useful vote button is not disabled'); } } From af09d55d98370a31be06c33a126a10b7507197e6 Mon Sep 17 00:00:00 2001 From: nmammadli Date: Mon, 23 Jan 2023 14:16:38 +0100 Subject: [PATCH 4/6] Update database-recommendations.e2e.ts Delete .only --- .../database-overview/database-recommendations.e2e.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/tests/critical-path/database-overview/database-recommendations.e2e.ts b/tests/e2e/tests/critical-path/database-overview/database-recommendations.e2e.ts index d4d169bfe9..eaad806d13 100644 --- a/tests/e2e/tests/critical-path/database-overview/database-recommendations.e2e.ts +++ b/tests/e2e/tests/critical-path/database-overview/database-recommendations.e2e.ts @@ -27,7 +27,7 @@ fixture `Upvote recommendations` .afterEach(async() => { await deleteStandaloneDatabaseApi(ossStandaloneConfig); }); -test.only('Verify that user can upvote recommendations', async t => { +test('Verify that user can upvote recommendations', async t => { await recommendationPage.voteForVeryUsefulAndVerifyDisabled(); // Verify that user can see previous votes when reload the page await common.reloadPage(); From e4b40fed841175f007e15384f68d160dfc42c31f Mon Sep 17 00:00:00 2001 From: nmammadli Date: Tue, 24 Jan 2023 09:21:15 +0100 Subject: [PATCH 5/6] Refactor Refactor for page objects --- .../memory-efficiency-actions.ts} | 24 +++++----- .../e2e/pageObjects/memory-efficiency-page.ts | 6 ++- .../database-recommendations.e2e.ts | 44 ------------------- .../memory-efficiency/recommendations.e2e.ts | 26 +++++++++++ 4 files changed, 41 insertions(+), 59 deletions(-) rename tests/e2e/{pageObjects/recommendations-page.ts => common-actions/memory-efficiency-actions.ts} (52%) delete mode 100644 tests/e2e/tests/critical-path/database-overview/database-recommendations.e2e.ts diff --git a/tests/e2e/pageObjects/recommendations-page.ts b/tests/e2e/common-actions/memory-efficiency-actions.ts similarity index 52% rename from tests/e2e/pageObjects/recommendations-page.ts rename to tests/e2e/common-actions/memory-efficiency-actions.ts index 0be344b64c..49dabfd61a 100644 --- a/tests/e2e/pageObjects/recommendations-page.ts +++ b/tests/e2e/common-actions/memory-efficiency-actions.ts @@ -1,33 +1,29 @@ -import {Selector, t} from 'testcafe'; - -export class RecommendationsPage { - veryUsefulVoteBtn = Selector('[data-testid=very-useful-vote-btn]').nth(0); - usefulVoteBtn = Selector('[data-testid=useful-vote-btn]').nth(0); - notUsefulVoteBtn = Selector('[data-testid=not-useful-vote-btn]').nth(0); - recommendationsFeedbackBtn = Selector('[data-testid=recommendation-feedback-btn]'); +import {t} from 'testcafe'; +import { MemoryEfficiencyPage } from '../pageObjects'; +const memoryEfficiencyPage = new MemoryEfficiencyPage(); +export class MemoryEfficiencyActions { async voteForVeryUsefulAndVerifyDisabled(): Promise { - await t.click(this.veryUsefulVoteBtn); + await t.click(memoryEfficiencyPage.veryUsefulVoteBtn); await this.verifyVoteDisabled(); } async voteForUsefulAndVerifyDisabled(): Promise { - await t.click(this.usefulVoteBtn); + await t.click(memoryEfficiencyPage.usefulVoteBtn); await this.verifyVoteDisabled(); } async voteForNotUsefulAndVerifyDisabled(): Promise { - await t.click(this.notUsefulVoteBtn); + await t.click(memoryEfficiencyPage.notUsefulVoteBtn); await this.verifyVoteDisabled(); } - async verifyVoteDisabled(): Promise{ // Verify that user can rate recommendations with one of 3 existing types at the same time - await t.expect(this.veryUsefulVoteBtn + await t.expect(memoryEfficiencyPage.veryUsefulVoteBtn .hasAttribute('disabled')).ok('very useful vote button is not disabled'); - await t.expect(this.usefulVoteBtn + await t.expect(memoryEfficiencyPage.usefulVoteBtn .hasAttribute('disabled')).ok('useful vote button is not disabled'); - await t.expect(this.notUsefulVoteBtn + await t.expect(memoryEfficiencyPage.notUsefulVoteBtn .hasAttribute('disabled')).ok('not useful vote button is not disabled'); } } diff --git a/tests/e2e/pageObjects/memory-efficiency-page.ts b/tests/e2e/pageObjects/memory-efficiency-page.ts index 376172ca8c..6a70527dbf 100644 --- a/tests/e2e/pageObjects/memory-efficiency-page.ts +++ b/tests/e2e/pageObjects/memory-efficiency-page.ts @@ -1,4 +1,4 @@ -import { Selector } from 'testcafe'; +import {Selector} from 'testcafe'; export class MemoryEfficiencyPage { //------------------------------------------------------------------------------------------- @@ -64,4 +64,8 @@ export class MemoryEfficiencyPage { avoidLogicalDbAccordion = Selector('[data-testid=avoidLogicalDatabases-accordion]'); convertHashToZipAccordion = Selector('[data-testid=convertHashtableToZiplist-accordion]'); compressHashAccordion = Selector('[data-testid=compressHashFieldNames-accordion]'); + veryUsefulVoteBtn = Selector('[data-testid=very-useful-vote-btn]').nth(0); + usefulVoteBtn = Selector('[data-testid=useful-vote-btn]').nth(0); + notUsefulVoteBtn = Selector('[data-testid=not-useful-vote-btn]').nth(0); + recommendationsFeedbackBtn = Selector('[data-testid=recommendation-feedback-btn]'); } diff --git a/tests/e2e/tests/critical-path/database-overview/database-recommendations.e2e.ts b/tests/e2e/tests/critical-path/database-overview/database-recommendations.e2e.ts deleted file mode 100644 index eaad806d13..0000000000 --- a/tests/e2e/tests/critical-path/database-overview/database-recommendations.e2e.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { acceptLicenseTermsAndAddDatabaseApi } from '../../../helpers/database'; -import { rte } from '../../../helpers/constants'; -import { - commonUrl, - ossStandaloneConfig -} from '../../../helpers/conf'; -import { deleteStandaloneDatabaseApi } from '../../../helpers/api/api-database'; -import {MemoryEfficiencyPage, MyRedisDatabasePage} from '../../../pageObjects'; -import {RecommendationsPage} from '../../../pageObjects/recommendations-page'; -import {Common} from '../../../helpers/common'; - -const myRedisDatabasePage = new MyRedisDatabasePage(); -const memoryEfficiencyPage = new MemoryEfficiencyPage(); -const recommendationPage = new RecommendationsPage(); -const common = new Common(); - -fixture `Upvote recommendations` - .meta({ type: 'critical_path', rte: rte.standalone }) - .page(commonUrl) - .beforeEach(async t => { - await acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig, ossStandaloneConfig.databaseName); - // Go to Analysis Tools page and create new report and open recommendations - await t.click(myRedisDatabasePage.analysisPageButton); - await t.click(memoryEfficiencyPage.newReportBtn); - await t.click(memoryEfficiencyPage.recommendationsTab); - }) - .afterEach(async() => { - await deleteStandaloneDatabaseApi(ossStandaloneConfig); - }); -test('Verify that user can upvote recommendations', async t => { - await recommendationPage.voteForVeryUsefulAndVerifyDisabled(); - // Verify that user can see previous votes when reload the page - await common.reloadPage(); - await t.click(memoryEfficiencyPage.recommendationsTab); - await recommendationPage.verifyVoteDisabled(); - - await t.click(memoryEfficiencyPage.newReportBtn); - await recommendationPage.voteForUsefulAndVerifyDisabled(); - - await t.click(memoryEfficiencyPage.newReportBtn); - await recommendationPage.voteForNotUsefulAndVerifyDisabled(); - // Verify that user can see the popup with link when he votes for “Not useful” - await t.expect(recommendationPage.recommendationsFeedbackBtn.visible).ok(); -}); diff --git a/tests/e2e/tests/critical-path/memory-efficiency/recommendations.e2e.ts b/tests/e2e/tests/critical-path/memory-efficiency/recommendations.e2e.ts index 9ea4f2c7cd..4b010ed580 100644 --- a/tests/e2e/tests/critical-path/memory-efficiency/recommendations.e2e.ts +++ b/tests/e2e/tests/critical-path/memory-efficiency/recommendations.e2e.ts @@ -4,6 +4,7 @@ import { acceptLicenseTermsAndAddDatabaseApi, deleteCustomDatabase } from '../.. import { commonUrl, ossStandaloneBigConfig, ossStandaloneConfig } from '../../../helpers/conf'; import { deleteStandaloneDatabaseApi } from '../../../helpers/api/api-database'; import { CliActions } from '../../../common-actions/cli-actions'; +import { MemoryEfficiencyActions } from '../../../common-actions/memory-efficiency-actions'; import { Common } from '../../../helpers/common'; const memoryEfficiencyPage = new MemoryEfficiencyPage(); @@ -13,6 +14,7 @@ const common = new Common(); const browserPage = new BrowserPage(); const cliPage = new CliPage(); const addRedisDatabasePage = new AddRedisDatabasePage(); +const memoryEfficiencyActions = new MemoryEfficiencyActions(); const externalPageLink = 'https://docs.redis.com/latest/ri/memory-optimizations/'; let keyName = `recomKey-${common.generateWord(10)}`; @@ -119,3 +121,27 @@ test await t.expect(memoryEfficiencyPage.avoidLogicalDbAccordion.exists).ok('Avoid using logical databases recommendation not displayed'); await t.expect(memoryEfficiencyPage.codeChangesLabel.exists).ok('Avoid using logical databases recommendation not have Code Changes label'); }); +test + .before(async t => { + await acceptLicenseTermsAndAddDatabaseApi(ossStandaloneConfig, ossStandaloneConfig.databaseName); + // Go to Analysis Tools page and create new report and open recommendations + await t.click(myRedisDatabasePage.analysisPageButton); + await t.click(memoryEfficiencyPage.newReportBtn); + await t.click(memoryEfficiencyPage.recommendationsTab); + }).after(async() => { + await deleteStandaloneDatabaseApi(ossStandaloneConfig); + })('Verify that user can upvote recommendations', async t => { + await memoryEfficiencyActions.voteForVeryUsefulAndVerifyDisabled(); + // Verify that user can see previous votes when reload the page + await common.reloadPage(); + await t.click(memoryEfficiencyPage.recommendationsTab); + await memoryEfficiencyActions.verifyVoteDisabled(); + + await t.click(memoryEfficiencyPage.newReportBtn); + await memoryEfficiencyActions.voteForUsefulAndVerifyDisabled(); + + await t.click(memoryEfficiencyPage.newReportBtn); + await memoryEfficiencyActions.voteForNotUsefulAndVerifyDisabled(); + // Verify that user can see the popup with link when he votes for “Not useful” + await t.expect(memoryEfficiencyPage.recommendationsFeedbackBtn.visible).ok('popup did not appear after voting for not useful'); + }); From ccf980c30e67754c1307ba80affed63bedf4010c Mon Sep 17 00:00:00 2001 From: nmammadli Date: Tue, 24 Jan 2023 12:45:31 +0100 Subject: [PATCH 6/6] Update memory-efficiency-actions.ts Add comments to methods --- tests/e2e/common-actions/memory-efficiency-actions.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/e2e/common-actions/memory-efficiency-actions.ts b/tests/e2e/common-actions/memory-efficiency-actions.ts index 49dabfd61a..edb67920ee 100644 --- a/tests/e2e/common-actions/memory-efficiency-actions.ts +++ b/tests/e2e/common-actions/memory-efficiency-actions.ts @@ -3,16 +3,23 @@ import { MemoryEfficiencyPage } from '../pageObjects'; const memoryEfficiencyPage = new MemoryEfficiencyPage(); export class MemoryEfficiencyActions { + /* + vote for very useful and verify others are disabled + */ async voteForVeryUsefulAndVerifyDisabled(): Promise { await t.click(memoryEfficiencyPage.veryUsefulVoteBtn); await this.verifyVoteDisabled(); } - + /* + vote for useful and verify others are disabled + */ async voteForUsefulAndVerifyDisabled(): Promise { await t.click(memoryEfficiencyPage.usefulVoteBtn); await this.verifyVoteDisabled(); } - + /* + vote for not useful and verify others are disabled + */ async voteForNotUsefulAndVerifyDisabled(): Promise { await t.click(memoryEfficiencyPage.notUsefulVoteBtn); await this.verifyVoteDisabled();