From 00c5b46b5f16a4e49879411910cb647aa08d35bd Mon Sep 17 00:00:00 2001 From: Leah Schumann Date: Wed, 18 Jan 2023 09:15:04 -0500 Subject: [PATCH 1/4] Revamping to prevent JAWS Error, an additional changes to resolve issues caused by the fix --- .../address-questions/address-questions.vue | 104 +++++++++--------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue index 4ad515fbb..6f09ecf6c 100644 --- a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue +++ b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue @@ -78,6 +78,7 @@ import { applicationConfig } from "@/constants/application-config.js"; import { defineRule } from "vee-validate"; import { required, regex } from "@/helpers/validation-rules"; import { errorMessages } from "@/constants/error-messages"; +import { fill } from "lodash"; // DEFINE VALIDATION RULES defineRule("street-address-required", required(errorMessages.STREET_ADDRESS_REQUIRED)); @@ -113,7 +114,6 @@ export default { matchingIndirectly: false, matchFound: null, // null = no attempted match, true = match was found, false = match was not found enterPressed: false, - isAddressWatchActive: false, // Only deep watch the address model when a match was not found }; }, computed: { @@ -235,27 +235,23 @@ export default { }); addressField1.addEventListener("keydown", (e) => { - if (e.code === "Enter" || e.code === "NumpadEnter" || e.code === "Tab") { - if (e.code === "Tab") { - self.matchingIndirectly = true; + if (e.code === "Enter" || e.code === "NumpadEnter") { + const selectedItem = document.querySelector(".pac-container .pac-item-selected"); + if (selectedItem !== null) { + // Fill-in the address using selected item in the list. + fillInAddress(selectedItem); } else { - self.enterPressed = true; - } - - addressField1.blur(); + // Fill-in the address using first item in the list. + fillInAddressUsingFirstItem(); + } } else { return; } }); addressField1.addEventListener("change", () => { - // NOTE: The "place_changed" event of the autocomplete fires after this and will use either the address the user had chosen - // using either the down / up arrows or the address the user was hovering over when they pressed "Enter." - - // If a match has been previously found then do nothing - // OR - // If the user pressed "Enter" then do nothing - if (self.matchFound || self.enterPressed) { + // If a match has been previously attempted then do nothing + if (self.matchFound !== null) { return; } @@ -267,29 +263,33 @@ export default { // If the Street Address field changed without clicking (i.e. by pressing Tab, or clicking outside the field) if (clickedAddress === null) { // Fill-in the address using first item in the list. - const item = document.querySelector(".pac-container .pac-item"); - if (item != null) { - self.matchingIndirectly = true; - - const firstResult = item.textContent; - const geocoder = new window.google.maps.Geocoder(); - geocoder.geocode( - { - address: firstResult, - }, - function (results, status) { - if (status === window.google.maps.GeocoderStatus.OK) { - fillInAddress(results[0]); - } - } - ); - } else { - // No addresses found for the input - self.matchFound = false; - } + fillInAddressUsingFirstItem(); } + }); + function fillInAddressUsingFirstItem() { + // Fill-in the address using first item in the list. + const item = document.querySelector(".pac-container .pac-item"); + if (item != null) { + const firstResult = item.textContent; + const geocoder = new window.google.maps.Geocoder(); + geocoder.geocode( + { + address: firstResult, + }, + function (results, status) { + if (status === window.google.maps.GeocoderStatus.OK) { + fillInAddress(results[0]); + self.displayVerificationWarning = true; + } + } + ); + } else { + self.matchFound = false; + } + } + function fillInAddress(place) { if (!place) { place = autocomplete.getPlace(); @@ -297,6 +297,7 @@ export default { if (place && place.address_components) { self.matchFound = true; + self.addressModel.streetAddress = ""; self.$nextTick(function () { self.showAddressFields = true; @@ -329,8 +330,6 @@ export default { } } - self.displayVerificationWarning = self.matchingIndirectly; - // after showing the address fields, disable the address autocomplete window.google.maps.event.removeListener(autocompleteListener); window.google.maps.event.clearInstanceListeners(autocomplete); @@ -340,8 +339,6 @@ export default { pacContainer.remove(); } }); - } else { - self.displayVerificationWarning = true; } } }) @@ -357,6 +354,13 @@ export default { watch: { matchFound: { handler(newValue) { + if (newValue === null) { + this.displayNoMatchWarning = false; + this.displayVerificationWarning = false; + this.unwatchAddress(); + return; + } + if (!newValue) { this.displayNoMatchWarning = true; @@ -366,22 +370,18 @@ export default { this.showAddressFields = true; this.displayVerificationWarning = false; - this.$nextTick(function () { - // Only deep watch the Address Model after a failed match - this.isAddressWatchActive = true; - }); + // Only deep watch the Address Model after a failed match + this.unwatchAddress = this.$watch( + "addressModel", + () => { + // When the address model changes reset to "no attempted match" + this.matchFound = null; + }, + { deep: true } + ); } }, }, - addressModel: { - handler() { - if (this.isAddressWatchActive) { - this.displayNoMatchWarning = false; - this.isAddressWatchActive = false; - } - }, - deep: true, - }, }, components: { textboxQuestion, From 2545b655d37faffa0b68735f698679e43c4cd0da Mon Sep 17 00:00:00 2001 From: Leah Schumann Date: Wed, 18 Jan 2023 13:11:48 -0500 Subject: [PATCH 2/4] Removing unused state variables --- .../address-questions/address-questions.vue | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue index 6f09ecf6c..060ee806b 100644 --- a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue +++ b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue @@ -111,9 +111,7 @@ export default { alertCopyVerificationWarning: "", alertHeadlineNoMatchWarning: "", alertCopyNoMatchWarning: "", - matchingIndirectly: false, matchFound: null, // null = no attempted match, true = match was found, false = match was not found - enterPressed: false, }; }, computed: { @@ -235,15 +233,17 @@ export default { }); addressField1.addEventListener("keydown", (e) => { - if (e.code === "Enter" || e.code === "NumpadEnter") { - const selectedItem = document.querySelector(".pac-container .pac-item-selected"); + if (e.code === "Enter" || e.code === "NumpadEnter") { + const selectedItem = document.querySelector( + ".pac-container .pac-item-selected" + ); if (selectedItem !== null) { // Fill-in the address using selected item in the list. - fillInAddress(selectedItem); + fillInAddress(selectedItem); } else { // Fill-in the address using first item in the list. fillInAddressUsingFirstItem(); - } + } } else { return; } @@ -265,7 +265,6 @@ export default { // Fill-in the address using first item in the list. fillInAddressUsingFirstItem(); } - }); function fillInAddressUsingFirstItem() { From f708551c883d99d70679ded51f4b466798e198e1 Mon Sep 17 00:00:00 2001 From: Leah Schumann Date: Fri, 20 Jan 2023 09:21:34 -0500 Subject: [PATCH 3/4] Updated unit tests for most recent changes --- .../address-questions.spec.js | 164 ++++++++---------- .../address-questions/address-questions.vue | 3 +- 2 files changed, 70 insertions(+), 97 deletions(-) diff --git a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.spec.js b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.spec.js index 0ab14d352..0c149413e 100644 --- a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.spec.js +++ b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.spec.js @@ -7,6 +7,7 @@ import { mount, shallowMount } from "@vue/test-utils"; import { getMountOptions } from "@/helpers/unit-test-helper.js"; import { storeMutations } from "@/constants/store-mutations"; import store from "@/store"; +import { createImportSpecifier } from "typescript"; let autocompleteElement; describe("address-questions.vue", () => { @@ -18,7 +19,7 @@ describe("address-questions.vue", () => { }); describe("initial state", () => { - test("only street address field is shown", () => { + test("Should only show the street address field", () => { // Arrange const { wrapper } = setupMocks({}); @@ -58,7 +59,7 @@ describe("address-questions.vue", () => { expect(zipCode.exists()).toBe(true); }); - test("Should it set this.showAddressFields to true when the model is prepopulated", async () => { + test("Should set this.showAddressFields to true when the model is prepopulated", async () => { // Arrange // Act const newAddressModel = { @@ -305,38 +306,6 @@ describe("address-questions.vue", () => { }); describe("alerts", () => { - const places = [null, { address_components: null }, undefined, {}]; - test.each(places)( - "selected place/place properties is null => display verification alert", - async (place) => { - // Arrange - const { wrapper } = setupMocks({}); - await wrapper.setData({ - addressModel: { - streetAddress: "123 Test Street", - }, - }); - - const selectedPlace = place; - - // Act - autocompleteElement.dispatchEvent( - new CustomEvent("place_changed", { detail: selectedPlace }) - ); - await wrapper.vm.$nextTick(); - - // Assert - const verificationAlert = wrapper.findComponent({ - ref: "alertVerificationWarning", - }); - expect(verificationAlert.exists()).toBe(true); - expect(verificationAlert.isVisible()).toBe(true); - - const noMatchAlert = wrapper.findComponent({ ref: "alertNoMatchWarning" }); - expect(noMatchAlert.exists()).toBe(false); - } - ); - test("user enters address that yields no autocomplete results => show noMatch alert", async () => { // Arrange let changeEventCallbackFunction; @@ -413,110 +382,112 @@ describe("address-questions.vue", () => { describe("noMatch alert is cleared on address change", () => { test("user sees noMatch warning and modifies street address => noMatch warning is removed", async () => { // Arrange - const { wrapper } = setupMocks({}); + const { wrapper } = setupMocks({ + props: { + modelValue: { + streetAddress: "LS", + city: "", + state: "", + zipCode: "", + }, + } + }); + // Initial condition to display noMatch warning await wrapper.setData({ matchFound: false, }); + + // Act + wrapper.vm.addressModel.streetAddress = "LJS"; await wrapper.vm.$nextTick(); - let noMatchAlert = wrapper.findComponent({ ref: "alertNoMatchWarning" }); - expect(noMatchAlert.exists()).toBeTruthy(); - expect(noMatchAlert.isVisible()).toBeTruthy(); - - // // Act - wrapper.vm.$options.watch.addressModel.handler.call(wrapper.vm, { - streetAddress: "LS", - }); - // Assert - wrapper.vm.$nextTick(function () { - expect(wrapper.vm.displayNoMatchWarning).toBeFalsy(); + let noMatchAlert = wrapper.findComponent({ ref: "alertNoMatchWarning" }); + expect(noMatchAlert.exists()).toBeFalsy(); - noMatchAlert = wrapper.findComponent({ ref: "alertNoMatchWarning" }); - expect(noMatchAlert.exists()).toBeFalsy(); - }); }); test("user sees noMatch warning and enters city => noMatch warning is removed", async () => { // Arrange - const { wrapper } = setupMocks({}); + const { wrapper } = setupMocks({ + props: { + modelValue: { + streetAddress: "", + city: "LS", + state: "", + zipCode: "", + }, + } + }); + // Initial condition to display noMatch warning await wrapper.setData({ matchFound: false, }); + + // Act + wrapper.vm.addressModel.city = "LJS"; await wrapper.vm.$nextTick(); - let noMatchAlert = wrapper.findComponent({ ref: "alertNoMatchWarning" }); - expect(noMatchAlert.exists()).toBeTruthy(); - expect(noMatchAlert.isVisible()).toBeTruthy(); - - // // Act - wrapper.vm.$options.watch.addressModel.handler.call(wrapper.vm, { - city: "LS", - }); - // Assert - wrapper.vm.$nextTick(function () { - expect(wrapper.vm.displayNoMatchWarning).toBeFalsy(); + let noMatchAlert = wrapper.findComponent({ ref: "alertNoMatchWarning" }); + expect(noMatchAlert.exists()).toBeFalsy(); - noMatchAlert = wrapper.findComponent({ ref: "alertNoMatchWarning" }); - expect(noMatchAlert.exists()).toBeFalsy(); - }); }); test("user sees noMatch warning and enters state => noMatch warning is removed", async () => { // Arrange - const { wrapper } = setupMocks({}); + const { wrapper } = setupMocks({ + props: { + modelValue: { + streetAddress: "", + city: "", + state: "LS", + zipCode: "", + }, + } + }); + // Initial condition to display noMatch warning await wrapper.setData({ matchFound: false, }); + + // Act + wrapper.vm.addressModel.state = "LJS"; await wrapper.vm.$nextTick(); - let noMatchAlert = wrapper.findComponent({ ref: "alertNoMatchWarning" }); - expect(noMatchAlert.exists()).toBeTruthy(); - expect(noMatchAlert.isVisible()).toBeTruthy(); - - // // Act - wrapper.vm.$options.watch.addressModel.handler.call(wrapper.vm, { - state: "KO", - }); - // Assert - wrapper.vm.$nextTick(function () { - expect(wrapper.vm.displayNoMatchWarning).toBeFalsy(); - - noMatchAlert = wrapper.findComponent({ ref: "alertNoMatchWarning" }); - expect(noMatchAlert.exists()).toBeFalsy(); - }); + let noMatchAlert = wrapper.findComponent({ ref: "alertNoMatchWarning" }); + expect(noMatchAlert.exists()).toBeFalsy(); }); test("user sees noMatch warning and enters zip code => noMatch warning is removed", async () => { // Arrange - const { wrapper } = setupMocks({}); + const { wrapper } = setupMocks({ + props: { + modelValue: { + streetAddress: "", + city: "", + state: "", + zipCode: "LS", + }, + } + }); + // Initial condition to display noMatch warning await wrapper.setData({ matchFound: false, }); + + // Act + wrapper.vm.addressModel.zipCode = "LJS"; await wrapper.vm.$nextTick(); - let noMatchAlert = wrapper.findComponent({ ref: "alertNoMatchWarning" }); - expect(noMatchAlert.exists()).toBeTruthy(); - expect(noMatchAlert.isVisible()).toBeTruthy(); - - // // Act - wrapper.vm.$options.watch.addressModel.handler.call(wrapper.vm, { - zipCode: "12345", - }); - // Assert - wrapper.vm.$nextTick(function () { - expect(wrapper.vm.displayNoMatchWarning).toBeFalsy(); - - noMatchAlert = wrapper.findComponent({ ref: "alertNoMatchWarning" }); - expect(noMatchAlert.exists()).toBeFalsy(); - }); + let noMatchAlert = wrapper.findComponent({ ref: "alertNoMatchWarning" }); + expect(noMatchAlert.exists()).toBeFalsy(); }); }); }); @@ -576,6 +547,7 @@ function setupMocks({ const wrapper = isShallowMount ? shallowMount(addressQuestions, resultingMountOptions) : mount(addressQuestions, resultingMountOptions); + document.querySelector = jest.fn().mockImplementation((query) => { let result = null; if (query == ".pac-container") result = document.createElement("div"); diff --git a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue index f93112eed..1f2227cc3 100644 --- a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue +++ b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.vue @@ -375,8 +375,9 @@ export default { () => { // When the address model changes reset to "no attempted match" this.matchFound = null; + this.$nextTick(); }, - { deep: true } + { deep: true, flush: "post" } ); } }, From 316efeda3c2a34ff6795c30d640863d128b6e471 Mon Sep 17 00:00:00 2001 From: Leah Schumann Date: Fri, 20 Jan 2023 09:26:46 -0500 Subject: [PATCH 4/4] Prettified --- .../address-questions/address-questions.spec.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.spec.js b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.spec.js index a7a06b597..cf620b15f 100644 --- a/src/layouts/address-lookup/customer-questions/address-questions/address-questions.spec.js +++ b/src/layouts/address-lookup/customer-questions/address-questions/address-questions.spec.js @@ -390,7 +390,7 @@ describe("address-questions.vue", () => { state: "", zipCode: "", }, - } + }, }); // Initial condition to display noMatch warning @@ -405,7 +405,6 @@ describe("address-questions.vue", () => { // Assert let noMatchAlert = wrapper.findComponent({ ref: "alertNoMatchWarning" }); expect(noMatchAlert.exists()).toBeFalsy(); - }); test("user sees noMatch warning and enters city => noMatch warning is removed", async () => { @@ -418,7 +417,7 @@ describe("address-questions.vue", () => { state: "", zipCode: "", }, - } + }, }); // Initial condition to display noMatch warning @@ -433,7 +432,6 @@ describe("address-questions.vue", () => { // Assert let noMatchAlert = wrapper.findComponent({ ref: "alertNoMatchWarning" }); expect(noMatchAlert.exists()).toBeFalsy(); - }); test("user sees noMatch warning and enters state => noMatch warning is removed", async () => { @@ -446,7 +444,7 @@ describe("address-questions.vue", () => { state: "LS", zipCode: "", }, - } + }, }); // Initial condition to display noMatch warning @@ -473,7 +471,7 @@ describe("address-questions.vue", () => { state: "", zipCode: "LS", }, - } + }, }); // Initial condition to display noMatch warning