diff --git a/benefit-finder/cypress/e2e/storybook/dataLayer.cy.js b/benefit-finder/cypress/e2e/storybook/dataLayer.cy.js index 31dc6e51a..777a74f82 100644 --- a/benefit-finder/cypress/e2e/storybook/dataLayer.cy.js +++ b/benefit-finder/cypress/e2e/storybook/dataLayer.cy.js @@ -4,43 +4,178 @@ import { dataLayerUtils } from '../../../src/shared/utils' import { pageObjects } from '../../support/pageObjects' import * as EN_LOCALE_DATA from '../../../../benefit-finder/src/shared/locales/en/en.json' import * as BENEFITS_ELIBILITY_DATA from '../../fixtures/benefits-eligibility.json' +import content from '../../../src/shared/api/mock-data/current.json' +// establish some common data points from our mock values and scenarios const { intro, lifeEventSection, resultsView, openAllBenefitAccordions } = dataLayerUtils.dataLayerStructure +const { lifeEventForm } = content.data +const selectedData = BENEFITS_ELIBILITY_DATA.scenario_1_covid.en.param +const enResults = BENEFITS_ELIBILITY_DATA.scenario_1_covid.en.results +const zero_benefit_view = BENEFITS_ELIBILITY_DATA.zero_benefit_view.en.results +const scenario = utils.encodeURIFromObject(selectedData) +const wait = 1000 -const dataLayerValues = [ - { - event: intro.event, - bfData: { - pageView: intro.bfData.pageView, - viewTitle: 'Benefit finder: death of a loved one', - }, - }, - { - event: lifeEventSection.event, - bfData: { - pageView: `${lifeEventSection.bfData.pageView}-1`, - viewTitle: 'About the applicant', - }, - }, - { - event: resultsView.event, - bfData: { - pageView: resultsView.bfData.pageView[0], - viewTitle: 'Your potential benefits', - eligibleBenefitCount: { number: 4, string: '4' }, - moreInfoBenefitCount: { number: 1, string: '1' }, - notEligibleBenefitCount: { number: 25, string: '25' }, - }, - }, - { - event: openAllBenefitAccordions.event, - bfData: { - accordionsOpen: openAllBenefitAccordions.bfData.accordionsOpen, - }, +// calculate out elibibility counts we expect for our event values +const eligibilityCount = { + eligibleBenefitCount: { + number: enResults.eligible.length, + string: `${enResults.eligible.length}`, + }, + moreInfoBenefitCount: { + number: enResults.moreInformationNeeded.length, + string: `${enResults.moreInformationNeeded.length}`, + }, + notEligibleBenefitCount: { + number: + enResults.total_benefits - + (enResults.eligible.length + enResults.moreInformationNeeded.length), + string: `${ + enResults.total_benefits - + (enResults.eligible.length + enResults.moreInformationNeeded.length) + }`, + }, +} + +const zeroBenefitsEligibilityCount = { + eligibleBenefitCount: { + number: zero_benefit_view.eligible.length, + string: `${zero_benefit_view.eligible.length}`, + }, + moreInfoBenefitCount: { + number: zero_benefit_view.moreInformationNeeded.length, + string: `${zero_benefit_view.moreInformationNeeded.length}`, + }, + notEligibleBenefitCount: { + number: + zero_benefit_view.total_benefits - + (zero_benefit_view.eligible.length + + zero_benefit_view.moreInformationNeeded.length), + string: `${ + zero_benefit_view.total_benefits - + (zero_benefit_view.eligible.length + + zero_benefit_view.moreInformationNeeded.length) + }`, + }, +} + +// create an object for each of our dataLayer assertions +const dataLayerValueIntro = { + event: intro.event, + bfData: { + pageView: intro.bfData.pageView, + viewTitle: lifeEventForm.title, + }, +} + +const dataLayerValueFormStepOne = { + event: lifeEventSection.event, + bfData: { + pageView: `${lifeEventSection.bfData.pageView}-1`, + viewTitle: lifeEventForm.sectionsEligibilityCriteria[0].section.heading, + }, +} + +const dataLayerValueFormStepTwo = { + event: lifeEventSection.event, + bfData: { + pageView: `${lifeEventSection.bfData.pageView}-2`, + viewTitle: lifeEventForm.sectionsEligibilityCriteria[1].section.heading, + }, +} + +const dataLayerValueResultsViewEligible = { + event: resultsView.event, + bfData: { + pageView: resultsView.bfData.pageView[0], + viewTitle: EN_LOCALE_DATA.resultsView.eligible.chevron.heading, + ...eligibilityCount, + }, +} + +const dataLayerValueResultsViewNotEligible = { + event: resultsView.event, + bfData: { + pageView: resultsView.bfData.pageView[1], + viewTitle: EN_LOCALE_DATA.resultsView.notEligible.chevron.heading, + ...eligibilityCount, + }, +} + +const dataLayerValueOpenAllAccordions = { + event: openAllBenefitAccordions.event, + bfData: { + accordionsOpen: openAllBenefitAccordions.bfData.accordionsOpen, + }, +} + +const dataLayerValueAccordionOpen = { + event: 'bf_accordion_open', + bfData: { + benefitTitle: enResults.eligible.eligible_benefits[0], + }, +} + +const dataLayerValueBenefitLink = { + event: 'bf_benefit_link', + bfData: { + benefitTitle: enResults.eligible.eligible_benefits[0], + }, +} + +const dataLayerValueFormCompletionModal = { + event: 'bf_page_change', + bfData: { + pageView: 'bf-form-completion-modal', + viewTitle: `${lifeEventForm.sectionsEligibilityCriteria[1].section.heading} modal`, + }, +} + +const dataLayerValueVerifySecletions = { + event: 'bf_page_change', + bfData: { + pageView: 'bf-verify-selections', + viewTitle: EN_LOCALE_DATA.verifySelectionsView.heading, + }, +} + +const dataLayerValueZeroResultsViewEligible = { + event: resultsView.event, + bfData: { + pageView: resultsView.bfData.pageView[0], + viewTitle: EN_LOCALE_DATA.resultsView.zeroBenefits.eligible.chevron.heading, + ...zeroBenefitsEligibilityCount, + }, +} + +const dataLayerValueZeroResultsViewNotEligible = { + event: resultsView.event, + bfData: { + pageView: resultsView.bfData.pageView[1], + viewTitle: + EN_LOCALE_DATA.resultsView.zeroBenefits.notEligible.chevron.heading, + ...zeroBenefitsEligibilityCount, }, +} + +// create a combined dataLayer assertions array, this is what we might expect to see for a user journey value that triggers all the events expected +const dataLayerValues = [ + dataLayerValueIntro, + dataLayerValueFormStepOne, + dataLayerValueFormStepTwo, + dataLayerValueFormCompletionModal, + dataLayerValueVerifySecletions, + dataLayerValueZeroResultsViewEligible, + dataLayerValueZeroResultsViewNotEligible, + dataLayerValueOpenAllAccordions, + { ...dataLayerValueOpenAllAccordions, bfData: { accordionsOpen: false } }, + dataLayerValueAccordionOpen, + dataLayerValueBenefitLink, ] +const removeID = item => delete item['gtm.uniqueEventId'] + +// check to make sure our data layer exists describe('Basic Data Layer Checks', () => { it('has a dataLayer and loads GTM', () => { cy.visit(utils.storybookUri) @@ -68,14 +203,93 @@ describe('Calls to Google Analytics Object', function () { .then(() => { // get the last pushed event const ev = { ...window.dataLayer[window.dataLayer.length - 1] } - delete ev['gtm.uniqueEventId'] + removeID(ev) - expect(ev).to.deep.equal(dataLayerValues[0]) + expect(ev).to.deep.equal(dataLayerValueIntro) }) }) }) - it('homepage has a bf_page_change event', function () { + it('first form step bf_page_change event', function () { + cy.visit(utils.storybookUri) + pageObjects.button().contains(EN_LOCALE_DATA.intro.button).click() + + cy.window().then(window => { + assert.isDefined(window.dataLayer, 'window.dataLayer is defined') + + pageObjects + .button() + .contains(EN_LOCALE_DATA.buttonGroup[1].value) + .then(() => { + // get the last pushed event + const ev = { ...window.dataLayer[window.dataLayer.length - 1] } + removeID(ev) + + expect(ev).to.deep.equal(dataLayerValueFormStepOne) + }) + }) + }) + + it('second form step bf_page_change event, asserts incrmenting values', function () { + cy.visit(utils.storybookUri) + pageObjects.button().contains(EN_LOCALE_DATA.intro.button).click() + + cy.window().then(window => { + assert.isDefined(window.dataLayer, 'window.dataLayer is defined') + + pageObjects + .button() + .contains(EN_LOCALE_DATA.buttonGroup[1].value) + .then(() => { + // get the last pushed event + const ev = { ...window.dataLayer[window.dataLayer.length - 1] } + removeID(ev) + + expect(ev).to.deep.equal(dataLayerValueFormStepOne) + + // fill out required fields + const dateOfBirth = utils.getDateByOffset(-(18 * 365.2425 - 1)) + cy.visit('/iframe.html?args=&id=app--primary&viewMode=story') + + pageObjects.button().contains(EN_LOCALE_DATA.intro.button).click() + cy.enterDateOfBirth( + dateOfBirth.month, + dateOfBirth.day, + dateOfBirth.year + ) + pageObjects + .applicantRelationshipToDeceased() + .select( + lifeEventForm.sectionsEligibilityCriteria[0].section.fieldsets[1] + .fieldset.inputs[0].inputCriteria.values[1].value + ) + pageObjects + .applicantMaritalStatus() + .select( + lifeEventForm.sectionsEligibilityCriteria[0].section.fieldsets[2] + .fieldset.inputs[0].inputCriteria.values[1].value + ) + + pageObjects + .button() + .contains(EN_LOCALE_DATA.buttonGroup[1].value) + .click() + .then(() => { + // get all the events in our layer that matches the event value + const ev = [ + ...window.dataLayer.filter( + x => x?.event === dataLayerValueFormStepTwo.event + ), + ] + removeID(ev[2]) + + expect(ev[2]).to.deep.equal(dataLayerValueFormStepTwo) + }) + }) + }) + }) + + it('clicking Continue on the final form step opens a modal and triggers the modal event', function () { cy.visit(utils.storybookUri) pageObjects.button().contains(EN_LOCALE_DATA.intro.button).click() @@ -88,17 +302,77 @@ describe('Calls to Google Analytics Object', function () { .then(() => { // get the last pushed event const ev = { ...window.dataLayer[window.dataLayer.length - 1] } - delete ev['gtm.uniqueEventId'] + removeID(ev) + + expect(ev).to.deep.equal(dataLayerValueFormStepOne) + + // fill out required fields + const dateOfBirth = utils.getDateByOffset(-(18 * 365.2425 - 1)) + cy.visit('/iframe.html?args=&id=app--primary&viewMode=story') - expect(dataLayerValues[1]).to.deep.equal(ev) + pageObjects.button().contains(EN_LOCALE_DATA.intro.button).click() + cy.enterDateOfBirth( + dateOfBirth.month, + dateOfBirth.day, + dateOfBirth.year + ) + pageObjects + .applicantRelationshipToDeceased() + .select( + lifeEventForm.sectionsEligibilityCriteria[0].section.fieldsets[1] + .fieldset.inputs[0].inputCriteria.values[1].value + ) + pageObjects + .applicantMaritalStatus() + .select( + lifeEventForm.sectionsEligibilityCriteria[0].section.fieldsets[2] + .fieldset.inputs[0].inputCriteria.values[1].value + ) + + pageObjects + .button() + .contains(EN_LOCALE_DATA.buttonGroup[1].value) + .click() + .then(() => { + // get all the events in our layer that matches the event value + const ev = [ + ...window.dataLayer.filter( + x => x?.event === dataLayerValueFormStepTwo.event + ), + ] + removeID(ev[2]) + + expect(ev[2]).to.deep.equal(dataLayerValueFormStepTwo) + + // Date of death - 30 days ago + const dateOfDeath = utils.getDateByOffset(-30) + cy.enterDateOfDeath( + dateOfDeath.month, + dateOfDeath.day, + dateOfDeath.year + ) + + pageObjects + .button() + .contains(EN_LOCALE_DATA.buttonGroup[1].value) + .click() + .then(() => { + // get all the events in our layer that matches the event value + const ev = [ + ...window.dataLayer.filter( + x => x?.event === dataLayerValueFormCompletionModal.event + ), + ] + removeID(ev[3]) + + expect(ev[3]).to.deep.equal(dataLayerValueFormCompletionModal) + }) + }) }) }) }) - it('results page has a bf_page_change and bf_count events', function () { - const selectedData = BENEFITS_ELIBILITY_DATA.scenario_1_covid.en.param - const enResults = BENEFITS_ELIBILITY_DATA.scenario_1_covid.en.results - const scenario = utils.encodeURIFromObject(selectedData) + it('results page with eligible benefits has a bf_page_change and bf_count events', function () { cy.visit(`${utils.storybookUri}${scenario}`) cy.window().then(window => { @@ -107,28 +381,249 @@ describe('Calls to Google Analytics Object', function () { pageObjects .benefitsAccordion() .filter(':visible') - .should('have.length', enResults.eligible.length) + .should( + 'have.length', + dataLayerValueResultsViewEligible.bfData.eligibleBenefitCount.number + ) .then(() => { // we wait for the last event to fire // eslint-disable-next-line cypress/no-unnecessary-waiting - cy.wait(100).then(() => { - // check last page change event + cy.wait(wait).then(() => { + // get all the events in our layer that matches the event value const ev = { ...window.dataLayer.filter( - x => x?.event === dataLayerValues[2].event + x => x?.event === dataLayerValueResultsViewEligible.event ), } - delete ev[0]['gtm.uniqueEventId'] + removeID(ev[0]) + + expect(ev[0]).to.deep.equal(dataLayerValueResultsViewEligible) + }) + }) + }) + }) + + it('clicking an accordion on the results page with eligible benefits has a bf_accordion_open event', function () { + cy.visit(`${utils.storybookUri}${scenario}`) + + cy.window().then(window => { + assert.isDefined(window.dataLayer, 'window.dataLayer is defined') - expect(ev[0]).to.deep.equal(dataLayerValues[2]) + pageObjects + .benefitsAccordion() + .filter(':visible') + .should( + 'have.length', + dataLayerValueResultsViewEligible.bfData.eligibleBenefitCount.number + ) + .then(() => { + pageObjects.accordion(enResults.eligible.eligible_benefits[0]).click() + // we wait for the last event to fire + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(wait).then(() => { + // get all the events in our layer that matches the event value + const ev = [ + ...window.dataLayer.filter( + x => x?.event === dataLayerValueAccordionOpen.event + ), + ] + removeID(ev[0]) + + expect(ev[0]).to.deep.equal(dataLayerValueAccordionOpen) + }) + }) + }) + }) + + it('clicking a obfuscated link in an open accordion on the results page with eligible benefits has a bf_benefit_link event', function () { + cy.visit(`${utils.storybookUri}${scenario}`) + + cy.window().then(window => { + assert.isDefined(window.dataLayer, 'window.dataLayer is defined') + + pageObjects + .benefitsAccordion() + .filter(':visible') + .should( + 'have.length', + dataLayerValueResultsViewEligible.bfData.eligibleBenefitCount.number + ) + .then(() => { + pageObjects.accordion(enResults.eligible.eligible_benefits[0]).click() + // we wait for the last event to fire + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(wait).then(() => { + // get all the events in our layer that matches the event value + const ev = [ + ...window.dataLayer.filter( + x => x?.event === dataLayerValueAccordionOpen.event + ), + ] + removeID(ev[0]) + + expect(ev[0]).to.deep.equal(dataLayerValueAccordionOpen) + // we wait for the last event to fire + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(2500) + pageObjects + .benefitsAccordionLink(enResults.eligible.eligible_benefits[0]) + .invoke('removeAttr', 'href') + .click({ force: true }) + .then(() => { + // get all the events in our layer that matches the event value + const ev = [ + ...window.dataLayer.filter( + x => x?.event === dataLayerValueBenefitLink.event + ), + ] + removeID(ev[0]) + + expect(ev[0]).to.deep.equal(dataLayerValueBenefitLink) + }) }) }) }) }) + it('results page with not eligible benefits has a bf_page_change and bf_count events', function () { + cy.visit(`${utils.storybookUri}${scenario}`) + + // click not eligible benefits view + pageObjects.notEligibleResultsButton().click() + + cy.window().then(window => { + assert.isDefined(window.dataLayer, 'window.dataLayer is defined') + + pageObjects + .benefitsAccordion() + .filter(':visible') + .should( + 'have.length', + dataLayerValueResultsViewNotEligible.bfData.notEligibleBenefitCount + .number + + dataLayerValueResultsViewNotEligible.bfData.moreInfoBenefitCount + .number + ) + .then(() => { + // we wait for the last event to fire + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(wait).then(() => { + // get all the events in our layer that matches the event value + const ev = [ + ...window.dataLayer.filter( + x => x?.event === dataLayerValueResultsViewNotEligible.event + ), + ] + removeID(ev[1]) + + expect(ev[1]).to.deep.equal(dataLayerValueResultsViewNotEligible) + }) + }) + }) + }) + + it('clicking Continue on the final form step opens a modal, clicking Review selections loads the verification view and a bf_page_change event', function () { + cy.visit(utils.storybookUri) + pageObjects.button().contains(EN_LOCALE_DATA.intro.button).click() + + cy.window().then(window => { + assert.isDefined(window.dataLayer, 'window.dataLayer is defined') + + pageObjects + .button() + .contains(EN_LOCALE_DATA.buttonGroup[1].value) + .then(() => { + // get the last pushed event + const ev = { ...window.dataLayer[window.dataLayer.length - 1] } + removeID(ev) + + expect(ev).to.deep.equal(dataLayerValueFormStepOne) + + // fill out required fields + const dateOfBirth = utils.getDateByOffset(-(18 * 365.2425 - 1)) + cy.visit('/iframe.html?args=&id=app--primary&viewMode=story') + + pageObjects.button().contains(EN_LOCALE_DATA.intro.button).click() + cy.enterDateOfBirth( + dateOfBirth.month, + dateOfBirth.day, + dateOfBirth.year + ) + pageObjects + .applicantRelationshipToDeceased() + .select( + lifeEventForm.sectionsEligibilityCriteria[0].section.fieldsets[1] + .fieldset.inputs[0].inputCriteria.values[1].value + ) + pageObjects + .applicantMaritalStatus() + .select( + lifeEventForm.sectionsEligibilityCriteria[0].section.fieldsets[2] + .fieldset.inputs[0].inputCriteria.values[1].value + ) + + pageObjects + .button() + .contains(EN_LOCALE_DATA.buttonGroup[1].value) + .click() + .then(() => { + // get all the events in our layer that matches the event value + const ev = [ + ...window.dataLayer.filter( + x => x?.event === dataLayerValueFormStepTwo.event + ), + ] + removeID(ev[2]) + + expect(ev[2]).to.deep.equal(dataLayerValueFormStepTwo) + + // Date of death - 30 days ago + const dateOfDeath = utils.getDateByOffset(-30) + cy.enterDateOfDeath( + dateOfDeath.month, + dateOfDeath.day, + dateOfDeath.year + ) + + pageObjects + .button() + .contains(EN_LOCALE_DATA.buttonGroup[1].value) + .click() + .then(() => { + // get all the events in our layer that matches the event value + const ev = [ + ...window.dataLayer.filter( + x => x?.event === dataLayerValueFormCompletionModal.event + ), + ] + removeID(ev[3]) + + expect(ev[3]).to.deep.equal(dataLayerValueFormCompletionModal) + + pageObjects + .button() + .contains('Review selections') + .click() + .then(() => { + // get all the events in our layer that matches the event value + const ev = [ + ...window.dataLayer.filter( + x => x?.event === dataLayerValueVerifySecletions.event + ), + ] + removeID(ev[4]) + + expect(ev[4]).to.deep.equal( + dataLayerValueVerifySecletions + ) + }) + }) + }) + }) + }) + }) + it('clicking open all on results page has a bf_open_all_accordions event', function () { - const selectedData = BENEFITS_ELIBILITY_DATA.scenario_1_covid.en.param - const scenario = utils.encodeURIFromObject(selectedData) cy.visit(`${utils.storybookUri}${scenario}`) cy.window().then(window => { @@ -139,30 +634,415 @@ describe('Calls to Google Analytics Object', function () { .click() .then(() => { // check last page change event - const ev = { + const ev = [ ...window.dataLayer.filter( - x => x?.event === dataLayerValues[3].event + x => x?.event === dataLayerValueOpenAllAccordions.event ), - } - delete ev[0]['gtm.uniqueEventId'] + ] + removeID(ev[0]) - expect(dataLayerValues[3]).to.deep.equal(ev[0]) + expect(ev[0]).to.deep.equal(dataLayerValueOpenAllAccordions) }) pageObjects .expandAll() .click() .then(() => { - // check last page change event - const ev = { + // get all the events in our layer that matches the event value + const ev = [ ...window.dataLayer.filter( - x => x?.event === dataLayerValues[3].event + x => x?.event === dataLayerValueOpenAllAccordions.event ), - } - // we ignore dedup here so there can be multiple fires - delete ev[1]['gtm.uniqueEventId'] + ] + removeID(ev[1]) + + expect(ev[1].bfData.accordionsOpen).to.equal( + !dataLayerValueOpenAllAccordions.bfData.accordionsOpen + ) + }) + }) + }) + + it('navigating through all the form results in zeroBenefits views', function () { + cy.visit(utils.storybookUri) + pageObjects.button().contains(EN_LOCALE_DATA.intro.button).click() + + cy.window().then(window => { + assert.isDefined(window.dataLayer, 'window.dataLayer is defined') + + pageObjects + .button() + .contains(EN_LOCALE_DATA.buttonGroup[1].value) + .then(() => { + // get the last pushed event + const ev = { ...window.dataLayer[window.dataLayer.length - 1] } + removeID(ev) + + expect(ev).to.deep.equal(dataLayerValueFormStepOne) + + // fill out required fields + const dateOfBirth = utils.getDateByOffset(-(18 * 365.2425 - 1)) + cy.visit('/iframe.html?args=&id=app--primary&viewMode=story') + + pageObjects.button().contains(EN_LOCALE_DATA.intro.button).click() + cy.enterDateOfBirth( + dateOfBirth.month, + dateOfBirth.day, + dateOfBirth.year + ) + pageObjects + .applicantRelationshipToDeceased() + .select( + lifeEventForm.sectionsEligibilityCriteria[0].section.fieldsets[1] + .fieldset.inputs[0].inputCriteria.values[1].value + ) + pageObjects + .applicantMaritalStatus() + .select( + lifeEventForm.sectionsEligibilityCriteria[0].section.fieldsets[2] + .fieldset.inputs[0].inputCriteria.values[1].value + ) + + pageObjects + .button() + .contains(EN_LOCALE_DATA.buttonGroup[1].value) + .click() + .then(() => { + // get all the events in our layer that matches the event value + const ev = [ + ...window.dataLayer.filter( + x => x?.event === dataLayerValueFormStepTwo.event + ), + ] + removeID(ev[2]) + + expect(ev[2]).to.deep.equal(dataLayerValueFormStepTwo) + + // Date of death - 30 days ago + const dateOfDeath = utils.getDateByOffset(-30) + cy.enterDateOfDeath( + dateOfDeath.month, + dateOfDeath.day, + dateOfDeath.year + ) + + pageObjects + .button() + .contains(EN_LOCALE_DATA.buttonGroup[1].value) + .click() + .then(() => { + const ev = [ + ...window.dataLayer.filter( + x => x?.event === dataLayerValueFormCompletionModal.event + ), + ] + removeID(ev[3]) + + expect(ev[3]).to.deep.equal(dataLayerValueFormCompletionModal) + + pageObjects + .button() + .contains('Review selections') + .click() + .then(() => { + // get all the events in our layer that matches the event value + const ev = [ + ...window.dataLayer.filter( + x => x?.event === dataLayerValueVerifySecletions.event + ), + ] + removeID(ev[4]) + + expect(ev[4]).to.deep.equal( + dataLayerValueVerifySecletions + ) + + pageObjects + .button() + .contains(EN_LOCALE_DATA.buttonGroup[1].value) + .click() + .then(() => { + // get all the events in our layer that matches the event value + const ev = [ + ...window.dataLayer.filter( + x => + x?.event === + dataLayerValueZeroResultsViewEligible.event + ), + ] + removeID(ev[5]) + + expect(ev[5]).to.deep.equal( + dataLayerValueZeroResultsViewEligible + ) + + pageObjects + .seeAllBenefitsButton() + .click() + .then(() => { + // get all the events in our layer that matches the event value + const ev = [ + ...window.dataLayer.filter( + x => + x?.event === + dataLayerValueZeroResultsViewNotEligible.event + ), + ] + removeID(ev[6]) + + expect(ev[6]).to.deep.equal( + dataLayerValueZeroResultsViewNotEligible + ) + }) + }) + }) + }) + }) + }) + }) + }) + + it('navigating through all the test steps produces a deep equal comparison to our expected dataLayer array values', function () { + cy.visit(utils.storybookUri) + pageObjects.button().contains(EN_LOCALE_DATA.intro.button).click() + + cy.window().then(window => { + assert.isDefined(window.dataLayer, 'window.dataLayer is defined') + + pageObjects + .button() + .contains(EN_LOCALE_DATA.buttonGroup[1].value) + .then(() => { + // get the last pushed event + const ev = { ...window.dataLayer[window.dataLayer.length - 1] } + // delete ev['gtm.uniqueEventId'] + removeID(ev) + + expect(ev).to.deep.equal(dataLayerValueFormStepOne) + + // fill out required fields + const dateOfBirth = utils.getDateByOffset(-(18 * 365.2425 - 1)) + cy.visit('/iframe.html?args=&id=app--primary&viewMode=story') + + pageObjects.button().contains(EN_LOCALE_DATA.intro.button).click() + cy.enterDateOfBirth( + dateOfBirth.month, + dateOfBirth.day, + dateOfBirth.year + ) + pageObjects + .applicantRelationshipToDeceased() + .select( + lifeEventForm.sectionsEligibilityCriteria[0].section.fieldsets[1] + .fieldset.inputs[0].inputCriteria.values[1].value + ) + pageObjects + .applicantMaritalStatus() + .select( + lifeEventForm.sectionsEligibilityCriteria[0].section.fieldsets[2] + .fieldset.inputs[0].inputCriteria.values[1].value + ) + + pageObjects + .button() + .contains(EN_LOCALE_DATA.buttonGroup[1].value) + .click() + .then(() => { + // get the last pushed event + const ev = [ + ...window.dataLayer.filter( + x => x?.event === dataLayerValueFormStepTwo.event + ), + ] + + // delete ev[2]['gtm.uniqueEventId'] + removeID(ev[2]) + + expect(ev[2]).to.deep.equal(dataLayerValueFormStepTwo) + + // Date of death - 30 days ago + const dateOfDeath = utils.getDateByOffset(-30) + cy.enterDateOfDeath( + dateOfDeath.month, + dateOfDeath.day, + dateOfDeath.year + ) + + pageObjects + .button() + .contains(EN_LOCALE_DATA.buttonGroup[1].value) + .click() + .then(() => { + const ev = [ + ...window.dataLayer.filter( + x => x?.event === dataLayerValueFormCompletionModal.event + ), + ] + + // delete ev[3]['gtm.uniqueEventId'] + removeID(ev[3]) + + expect(ev[3]).to.deep.equal(dataLayerValueFormCompletionModal) + + pageObjects + .button() + .contains('Review selections') + .click() + .then(() => { + const ev = [ + ...window.dataLayer.filter( + x => x?.event === dataLayerValueVerifySecletions.event + ), + ] + + // delete ev[4]['gtm.uniqueEventId'] + removeID(ev[4]) + + expect(ev[4]).to.deep.equal( + dataLayerValueVerifySecletions + ) + + pageObjects + .button() + .contains(EN_LOCALE_DATA.buttonGroup[1].value) + .click() + .then(() => { + const ev = [ + ...window.dataLayer.filter( + x => + x?.event === + dataLayerValueZeroResultsViewEligible.event + ), + ] + removeID(ev[5]) + + expect(ev[5]).to.deep.equal( + dataLayerValueZeroResultsViewEligible + ) + + pageObjects + .seeAllBenefitsButton() + .click() + .then(() => { + const ev = [ + ...window.dataLayer.filter( + x => + x?.event === + dataLayerValueZeroResultsViewNotEligible.event + ), + ] + removeID(ev[6]) + + expect(ev[6]).to.deep.equal( + dataLayerValueZeroResultsViewNotEligible + ) + }) + // confirm zero benefits event and view + // click see all benefits + pageObjects + .expandAll() + .click() + .then(() => { + // check last page change event + const ev = [ + ...window.dataLayer.filter( + x => + x?.event === + dataLayerValueOpenAllAccordions.event + ), + ] + removeID(ev[0]) + + expect(ev[0]).to.deep.equal( + dataLayerValueOpenAllAccordions + ) + pageObjects + .expandAll() + .click() + .then(() => { + // check last page change event + const ev = [ + ...window.dataLayer.filter( + x => + x?.event === + dataLayerValueOpenAllAccordions.event + ), + ] + + // we ignore dedup here so there can be multiple fires + removeID(ev[1]) + + expect(ev[1].bfData.accordionsOpen).to.equal( + !dataLayerValueOpenAllAccordions.bfData + .accordionsOpen + ) + + pageObjects + .accordion( + enResults.eligible.eligible_benefits[0] + ) + .click() + // we wait for the last event to fire + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(wait).then(() => { + // check last page change event + const ev = [ + ...window.dataLayer.filter( + x => + x?.event === + dataLayerValueAccordionOpen.event + ), + ] + removeID(ev[0]) + + expect(ev[0]).to.deep.equal( + dataLayerValueAccordionOpen + ) + + pageObjects + .benefitsAccordionLink( + enResults.eligible.eligible_benefits[0] + ) + .invoke('removeAttr', 'href') + .click() + .then(() => { + const ev = [ + ...window.dataLayer.filter( + x => + x?.event === + dataLayerValueBenefitLink.event + ), + ] + // delete ev[0]['gtm.uniqueEventId'] + removeID(ev[0]) + expect(ev[0]).to.deep.equal( + dataLayerValueBenefitLink + ) + + // loop through the data layer and remove any events that are gtm + + const bfDataLayer = + window.dataLayer.filter( + item => !item.event.includes('gtm') + ) + + const cleanBfDataLayer = + bfDataLayer.map(item => { + removeID(item) + return item + }) - expect(dataLayerValues[4]).to.not.deep.equal(ev[1]) + expect(cleanBfDataLayer).to.deep.equal( + dataLayerValues + ) + }) + }) + }) + }) + }) + }) + }) + }) }) }) }) diff --git a/benefit-finder/cypress/fixtures/benefits-eligibility.json b/benefit-finder/cypress/fixtures/benefits-eligibility.json index 3a6083967..232c05fb7 100644 --- a/benefit-finder/cypress/fixtures/benefits-eligibility.json +++ b/benefit-finder/cypress/fixtures/benefits-eligibility.json @@ -230,7 +230,11 @@ "results": { "eligible": { "length": 0 - } + }, + "moreInformationNeeded": { + "length": 22 + }, + "total_benefits": 30 } } } diff --git a/benefit-finder/cypress/support/pageObjects.js b/benefit-finder/cypress/support/pageObjects.js index e85dd6117..561db5e8c 100644 --- a/benefit-finder/cypress/support/pageObjects.js +++ b/benefit-finder/cypress/support/pageObjects.js @@ -77,6 +77,12 @@ class PageObjects { return cy.get('.usa-accordion__button') } + benefitsAccordionLink(accordionHeading) { + return cy.get( + `[data-analytics-content="${accordionHeading}"] a[data-testid="bf-benefit-link"]` + ) + } + menuButton() { return cy.get('.usa-menu-btn') } diff --git a/benefit-finder/src/App/__tests__/__snapshots__/index.spec.jsx.snap b/benefit-finder/src/App/__tests__/__snapshots__/index.spec.jsx.snap index b512d6850..3e9af63f7 100644 --- a/benefit-finder/src/App/__tests__/__snapshots__/index.spec.jsx.snap +++ b/benefit-finder/src/App/__tests__/__snapshots__/index.spec.jsx.snap @@ -632,6 +632,7 @@ exports[`loads window query scenario 1 1`] = ` renders a match to the previous snapshot 1`] = handleBenefitLinkClick(title)} + data-testid="bf-benefit-link" > {visitLabel} {agency.title}{' '} {sourceIsEnglish && SourceIsEnglish === true diff --git a/benefit-finder/src/shared/components/ResultsView/__tests__/__snapshots__/index.spec.jsx.snap b/benefit-finder/src/shared/components/ResultsView/__tests__/__snapshots__/index.spec.jsx.snap index 1e5dda5c2..e0cd80c86 100644 --- a/benefit-finder/src/shared/components/ResultsView/__tests__/__snapshots__/index.spec.jsx.snap +++ b/benefit-finder/src/shared/components/ResultsView/__tests__/__snapshots__/index.spec.jsx.snap @@ -371,6 +371,7 @@ exports[`loads view 1`] = `