From a3cba745c0dc909a2f6ae803a4c4a4ff89218e2c Mon Sep 17 00:00:00 2001 From: Igor Braginsky Date: Mon, 11 Dec 2023 17:34:48 +0200 Subject: [PATCH] [RFR] Refactored issues tests to be more generic and flexible (#868) * Refactored issues tests to be more generic and flexible Signed-off-by: Igor Braginsky * Refactored all issue filtering tests Signed-off-by: Igor Braginsky * Cleanup Signed-off-by: Igor Braginsky --------- Signed-off-by: Igor Braginsky --- .../applicationinventory/application.ts | 9 -- .../migration/dynamic-report/issues/issues.ts | 82 +++++++++++++----- .../issues/allIssues/filter.test.ts | 85 +++++++++++-------- .../issues/singleApplication/filter.test.ts | 47 +++++----- cypress/e2e/types/constants.ts | 2 +- cypress/e2e/views/issue.view.ts | 9 ++ cypress/fixtures/analysis.json | 3 +- cypress/utils/utils.ts | 25 ++++-- 8 files changed, 166 insertions(+), 96 deletions(-) diff --git a/cypress/e2e/models/migration/applicationinventory/application.ts b/cypress/e2e/models/migration/applicationinventory/application.ts index 90627017a..00ce86e9f 100644 --- a/cypress/e2e/models/migration/applicationinventory/application.ts +++ b/cypress/e2e/models/migration/applicationinventory/application.ts @@ -25,7 +25,6 @@ import { analyzeButton, reviewAppButton, migration, - filterIssue, details, legacyPathfinder, } from "../../../types/constants"; @@ -76,7 +75,6 @@ import { doesExistButton, clickWithin, validateSingleApplicationIssue, - filterIssueBy, checkSuccessAlert, } from "../../../../utils/utils"; import { AppIssue, applicationData, RbacValidationRules } from "../../../types/types"; @@ -470,13 +468,6 @@ export class Application { }); } - validateIssueFilter(issues: AppIssue[], filterType: filterIssue, filterValue: string): void { - Issues.openSingleApplication(this.name); - issues.forEach((currentIssue) => { - filterIssueBy(filterType, currentIssue[filterValue]); - validateSingleApplicationIssue(currentIssue); - }); - } editApplicationFromApplicationProfile(): void { this.applicationDetailsTab(details); cy.wait(2000); diff --git a/cypress/e2e/models/migration/dynamic-report/issues/issues.ts b/cypress/e2e/models/migration/dynamic-report/issues/issues.ts index c2d04f7ca..75e9e0456 100644 --- a/cypress/e2e/models/migration/dynamic-report/issues/issues.ts +++ b/cypress/e2e/models/migration/dynamic-report/issues/issues.ts @@ -1,22 +1,33 @@ import { click, clickByText, - filterIssueBy, getUrl, + inputText, + selectFilter, selectItemsPerPage, selectUserPerspective, + validateAnyNumberPresence, + validateNumberPresence, validateTextPresence, } from "../../../../../utils/utils"; import { button, - filterIssue, + issueFilter, migration, SEC, singleApplication, + trTag, } from "../../../../types/constants"; import { navMenu } from "../../../../views/menu.view"; -import { singleAppDropList, singleApplicationColumns } from "../../../../views/issue.view"; +import { + bsFilterName, + issueColumns, + singleAppDropList, + singleApplicationColumns, + tagFilterName, +} from "../../../../views/issue.view"; import { AppIssue } from "../../../../types/types"; +import { liTag, searchButton, searchInput, span } from "../../../../views/common.view"; export class Issues { /** Contains URL of issues web page */ @@ -41,25 +52,56 @@ export class Issues { clickByText(button, applicationName); } - public static validateFilter( - issues: AppIssue[], - filterType: filterIssue, - filterValue: string + public static validateFilter(issue: AppIssue, isSingle = false): void { + cy.contains(issue.name) + .closest(trTag) + .within(() => { + validateTextPresence(issueColumns.issue, issue.name); + validateTextPresence(issueColumns.category, issue.category); + validateTextPresence(issueColumns.source, issue.source); + cy.get(issueColumns.target).within(() => { + issue.targets.forEach((currentTarget) => { + validateTextPresence(liTag, currentTarget); + }); + }); + validateNumberPresence(issueColumns.effort, issue.effort); + if (!isSingle) { + validateAnyNumberPresence(issueColumns.applications); + } else { + validateAnyNumberPresence(singleApplicationColumns.files); + } + }); + } + + public static applyFilter( + filterType: issueFilter, + filterValue: string, + isSingle = false ): void { - issues.forEach((issue: AppIssue) => { - const isApplicableFilter = - filterType === filterIssue.tags || - filterType === filterIssue.category || - filterType === filterIssue.source || - filterType === filterIssue.target; + let selector = ""; + if (!isSingle) { + Issues.openList(); + selectFilter(filterType); + } + + const isApplicableFilter = + filterType === issueFilter.appName || + filterType === issueFilter.category || + filterType === issueFilter.source || + filterType === issueFilter.target; - if (isApplicableFilter) { - filterValue = issue[filterValue]; + if (isApplicableFilter) { + inputText(searchInput, filterValue); + click(searchButton); + } else { + if (filterType == issueFilter.bs) { + selector = bsFilterName; + } else if (filterType == issueFilter.tags) { + selector = tagFilterName; } - Issues.openList(); - filterIssueBy(filterType, filterValue); - cy.get("tr").should("not.contain", "No data available"); - validateTextPresence(singleApplicationColumns.issue, issue["name"]); - }); + click(selector); + clickByText(span, filterValue); + click(selector); + } } } diff --git a/cypress/e2e/tests/migration/dynamic-report/issues/allIssues/filter.test.ts b/cypress/e2e/tests/migration/dynamic-report/issues/allIssues/filter.test.ts index fafd3366e..c8fbcadd5 100644 --- a/cypress/e2e/tests/migration/dynamic-report/issues/allIssues/filter.test.ts +++ b/cypress/e2e/tests/migration/dynamic-report/issues/allIssues/filter.test.ts @@ -16,21 +16,23 @@ limitations under the License. /// import { - login, - getRandomApplicationData, - getRandomAnalysisData, - deleteByList, clearAllFilters, + deleteByList, + getRandomAnalysisData, + getRandomApplicationData, + login, } from "../../../../../../utils/utils"; import { Analysis } from "../../../../../models/migration/applicationinventory/analysis"; -import { SEC, filterIssue } from "../../../../../types/constants"; +import { issueFilter, SEC } from "../../../../../types/constants"; import { Issues } from "../../../../../models/migration/dynamic-report/issues/issues"; import { BusinessServices } from "../../../../../models/migration/controls/businessservices"; import * as data from "../../../../../../utils/data_utils"; +import { AppIssue } from "../../../../../types/types"; + let applicationsList: Array = []; let businessService: BusinessServices; -describe(["@tier2"], "1 Bug: Issues filtering", () => { +describe(["@tier2"], "Issues filtering", () => { before("Login", function () { login(); businessService = new BusinessServices(data.getCompanyName(), data.getDescription()); @@ -60,57 +62,68 @@ describe(["@tier2"], "1 Bug: Issues filtering", () => { application.analyze(); application.verifyAnalysisStatus("Completed"); - Issues.validateFilter( - this.analysisData["source_analysis_on_bookserverapp"]["issues"], - filterIssue.appName, - application.name + Issues.applyFilter(issueFilter.appName, application.name); + this.analysisData["source_analysis_on_bookserverapp"]["issues"].forEach( + (issue: AppIssue) => { + Issues.validateFilter(issue); + } ); clearAllFilters(); }); it("Filtering issues by BS", function () { - Issues.validateFilter( - this.analysisData["source_analysis_on_bookserverapp"]["issues"], - filterIssue.bs, - businessService.name + Issues.applyFilter(issueFilter.bs, businessService.name); + this.analysisData["source_analysis_on_bookserverapp"]["issues"].forEach( + (issue: AppIssue) => { + Issues.validateFilter(issue); + } ); clearAllFilters(); }); it("Filtering issues by tags", function () { - Issues.validateFilter( - this.analysisData["source_analysis_on_bookserverapp"]["issues"], - filterIssue.tags, - "tags" + this.analysisData["source_analysis_on_bookserverapp"]["tags"].forEach( + (currentTag: string) => { + Issues.applyFilter(issueFilter.tags, currentTag); + this.analysisData["source_analysis_on_bookserverapp"]["issues"].forEach( + (issue: AppIssue) => { + Issues.validateFilter(issue); + } + ); + clearAllFilters(); + } ); - clearAllFilters(); }); it("Filtering issues by category", function () { - Issues.validateFilter( - this.analysisData["source_analysis_on_bookserverapp"]["issues"], - filterIssue.category, - "category" + this.analysisData["source_analysis_on_bookserverapp"]["issues"].forEach( + (issue: AppIssue) => { + Issues.applyFilter(issueFilter.category, issue.category); + Issues.validateFilter(issue); + clearAllFilters(); + } ); - clearAllFilters(); }); - it("Bug MTA-1779 - Filtering issues by source", function () { - Issues.validateFilter( - this.analysisData["source_analysis_on_bookserverapp"]["issues"], - filterIssue.source, - "source" + it("Filtering issues by source", function () { + this.analysisData["source_analysis_on_bookserverapp"]["issues"].forEach( + (issue: AppIssue) => { + Issues.applyFilter(issueFilter.source, issue.source); + Issues.validateFilter(issue); + clearAllFilters(); + } ); - clearAllFilters(); }); it("Filtering issues by target", function () { - Issues.validateFilter( - this.analysisData["source_analysis_on_bookserverapp"]["issues"], - filterIssue.target, - "targets" - ); - clearAllFilters(); + let issues = this.analysisData["source_analysis_on_bookserverapp"]["issues"]; + issues.forEach((issue: AppIssue) => { + issue.targets.forEach((target: string) => { + Issues.applyFilter(issueFilter.target, target); + Issues.validateFilter(issue); + clearAllFilters(); + }); + }); }); after("Perform test data clean up", function () { diff --git a/cypress/e2e/tests/migration/dynamic-report/issues/singleApplication/filter.test.ts b/cypress/e2e/tests/migration/dynamic-report/issues/singleApplication/filter.test.ts index 27aad7a25..ae6ce2730 100644 --- a/cypress/e2e/tests/migration/dynamic-report/issues/singleApplication/filter.test.ts +++ b/cypress/e2e/tests/migration/dynamic-report/issues/singleApplication/filter.test.ts @@ -23,11 +23,13 @@ import { clearAllFilters, } from "../../../../../../utils/utils"; import { Analysis } from "../../../../../models/migration/applicationinventory/analysis"; -import { SEC, filterIssue } from "../../../../../types/constants"; +import { SEC, issueFilter } from "../../../../../types/constants"; +import { Issues } from "../../../../../models/migration/dynamic-report/issues/issues"; +import { AppIssue } from "../../../../../types/types"; let applicationsList: Array = []; let application: Analysis; -describe(["@tier2"], "1 Bug: Single application issues filtering", () => { +describe(["@tier2"], "Single application issues filtering", () => { before("Login", function () { login(); }); @@ -54,30 +56,37 @@ describe(["@tier2"], "1 Bug: Single application issues filtering", () => { application.analyze(); application.verifyAnalysisStatus("Completed"); - application.validateIssueFilter( - this.analysisData["source_analysis_on_bookserverapp"]["issues"], - filterIssue.category, - "category" + Issues.openSingleApplication(application.name); + this.analysisData["source_analysis_on_bookserverapp"]["issues"].forEach( + (issue: AppIssue) => { + Issues.applyFilter(issueFilter.category, issue.category, true); + Issues.validateFilter(issue, true); + clearAllFilters(); + } ); - clearAllFilters(); }); - it("Bug MTA-1779 - Filtering issues by source", function () { - application.validateIssueFilter( - this.analysisData["source_analysis_on_bookserverapp"]["issues"], - filterIssue.source, - "source" + it("Filtering issues by source", function () { + Issues.openSingleApplication(application.name); + this.analysisData["source_analysis_on_bookserverapp"]["issues"].forEach( + (issue: AppIssue) => { + Issues.applyFilter(issueFilter.source, issue.source, true); + Issues.validateFilter(issue, true); + clearAllFilters(); + } ); - clearAllFilters(); }); it("Filtering issues by target", function () { - application.validateIssueFilter( - this.analysisData["source_analysis_on_bookserverapp"]["issues"], - filterIssue.target, - "targets" - ); - clearAllFilters(); + Issues.openSingleApplication(application.name); + let issues = this.analysisData["source_analysis_on_bookserverapp"]["issues"]; + issues.forEach((issue: AppIssue) => { + issue.targets.forEach((target: string) => { + Issues.applyFilter(issueFilter.target, target, true); + Issues.validateFilter(issue, true); + clearAllFilters(); + }); + }); }); after("Perform test data clean up", function () { diff --git a/cypress/e2e/types/constants.ts b/cypress/e2e/types/constants.ts index e14ac33b7..75cc22490 100644 --- a/cypress/e2e/types/constants.ts +++ b/cypress/e2e/types/constants.ts @@ -182,7 +182,7 @@ export enum SortType { descending = "descending", } -export enum filterIssue { +export enum issueFilter { appName = "Application name", archetype = "Archetype", bs = "Business service", diff --git a/cypress/e2e/views/issue.view.ts b/cypress/e2e/views/issue.view.ts index e330f62eb..2d910c6c1 100644 --- a/cypress/e2e/views/issue.view.ts +++ b/cypress/e2e/views/issue.view.ts @@ -11,3 +11,12 @@ export enum singleApplicationColumns { effort = 'td[data-label="Effort"]', files = 'td[data-label="Affected files"]', } + +export enum issueColumns { + issue = 'td[data-label="Issue"]', + category = 'td[data-label="Category"]', + source = 'td[data-label="Source"]', + target = 'td[data-label="Target(s)"]', + effort = 'td[data-label="Effort"]', + applications = 'td[data-label="Affected applications"]', +} diff --git a/cypress/fixtures/analysis.json b/cypress/fixtures/analysis.json index 10d6bfcf6..3d1d0567e 100644 --- a/cypress/fixtures/analysis.json +++ b/cypress/fixtures/analysis.json @@ -12,8 +12,7 @@ "source": "None", "targets": ["cloud-readiness"], "effort": 1, - "affectedFiles": 1, - "tags": ["EJB XML", "Java EE Batch", "EJB XML"] + "affectedFiles": 1 } ], "dependencies": [ diff --git a/cypress/utils/utils.ts b/cypress/utils/utils.ts index 04ad8a914..422a36bca 100644 --- a/cypress/utils/utils.ts +++ b/cypress/utils/utils.ts @@ -49,8 +49,7 @@ import { JiraType, migration, businessServiceLower, - filterIssue, - appName, + issueFilter, } from "../e2e/types/constants"; import { actionButton, @@ -309,6 +308,14 @@ export function validateNumberPresence(fieldId: string, value: number): void { }); } +export function validateAnyNumberPresence(fieldId: string): void { + cy.get(fieldId) + .invoke("text") + .then((text) => { + expect(parseFloat(text)).to.not.be.NaN; + }); +} + export function closeSuccessAlert(): void { cy.get(closeSuccessNotification, { timeout: 10 * SEC }) .first() @@ -358,14 +365,14 @@ export function clearAllFilters(): void { cy.contains(button, "Clear all filters").click({ force: true }); } -export function filterIssueBy(filterType: filterIssue, filterValue: string | string[]): void { +export function filterIssueBy(filterType: issueFilter, filterValue: string | string[]): void { let selector = ""; selectFilter(filterType); const isApplicableFilter = - filterType === filterIssue.appName || - filterType === filterIssue.category || - filterType === filterIssue.source || - filterType === filterIssue.target; + filterType === issueFilter.appName || + filterType === issueFilter.category || + filterType === issueFilter.source || + filterType === issueFilter.target; if (isApplicableFilter) { if (Array.isArray(filterValue)) { @@ -378,9 +385,9 @@ export function filterIssueBy(filterType: filterIssue, filterValue: string | str click(searchButton); } } else { - if (filterType == filterIssue.bs) { + if (filterType == issueFilter.bs) { selector = bsFilterName; - } else if (filterType == filterIssue.tags) { + } else if (filterType == issueFilter.tags) { selector = tagFilterName; } click(selector);