From 903a52316dbdbbb2a1e4dc3cd4dfcd37272370a1 Mon Sep 17 00:00:00 2001 From: Krista Chan Date: Wed, 4 Mar 2026 15:35:20 -0800 Subject: [PATCH 01/14] Moving new organization tests from NEDSSDev --- .../cypress/e2e/features/organization.feature | 187 +++++++++++++ .../e2e/pages/editOrganization.page.js | 209 ++++++++++++++ .../cypress/e2e/pages/organization.page.js | 259 ++++++++++++++++++ .../step_definitions/organization.steps.js | 197 +++++++++++++ 4 files changed, 852 insertions(+) create mode 100644 testing/regression/cypress/e2e/features/organization.feature create mode 100644 testing/regression/cypress/e2e/pages/editOrganization.page.js create mode 100644 testing/regression/cypress/e2e/pages/organization.page.js create mode 100644 testing/regression/cypress/step_definitions/organization.steps.js diff --git a/testing/regression/cypress/e2e/features/organization.feature b/testing/regression/cypress/e2e/features/organization.feature new file mode 100644 index 0000000000..21f2dd5fb3 --- /dev/null +++ b/testing/regression/cypress/e2e/features/organization.feature @@ -0,0 +1,187 @@ +Feature: Classic NBS - Dedupe - User can view data in NBS Organization Search Page + + Background: + Given I am logged in as secure user and stay on classic + + # Data Entry Tests + + ## Search Organization + + Scenario: Verify organization exists by searching name + When I navigate to classic organization Search pane + And I enter organization name in input text field "Piedmont Hospital" + And I click on the Submit button + Then the search results should include "Piedmont Hospital" + + Scenario: Verify organization exists by searching address + When I navigate to classic organization Search pane + And I enter organization address in input text field "1364 Clifton Road" + And I click on the Submit button + Then the search results should include "Emory University Hospital" + And the search results should include address "1364 Clifton Road" + + Scenario: Add new organization with basic info + When I navigate to classic organization Search pane + And I enter a unique organization name in the name field + And I click on the Submit button + Then I should see a message that no matching organizations were found + And I click the Add button + And I select the role "Allergy clinic" + And I click on the Submit button + And I click the Add button + And I navigate to classic organization Search pane + And I enter the same organization name in the Search Pane + And I click on the Submit button + Then the organization should appear in search results + + Scenario: Add new organization with all info + When I navigate to classic organization Search pane + And I enter a unique organization name in the name field + And I click on the Submit button + Then I should see a message that no matching organizations were found + And I click the Add button + And I select a random ID Type + And I select a random Assigning Authority + And I enter a random ID Value + And I click the Add Identification button + And I select address use "Primary Work Place" + And I select address type "Office" + And I enter street address "1600 Clifton Road NE" + And I enter city "Atlanta" + And I enter zip code "30333" + And I click the Add Address button + And I select telephone use "Primary Work Place" + And I select telephone type "Phone" + And I enter telephone number "404", "639", "3311" + And I click the Add Telephone button + And I click on the Submit button + And I navigate to classic organization Search pane + And I enter the same organization name in the Search Pane + And I click on the Submit button + Then the organization should appear in search results + + ## View Organization + + Scenario: All organization details exist + When I navigate to classic organization Search pane + And I enter organization name in input text field "Piedmont Hospital" + And I click on the Submit button + And I click View on the search results + Then I should see all organization details are correct + + Scenario: Edit with overwrite + When I navigate to classic organization Search pane + And I enter organization name in input text field "CHOA - Scottish Rite" + And I click on the Submit button + And I click View on the search results + And I click the Edit button + And I select "Typographical error correction or additional information" as the reason for edit + And I select address use "Primary Work Place" + And I select address type "Office" + And I enter street address "1600 Clifton Road NE" + And I enter city "Atlanta" + And I enter zip code "30333" + And I click the Add Address button + And I select telephone use "Primary Work Place" + And I select telephone type "Phone" + And I enter telephone number "404", "639", "3311" + And I click the Add Telephone button + And I click on the Submit button + And I navigate to classic organization Search pane + And I enter organization name in input text field "CHOA - Scottish Rite" + And I click on the Submit button + Then the search results should include "CHOA - Scottish Rite" + And the search results should include address "1600 Clifton Road NE" + And the search results should include telephone "404-639-3311" + + Scenario: Edit with new organization + When I navigate to classic organization Search pane + And I enter organization name in input text field "CHOA - Scottish Rite" + And I click on the Submit button + And I click View on the search results + And I click the Edit button + And I select "A change to existing information for non typographical reasons" as the reason for edit + And I enter a unique quick code + And I delete the existing address + And I select address use "Organizational Contact" + And I select address type "Postal/Mailing" + And I enter street address "456 Main Street" + And I click the Add Address button + And I click on the Submit button + And I navigate to classic organization Search pane + And I enter organization name in input text field "CHOA - Scottish Rite" + And I click on the Submit button + Then there should be 2 search results + And one of the search results should have the generated quick code + And the search results should include address "456 Main Street" + + Scenario: Provide multiple contact records (two new telephone numbers) for organization + When I navigate to classic organization Search pane + And I enter organization name in input text field "Northside Hospital" + And I click on the Submit button + And I click View on the search results + And I click the Edit button + And I select "Typographical error correction or additional information" as the reason for edit + And I add a new telephone with use "Primary Work Place", type "Phone", number "770"-"555"-"1234" + And I add a new telephone with use "Alternate Work Place", type "Phone", number "678"-"555"-"5678" + And I click on the Submit button + And I navigate to classic organization Search pane + And I enter organization name in input text field "Northside Hospital" + And I click on the Submit button + Then the search results should include telephone "770-555-1234" + And the search results should include telephone "678-555-5678" + + Scenario: Provide multiple contact records (two new addresses) for organization + When I navigate to classic organization Search pane + And I enter organization name in input text field "St. Joseph's Hospital" + And I click on the Submit button + And I click View on the search results + And I click the Edit button + And I select "Typographical error correction or additional information" as the reason for edit + And I select address use "Alternate Work Place" + And I select address type "Office" + And I enter street address "123 Drury Lane" + And I enter city "Oakland" + And I enter zip code "94611" + And I click the Add Address button + And I select address use "Organizational Contact" + And I select address type "Postal/Mailing" + And I enter street address "456 Main Street" + And I enter city "Oakland" + And I enter zip code "94611" + And I click the Add Address button + And I click on the Submit button + And I navigate to classic organization Search pane + And I enter organization name in input text field "St. Joseph's Hospital" + And I click on the Submit button + Then the search results should include address "123 Drury Lane" + And the search results should include address "456 Main Street" + + Scenario: Provide multiple ID records for organization + When I navigate to classic organization Search pane + And I enter organization name in input text field "St. Joseph's Hospital" + And I click on the Submit button + And I click View on the search results + And I click the Edit button + And I select "Typographical error correction or additional information" as the reason for edit + And I add a new ID record with type "ABCs Hospital ID", authority "CMS Provider", value "CMS1234" + And I add a new ID record with type "Organization identifier", authority "CLIA (CMS)", value "CLIA5678" + And I click on the Submit button + And I navigate to classic organization Search pane + And I enter organization name in input text field "St. Joseph's Hospital" + And I click on the Submit button + Then the search results should include ID Type "ABCs Hospital ID" with ID Value "CMS1234" + And the search results should include ID Type "Organization identifier" with ID Value "CLIA5678" + + Scenario: Inactivate an existing organization + When I navigate to classic organization Search pane + And I enter organization name in input text field "Northside Hospital" + And I click on the Submit button + Then the search results should include "Northside Hospital" + When I click View on the search results + And I click the Inactivate button + When I confirm the inactivation + And I navigate to classic organization Search pane + And I enter organization name in input text field "Northside Hospital" + And I click on the Submit button + Then I should see a message that no matching organizations were found \ No newline at end of file diff --git a/testing/regression/cypress/e2e/pages/editOrganization.page.js b/testing/regression/cypress/e2e/pages/editOrganization.page.js new file mode 100644 index 0000000000..9b0b5b9575 --- /dev/null +++ b/testing/regression/cypress/e2e/pages/editOrganization.page.js @@ -0,0 +1,209 @@ +import { selectRandomDropdownValue } from "./utils"; + +class EditOrganizationPage { + selectEditReason(reasonValue) { + cy.get(`input[type="radio"][value="${reasonValue}"]`, { timeout: 10000 }) + .should('be.visible') + .check({ force: true }); + cy.log(`Selected edit reason: ${reasonValue}`); + } + enterUniqueQuickCode() { + cy.log('Entering unique quick code'); + + // Generate a random 6-character alphanumeric string + const quickCode = Math.random().toString(36).substring(2, 8).toUpperCase(); + cy.log(`Generated quick code: ${quickCode}`); + + // Find the Quick Code input field and type the generated code + cy.get('input[name="quickCodeIdDT.rootExtensionTxt"]', { timeout: 10000 }) + .should('be.visible') + .clear() + .type(quickCode); + + // Store the generated quick code for later verification if needed + cy.wrap(quickCode).as('generatedQuickCode'); + } + selectRole(roleName) { + cy.log(`Selecting role: ${roleName}`); + cy.get('select#rolesList', { timeout: 10000 }) + .should('be.visible') + .select(roleName); + } + + selectRandomIdType() { + selectRandomDropdownValue('select[fieldlabel="ID Type"]'); + } + + selectRandomAssigningAuthority() { + selectRandomDropdownValue('select[header="Authority"]'); + } + enterRandomIdValue() { + cy.log('Entering random ID Value'); + + // Generate a random string (8 characters alphanumeric) + const randomId = Math.random().toString(36).substring(2, 10).toUpperCase(); + cy.log(`Random ID Value: ${randomId}`); + + // Find the ID Value textbox and type the random string + cy.get('[id="organization.entityIdDT_s[i].rootExtensionTxt"]', { timeout: 10000 }) + .should('be.visible') + .clear() + .type(randomId); + + cy.wrap(randomId).as('generatedIdValue'); + } + + clickAddIdentificationButton() { + cy.log('Clicking Add Identification button'); + + // Click the Add Identification button + cy.get('#BatchEntryAddButtonIdentification', { timeout: 10000 }) + .should('be.visible') + .click(); + + cy.log('Add Identification button clicked'); + + } + + + addNewIdEntry(idDetails) { + cy.log(`Adding new ID entry with Type: ${idDetails.type}, Authority: ${idDetails.authority}`); + + // Scroll to Identification section + cy.contains('Identification Information').scrollIntoView(); + + // Click the Type dropdown arrow and select + cy.get('[name="organization.entityIdDT_s[i].typeCd_button"]').click(); + cy.wait(500); + cy.get('select[name="organization.entityIdDT_s[i].typeCd"]').select(idDetails.type, { force: true }); + + // Click the Assigning Authority dropdown arrow and select + cy.get('[name="organization.entityIdDT_s[i].assigningAuthorityCd_button"]').click() + cy.wait(500); + cy.get('select[name="organization.entityIdDT_s[i].assigningAuthorityCd"]').select(idDetails.authority, { force: true }); + + cy.get('[id="organization.entityIdDT_s[i].rootExtensionTxt"]', { timeout: 10000 }) + .should('be.visible') + .clear() + .type(idDetails.idValue); + this.clickAddIdentificationButton(); + } + + deleteExistingAddress() { + cy.log('Deleting first address entry'); + + // Scroll to Address section + cy.contains('Address Information').scrollIntoView(); + + // Find the first address entry in the history box and click its Delete link + cy.get('#nestedElementsHistoryBox\\|Address tr', { timeout: 10000 }) + .first() + .within(() => { + cy.contains('Delete').click(); + }); + + cy.wait(500); // Wait for the deletion to process + } + + // Methods to add new contact information (telephone and address) + + addNewTelephoneEntry(telephoneDetails) { + cy.log(`Adding new telephone: ${telephoneDetails.areaCode}-${telephoneDetails.prefix}-${telephoneDetails.lineNumber}`); + + // Scroll to Telephone section + cy.contains('Telephone Information').scrollIntoView(); + + // Click the Use dropdown arrow and select + cy.get('[name="telephone[i].useCd_button"]').click(); + cy.wait(500); + cy.get('select[name="telephone[i].useCd"]').select(telephoneDetails.use, { force: true }); + + // Click the Type dropdown arrow and select + cy.get('[name="telephone[i].cd_button"]').click(); + cy.wait(500); + cy.get('select[name="telephone[i].cd"]').select(telephoneDetails.type, { force: true }); + + // Find empty phone number fields and fill them + cy.get('input[id*="phoneNbrTxt1"]').filter((i, el) => !el.value).first() + .clear().type(telephoneDetails.areaCode); + cy.get('input[id*="phoneNbrTxt2"]').filter((i, el) => !el.value).first() + .clear().type(telephoneDetails.prefix); + cy.get('input[id*="phoneNbrTxt3"]').filter((i, el) => !el.value).first() + .clear().type(telephoneDetails.lineNumber); + + // Click Add Telephone button + cy.get('#BatchEntryAddButtonTelephone').click(); + cy.wait(1000); + } + + enterTelephoneUse(useValue) { + cy.log(`Selecting telephone use: ${useValue}`); + cy.get('select[name="telephone[i].useCd"]').select(useValue, { force: true }); + } + + enterTelephoneType(typeValue) { + cy.log(`Selecting telephone type: ${typeValue}`); + cy.get('select[name="telephone[i].cd"]').select(typeValue, { force: true }); + } + + enterTelephoneNumber(areaCode, prefix, lineNumber) { + cy.log(`Entering telephone: ${areaCode}-${prefix}-${lineNumber}`); + cy.get('input[id*="phoneNbrTxt1"]').clear().type(areaCode); + cy.get('input[id*="phoneNbrTxt2"]').clear().type(prefix); + cy.get('input[id*="phoneNbrTxt3"]').clear().type(lineNumber); + } + + clickAddTelephoneButton() { + cy.log('Clicking Add Telephone button'); + cy.get('#BatchEntryAddButtonTelephone', { timeout: 10000 }) + .should('be.visible') + .click(); + cy.wait(500); + } + + enterAddressUse(useValue) { + cy.log(`Selecting address use: ${useValue}`); + cy.get('select[name="address[i].useCd"]').select(useValue, { force: true }); + } + + enterAddressType(typeValue) { + cy.log(`Selecting address type: ${typeValue}`); + cy.get('select[name="address[i].cd"]').select(typeValue, { force: true }); + } + + enterStreetAddress1(address) { + cy.log(`Entering street address: ${address}`); + cy.get('input[name="address[i].thePostalLocatorDT_s.streetAddr1"]') + .should('be.visible') + .clear() + .type(address); + } + + enterCity(city) { + cy.log(`Entering city: ${city}`); + cy.get('input[name="address[i].thePostalLocatorDT_s.cityDescTxt"]') + .should('be.visible') + .clear() + .type(city); + } + + enterZipCode(zip) { + cy.log(`Entering zip code: ${zip}`); + cy.get('input[name="address[i].thePostalLocatorDT_s.zipCd"]') + .should('be.visible') + .clear() + .type(zip); + } + + clickAddAddressButton() { + cy.log('Clicking Add Address button'); + cy.get('#BatchEntryAddButtonAddress', { timeout: 10000 }) + .should('be.visible') + .click(); + cy.wait(500); + } + + +} + +export default new EditOrganizationPage(); \ No newline at end of file diff --git a/testing/regression/cypress/e2e/pages/organization.page.js b/testing/regression/cypress/e2e/pages/organization.page.js new file mode 100644 index 0000000000..62e40135a9 --- /dev/null +++ b/testing/regression/cypress/e2e/pages/organization.page.js @@ -0,0 +1,259 @@ + +class ClassicOrganizationPage { + + // Navigation methods + navigateToClassicOrganizationSearchPane() { + cy.contains('Data Entry').eq(0).click() + cy.contains('Organization').eq(0).click() + } + + // Search methods + enterOrganizationNameInSearch(name) { + cy.get('input[id="organizationSearch.nmTxt"]').type(name) + } + + enterOrganizationAddressInSearch(address) { + cy.get('input[id="organizationSearch.streetAddr1"]').type(address) + } + + enterUniqueOrganizationNameInSearch() { + const timestamp = Date.now(); + const uniqueName = `random string ${timestamp}`; + cy.log(`Using unique organization name: ${uniqueName}`); + cy.wrap(uniqueName).as('orgName'); + cy.get('input[id="organizationSearch.nmTxt"]').type(uniqueName) + cy.wrap(uniqueName).as('createdOrgName'); + } + + enterSameOrganizationNameInSearchPane() { + // Retrieve the name from the alias and use it + cy.get('@createdOrgName').then((orgName) => { + cy.log(`Using stored organization name in search pane: ${orgName}`); + cy.get('input[id="organizationSearch.nmTxt"]') + .should('be.visible') + .clear() + .type(orgName); + }); + } + // Add/Edit methods + + clickEditButton() { + cy.get('input[name="Edit"]').eq(0).click() + } + + /** + * Click the Inactivate button on the View Organization page + */ + clickInactivateButton() { + cy.log('Clicking Inactivate button'); + cy.get('#Inactivate').eq(0).click(); + } + acceptConfirmationPopup() { + cy.log('Accepting confirmation popup'); + + // Cypress automatically handles native browser dialogs + // This event listener will click OK on the confirm popup + cy.on('window:confirm', () => { + cy.log('Confirmation popup accepted'); + return true; // true clicks OK, false would click Cancel + }); + } + + // Navigation from search results to view + clickViewOnSearchResults() { + cy.log('Clicking View on search results'); + cy.contains('View').eq(0).click(); + } + + verifySearchResultsCount(expectedCount) { + cy.log(`Verifying search results message shows ${expectedCount} possible matches`); + + // Check the red text div for the expected count + cy.get('div.boldTenDkRed', { timeout: 10000 }) + .should('be.visible') + .and('contain', `resulted in ${expectedCount} possible matches`); + } + + // Verification methods + verifySearchResultsContain(expectedText) { + cy.log(`Verifying search results include: ${expectedText}`); + cy.get('#searchResultsTable', { timeout: 10000 }) + .should('be.visible') + .and('contain', expectedText); + } + + verifySearchResultContainsGeneratedQuickCode() { + cy.log('Verifying search result contains generated quick code'); + + cy.get('@generatedQuickCode').then((quickCode) => { + cy.log(`Looking for quick code: ${quickCode}`); + + cy.get('#searchResultsTable', { timeout: 10000 }) + .should('be.visible') + .and('contain', quickCode); + }); + } + + verifySearchResultsContainAddress(expectedAddress) { + cy.log(`Verifying search results include address: ${expectedAddress}`); + cy.get('#searchResultsTable', { timeout: 10000 }) + .should('be.visible') + .and('contain', expectedAddress); + } + + verifySearchResultsContainTelephone(expectedTelephone) { + cy.log(`Verifying search results include telephone: ${expectedTelephone}`); + cy.get('#searchResultsTable', { timeout: 10000 }) + .should('be.visible') + .and('contain', expectedTelephone); + } + + verifySearchResultsContainIdTypeAndValue(expectedType, expectedValue) { + cy.log(`Verifying search results include ID Type: ${expectedType} with ID Value: ${expectedValue}`); + cy.get('#searchResultsTable', { timeout: 10000 }) + .should('be.visible') + .and('contain', expectedType) + .and('contain', expectedValue); + } + + verifyNoResultsFound() { + cy.log('Verifying no results message'); + cy.get('div.boldTenDkRed', { timeout: 10000 }) + .should('be.visible') + .and('contain', 'resulted in 0 possible matches'); + cy.get('div.boldTenDkRed a') + .should('be.visible') + .and('contain', 'refine your search?'); + cy.get('#searchResultsTable') + .should('contain', 'There is no information to display'); + } + + verifyOrganizationWasCreated() { + cy.get('@createdOrgName').then((orgName) => { + cy.log(`Verifying search results include: ${orgName}`); + cy.get('#searchResultsTable', { timeout: 10000 }) + .should('be.visible') + .and('contain', orgName); + }); + + } + verifySuccessMessage() { + cy.url().should('include', 'ViewOrganization'); + cy.get('body').should('contain', 'created') + .or('contain', 'added') + .or('contain', 'successful'); + } + + // Administrative Information verification + verifyQuickCode(expectedValue) { + cy.log(`Verifying Quick Code: ${expectedValue}`); + cy.get('#test').should('contain', expectedValue); + } + + verifyStandardIndustryClass(expectedValue) { + cy.log(`Verifying Standard Industry Class: ${expectedValue}`); + cy.get('[id="organization.theOrganizationDT.standardIndustryClassCd"]').should('contain', expectedValue); + } + + verifyRole(expectedRole) { + cy.log(`Verifying Role: ${expectedRole}`); + cy.get('#rolesList').should('contain', expectedRole); + } + + // Name verification + verifyOrganizationName(expectedName) { + cy.log(`Verifying Organization Name: ${expectedName}`); + cy.get('#name\\.nmTxt').should('contain', expectedName); + } + + // Identification Information verification + verifyIdentificationType(expectedType) { + cy.log(`Verifying Identification Type: ${expectedType}`); + cy.get('#nestedElementsHistoryBox\\|Identification tr').first().find('td').eq(1).should('contain', expectedType); + } + + verifyIdentificationAuthority(expectedAuthority) { + cy.log(`Verifying Identification Authority: ${expectedAuthority}`); + cy.get('#nestedElementsHistoryBox\\|Identification tr').first().find('td').eq(2).should('contain', expectedAuthority); + } + + verifyIdentificationValue(expectedValue) { + cy.log(`Verifying Identification Value: ${expectedValue}`); + cy.get('#nestedElementsHistoryBox\\|Identification tr').first().find('td').eq(3).should('contain', expectedValue); + } + + // Address Information verification + verifyAddressUse(expectedUse) { + cy.log(`Verifying Address Use: ${expectedUse}`); + cy.get('#nestedElementsHistoryBox\\|Address tr').first().find('td').eq(1).should('contain', expectedUse); + } + + verifyStreetAddress(expectedAddress) { + cy.log(`Verifying Street Address: ${expectedAddress}`); + cy.get('#nestedElementsHistoryBox\\|Address tr').first().find('td').eq(2).should('contain', expectedAddress); + } + + verifyCity(expectedCity) { + cy.log(`Verifying City: ${expectedCity}`); + cy.get('#nestedElementsHistoryBox\\|Address tr').first().find('td').eq(3).should('contain', expectedCity); + } + + verifyState(expectedState) { + cy.log(`Verifying State: ${expectedState}`); + cy.get('#nestedElementsHistoryBox\\|Address tr').first().find('td').eq(4).should('contain', expectedState); + } + + verifyZip(expectedZip) { + cy.log(`Verifying Zip: ${expectedZip}`); + cy.get('#nestedElementsHistoryBox\\|Address tr').first().find('td').eq(5).should('contain', expectedZip); + } + + // Telephone Information verification + verifyTelephoneUse(expectedUse) { + cy.log(`Verifying Telephone Use: ${expectedUse}`); + cy.get('#nestedElementsHistoryBox\\|Telephone tr').first().find('td').eq(1).should('contain', expectedUse); + } + + verifyTelephoneType(expectedType) { + cy.log(`Verifying Telephone Type: ${expectedType}`); + cy.get('#nestedElementsHistoryBox\\|Telephone tr').first().find('td').eq(2).should('contain', expectedType); + } + + verifyTelephoneNumber(expectedNumber) { + cy.log(`Verifying Telephone Number: ${expectedNumber}`); + cy.get('#nestedElementsHistoryBox\\|Telephone tr').first().find('td').eq(3).should('contain', expectedNumber); + } + + // Combined verification method for all organization details + verifyAllOrganizationDetails() { + cy.log('Verifying all organization details'); + + // Administrative Information + this.verifyQuickCode('1'); + this.verifyStandardIndustryClass('Health Care and Social Assistance'); + this.verifyRole('Hospital'); + + // Name + this.verifyOrganizationName('Piedmont Hospital'); + + // Identification Information + this.verifyIdentificationType('Organization identifier'); + this.verifyIdentificationAuthority('CMS Provider'); + this.verifyIdentificationValue('CMS1234'); + + // Address Information + this.verifyAddressUse('Primary Work Place'); + this.verifyStreetAddress('1968 Peachtree Road NW'); + this.verifyCity('Atlanta'); + this.verifyState('Georgia'); + this.verifyZip('30056'); + + // Telephone Information + this.verifyTelephoneUse('Primary Work Place'); + this.verifyTelephoneType('Phone'); + this.verifyTelephoneNumber('404-605-5000'); + } + +} + +export default new ClassicOrganizationPage(); \ No newline at end of file diff --git a/testing/regression/cypress/step_definitions/organization.steps.js b/testing/regression/cypress/step_definitions/organization.steps.js new file mode 100644 index 0000000000..a89215cbf5 --- /dev/null +++ b/testing/regression/cypress/step_definitions/organization.steps.js @@ -0,0 +1,197 @@ +import { When, Then } from "@badeball/cypress-cucumber-preprocessor"; +import classicOrganizationPage from "../../e2e/pages/nbs-classic/organization.page"; +import editOrganizationPage from "../../e2e/pages/nbs-classic/editOrganization.page"; +import { maps } from "./organizationValueMaps"; +import { clickSubmitButton, clickAddButton } from "../../e2e/pages/nbs-classic/utils"; + +// Navigation and search steps +When("I navigate to classic organization Search pane", () => { + classicOrganizationPage.navigateToClassicOrganizationSearchPane() +}); + +When("I enter organization name in input text field {string}", (text) => { + classicOrganizationPage.enterOrganizationNameInSearch(text) +}); + +When("I enter a unique organization name in the name field", () => { + classicOrganizationPage.enterUniqueOrganizationNameInSearch() +}); + +When("I enter the same organization name in the Search Pane", () => { + classicOrganizationPage.enterSameOrganizationNameInSearchPane(); +}); + +When("I enter organization address in input text field {string}", (text) => { + classicOrganizationPage.enterOrganizationAddressInSearch(text) +}); + +When("I click on the Submit button", () => { + clickSubmitButton() +}); + +// Add organization steps + +When("I enter a random ID Value", () => { + editOrganizationPage.enterRandomIdValue() +}); + + +When("I select the role {string}", (roleName) => { + editOrganizationPage.selectRole(roleName) +}); + +When ("I click the Add button", () => { + clickAddButton() +}); + +When ("I select a random ID Type", () => { + editOrganizationPage.selectRandomIdType() +}); + +When ("I select a random Assigning Authority", () => { + editOrganizationPage.selectRandomAssigningAuthority() +}); + +When ("I click the Add Identification button", () => { + editOrganizationPage.clickAddIdentificationButton() +}); + +When("I add two new ID records with different ID Types and Assigning Authorities", () => { + classicOrganizationPage.addTwoNewIdRecords(); +}); + +When("I click View on the search results", () => { + classicOrganizationPage.clickViewOnSearchResults(); +}); + +// Address Information steps +When("I select address use {string}", (useDisplay) => { + editOrganizationPage.enterAddressUse(maps.addressUseToValue(useDisplay)); +}); + +When("I select address type {string}", (typeDisplay) => { + editOrganizationPage.enterAddressType(maps.addressTypeToValue(typeDisplay)); +}); + +When("I enter street address {string}", (address) => { + editOrganizationPage.enterStreetAddress1(address); +}); + +When("I enter city {string}", (city) => { + editOrganizationPage.enterCity(city); +}); + +When("I enter zip code {string}", (zip) => { + editOrganizationPage.enterZipCode(zip); +}); + +When("I click the Add Address button", () => { + editOrganizationPage.clickAddAddressButton(); +}); + + +// Telephone Information steps +When("I select telephone use {string}", (useDisplay) => { + editOrganizationPage.enterTelephoneUse(maps.telephoneUseToValue(useDisplay)); +}); + +When("I select telephone type {string}", (typeDisplay) => { + editOrganizationPage.enterTelephoneType(maps.telephoneTypeToValue(typeDisplay)); +}); + +When("I enter telephone number {string}, {string}, {string}", (areaCode, prefix, lineNumber) => { + editOrganizationPage.enterTelephoneNumber(areaCode, prefix, lineNumber); +}); + +When("I click the Add Telephone button", () => { + editOrganizationPage.clickAddTelephoneButton(); +}); + +When("I add a new telephone with use {string}, type {string}, number {string}-{string}-{string}", + (useDisplay, typeDisplay, areaCode, prefix, lineNumber) => { + editOrganizationPage.addNewTelephoneEntry({ + use: maps.telephoneUseToValue(useDisplay), + type: maps.telephoneTypeToValue(typeDisplay), + areaCode: areaCode, + prefix: prefix, + lineNumber: lineNumber + }); +}); + +// ID Information steps +When("I add a new ID record with type {string}, authority {string}, value {string}", + (typeDisplay, authorityDisplay, value) => { + editOrganizationPage.addNewIdEntry({ + type: maps.idTypeToValue(typeDisplay), + authority: maps.idAuthorityToValue(authorityDisplay), + idValue: value + }); +}); + + +// Edit organization steps +When("I click the Edit button", () => { + classicOrganizationPage.clickEditButton(); +}); + +When("I select {string} as the reason for edit", (reasonDisplay) => { + editOrganizationPage.selectEditReason(maps.editReasonToValue(reasonDisplay)); +}); + +When("I enter a unique quick code", () => { + editOrganizationPage.enterUniqueQuickCode(); +}); + +When("I delete the existing address", () => { + editOrganizationPage.deleteExistingAddress(); +}); + +// Inactivate organization steps +When("I click the Inactivate button", () => { + classicOrganizationPage.clickInactivateButton(); +}); + +When("I confirm the inactivation", () => { + classicOrganizationPage.acceptConfirmationPopup(); +}); + +// Verification steps +Then("the search results should include {string}", (expectedText) => { + classicOrganizationPage.verifySearchResultsContain(expectedText) +}); + +Then("there should be {int} search result(s)", (expectedCount) => { + classicOrganizationPage.verifySearchResultsCount(expectedCount); +}); + +Then("one of the search results should have the generated quick code", () => { + classicOrganizationPage.verifySearchResultContainsGeneratedQuickCode(); +}); + +Then("the search results should include address {string}", (expectedAddress) => { + classicOrganizationPage.verifySearchResultsContainAddress(expectedAddress) +}); + +Then("I should see a message that no matching organizations were found", () => { + classicOrganizationPage.verifyNoResultsFound() +}); + +Then("the organization should appear in search results", () => { + classicOrganizationPage.verifyOrganizationWasCreated(); +}); + +Then("I should see a success message", () => { + classicOrganizationPage.verifySuccessMessage() +}); + +Then("I should see all organization details are correct", () => { + classicOrganizationPage.verifyAllOrganizationDetails(); +}); + +Then("the search results should include telephone {string}", (expectedTelephone) => { + classicOrganizationPage.verifySearchResultsContainTelephone(expectedTelephone); +}); + +Then("the search results should include ID Type {string} with ID Value {string}", (expectedType, expectedValue) => { + classicOrganizationPage.verifySearchResultsContainIdTypeAndValue(expectedType, expectedValue); +}); \ No newline at end of file From a86a43c58bbbaf873ada67f0ce756721c21b55ed Mon Sep 17 00:00:00 2001 From: Krista Chan Date: Fri, 6 Mar 2026 10:33:00 -0800 Subject: [PATCH 02/14] Copied org test changes from NEDSSDev --- .../nbs-classic/editOrganization.page.js | 209 ++++++++++++++ .../pages/nbs-classic/organization.page.js | 257 ++++++++++++++++-- .../cypress/e2e/pages/nbs-classic/utils.js | 43 +++ 3 files changed, 489 insertions(+), 20 deletions(-) create mode 100644 testing/regression/cypress/e2e/pages/nbs-classic/editOrganization.page.js create mode 100644 testing/regression/cypress/e2e/pages/nbs-classic/utils.js diff --git a/testing/regression/cypress/e2e/pages/nbs-classic/editOrganization.page.js b/testing/regression/cypress/e2e/pages/nbs-classic/editOrganization.page.js new file mode 100644 index 0000000000..9b0b5b9575 --- /dev/null +++ b/testing/regression/cypress/e2e/pages/nbs-classic/editOrganization.page.js @@ -0,0 +1,209 @@ +import { selectRandomDropdownValue } from "./utils"; + +class EditOrganizationPage { + selectEditReason(reasonValue) { + cy.get(`input[type="radio"][value="${reasonValue}"]`, { timeout: 10000 }) + .should('be.visible') + .check({ force: true }); + cy.log(`Selected edit reason: ${reasonValue}`); + } + enterUniqueQuickCode() { + cy.log('Entering unique quick code'); + + // Generate a random 6-character alphanumeric string + const quickCode = Math.random().toString(36).substring(2, 8).toUpperCase(); + cy.log(`Generated quick code: ${quickCode}`); + + // Find the Quick Code input field and type the generated code + cy.get('input[name="quickCodeIdDT.rootExtensionTxt"]', { timeout: 10000 }) + .should('be.visible') + .clear() + .type(quickCode); + + // Store the generated quick code for later verification if needed + cy.wrap(quickCode).as('generatedQuickCode'); + } + selectRole(roleName) { + cy.log(`Selecting role: ${roleName}`); + cy.get('select#rolesList', { timeout: 10000 }) + .should('be.visible') + .select(roleName); + } + + selectRandomIdType() { + selectRandomDropdownValue('select[fieldlabel="ID Type"]'); + } + + selectRandomAssigningAuthority() { + selectRandomDropdownValue('select[header="Authority"]'); + } + enterRandomIdValue() { + cy.log('Entering random ID Value'); + + // Generate a random string (8 characters alphanumeric) + const randomId = Math.random().toString(36).substring(2, 10).toUpperCase(); + cy.log(`Random ID Value: ${randomId}`); + + // Find the ID Value textbox and type the random string + cy.get('[id="organization.entityIdDT_s[i].rootExtensionTxt"]', { timeout: 10000 }) + .should('be.visible') + .clear() + .type(randomId); + + cy.wrap(randomId).as('generatedIdValue'); + } + + clickAddIdentificationButton() { + cy.log('Clicking Add Identification button'); + + // Click the Add Identification button + cy.get('#BatchEntryAddButtonIdentification', { timeout: 10000 }) + .should('be.visible') + .click(); + + cy.log('Add Identification button clicked'); + + } + + + addNewIdEntry(idDetails) { + cy.log(`Adding new ID entry with Type: ${idDetails.type}, Authority: ${idDetails.authority}`); + + // Scroll to Identification section + cy.contains('Identification Information').scrollIntoView(); + + // Click the Type dropdown arrow and select + cy.get('[name="organization.entityIdDT_s[i].typeCd_button"]').click(); + cy.wait(500); + cy.get('select[name="organization.entityIdDT_s[i].typeCd"]').select(idDetails.type, { force: true }); + + // Click the Assigning Authority dropdown arrow and select + cy.get('[name="organization.entityIdDT_s[i].assigningAuthorityCd_button"]').click() + cy.wait(500); + cy.get('select[name="organization.entityIdDT_s[i].assigningAuthorityCd"]').select(idDetails.authority, { force: true }); + + cy.get('[id="organization.entityIdDT_s[i].rootExtensionTxt"]', { timeout: 10000 }) + .should('be.visible') + .clear() + .type(idDetails.idValue); + this.clickAddIdentificationButton(); + } + + deleteExistingAddress() { + cy.log('Deleting first address entry'); + + // Scroll to Address section + cy.contains('Address Information').scrollIntoView(); + + // Find the first address entry in the history box and click its Delete link + cy.get('#nestedElementsHistoryBox\\|Address tr', { timeout: 10000 }) + .first() + .within(() => { + cy.contains('Delete').click(); + }); + + cy.wait(500); // Wait for the deletion to process + } + + // Methods to add new contact information (telephone and address) + + addNewTelephoneEntry(telephoneDetails) { + cy.log(`Adding new telephone: ${telephoneDetails.areaCode}-${telephoneDetails.prefix}-${telephoneDetails.lineNumber}`); + + // Scroll to Telephone section + cy.contains('Telephone Information').scrollIntoView(); + + // Click the Use dropdown arrow and select + cy.get('[name="telephone[i].useCd_button"]').click(); + cy.wait(500); + cy.get('select[name="telephone[i].useCd"]').select(telephoneDetails.use, { force: true }); + + // Click the Type dropdown arrow and select + cy.get('[name="telephone[i].cd_button"]').click(); + cy.wait(500); + cy.get('select[name="telephone[i].cd"]').select(telephoneDetails.type, { force: true }); + + // Find empty phone number fields and fill them + cy.get('input[id*="phoneNbrTxt1"]').filter((i, el) => !el.value).first() + .clear().type(telephoneDetails.areaCode); + cy.get('input[id*="phoneNbrTxt2"]').filter((i, el) => !el.value).first() + .clear().type(telephoneDetails.prefix); + cy.get('input[id*="phoneNbrTxt3"]').filter((i, el) => !el.value).first() + .clear().type(telephoneDetails.lineNumber); + + // Click Add Telephone button + cy.get('#BatchEntryAddButtonTelephone').click(); + cy.wait(1000); + } + + enterTelephoneUse(useValue) { + cy.log(`Selecting telephone use: ${useValue}`); + cy.get('select[name="telephone[i].useCd"]').select(useValue, { force: true }); + } + + enterTelephoneType(typeValue) { + cy.log(`Selecting telephone type: ${typeValue}`); + cy.get('select[name="telephone[i].cd"]').select(typeValue, { force: true }); + } + + enterTelephoneNumber(areaCode, prefix, lineNumber) { + cy.log(`Entering telephone: ${areaCode}-${prefix}-${lineNumber}`); + cy.get('input[id*="phoneNbrTxt1"]').clear().type(areaCode); + cy.get('input[id*="phoneNbrTxt2"]').clear().type(prefix); + cy.get('input[id*="phoneNbrTxt3"]').clear().type(lineNumber); + } + + clickAddTelephoneButton() { + cy.log('Clicking Add Telephone button'); + cy.get('#BatchEntryAddButtonTelephone', { timeout: 10000 }) + .should('be.visible') + .click(); + cy.wait(500); + } + + enterAddressUse(useValue) { + cy.log(`Selecting address use: ${useValue}`); + cy.get('select[name="address[i].useCd"]').select(useValue, { force: true }); + } + + enterAddressType(typeValue) { + cy.log(`Selecting address type: ${typeValue}`); + cy.get('select[name="address[i].cd"]').select(typeValue, { force: true }); + } + + enterStreetAddress1(address) { + cy.log(`Entering street address: ${address}`); + cy.get('input[name="address[i].thePostalLocatorDT_s.streetAddr1"]') + .should('be.visible') + .clear() + .type(address); + } + + enterCity(city) { + cy.log(`Entering city: ${city}`); + cy.get('input[name="address[i].thePostalLocatorDT_s.cityDescTxt"]') + .should('be.visible') + .clear() + .type(city); + } + + enterZipCode(zip) { + cy.log(`Entering zip code: ${zip}`); + cy.get('input[name="address[i].thePostalLocatorDT_s.zipCd"]') + .should('be.visible') + .clear() + .type(zip); + } + + clickAddAddressButton() { + cy.log('Clicking Add Address button'); + cy.get('#BatchEntryAddButtonAddress', { timeout: 10000 }) + .should('be.visible') + .click(); + cy.wait(500); + } + + +} + +export default new EditOrganizationPage(); \ No newline at end of file diff --git a/testing/regression/cypress/e2e/pages/nbs-classic/organization.page.js b/testing/regression/cypress/e2e/pages/nbs-classic/organization.page.js index 209a4d9f75..62e40135a9 100644 --- a/testing/regression/cypress/e2e/pages/nbs-classic/organization.page.js +++ b/testing/regression/cypress/e2e/pages/nbs-classic/organization.page.js @@ -1,42 +1,259 @@ -class ClassicPatientSearchPage { +class ClassicOrganizationPage { + + // Navigation methods navigateToClassicOrganizationSearchPane() { cy.contains('Data Entry').eq(0).click() cy.contains('Organization').eq(0).click() } - enterNameInClassicSearchOrganizationPage(text) { - cy.get('input[id="organizationSearch.nmTxt"]').type(text).should('have.value', text) - cy.wait(1000) + // Search methods + enterOrganizationNameInSearch(name) { + cy.get('input[id="organizationSearch.nmTxt"]').type(name) + } + + enterOrganizationAddressInSearch(address) { + cy.get('input[id="organizationSearch.streetAddr1"]').type(address) + } + + enterUniqueOrganizationNameInSearch() { + const timestamp = Date.now(); + const uniqueName = `random string ${timestamp}`; + cy.log(`Using unique organization name: ${uniqueName}`); + cy.wrap(uniqueName).as('orgName'); + cy.get('input[id="organizationSearch.nmTxt"]').type(uniqueName) + cy.wrap(uniqueName).as('createdOrgName'); + } + + enterSameOrganizationNameInSearchPane() { + // Retrieve the name from the alias and use it + cy.get('@createdOrgName').then((orgName) => { + cy.log(`Using stored organization name in search pane: ${orgName}`); + cy.get('input[id="organizationSearch.nmTxt"]') + .should('be.visible') + .clear() + .type(orgName); + }); + } + // Add/Edit methods + + clickEditButton() { + cy.get('input[name="Edit"]').eq(0).click() + } + + /** + * Click the Inactivate button on the View Organization page + */ + clickInactivateButton() { + cy.log('Clicking Inactivate button'); + cy.get('#Inactivate').eq(0).click(); + } + acceptConfirmationPopup() { + cy.log('Accepting confirmation popup'); + + // Cypress automatically handles native browser dialogs + // This event listener will click OK on the confirm popup + cy.on('window:confirm', () => { + cy.log('Confirmation popup accepted'); + return true; // true clicks OK, false would click Cancel + }); + } + + // Navigation from search results to view + clickViewOnSearchResults() { + cy.log('Clicking View on search results'); + cy.contains('View').eq(0).click(); + } + + verifySearchResultsCount(expectedCount) { + cy.log(`Verifying search results message shows ${expectedCount} possible matches`); + + // Check the red text div for the expected count + cy.get('div.boldTenDkRed', { timeout: 10000 }) + .should('be.visible') + .and('contain', `resulted in ${expectedCount} possible matches`); + } + + // Verification methods + verifySearchResultsContain(expectedText) { + cy.log(`Verifying search results include: ${expectedText}`); + cy.get('#searchResultsTable', { timeout: 10000 }) + .should('be.visible') + .and('contain', expectedText); + } + + verifySearchResultContainsGeneratedQuickCode() { + cy.log('Verifying search result contains generated quick code'); + + cy.get('@generatedQuickCode').then((quickCode) => { + cy.log(`Looking for quick code: ${quickCode}`); + + cy.get('#searchResultsTable', { timeout: 10000 }) + .should('be.visible') + .and('contain', quickCode); + }); + } + + verifySearchResultsContainAddress(expectedAddress) { + cy.log(`Verifying search results include address: ${expectedAddress}`); + cy.get('#searchResultsTable', { timeout: 10000 }) + .should('be.visible') + .and('contain', expectedAddress); + } + + verifySearchResultsContainTelephone(expectedTelephone) { + cy.log(`Verifying search results include telephone: ${expectedTelephone}`); + cy.get('#searchResultsTable', { timeout: 10000 }) + .should('be.visible') + .and('contain', expectedTelephone); + } + + verifySearchResultsContainIdTypeAndValue(expectedType, expectedValue) { + cy.log(`Verifying search results include ID Type: ${expectedType} with ID Value: ${expectedValue}`); + cy.get('#searchResultsTable', { timeout: 10000 }) + .should('be.visible') + .and('contain', expectedType) + .and('contain', expectedValue); + } + + verifyNoResultsFound() { + cy.log('Verifying no results message'); + cy.get('div.boldTenDkRed', { timeout: 10000 }) + .should('be.visible') + .and('contain', 'resulted in 0 possible matches'); + cy.get('div.boldTenDkRed a') + .should('be.visible') + .and('contain', 'refine your search?'); + cy.get('#searchResultsTable') + .should('contain', 'There is no information to display'); + } + + verifyOrganizationWasCreated() { + cy.get('@createdOrgName').then((orgName) => { + cy.log(`Verifying search results include: ${orgName}`); + cy.get('#searchResultsTable', { timeout: 10000 }) + .should('be.visible') + .and('contain', orgName); + }); + + } + verifySuccessMessage() { + cy.url().should('include', 'ViewOrganization'); + cy.get('body').should('contain', 'created') + .or('contain', 'added') + .or('contain', 'successful'); + } + + // Administrative Information verification + verifyQuickCode(expectedValue) { + cy.log(`Verifying Quick Code: ${expectedValue}`); + cy.get('#test').should('contain', expectedValue); + } + + verifyStandardIndustryClass(expectedValue) { + cy.log(`Verifying Standard Industry Class: ${expectedValue}`); + cy.get('[id="organization.theOrganizationDT.standardIndustryClassCd"]').should('contain', expectedValue); + } + + verifyRole(expectedRole) { + cy.log(`Verifying Role: ${expectedRole}`); + cy.get('#rolesList').should('contain', expectedRole); + } + + // Name verification + verifyOrganizationName(expectedName) { + cy.log(`Verifying Organization Name: ${expectedName}`); + cy.get('#name\\.nmTxt').should('contain', expectedName); + } + + // Identification Information verification + verifyIdentificationType(expectedType) { + cy.log(`Verifying Identification Type: ${expectedType}`); + cy.get('#nestedElementsHistoryBox\\|Identification tr').first().find('td').eq(1).should('contain', expectedType); + } + + verifyIdentificationAuthority(expectedAuthority) { + cy.log(`Verifying Identification Authority: ${expectedAuthority}`); + cy.get('#nestedElementsHistoryBox\\|Identification tr').first().find('td').eq(2).should('contain', expectedAuthority); + } + + verifyIdentificationValue(expectedValue) { + cy.log(`Verifying Identification Value: ${expectedValue}`); + cy.get('#nestedElementsHistoryBox\\|Identification tr').first().find('td').eq(3).should('contain', expectedValue); + } + + // Address Information verification + verifyAddressUse(expectedUse) { + cy.log(`Verifying Address Use: ${expectedUse}`); + cy.get('#nestedElementsHistoryBox\\|Address tr').first().find('td').eq(1).should('contain', expectedUse); + } + + verifyStreetAddress(expectedAddress) { + cy.log(`Verifying Street Address: ${expectedAddress}`); + cy.get('#nestedElementsHistoryBox\\|Address tr').first().find('td').eq(2).should('contain', expectedAddress); + } + + verifyCity(expectedCity) { + cy.log(`Verifying City: ${expectedCity}`); + cy.get('#nestedElementsHistoryBox\\|Address tr').first().find('td').eq(3).should('contain', expectedCity); } - clickSearchBtnInClassicOrganizationSearchPane() { - cy.get('input[name="Submit"][id="Submit"]').eq(0).click() + verifyState(expectedState) { + cy.log(`Verifying State: ${expectedState}`); + cy.get('#nestedElementsHistoryBox\\|Address tr').first().find('td').eq(4).should('contain', expectedState); } - viewOrganizationDetails() { - cy.contains('View', { timeout: 10000 }).eq(0).click() + verifyZip(expectedZip) { + cy.log(`Verifying Zip: ${expectedZip}`); + cy.get('#nestedElementsHistoryBox\\|Address tr').first().find('td').eq(5).should('contain', expectedZip); } - navigateToAddOrganisation() { - this.navigateToClassicOrganizationSearchPane() - this.enterNameInClassicSearchOrganizationPage('test') - this.clickSearchBtnInClassicOrganizationSearchPane() + // Telephone Information verification + verifyTelephoneUse(expectedUse) { + cy.log(`Verifying Telephone Use: ${expectedUse}`); + cy.get('#nestedElementsHistoryBox\\|Telephone tr').first().find('td').eq(1).should('contain', expectedUse); } - clickAddButtonOnAddOrganisation() { - cy.get('#Add').eq(0).click() + verifyTelephoneType(expectedType) { + cy.log(`Verifying Telephone Type: ${expectedType}`); + cy.get('#nestedElementsHistoryBox\\|Telephone tr').first().find('td').eq(2).should('contain', expectedType); } - enterQuickCode() { - const newName = Math.random().toString(36).substring(2, 8) - cy.get('input[name="quickCodeIdDT.rootExtensionTxt"]').eq(0).type(newName) + verifyTelephoneNumber(expectedNumber) { + cy.log(`Verifying Telephone Number: ${expectedNumber}`); + cy.get('#nestedElementsHistoryBox\\|Telephone tr').first().find('td').eq(3).should('contain', expectedNumber); } - clickSubmitBtnOnOrganisation() { - cy.get('input[name="Submit"][id="Submit"]').eq(0).click() + // Combined verification method for all organization details + verifyAllOrganizationDetails() { + cy.log('Verifying all organization details'); + + // Administrative Information + this.verifyQuickCode('1'); + this.verifyStandardIndustryClass('Health Care and Social Assistance'); + this.verifyRole('Hospital'); + + // Name + this.verifyOrganizationName('Piedmont Hospital'); + + // Identification Information + this.verifyIdentificationType('Organization identifier'); + this.verifyIdentificationAuthority('CMS Provider'); + this.verifyIdentificationValue('CMS1234'); + + // Address Information + this.verifyAddressUse('Primary Work Place'); + this.verifyStreetAddress('1968 Peachtree Road NW'); + this.verifyCity('Atlanta'); + this.verifyState('Georgia'); + this.verifyZip('30056'); + + // Telephone Information + this.verifyTelephoneUse('Primary Work Place'); + this.verifyTelephoneType('Phone'); + this.verifyTelephoneNumber('404-605-5000'); } } -export default new ClassicPatientSearchPage(); +export default new ClassicOrganizationPage(); \ No newline at end of file diff --git a/testing/regression/cypress/e2e/pages/nbs-classic/utils.js b/testing/regression/cypress/e2e/pages/nbs-classic/utils.js new file mode 100644 index 0000000000..df1247aebf --- /dev/null +++ b/testing/regression/cypress/e2e/pages/nbs-classic/utils.js @@ -0,0 +1,43 @@ + +/** + * Utility functions for handling dropdowns + */ + +/** + * Select a random value from any dropdown + * @param {string} dropdownSelector - Selector for the dropdown element + * @returns {Cypress.Chainable} - The selected value + */ + +export function selectRandomDropdownValue(dropdownSelector) { + cy.log(`Selecting random value from dropdown: ${dropdownSelector}`); + + // Get all non-empty option values from the dropdown + cy.get(`${dropdownSelector} option:not([value=""])`).then(($options) => { + const optionCount = $options.length; + + if (optionCount === 0) { + cy.log('No options found in dropdown'); + return; + } + + cy.log(`Dropdown has ${optionCount} options`); + + // Create array of values and pick a random one + const optionValues = $options.toArray().map(opt => opt.value); + const randomValue = optionValues[Math.floor(Math.random() * optionCount)]; + + cy.log(`Selected value: ${randomValue}`); + + // Select the random value (using force: true in case the select is disabled) + cy.get(dropdownSelector).select(randomValue, { force: true }); + }); +} +export function clickSubmitButton() { + cy.get('input[name="Submit"][id="Submit"]').eq(0).click() + cy.wait(1000); +} + +export function clickAddButton() { + cy.get('#Add').eq(0).click() +} \ No newline at end of file From 0f7a21c899b4a5332f51b0468dcc8b06d00082d5 Mon Sep 17 00:00:00 2001 From: Krista Chan Date: Fri, 6 Mar 2026 11:47:01 -0800 Subject: [PATCH 03/14] fixes to imports --- .../features/nbs-classic/organization.feature | 193 +++++++++++++++- .../e2e/pages/editOrganization.page.js | 209 ------------------ .../step_definitions/organization.steps.js | 6 +- .../step_definitions/organizationValueMaps.js | 109 +++++++++ 4 files changed, 294 insertions(+), 223 deletions(-) delete mode 100644 testing/regression/cypress/e2e/pages/editOrganization.page.js create mode 100644 testing/regression/cypress/step_definitions/organizationValueMaps.js diff --git a/testing/regression/cypress/e2e/features/nbs-classic/organization.feature b/testing/regression/cypress/e2e/features/nbs-classic/organization.feature index 51957ed856..21f2dd5fb3 100644 --- a/testing/regression/cypress/e2e/features/nbs-classic/organization.feature +++ b/testing/regression/cypress/e2e/features/nbs-classic/organization.feature @@ -3,14 +3,185 @@ Feature: Classic NBS - Dedupe - User can view data in NBS Organization Search Pa Background: Given I am logged in as secure user and stay on classic - Scenario: Add organization - Then Navigate to classic organization add page - Then Click on Add button on organization add page - Then Enter quick code for new organisation - Then Click Submit button on organization add page - - Scenario: Search organization - Then Navigate to classic organization Search pane - Then Enter organization name in input text field "test" - Then Click on Search in classic organization Search pane - Then View organization details through classic search + # Data Entry Tests + + ## Search Organization + + Scenario: Verify organization exists by searching name + When I navigate to classic organization Search pane + And I enter organization name in input text field "Piedmont Hospital" + And I click on the Submit button + Then the search results should include "Piedmont Hospital" + + Scenario: Verify organization exists by searching address + When I navigate to classic organization Search pane + And I enter organization address in input text field "1364 Clifton Road" + And I click on the Submit button + Then the search results should include "Emory University Hospital" + And the search results should include address "1364 Clifton Road" + + Scenario: Add new organization with basic info + When I navigate to classic organization Search pane + And I enter a unique organization name in the name field + And I click on the Submit button + Then I should see a message that no matching organizations were found + And I click the Add button + And I select the role "Allergy clinic" + And I click on the Submit button + And I click the Add button + And I navigate to classic organization Search pane + And I enter the same organization name in the Search Pane + And I click on the Submit button + Then the organization should appear in search results + + Scenario: Add new organization with all info + When I navigate to classic organization Search pane + And I enter a unique organization name in the name field + And I click on the Submit button + Then I should see a message that no matching organizations were found + And I click the Add button + And I select a random ID Type + And I select a random Assigning Authority + And I enter a random ID Value + And I click the Add Identification button + And I select address use "Primary Work Place" + And I select address type "Office" + And I enter street address "1600 Clifton Road NE" + And I enter city "Atlanta" + And I enter zip code "30333" + And I click the Add Address button + And I select telephone use "Primary Work Place" + And I select telephone type "Phone" + And I enter telephone number "404", "639", "3311" + And I click the Add Telephone button + And I click on the Submit button + And I navigate to classic organization Search pane + And I enter the same organization name in the Search Pane + And I click on the Submit button + Then the organization should appear in search results + + ## View Organization + + Scenario: All organization details exist + When I navigate to classic organization Search pane + And I enter organization name in input text field "Piedmont Hospital" + And I click on the Submit button + And I click View on the search results + Then I should see all organization details are correct + + Scenario: Edit with overwrite + When I navigate to classic organization Search pane + And I enter organization name in input text field "CHOA - Scottish Rite" + And I click on the Submit button + And I click View on the search results + And I click the Edit button + And I select "Typographical error correction or additional information" as the reason for edit + And I select address use "Primary Work Place" + And I select address type "Office" + And I enter street address "1600 Clifton Road NE" + And I enter city "Atlanta" + And I enter zip code "30333" + And I click the Add Address button + And I select telephone use "Primary Work Place" + And I select telephone type "Phone" + And I enter telephone number "404", "639", "3311" + And I click the Add Telephone button + And I click on the Submit button + And I navigate to classic organization Search pane + And I enter organization name in input text field "CHOA - Scottish Rite" + And I click on the Submit button + Then the search results should include "CHOA - Scottish Rite" + And the search results should include address "1600 Clifton Road NE" + And the search results should include telephone "404-639-3311" + + Scenario: Edit with new organization + When I navigate to classic organization Search pane + And I enter organization name in input text field "CHOA - Scottish Rite" + And I click on the Submit button + And I click View on the search results + And I click the Edit button + And I select "A change to existing information for non typographical reasons" as the reason for edit + And I enter a unique quick code + And I delete the existing address + And I select address use "Organizational Contact" + And I select address type "Postal/Mailing" + And I enter street address "456 Main Street" + And I click the Add Address button + And I click on the Submit button + And I navigate to classic organization Search pane + And I enter organization name in input text field "CHOA - Scottish Rite" + And I click on the Submit button + Then there should be 2 search results + And one of the search results should have the generated quick code + And the search results should include address "456 Main Street" + + Scenario: Provide multiple contact records (two new telephone numbers) for organization + When I navigate to classic organization Search pane + And I enter organization name in input text field "Northside Hospital" + And I click on the Submit button + And I click View on the search results + And I click the Edit button + And I select "Typographical error correction or additional information" as the reason for edit + And I add a new telephone with use "Primary Work Place", type "Phone", number "770"-"555"-"1234" + And I add a new telephone with use "Alternate Work Place", type "Phone", number "678"-"555"-"5678" + And I click on the Submit button + And I navigate to classic organization Search pane + And I enter organization name in input text field "Northside Hospital" + And I click on the Submit button + Then the search results should include telephone "770-555-1234" + And the search results should include telephone "678-555-5678" + + Scenario: Provide multiple contact records (two new addresses) for organization + When I navigate to classic organization Search pane + And I enter organization name in input text field "St. Joseph's Hospital" + And I click on the Submit button + And I click View on the search results + And I click the Edit button + And I select "Typographical error correction or additional information" as the reason for edit + And I select address use "Alternate Work Place" + And I select address type "Office" + And I enter street address "123 Drury Lane" + And I enter city "Oakland" + And I enter zip code "94611" + And I click the Add Address button + And I select address use "Organizational Contact" + And I select address type "Postal/Mailing" + And I enter street address "456 Main Street" + And I enter city "Oakland" + And I enter zip code "94611" + And I click the Add Address button + And I click on the Submit button + And I navigate to classic organization Search pane + And I enter organization name in input text field "St. Joseph's Hospital" + And I click on the Submit button + Then the search results should include address "123 Drury Lane" + And the search results should include address "456 Main Street" + + Scenario: Provide multiple ID records for organization + When I navigate to classic organization Search pane + And I enter organization name in input text field "St. Joseph's Hospital" + And I click on the Submit button + And I click View on the search results + And I click the Edit button + And I select "Typographical error correction or additional information" as the reason for edit + And I add a new ID record with type "ABCs Hospital ID", authority "CMS Provider", value "CMS1234" + And I add a new ID record with type "Organization identifier", authority "CLIA (CMS)", value "CLIA5678" + And I click on the Submit button + And I navigate to classic organization Search pane + And I enter organization name in input text field "St. Joseph's Hospital" + And I click on the Submit button + Then the search results should include ID Type "ABCs Hospital ID" with ID Value "CMS1234" + And the search results should include ID Type "Organization identifier" with ID Value "CLIA5678" + + Scenario: Inactivate an existing organization + When I navigate to classic organization Search pane + And I enter organization name in input text field "Northside Hospital" + And I click on the Submit button + Then the search results should include "Northside Hospital" + When I click View on the search results + And I click the Inactivate button + When I confirm the inactivation + And I navigate to classic organization Search pane + And I enter organization name in input text field "Northside Hospital" + And I click on the Submit button + Then I should see a message that no matching organizations were found \ No newline at end of file diff --git a/testing/regression/cypress/e2e/pages/editOrganization.page.js b/testing/regression/cypress/e2e/pages/editOrganization.page.js deleted file mode 100644 index 9b0b5b9575..0000000000 --- a/testing/regression/cypress/e2e/pages/editOrganization.page.js +++ /dev/null @@ -1,209 +0,0 @@ -import { selectRandomDropdownValue } from "./utils"; - -class EditOrganizationPage { - selectEditReason(reasonValue) { - cy.get(`input[type="radio"][value="${reasonValue}"]`, { timeout: 10000 }) - .should('be.visible') - .check({ force: true }); - cy.log(`Selected edit reason: ${reasonValue}`); - } - enterUniqueQuickCode() { - cy.log('Entering unique quick code'); - - // Generate a random 6-character alphanumeric string - const quickCode = Math.random().toString(36).substring(2, 8).toUpperCase(); - cy.log(`Generated quick code: ${quickCode}`); - - // Find the Quick Code input field and type the generated code - cy.get('input[name="quickCodeIdDT.rootExtensionTxt"]', { timeout: 10000 }) - .should('be.visible') - .clear() - .type(quickCode); - - // Store the generated quick code for later verification if needed - cy.wrap(quickCode).as('generatedQuickCode'); - } - selectRole(roleName) { - cy.log(`Selecting role: ${roleName}`); - cy.get('select#rolesList', { timeout: 10000 }) - .should('be.visible') - .select(roleName); - } - - selectRandomIdType() { - selectRandomDropdownValue('select[fieldlabel="ID Type"]'); - } - - selectRandomAssigningAuthority() { - selectRandomDropdownValue('select[header="Authority"]'); - } - enterRandomIdValue() { - cy.log('Entering random ID Value'); - - // Generate a random string (8 characters alphanumeric) - const randomId = Math.random().toString(36).substring(2, 10).toUpperCase(); - cy.log(`Random ID Value: ${randomId}`); - - // Find the ID Value textbox and type the random string - cy.get('[id="organization.entityIdDT_s[i].rootExtensionTxt"]', { timeout: 10000 }) - .should('be.visible') - .clear() - .type(randomId); - - cy.wrap(randomId).as('generatedIdValue'); - } - - clickAddIdentificationButton() { - cy.log('Clicking Add Identification button'); - - // Click the Add Identification button - cy.get('#BatchEntryAddButtonIdentification', { timeout: 10000 }) - .should('be.visible') - .click(); - - cy.log('Add Identification button clicked'); - - } - - - addNewIdEntry(idDetails) { - cy.log(`Adding new ID entry with Type: ${idDetails.type}, Authority: ${idDetails.authority}`); - - // Scroll to Identification section - cy.contains('Identification Information').scrollIntoView(); - - // Click the Type dropdown arrow and select - cy.get('[name="organization.entityIdDT_s[i].typeCd_button"]').click(); - cy.wait(500); - cy.get('select[name="organization.entityIdDT_s[i].typeCd"]').select(idDetails.type, { force: true }); - - // Click the Assigning Authority dropdown arrow and select - cy.get('[name="organization.entityIdDT_s[i].assigningAuthorityCd_button"]').click() - cy.wait(500); - cy.get('select[name="organization.entityIdDT_s[i].assigningAuthorityCd"]').select(idDetails.authority, { force: true }); - - cy.get('[id="organization.entityIdDT_s[i].rootExtensionTxt"]', { timeout: 10000 }) - .should('be.visible') - .clear() - .type(idDetails.idValue); - this.clickAddIdentificationButton(); - } - - deleteExistingAddress() { - cy.log('Deleting first address entry'); - - // Scroll to Address section - cy.contains('Address Information').scrollIntoView(); - - // Find the first address entry in the history box and click its Delete link - cy.get('#nestedElementsHistoryBox\\|Address tr', { timeout: 10000 }) - .first() - .within(() => { - cy.contains('Delete').click(); - }); - - cy.wait(500); // Wait for the deletion to process - } - - // Methods to add new contact information (telephone and address) - - addNewTelephoneEntry(telephoneDetails) { - cy.log(`Adding new telephone: ${telephoneDetails.areaCode}-${telephoneDetails.prefix}-${telephoneDetails.lineNumber}`); - - // Scroll to Telephone section - cy.contains('Telephone Information').scrollIntoView(); - - // Click the Use dropdown arrow and select - cy.get('[name="telephone[i].useCd_button"]').click(); - cy.wait(500); - cy.get('select[name="telephone[i].useCd"]').select(telephoneDetails.use, { force: true }); - - // Click the Type dropdown arrow and select - cy.get('[name="telephone[i].cd_button"]').click(); - cy.wait(500); - cy.get('select[name="telephone[i].cd"]').select(telephoneDetails.type, { force: true }); - - // Find empty phone number fields and fill them - cy.get('input[id*="phoneNbrTxt1"]').filter((i, el) => !el.value).first() - .clear().type(telephoneDetails.areaCode); - cy.get('input[id*="phoneNbrTxt2"]').filter((i, el) => !el.value).first() - .clear().type(telephoneDetails.prefix); - cy.get('input[id*="phoneNbrTxt3"]').filter((i, el) => !el.value).first() - .clear().type(telephoneDetails.lineNumber); - - // Click Add Telephone button - cy.get('#BatchEntryAddButtonTelephone').click(); - cy.wait(1000); - } - - enterTelephoneUse(useValue) { - cy.log(`Selecting telephone use: ${useValue}`); - cy.get('select[name="telephone[i].useCd"]').select(useValue, { force: true }); - } - - enterTelephoneType(typeValue) { - cy.log(`Selecting telephone type: ${typeValue}`); - cy.get('select[name="telephone[i].cd"]').select(typeValue, { force: true }); - } - - enterTelephoneNumber(areaCode, prefix, lineNumber) { - cy.log(`Entering telephone: ${areaCode}-${prefix}-${lineNumber}`); - cy.get('input[id*="phoneNbrTxt1"]').clear().type(areaCode); - cy.get('input[id*="phoneNbrTxt2"]').clear().type(prefix); - cy.get('input[id*="phoneNbrTxt3"]').clear().type(lineNumber); - } - - clickAddTelephoneButton() { - cy.log('Clicking Add Telephone button'); - cy.get('#BatchEntryAddButtonTelephone', { timeout: 10000 }) - .should('be.visible') - .click(); - cy.wait(500); - } - - enterAddressUse(useValue) { - cy.log(`Selecting address use: ${useValue}`); - cy.get('select[name="address[i].useCd"]').select(useValue, { force: true }); - } - - enterAddressType(typeValue) { - cy.log(`Selecting address type: ${typeValue}`); - cy.get('select[name="address[i].cd"]').select(typeValue, { force: true }); - } - - enterStreetAddress1(address) { - cy.log(`Entering street address: ${address}`); - cy.get('input[name="address[i].thePostalLocatorDT_s.streetAddr1"]') - .should('be.visible') - .clear() - .type(address); - } - - enterCity(city) { - cy.log(`Entering city: ${city}`); - cy.get('input[name="address[i].thePostalLocatorDT_s.cityDescTxt"]') - .should('be.visible') - .clear() - .type(city); - } - - enterZipCode(zip) { - cy.log(`Entering zip code: ${zip}`); - cy.get('input[name="address[i].thePostalLocatorDT_s.zipCd"]') - .should('be.visible') - .clear() - .type(zip); - } - - clickAddAddressButton() { - cy.log('Clicking Add Address button'); - cy.get('#BatchEntryAddButtonAddress', { timeout: 10000 }) - .should('be.visible') - .click(); - cy.wait(500); - } - - -} - -export default new EditOrganizationPage(); \ No newline at end of file diff --git a/testing/regression/cypress/step_definitions/organization.steps.js b/testing/regression/cypress/step_definitions/organization.steps.js index a89215cbf5..e42fa0858c 100644 --- a/testing/regression/cypress/step_definitions/organization.steps.js +++ b/testing/regression/cypress/step_definitions/organization.steps.js @@ -1,8 +1,8 @@ import { When, Then } from "@badeball/cypress-cucumber-preprocessor"; -import classicOrganizationPage from "../../e2e/pages/nbs-classic/organization.page"; -import editOrganizationPage from "../../e2e/pages/nbs-classic/editOrganization.page"; +import classicOrganizationPage from "../e2e/pages/nbs-classic/organization.page"; +import editOrganizationPage from "../e2e/pages/nbs-classic/editOrganization.page"; import { maps } from "./organizationValueMaps"; -import { clickSubmitButton, clickAddButton } from "../../e2e/pages/nbs-classic/utils"; +import { clickSubmitButton, clickAddButton } from "../e2e/pages/nbs-classic/utils"; // Navigation and search steps When("I navigate to classic organization Search pane", () => { diff --git a/testing/regression/cypress/step_definitions/organizationValueMaps.js b/testing/regression/cypress/step_definitions/organizationValueMaps.js new file mode 100644 index 0000000000..6bac1eb0fc --- /dev/null +++ b/testing/regression/cypress/step_definitions/organizationValueMaps.js @@ -0,0 +1,109 @@ + +// ============================================================================ +// DISPLAY TEXT TO VALUE MAPPING FUNCTIONS +// ============================================================================ + +export const maps = { + /** + * Map address use display text to value + * @param {string} displayText - Display text (e.g., 'Primary Work Place') + * @returns {string} - Value code (e.g., 'WP') + */ + addressUseToValue(displayText) { + const map = { + 'Primary Work Place': 'WP', + 'Alternate Work Place': 'SB', + 'Organizational Contact': 'OC' + }; + return map[displayText] || displayText; + }, + + /** + * Map address type display text to value + * @param {string} displayText - Display text (e.g., 'Office') + * @returns {string} - Value code (e.g., 'O') + */ + addressTypeToValue(displayText) { + const map = { + 'Office': 'O', + 'Postal/Mailing': 'M' + }; + return map[displayText] || displayText; + }, + + /** + * Map telephone use display text to value + * @param {string} displayText - Display text (e.g., 'Primary Work Place') + * @returns {string} - Value code (e.g., 'WP') + */ + telephoneUseToValue(displayText) { + const map = { + 'Primary Work Place': 'WP', + 'Alternate Work Place': 'SB', + 'Organizational Contact': 'OC' + }; + return map[displayText] || displayText; + }, + + /** + * Map telephone type display text to value + * @param {string} displayText - Display text (e.g., 'Phone') + * @returns {string} - Value code (e.g., 'PH') + */ + telephoneTypeToValue(displayText) { + const map = { + 'Phone': 'PH', + 'FAX': 'FAX', + 'Answering service': 'AN' + }; + return map[displayText] || displayText; + }, + + /** + * Map ID type display text to value + * @param {string} displayText - Display text (e.g., 'ABCs Hospital ID') + * @returns {string} - Value code (e.g., 'ABC') + */ + idTypeToValue(displayText) { + const map = { + 'ABCs Hospital ID': 'ABC', + 'Clinical Laboratory Improvement Amendments': 'CLIA', + 'Facility ID': 'FI', + 'Manufacturer Identifier': 'MID', + 'National employer identifier': 'NE', + 'National health plan identifier': 'NH', + 'Organization identifier': 'XX', + 'Partner Services Site ID': 'PSID', + 'Other': 'OTH' + }; + return map[displayText] || displayText; + }, + + /** + * Map ID authority display text to value + * @param {string} displayText - Display text (e.g., 'CMS Provider') + * @returns {string} - Value code (e.g., 'CMS') + */ + idAuthorityToValue(displayText) { + const map = { + 'AHA': 'AHA', + 'CLIA (CMS)': 'CLIA', + 'CMS Provider': 'CMS', + 'Other': 'OTH' + }; + return map[displayText] || displayText; + }, + + /** + * Map edit reason display text to value + * @param {string} displayText - Display text + * @returns {string} - Value code ('c' or 'n') + */ + editReasonToValue(displayText) { + const map = { + 'Typographical error correction or additional information': 'c', + 'A change to existing information for non typographical reasons': 'n' + }; + return map[displayText] || displayText; + } +}; \ No newline at end of file From 4d905f45962813cc304e0bca508ca085330d21fa Mon Sep 17 00:00:00 2001 From: Krista Chan Date: Mon, 9 Mar 2026 12:59:59 -0700 Subject: [PATCH 04/14] Upload cypress screenshots github action to help debug CI test fails --- .github/workflows/Regression-tests.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/Regression-tests.yaml b/.github/workflows/Regression-tests.yaml index 24f84ef3d2..5d0b4fa1e8 100644 --- a/.github/workflows/Regression-tests.yaml +++ b/.github/workflows/Regression-tests.yaml @@ -52,3 +52,11 @@ jobs: with: name: cypress-report path: testing/regression/cypress-report.zip + + # Upload cypress screenshots + - name: Upload cypress screenshots + uses: actions/upload-artifact@v3 + if: ${{ !cancelled() }} + with: + name: cypress-screenshots + path: testing/regression/cypress/screenshots/ From 0f80902a218a99143f9c455d52999b50c5c21a59 Mon Sep 17 00:00:00 2001 From: Krista Chan Date: Mon, 9 Mar 2026 13:03:18 -0700 Subject: [PATCH 05/14] Update to v4 of upload artifact --- .github/workflows/Regression-tests.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Regression-tests.yaml b/.github/workflows/Regression-tests.yaml index 5d0b4fa1e8..5c7b99a928 100644 --- a/.github/workflows/Regression-tests.yaml +++ b/.github/workflows/Regression-tests.yaml @@ -52,10 +52,10 @@ jobs: with: name: cypress-report path: testing/regression/cypress-report.zip - + # Upload cypress screenshots - name: Upload cypress screenshots - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ !cancelled() }} with: name: cypress-screenshots From dea1582f1610f5eac897625427e81c6a21ef4fd2 Mon Sep 17 00:00:00 2001 From: Krista Chan Date: Mon, 9 Mar 2026 14:12:37 -0700 Subject: [PATCH 06/14] Add step to clean up old containers and volumes so CI tests run on fresh db each time --- .github/workflows/Regression-tests.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/Regression-tests.yaml b/.github/workflows/Regression-tests.yaml index 5c7b99a928..1e2fda23ba 100644 --- a/.github/workflows/Regression-tests.yaml +++ b/.github/workflows/Regression-tests.yaml @@ -18,6 +18,10 @@ jobs: steps: - name: Checkout uses: actions/checkout@v6 + + - name: Clean up old containers and volumes + working-directory: ./cdc-sandbox + run: docker compose down -v - name: Run containers working-directory: ./cdc-sandbox From 777584c02d9aedbf66d26d68f58e2f8d7996e99c Mon Sep 17 00:00:00 2001 From: Krista Chan Date: Mon, 9 Mar 2026 15:37:10 -0700 Subject: [PATCH 07/14] ci: Try not retrying to see if org test passes --- .github/workflows/Regression-tests.yaml | 11 ----------- testing/regression/cypress.config.js | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/.github/workflows/Regression-tests.yaml b/.github/workflows/Regression-tests.yaml index 1e2fda23ba..bda89d73e9 100644 --- a/.github/workflows/Regression-tests.yaml +++ b/.github/workflows/Regression-tests.yaml @@ -18,10 +18,6 @@ jobs: steps: - name: Checkout uses: actions/checkout@v6 - - - name: Clean up old containers and volumes - working-directory: ./cdc-sandbox - run: docker compose down -v - name: Run containers working-directory: ./cdc-sandbox @@ -57,10 +53,3 @@ jobs: name: cypress-report path: testing/regression/cypress-report.zip - # Upload cypress screenshots - - name: Upload cypress screenshots - uses: actions/upload-artifact@v4 - if: ${{ !cancelled() }} - with: - name: cypress-screenshots - path: testing/regression/cypress/screenshots/ diff --git a/testing/regression/cypress.config.js b/testing/regression/cypress.config.js index 6dfac9fc05..7facfa172d 100644 --- a/testing/regression/cypress.config.js +++ b/testing/regression/cypress.config.js @@ -51,7 +51,7 @@ module.exports = defineConfig({ }, retries: { // Configure retry attempts for `cypress run` - runMode: 1, + runMode: 0, // Configure retry attempts for `cypress open` openMode: 0, }, From c25510b8c7197f974761e197837142da7f5dd6dc Mon Sep 17 00:00:00 2001 From: Krista Chan Date: Mon, 9 Mar 2026 15:42:17 -0700 Subject: [PATCH 08/14] ci:get rid of extra organization.feature file --- .../cypress/e2e/features/organization.feature | 187 ------------------ 1 file changed, 187 deletions(-) delete mode 100644 testing/regression/cypress/e2e/features/organization.feature diff --git a/testing/regression/cypress/e2e/features/organization.feature b/testing/regression/cypress/e2e/features/organization.feature deleted file mode 100644 index 21f2dd5fb3..0000000000 --- a/testing/regression/cypress/e2e/features/organization.feature +++ /dev/null @@ -1,187 +0,0 @@ -Feature: Classic NBS - Dedupe - User can view data in NBS Organization Search Page - - Background: - Given I am logged in as secure user and stay on classic - - # Data Entry Tests - - ## Search Organization - - Scenario: Verify organization exists by searching name - When I navigate to classic organization Search pane - And I enter organization name in input text field "Piedmont Hospital" - And I click on the Submit button - Then the search results should include "Piedmont Hospital" - - Scenario: Verify organization exists by searching address - When I navigate to classic organization Search pane - And I enter organization address in input text field "1364 Clifton Road" - And I click on the Submit button - Then the search results should include "Emory University Hospital" - And the search results should include address "1364 Clifton Road" - - Scenario: Add new organization with basic info - When I navigate to classic organization Search pane - And I enter a unique organization name in the name field - And I click on the Submit button - Then I should see a message that no matching organizations were found - And I click the Add button - And I select the role "Allergy clinic" - And I click on the Submit button - And I click the Add button - And I navigate to classic organization Search pane - And I enter the same organization name in the Search Pane - And I click on the Submit button - Then the organization should appear in search results - - Scenario: Add new organization with all info - When I navigate to classic organization Search pane - And I enter a unique organization name in the name field - And I click on the Submit button - Then I should see a message that no matching organizations were found - And I click the Add button - And I select a random ID Type - And I select a random Assigning Authority - And I enter a random ID Value - And I click the Add Identification button - And I select address use "Primary Work Place" - And I select address type "Office" - And I enter street address "1600 Clifton Road NE" - And I enter city "Atlanta" - And I enter zip code "30333" - And I click the Add Address button - And I select telephone use "Primary Work Place" - And I select telephone type "Phone" - And I enter telephone number "404", "639", "3311" - And I click the Add Telephone button - And I click on the Submit button - And I navigate to classic organization Search pane - And I enter the same organization name in the Search Pane - And I click on the Submit button - Then the organization should appear in search results - - ## View Organization - - Scenario: All organization details exist - When I navigate to classic organization Search pane - And I enter organization name in input text field "Piedmont Hospital" - And I click on the Submit button - And I click View on the search results - Then I should see all organization details are correct - - Scenario: Edit with overwrite - When I navigate to classic organization Search pane - And I enter organization name in input text field "CHOA - Scottish Rite" - And I click on the Submit button - And I click View on the search results - And I click the Edit button - And I select "Typographical error correction or additional information" as the reason for edit - And I select address use "Primary Work Place" - And I select address type "Office" - And I enter street address "1600 Clifton Road NE" - And I enter city "Atlanta" - And I enter zip code "30333" - And I click the Add Address button - And I select telephone use "Primary Work Place" - And I select telephone type "Phone" - And I enter telephone number "404", "639", "3311" - And I click the Add Telephone button - And I click on the Submit button - And I navigate to classic organization Search pane - And I enter organization name in input text field "CHOA - Scottish Rite" - And I click on the Submit button - Then the search results should include "CHOA - Scottish Rite" - And the search results should include address "1600 Clifton Road NE" - And the search results should include telephone "404-639-3311" - - Scenario: Edit with new organization - When I navigate to classic organization Search pane - And I enter organization name in input text field "CHOA - Scottish Rite" - And I click on the Submit button - And I click View on the search results - And I click the Edit button - And I select "A change to existing information for non typographical reasons" as the reason for edit - And I enter a unique quick code - And I delete the existing address - And I select address use "Organizational Contact" - And I select address type "Postal/Mailing" - And I enter street address "456 Main Street" - And I click the Add Address button - And I click on the Submit button - And I navigate to classic organization Search pane - And I enter organization name in input text field "CHOA - Scottish Rite" - And I click on the Submit button - Then there should be 2 search results - And one of the search results should have the generated quick code - And the search results should include address "456 Main Street" - - Scenario: Provide multiple contact records (two new telephone numbers) for organization - When I navigate to classic organization Search pane - And I enter organization name in input text field "Northside Hospital" - And I click on the Submit button - And I click View on the search results - And I click the Edit button - And I select "Typographical error correction or additional information" as the reason for edit - And I add a new telephone with use "Primary Work Place", type "Phone", number "770"-"555"-"1234" - And I add a new telephone with use "Alternate Work Place", type "Phone", number "678"-"555"-"5678" - And I click on the Submit button - And I navigate to classic organization Search pane - And I enter organization name in input text field "Northside Hospital" - And I click on the Submit button - Then the search results should include telephone "770-555-1234" - And the search results should include telephone "678-555-5678" - - Scenario: Provide multiple contact records (two new addresses) for organization - When I navigate to classic organization Search pane - And I enter organization name in input text field "St. Joseph's Hospital" - And I click on the Submit button - And I click View on the search results - And I click the Edit button - And I select "Typographical error correction or additional information" as the reason for edit - And I select address use "Alternate Work Place" - And I select address type "Office" - And I enter street address "123 Drury Lane" - And I enter city "Oakland" - And I enter zip code "94611" - And I click the Add Address button - And I select address use "Organizational Contact" - And I select address type "Postal/Mailing" - And I enter street address "456 Main Street" - And I enter city "Oakland" - And I enter zip code "94611" - And I click the Add Address button - And I click on the Submit button - And I navigate to classic organization Search pane - And I enter organization name in input text field "St. Joseph's Hospital" - And I click on the Submit button - Then the search results should include address "123 Drury Lane" - And the search results should include address "456 Main Street" - - Scenario: Provide multiple ID records for organization - When I navigate to classic organization Search pane - And I enter organization name in input text field "St. Joseph's Hospital" - And I click on the Submit button - And I click View on the search results - And I click the Edit button - And I select "Typographical error correction or additional information" as the reason for edit - And I add a new ID record with type "ABCs Hospital ID", authority "CMS Provider", value "CMS1234" - And I add a new ID record with type "Organization identifier", authority "CLIA (CMS)", value "CLIA5678" - And I click on the Submit button - And I navigate to classic organization Search pane - And I enter organization name in input text field "St. Joseph's Hospital" - And I click on the Submit button - Then the search results should include ID Type "ABCs Hospital ID" with ID Value "CMS1234" - And the search results should include ID Type "Organization identifier" with ID Value "CLIA5678" - - Scenario: Inactivate an existing organization - When I navigate to classic organization Search pane - And I enter organization name in input text field "Northside Hospital" - And I click on the Submit button - Then the search results should include "Northside Hospital" - When I click View on the search results - And I click the Inactivate button - When I confirm the inactivation - And I navigate to classic organization Search pane - And I enter organization name in input text field "Northside Hospital" - And I click on the Submit button - Then I should see a message that no matching organizations were found \ No newline at end of file From 1c74b51913e70ca9d744e9d1353c6593048cdc08 Mon Sep 17 00:00:00 2001 From: Krista Chan Date: Mon, 9 Mar 2026 16:26:06 -0700 Subject: [PATCH 09/14] ci: bring back the retry --- testing/regression/cypress.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/regression/cypress.config.js b/testing/regression/cypress.config.js index 7facfa172d..6dfac9fc05 100644 --- a/testing/regression/cypress.config.js +++ b/testing/regression/cypress.config.js @@ -51,7 +51,7 @@ module.exports = defineConfig({ }, retries: { // Configure retry attempts for `cypress run` - runMode: 0, + runMode: 1, // Configure retry attempts for `cypress open` openMode: 0, }, From eaf6d902f5bcbb494568855119c9be0033618517 Mon Sep 17 00:00:00 2001 From: Krista Chan Date: Mon, 9 Mar 2026 16:38:35 -0700 Subject: [PATCH 10/14] test: use the previously entered unique organization for inactivate test so that we don't have to delete 'Northside Hospital' --- .../cypress/e2e/features/nbs-classic/organization.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testing/regression/cypress/e2e/features/nbs-classic/organization.feature b/testing/regression/cypress/e2e/features/nbs-classic/organization.feature index 21f2dd5fb3..43b4893a39 100644 --- a/testing/regression/cypress/e2e/features/nbs-classic/organization.feature +++ b/testing/regression/cypress/e2e/features/nbs-classic/organization.feature @@ -175,13 +175,13 @@ Feature: Classic NBS - Dedupe - User can view data in NBS Organization Search Pa Scenario: Inactivate an existing organization When I navigate to classic organization Search pane - And I enter organization name in input text field "Northside Hospital" + And I enter the the same organization name in the Search Pane And I click on the Submit button - Then the search results should include "Northside Hospital" + Then the organization should appear in search results When I click View on the search results And I click the Inactivate button When I confirm the inactivation And I navigate to classic organization Search pane - And I enter organization name in input text field "Northside Hospital" + And I enter the the same organization name in the Search Pane And I click on the Submit button Then I should see a message that no matching organizations were found \ No newline at end of file From f7d0e36147bff547c7db1fe43ea9f806e3ef2261 Mon Sep 17 00:00:00 2001 From: Krista Chan Date: Mon, 9 Mar 2026 17:32:29 -0700 Subject: [PATCH 11/14] Modify edit with new organization to check that result count increased by 1 --- .../features/nbs-classic/organization.feature | 20 +++++--- .../cypress/e2e/pages/organization.page.js | 47 ++++++++++++++++--- .../step_definitions/organization.steps.js | 8 +++- 3 files changed, 60 insertions(+), 15 deletions(-) diff --git a/testing/regression/cypress/e2e/features/nbs-classic/organization.feature b/testing/regression/cypress/e2e/features/nbs-classic/organization.feature index 43b4893a39..e8f05ed5f0 100644 --- a/testing/regression/cypress/e2e/features/nbs-classic/organization.feature +++ b/testing/regression/cypress/e2e/features/nbs-classic/organization.feature @@ -99,6 +99,7 @@ Feature: Classic NBS - Dedupe - User can view data in NBS Organization Search Pa And I enter organization name in input text field "CHOA - Scottish Rite" And I click on the Submit button And I click View on the search results + And I save the number of search results And I click the Edit button And I select "A change to existing information for non typographical reasons" as the reason for edit And I enter a unique quick code @@ -111,7 +112,7 @@ Feature: Classic NBS - Dedupe - User can view data in NBS Organization Search Pa And I navigate to classic organization Search pane And I enter organization name in input text field "CHOA - Scottish Rite" And I click on the Submit button - Then there should be 2 search results + Then there should be 1 more search result than before And one of the search results should have the generated quick code And the search results should include address "456 Main Street" @@ -174,14 +175,21 @@ Feature: Classic NBS - Dedupe - User can view data in NBS Organization Search Pa And the search results should include ID Type "Organization identifier" with ID Value "CLIA5678" Scenario: Inactivate an existing organization + When I navigate to classic organization Search pane - And I enter the the same organization name in the Search Pane + And I enter a unique organization name in the name field And I click on the Submit button - Then the organization should appear in search results - When I click View on the search results + And I click the Add button + And I select the role "Allergy clinic" + And I click on the Submit button + And I click the Add button + And I navigate to classic organization Search pane + And I enter the same organization name in the Search Pane + And I click on the Submit button + And I click View on the search results And I click the Inactivate button - When I confirm the inactivation + And I confirm the inactivation And I navigate to classic organization Search pane - And I enter the the same organization name in the Search Pane + And I enter the same organization name in the Search Pane And I click on the Submit button Then I should see a message that no matching organizations were found \ No newline at end of file diff --git a/testing/regression/cypress/e2e/pages/organization.page.js b/testing/regression/cypress/e2e/pages/organization.page.js index 62e40135a9..fb636c31e3 100644 --- a/testing/regression/cypress/e2e/pages/organization.page.js +++ b/testing/regression/cypress/e2e/pages/organization.page.js @@ -35,6 +35,26 @@ class ClassicOrganizationPage { .type(orgName); }); } + + saveSearchResultsCount() { + cy.log('Saving search results count'); + + // Get the text from the red result message + cy.get('div.boldTenDkRed', { timeout: 10000 }) + .should('be.visible') + .invoke('text') + .then((text) => { + // Extract the number from text like "resulted in 3 possible matches" + const match = text.match(/resulted in (\d+) possible matches/); + const count = match ? parseInt(match[1]) : 0; + + cy.log(`Found ${count} search results`); + + // Save to alias for later use + cy.wrap(count).as('searchResultsCount'); + }); + } + // Add/Edit methods clickEditButton() { @@ -65,13 +85,26 @@ class ClassicOrganizationPage { cy.contains('View').eq(0).click(); } - verifySearchResultsCount(expectedCount) { - cy.log(`Verifying search results message shows ${expectedCount} possible matches`); - - // Check the red text div for the expected count - cy.get('div.boldTenDkRed', { timeout: 10000 }) - .should('be.visible') - .and('contain', `resulted in ${expectedCount} possible matches`); + verifySearchResultsCountIncreasedBy(additionalCount) { + cy.log(`Verifying search results count increased by ${additionalCount}`); + // Get the previously saved count + cy.get('@searchResultsCount').then((savedCount) => { + const expectedCount = savedCount + additionalCount; + + cy.log(`Saved count: ${savedCount}, Expected: ${expectedCount} (${additionalCount > 0 ? '+' : ''}${additionalCount})`); + + // Check the current count from the red text + cy.get('div.boldTenDkRed', { timeout: 10000 }) + .should('be.visible') + .invoke('text') + .then((text) => { + const match = text.match(/resulted in (\d+) possible matches/); + const currentCount = match ? parseInt(match[1]) : 0; + + cy.log(`Current count: ${currentCount}`); + expect(currentCount).to.equal(expectedCount); + }); + }); } // Verification methods diff --git a/testing/regression/cypress/step_definitions/organization.steps.js b/testing/regression/cypress/step_definitions/organization.steps.js index e42fa0858c..e0e43f2b7e 100644 --- a/testing/regression/cypress/step_definitions/organization.steps.js +++ b/testing/regression/cypress/step_definitions/organization.steps.js @@ -21,6 +21,10 @@ When("I enter the same organization name in the Search Pane", () => { classicOrganizationPage.enterSameOrganizationNameInSearchPane(); }); +When("I save the number of search results", () => { + classicOrganizationPage.saveSearchResultsCount(); +}); + When("I enter organization address in input text field {string}", (text) => { classicOrganizationPage.enterOrganizationAddressInSearch(text) }); @@ -160,8 +164,8 @@ Then("the search results should include {string}", (expectedText) => { classicOrganizationPage.verifySearchResultsContain(expectedText) }); -Then("there should be {int} search result(s)", (expectedCount) => { - classicOrganizationPage.verifySearchResultsCount(expectedCount); +Then("there should be {int} more search result than before", (additionalResultCount) => { + classicOrganizationPage.verifySearchResultsCountIncreasedBy(additionalResultCount); }); Then("one of the search results should have the generated quick code", () => { From 2917cbad5fa20d21bb2d88ef5b62dc5c713a3a34 Mon Sep 17 00:00:00 2001 From: Krista Chan Date: Mon, 9 Mar 2026 17:53:57 -0700 Subject: [PATCH 12/14] test: Get rid of redundant modules and only keep the one in nbs-classic folder --- .../pages/nbs-classic/organization.page.js | 8 - .../cypress/e2e/pages/organization.page.js | 292 ------------------ .../nbs-classic/organization.steps.js | 203 ++++++++++-- .../step_definitions/organization.steps.js | 201 ------------ 4 files changed, 185 insertions(+), 519 deletions(-) delete mode 100644 testing/regression/cypress/e2e/pages/organization.page.js delete mode 100644 testing/regression/cypress/step_definitions/organization.steps.js diff --git a/testing/regression/cypress/e2e/pages/nbs-classic/organization.page.js b/testing/regression/cypress/e2e/pages/nbs-classic/organization.page.js index 62e40135a9..c3ed40139e 100644 --- a/testing/regression/cypress/e2e/pages/nbs-classic/organization.page.js +++ b/testing/regression/cypress/e2e/pages/nbs-classic/organization.page.js @@ -65,14 +65,6 @@ class ClassicOrganizationPage { cy.contains('View').eq(0).click(); } - verifySearchResultsCount(expectedCount) { - cy.log(`Verifying search results message shows ${expectedCount} possible matches`); - - // Check the red text div for the expected count - cy.get('div.boldTenDkRed', { timeout: 10000 }) - .should('be.visible') - .and('contain', `resulted in ${expectedCount} possible matches`); - } // Verification methods verifySearchResultsContain(expectedText) { diff --git a/testing/regression/cypress/e2e/pages/organization.page.js b/testing/regression/cypress/e2e/pages/organization.page.js deleted file mode 100644 index fb636c31e3..0000000000 --- a/testing/regression/cypress/e2e/pages/organization.page.js +++ /dev/null @@ -1,292 +0,0 @@ - -class ClassicOrganizationPage { - - // Navigation methods - navigateToClassicOrganizationSearchPane() { - cy.contains('Data Entry').eq(0).click() - cy.contains('Organization').eq(0).click() - } - - // Search methods - enterOrganizationNameInSearch(name) { - cy.get('input[id="organizationSearch.nmTxt"]').type(name) - } - - enterOrganizationAddressInSearch(address) { - cy.get('input[id="organizationSearch.streetAddr1"]').type(address) - } - - enterUniqueOrganizationNameInSearch() { - const timestamp = Date.now(); - const uniqueName = `random string ${timestamp}`; - cy.log(`Using unique organization name: ${uniqueName}`); - cy.wrap(uniqueName).as('orgName'); - cy.get('input[id="organizationSearch.nmTxt"]').type(uniqueName) - cy.wrap(uniqueName).as('createdOrgName'); - } - - enterSameOrganizationNameInSearchPane() { - // Retrieve the name from the alias and use it - cy.get('@createdOrgName').then((orgName) => { - cy.log(`Using stored organization name in search pane: ${orgName}`); - cy.get('input[id="organizationSearch.nmTxt"]') - .should('be.visible') - .clear() - .type(orgName); - }); - } - - saveSearchResultsCount() { - cy.log('Saving search results count'); - - // Get the text from the red result message - cy.get('div.boldTenDkRed', { timeout: 10000 }) - .should('be.visible') - .invoke('text') - .then((text) => { - // Extract the number from text like "resulted in 3 possible matches" - const match = text.match(/resulted in (\d+) possible matches/); - const count = match ? parseInt(match[1]) : 0; - - cy.log(`Found ${count} search results`); - - // Save to alias for later use - cy.wrap(count).as('searchResultsCount'); - }); - } - - // Add/Edit methods - - clickEditButton() { - cy.get('input[name="Edit"]').eq(0).click() - } - - /** - * Click the Inactivate button on the View Organization page - */ - clickInactivateButton() { - cy.log('Clicking Inactivate button'); - cy.get('#Inactivate').eq(0).click(); - } - acceptConfirmationPopup() { - cy.log('Accepting confirmation popup'); - - // Cypress automatically handles native browser dialogs - // This event listener will click OK on the confirm popup - cy.on('window:confirm', () => { - cy.log('Confirmation popup accepted'); - return true; // true clicks OK, false would click Cancel - }); - } - - // Navigation from search results to view - clickViewOnSearchResults() { - cy.log('Clicking View on search results'); - cy.contains('View').eq(0).click(); - } - - verifySearchResultsCountIncreasedBy(additionalCount) { - cy.log(`Verifying search results count increased by ${additionalCount}`); - // Get the previously saved count - cy.get('@searchResultsCount').then((savedCount) => { - const expectedCount = savedCount + additionalCount; - - cy.log(`Saved count: ${savedCount}, Expected: ${expectedCount} (${additionalCount > 0 ? '+' : ''}${additionalCount})`); - - // Check the current count from the red text - cy.get('div.boldTenDkRed', { timeout: 10000 }) - .should('be.visible') - .invoke('text') - .then((text) => { - const match = text.match(/resulted in (\d+) possible matches/); - const currentCount = match ? parseInt(match[1]) : 0; - - cy.log(`Current count: ${currentCount}`); - expect(currentCount).to.equal(expectedCount); - }); - }); - } - - // Verification methods - verifySearchResultsContain(expectedText) { - cy.log(`Verifying search results include: ${expectedText}`); - cy.get('#searchResultsTable', { timeout: 10000 }) - .should('be.visible') - .and('contain', expectedText); - } - - verifySearchResultContainsGeneratedQuickCode() { - cy.log('Verifying search result contains generated quick code'); - - cy.get('@generatedQuickCode').then((quickCode) => { - cy.log(`Looking for quick code: ${quickCode}`); - - cy.get('#searchResultsTable', { timeout: 10000 }) - .should('be.visible') - .and('contain', quickCode); - }); - } - - verifySearchResultsContainAddress(expectedAddress) { - cy.log(`Verifying search results include address: ${expectedAddress}`); - cy.get('#searchResultsTable', { timeout: 10000 }) - .should('be.visible') - .and('contain', expectedAddress); - } - - verifySearchResultsContainTelephone(expectedTelephone) { - cy.log(`Verifying search results include telephone: ${expectedTelephone}`); - cy.get('#searchResultsTable', { timeout: 10000 }) - .should('be.visible') - .and('contain', expectedTelephone); - } - - verifySearchResultsContainIdTypeAndValue(expectedType, expectedValue) { - cy.log(`Verifying search results include ID Type: ${expectedType} with ID Value: ${expectedValue}`); - cy.get('#searchResultsTable', { timeout: 10000 }) - .should('be.visible') - .and('contain', expectedType) - .and('contain', expectedValue); - } - - verifyNoResultsFound() { - cy.log('Verifying no results message'); - cy.get('div.boldTenDkRed', { timeout: 10000 }) - .should('be.visible') - .and('contain', 'resulted in 0 possible matches'); - cy.get('div.boldTenDkRed a') - .should('be.visible') - .and('contain', 'refine your search?'); - cy.get('#searchResultsTable') - .should('contain', 'There is no information to display'); - } - - verifyOrganizationWasCreated() { - cy.get('@createdOrgName').then((orgName) => { - cy.log(`Verifying search results include: ${orgName}`); - cy.get('#searchResultsTable', { timeout: 10000 }) - .should('be.visible') - .and('contain', orgName); - }); - - } - verifySuccessMessage() { - cy.url().should('include', 'ViewOrganization'); - cy.get('body').should('contain', 'created') - .or('contain', 'added') - .or('contain', 'successful'); - } - - // Administrative Information verification - verifyQuickCode(expectedValue) { - cy.log(`Verifying Quick Code: ${expectedValue}`); - cy.get('#test').should('contain', expectedValue); - } - - verifyStandardIndustryClass(expectedValue) { - cy.log(`Verifying Standard Industry Class: ${expectedValue}`); - cy.get('[id="organization.theOrganizationDT.standardIndustryClassCd"]').should('contain', expectedValue); - } - - verifyRole(expectedRole) { - cy.log(`Verifying Role: ${expectedRole}`); - cy.get('#rolesList').should('contain', expectedRole); - } - - // Name verification - verifyOrganizationName(expectedName) { - cy.log(`Verifying Organization Name: ${expectedName}`); - cy.get('#name\\.nmTxt').should('contain', expectedName); - } - - // Identification Information verification - verifyIdentificationType(expectedType) { - cy.log(`Verifying Identification Type: ${expectedType}`); - cy.get('#nestedElementsHistoryBox\\|Identification tr').first().find('td').eq(1).should('contain', expectedType); - } - - verifyIdentificationAuthority(expectedAuthority) { - cy.log(`Verifying Identification Authority: ${expectedAuthority}`); - cy.get('#nestedElementsHistoryBox\\|Identification tr').first().find('td').eq(2).should('contain', expectedAuthority); - } - - verifyIdentificationValue(expectedValue) { - cy.log(`Verifying Identification Value: ${expectedValue}`); - cy.get('#nestedElementsHistoryBox\\|Identification tr').first().find('td').eq(3).should('contain', expectedValue); - } - - // Address Information verification - verifyAddressUse(expectedUse) { - cy.log(`Verifying Address Use: ${expectedUse}`); - cy.get('#nestedElementsHistoryBox\\|Address tr').first().find('td').eq(1).should('contain', expectedUse); - } - - verifyStreetAddress(expectedAddress) { - cy.log(`Verifying Street Address: ${expectedAddress}`); - cy.get('#nestedElementsHistoryBox\\|Address tr').first().find('td').eq(2).should('contain', expectedAddress); - } - - verifyCity(expectedCity) { - cy.log(`Verifying City: ${expectedCity}`); - cy.get('#nestedElementsHistoryBox\\|Address tr').first().find('td').eq(3).should('contain', expectedCity); - } - - verifyState(expectedState) { - cy.log(`Verifying State: ${expectedState}`); - cy.get('#nestedElementsHistoryBox\\|Address tr').first().find('td').eq(4).should('contain', expectedState); - } - - verifyZip(expectedZip) { - cy.log(`Verifying Zip: ${expectedZip}`); - cy.get('#nestedElementsHistoryBox\\|Address tr').first().find('td').eq(5).should('contain', expectedZip); - } - - // Telephone Information verification - verifyTelephoneUse(expectedUse) { - cy.log(`Verifying Telephone Use: ${expectedUse}`); - cy.get('#nestedElementsHistoryBox\\|Telephone tr').first().find('td').eq(1).should('contain', expectedUse); - } - - verifyTelephoneType(expectedType) { - cy.log(`Verifying Telephone Type: ${expectedType}`); - cy.get('#nestedElementsHistoryBox\\|Telephone tr').first().find('td').eq(2).should('contain', expectedType); - } - - verifyTelephoneNumber(expectedNumber) { - cy.log(`Verifying Telephone Number: ${expectedNumber}`); - cy.get('#nestedElementsHistoryBox\\|Telephone tr').first().find('td').eq(3).should('contain', expectedNumber); - } - - // Combined verification method for all organization details - verifyAllOrganizationDetails() { - cy.log('Verifying all organization details'); - - // Administrative Information - this.verifyQuickCode('1'); - this.verifyStandardIndustryClass('Health Care and Social Assistance'); - this.verifyRole('Hospital'); - - // Name - this.verifyOrganizationName('Piedmont Hospital'); - - // Identification Information - this.verifyIdentificationType('Organization identifier'); - this.verifyIdentificationAuthority('CMS Provider'); - this.verifyIdentificationValue('CMS1234'); - - // Address Information - this.verifyAddressUse('Primary Work Place'); - this.verifyStreetAddress('1968 Peachtree Road NW'); - this.verifyCity('Atlanta'); - this.verifyState('Georgia'); - this.verifyZip('30056'); - - // Telephone Information - this.verifyTelephoneUse('Primary Work Place'); - this.verifyTelephoneType('Phone'); - this.verifyTelephoneNumber('404-605-5000'); - } - -} - -export default new ClassicOrganizationPage(); \ No newline at end of file diff --git a/testing/regression/cypress/step_definitions/nbs-classic/organization.steps.js b/testing/regression/cypress/step_definitions/nbs-classic/organization.steps.js index 0e81a0a525..ed7324ccc4 100644 --- a/testing/regression/cypress/step_definitions/nbs-classic/organization.steps.js +++ b/testing/regression/cypress/step_definitions/nbs-classic/organization.steps.js @@ -1,34 +1,201 @@ -import { Given, When, Then } from "@badeball/cypress-cucumber-preprocessor"; -import classicSearchOrganizationPage from "@pages/nbs-classic/organization.page"; +import { When, Then } from "@badeball/cypress-cucumber-preprocessor"; +import classicOrganizationPage from "../../e2e/pages/nbs-classic/organization.page"; +import editOrganizationPage from "../../e2e/pages/nbs-classic/editOrganization.page"; +import { maps } from "../organizationValueMaps"; +import { clickSubmitButton, clickAddButton } from "../../e2e/pages/nbs-classic/utils"; -Then("Navigate to classic organization Search pane", () => { - classicSearchOrganizationPage.navigateToClassicOrganizationSearchPane() +// Navigation and search steps +When("I navigate to classic organization Search pane", () => { + classicOrganizationPage.navigateToClassicOrganizationSearchPane() }); -Then("Enter organization name in input text field {string}", (text) => { - classicSearchOrganizationPage.enterNameInClassicSearchOrganizationPage(text) +When("I enter organization name in input text field {string}", (text) => { + classicOrganizationPage.enterOrganizationNameInSearch(text) }); -Then("Click on Search in classic organization Search pane", () => { - classicSearchOrganizationPage.clickSearchBtnInClassicOrganizationSearchPane() +When("I enter a unique organization name in the name field", () => { + classicOrganizationPage.enterUniqueOrganizationNameInSearch() }); -Then("View organization details through classic search", () => { - classicSearchOrganizationPage.viewOrganizationDetails() +When("I enter the same organization name in the Search Pane", () => { + classicOrganizationPage.enterSameOrganizationNameInSearchPane(); }); -Then("Navigate to classic organization add page", () => { - classicSearchOrganizationPage.navigateToAddOrganisation() +When("I save the number of search results", () => { + classicOrganizationPage.saveSearchResultsCount(); }); -Then("Click on Add button on organization add page", () => { - classicSearchOrganizationPage.clickAddButtonOnAddOrganisation() +When("I enter organization address in input text field {string}", (text) => { + classicOrganizationPage.enterOrganizationAddressInSearch(text) }); -Then("Enter quick code for new organisation", () => { - classicSearchOrganizationPage.enterQuickCode() +When("I click on the Submit button", () => { + clickSubmitButton() }); -Then("Click Submit button on organization add page", () => { - classicSearchOrganizationPage.clickSubmitBtnOnOrganisation() +// Add organization steps + +When("I enter a random ID Value", () => { + editOrganizationPage.enterRandomIdValue() +}); + + +When("I select the role {string}", (roleName) => { + editOrganizationPage.selectRole(roleName) +}); + +When ("I click the Add button", () => { + clickAddButton() +}); + +When ("I select a random ID Type", () => { + editOrganizationPage.selectRandomIdType() +}); + +When ("I select a random Assigning Authority", () => { + editOrganizationPage.selectRandomAssigningAuthority() +}); + +When ("I click the Add Identification button", () => { + editOrganizationPage.clickAddIdentificationButton() +}); + +When("I add two new ID records with different ID Types and Assigning Authorities", () => { + classicOrganizationPage.addTwoNewIdRecords(); +}); + +When("I click View on the search results", () => { + classicOrganizationPage.clickViewOnSearchResults(); +}); + +// Address Information steps +When("I select address use {string}", (useDisplay) => { + editOrganizationPage.enterAddressUse(maps.addressUseToValue(useDisplay)); +}); + +When("I select address type {string}", (typeDisplay) => { + editOrganizationPage.enterAddressType(maps.addressTypeToValue(typeDisplay)); +}); + +When("I enter street address {string}", (address) => { + editOrganizationPage.enterStreetAddress1(address); +}); + +When("I enter city {string}", (city) => { + editOrganizationPage.enterCity(city); +}); + +When("I enter zip code {string}", (zip) => { + editOrganizationPage.enterZipCode(zip); +}); + +When("I click the Add Address button", () => { + editOrganizationPage.clickAddAddressButton(); +}); + + +// Telephone Information steps +When("I select telephone use {string}", (useDisplay) => { + editOrganizationPage.enterTelephoneUse(maps.telephoneUseToValue(useDisplay)); +}); + +When("I select telephone type {string}", (typeDisplay) => { + editOrganizationPage.enterTelephoneType(maps.telephoneTypeToValue(typeDisplay)); +}); + +When("I enter telephone number {string}, {string}, {string}", (areaCode, prefix, lineNumber) => { + editOrganizationPage.enterTelephoneNumber(areaCode, prefix, lineNumber); +}); + +When("I click the Add Telephone button", () => { + editOrganizationPage.clickAddTelephoneButton(); }); + +When("I add a new telephone with use {string}, type {string}, number {string}-{string}-{string}", + (useDisplay, typeDisplay, areaCode, prefix, lineNumber) => { + editOrganizationPage.addNewTelephoneEntry({ + use: maps.telephoneUseToValue(useDisplay), + type: maps.telephoneTypeToValue(typeDisplay), + areaCode: areaCode, + prefix: prefix, + lineNumber: lineNumber + }); +}); + +// ID Information steps +When("I add a new ID record with type {string}, authority {string}, value {string}", + (typeDisplay, authorityDisplay, value) => { + editOrganizationPage.addNewIdEntry({ + type: maps.idTypeToValue(typeDisplay), + authority: maps.idAuthorityToValue(authorityDisplay), + idValue: value + }); +}); + + +// Edit organization steps +When("I click the Edit button", () => { + classicOrganizationPage.clickEditButton(); +}); + +When("I select {string} as the reason for edit", (reasonDisplay) => { + editOrganizationPage.selectEditReason(maps.editReasonToValue(reasonDisplay)); +}); + +When("I enter a unique quick code", () => { + editOrganizationPage.enterUniqueQuickCode(); +}); + +When("I delete the existing address", () => { + editOrganizationPage.deleteExistingAddress(); +}); + +// Inactivate organization steps +When("I click the Inactivate button", () => { + classicOrganizationPage.clickInactivateButton(); +}); + +When("I confirm the inactivation", () => { + classicOrganizationPage.acceptConfirmationPopup(); +}); + +// Verification steps +Then("the search results should include {string}", (expectedText) => { + classicOrganizationPage.verifySearchResultsContain(expectedText) +}); + +Then("there should be {int} more search result than before", (additionalResultCount) => { + classicOrganizationPage.verifySearchResultsCountIncreasedBy(additionalResultCount); +}); + +Then("one of the search results should have the generated quick code", () => { + classicOrganizationPage.verifySearchResultContainsGeneratedQuickCode(); +}); + +Then("the search results should include address {string}", (expectedAddress) => { + classicOrganizationPage.verifySearchResultsContainAddress(expectedAddress) +}); + +Then("I should see a message that no matching organizations were found", () => { + classicOrganizationPage.verifyNoResultsFound() +}); + +Then("the organization should appear in search results", () => { + classicOrganizationPage.verifyOrganizationWasCreated(); +}); + +Then("I should see a success message", () => { + classicOrganizationPage.verifySuccessMessage() +}); + +Then("I should see all organization details are correct", () => { + classicOrganizationPage.verifyAllOrganizationDetails(); +}); + +Then("the search results should include telephone {string}", (expectedTelephone) => { + classicOrganizationPage.verifySearchResultsContainTelephone(expectedTelephone); +}); + +Then("the search results should include ID Type {string} with ID Value {string}", (expectedType, expectedValue) => { + classicOrganizationPage.verifySearchResultsContainIdTypeAndValue(expectedType, expectedValue); +}); \ No newline at end of file diff --git a/testing/regression/cypress/step_definitions/organization.steps.js b/testing/regression/cypress/step_definitions/organization.steps.js deleted file mode 100644 index e0e43f2b7e..0000000000 --- a/testing/regression/cypress/step_definitions/organization.steps.js +++ /dev/null @@ -1,201 +0,0 @@ -import { When, Then } from "@badeball/cypress-cucumber-preprocessor"; -import classicOrganizationPage from "../e2e/pages/nbs-classic/organization.page"; -import editOrganizationPage from "../e2e/pages/nbs-classic/editOrganization.page"; -import { maps } from "./organizationValueMaps"; -import { clickSubmitButton, clickAddButton } from "../e2e/pages/nbs-classic/utils"; - -// Navigation and search steps -When("I navigate to classic organization Search pane", () => { - classicOrganizationPage.navigateToClassicOrganizationSearchPane() -}); - -When("I enter organization name in input text field {string}", (text) => { - classicOrganizationPage.enterOrganizationNameInSearch(text) -}); - -When("I enter a unique organization name in the name field", () => { - classicOrganizationPage.enterUniqueOrganizationNameInSearch() -}); - -When("I enter the same organization name in the Search Pane", () => { - classicOrganizationPage.enterSameOrganizationNameInSearchPane(); -}); - -When("I save the number of search results", () => { - classicOrganizationPage.saveSearchResultsCount(); -}); - -When("I enter organization address in input text field {string}", (text) => { - classicOrganizationPage.enterOrganizationAddressInSearch(text) -}); - -When("I click on the Submit button", () => { - clickSubmitButton() -}); - -// Add organization steps - -When("I enter a random ID Value", () => { - editOrganizationPage.enterRandomIdValue() -}); - - -When("I select the role {string}", (roleName) => { - editOrganizationPage.selectRole(roleName) -}); - -When ("I click the Add button", () => { - clickAddButton() -}); - -When ("I select a random ID Type", () => { - editOrganizationPage.selectRandomIdType() -}); - -When ("I select a random Assigning Authority", () => { - editOrganizationPage.selectRandomAssigningAuthority() -}); - -When ("I click the Add Identification button", () => { - editOrganizationPage.clickAddIdentificationButton() -}); - -When("I add two new ID records with different ID Types and Assigning Authorities", () => { - classicOrganizationPage.addTwoNewIdRecords(); -}); - -When("I click View on the search results", () => { - classicOrganizationPage.clickViewOnSearchResults(); -}); - -// Address Information steps -When("I select address use {string}", (useDisplay) => { - editOrganizationPage.enterAddressUse(maps.addressUseToValue(useDisplay)); -}); - -When("I select address type {string}", (typeDisplay) => { - editOrganizationPage.enterAddressType(maps.addressTypeToValue(typeDisplay)); -}); - -When("I enter street address {string}", (address) => { - editOrganizationPage.enterStreetAddress1(address); -}); - -When("I enter city {string}", (city) => { - editOrganizationPage.enterCity(city); -}); - -When("I enter zip code {string}", (zip) => { - editOrganizationPage.enterZipCode(zip); -}); - -When("I click the Add Address button", () => { - editOrganizationPage.clickAddAddressButton(); -}); - - -// Telephone Information steps -When("I select telephone use {string}", (useDisplay) => { - editOrganizationPage.enterTelephoneUse(maps.telephoneUseToValue(useDisplay)); -}); - -When("I select telephone type {string}", (typeDisplay) => { - editOrganizationPage.enterTelephoneType(maps.telephoneTypeToValue(typeDisplay)); -}); - -When("I enter telephone number {string}, {string}, {string}", (areaCode, prefix, lineNumber) => { - editOrganizationPage.enterTelephoneNumber(areaCode, prefix, lineNumber); -}); - -When("I click the Add Telephone button", () => { - editOrganizationPage.clickAddTelephoneButton(); -}); - -When("I add a new telephone with use {string}, type {string}, number {string}-{string}-{string}", - (useDisplay, typeDisplay, areaCode, prefix, lineNumber) => { - editOrganizationPage.addNewTelephoneEntry({ - use: maps.telephoneUseToValue(useDisplay), - type: maps.telephoneTypeToValue(typeDisplay), - areaCode: areaCode, - prefix: prefix, - lineNumber: lineNumber - }); -}); - -// ID Information steps -When("I add a new ID record with type {string}, authority {string}, value {string}", - (typeDisplay, authorityDisplay, value) => { - editOrganizationPage.addNewIdEntry({ - type: maps.idTypeToValue(typeDisplay), - authority: maps.idAuthorityToValue(authorityDisplay), - idValue: value - }); -}); - - -// Edit organization steps -When("I click the Edit button", () => { - classicOrganizationPage.clickEditButton(); -}); - -When("I select {string} as the reason for edit", (reasonDisplay) => { - editOrganizationPage.selectEditReason(maps.editReasonToValue(reasonDisplay)); -}); - -When("I enter a unique quick code", () => { - editOrganizationPage.enterUniqueQuickCode(); -}); - -When("I delete the existing address", () => { - editOrganizationPage.deleteExistingAddress(); -}); - -// Inactivate organization steps -When("I click the Inactivate button", () => { - classicOrganizationPage.clickInactivateButton(); -}); - -When("I confirm the inactivation", () => { - classicOrganizationPage.acceptConfirmationPopup(); -}); - -// Verification steps -Then("the search results should include {string}", (expectedText) => { - classicOrganizationPage.verifySearchResultsContain(expectedText) -}); - -Then("there should be {int} more search result than before", (additionalResultCount) => { - classicOrganizationPage.verifySearchResultsCountIncreasedBy(additionalResultCount); -}); - -Then("one of the search results should have the generated quick code", () => { - classicOrganizationPage.verifySearchResultContainsGeneratedQuickCode(); -}); - -Then("the search results should include address {string}", (expectedAddress) => { - classicOrganizationPage.verifySearchResultsContainAddress(expectedAddress) -}); - -Then("I should see a message that no matching organizations were found", () => { - classicOrganizationPage.verifyNoResultsFound() -}); - -Then("the organization should appear in search results", () => { - classicOrganizationPage.verifyOrganizationWasCreated(); -}); - -Then("I should see a success message", () => { - classicOrganizationPage.verifySuccessMessage() -}); - -Then("I should see all organization details are correct", () => { - classicOrganizationPage.verifyAllOrganizationDetails(); -}); - -Then("the search results should include telephone {string}", (expectedTelephone) => { - classicOrganizationPage.verifySearchResultsContainTelephone(expectedTelephone); -}); - -Then("the search results should include ID Type {string} with ID Value {string}", (expectedType, expectedValue) => { - classicOrganizationPage.verifySearchResultsContainIdTypeAndValue(expectedType, expectedValue); -}); \ No newline at end of file From 2cb1eeabcbdf5bafe3c46b5b25f606ec19812783 Mon Sep 17 00:00:00 2001 From: Krista Chan Date: Mon, 9 Mar 2026 17:57:45 -0700 Subject: [PATCH 13/14] test: Functions to check that search results incremented by X --- .../pages/nbs-classic/organization.page.js | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/testing/regression/cypress/e2e/pages/nbs-classic/organization.page.js b/testing/regression/cypress/e2e/pages/nbs-classic/organization.page.js index c3ed40139e..1363c55070 100644 --- a/testing/regression/cypress/e2e/pages/nbs-classic/organization.page.js +++ b/testing/regression/cypress/e2e/pages/nbs-classic/organization.page.js @@ -35,6 +35,26 @@ class ClassicOrganizationPage { .type(orgName); }); } + + saveSearchResultsCount() { + cy.log('Saving search results count'); + + // Get the text from the red result message + cy.get('div.boldTenDkRed', { timeout: 10000 }) + .should('be.visible') + .invoke('text') + .then((text) => { + // Extract the number from text like "resulted in 3 possible matches" + const match = text.match(/resulted in (\d+) possible matches/); + const count = match ? parseInt(match[1]) : 0; + + cy.log(`Found ${count} search results`); + + // Save to alias for later use + cy.wrap(count).as('searchResultsCount'); + }); + } + // Add/Edit methods clickEditButton() { @@ -136,6 +156,30 @@ class ClassicOrganizationPage { .or('contain', 'successful'); } + verifySearchResultsCountIncreasedBy(additionalCount) { + cy.log(`Verifying search results count increased by ${additionalCount}`); + + // Get the previously saved count + cy.get('@searchResultsCount').then((savedCount) => { + const expectedCount = savedCount + additionalCount; + + cy.log(`Saved count: ${savedCount}, Expected: ${expectedCount} (${additionalCount > 0 ? '+' : ''}${additionalCount})`); + + // Check the current count from the red text + cy.get('div.boldTenDkRed', { timeout: 10000 }) + .should('be.visible') + .invoke('text') + .then((text) => { + const match = text.match(/resulted in (\d+) possible matches/); + const currentCount = match ? parseInt(match[1]) : 0; + + cy.log(`Current count: ${currentCount}`); + expect(currentCount).to.equal(expectedCount); + }); + }); + } + + // Administrative Information verification verifyQuickCode(expectedValue) { cy.log(`Verifying Quick Code: ${expectedValue}`); From e086321439c21921810270cff06db75a791d955e Mon Sep 17 00:00:00 2001 From: Krista Chan Date: Mon, 9 Mar 2026 17:59:00 -0700 Subject: [PATCH 14/14] test:fix test step order typo --- .../cypress/e2e/features/nbs-classic/organization.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/regression/cypress/e2e/features/nbs-classic/organization.feature b/testing/regression/cypress/e2e/features/nbs-classic/organization.feature index e8f05ed5f0..c141cc20bf 100644 --- a/testing/regression/cypress/e2e/features/nbs-classic/organization.feature +++ b/testing/regression/cypress/e2e/features/nbs-classic/organization.feature @@ -98,8 +98,8 @@ Feature: Classic NBS - Dedupe - User can view data in NBS Organization Search Pa When I navigate to classic organization Search pane And I enter organization name in input text field "CHOA - Scottish Rite" And I click on the Submit button - And I click View on the search results And I save the number of search results + And I click View on the search results And I click the Edit button And I select "A change to existing information for non typographical reasons" as the reason for edit And I enter a unique quick code