Merge branch 'develop' into feature/jnou/more-fixes-playwright

This commit is contained in:
JennyNou 2026-04-27 10:57:06 -04:00
commit 51b4d8e443
10 changed files with 64 additions and 29 deletions

View file

@ -20,6 +20,7 @@ variables:
# - group: Digital-Infrastructure
# - group: ISS-BuildBranches
- group: SafelitePlaywright
- group: ISSNextgenRegressionAutomationPlaywright
- name: dockerImageName
value: 'playwright-tests'
- name: imageTag

27
package-lock.json generated
View file

@ -9,14 +9,13 @@
"version": "0.1.0",
"dependencies": {
"@adyen/adyen-web": "^6.31.1",
"axios": "^1.13.5",
"axios-retry": "^3.5.0",
"bootstrap": "^5.3",
"iframe-resizer": "^4.3.9",
"maska": "^2.1.1",
"pinia": "^2.1.4",
"pinia-plugin-persistedstate": "^2.2.0",
"uuid": "^9.0.1",
"uuid": "^14.0.0",
"vee-validate": "^4.5.7",
"vue": "^3.3.4",
"vue-plugin-load-script": "^2.1.0",
@ -47,7 +46,7 @@
"@vue/test-utils": "^2.4.1",
"@vue/vue3-jest": "^27.0.0-alpha.1",
"axe-core": "^4.10.2",
"axios": "^1.13.5",
"axios": "^1.15.0",
"axios-mock-adapter": "^1.21.5",
"babel-jest": "^27.0.6",
"concurrently": "^9.1.2",
@ -6567,13 +6566,15 @@
}
},
"node_modules/axios": {
"version": "1.13.5",
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.15.0.tgz",
"integrity": "sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.11",
"form-data": "^4.0.5",
"proxy-from-env": "^1.1.0"
"proxy-from-env": "^2.1.0"
}
},
"node_modules/axios-mock-adapter": {
@ -6618,6 +6619,16 @@
"is-retry-allowed": "^2.2.0"
}
},
"node_modules/axios/node_modules/proxy-from-env": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
"integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
}
},
"node_modules/b4a": {
"version": "1.6.7",
"dev": true,
@ -20338,14 +20349,16 @@
}
},
"node_modules/uuid": {
"version": "9.0.1",
"version": "14.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz",
"integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
"uuid": "dist/bin/uuid"
"uuid": "dist-node/bin/uuid"
}
},
"node_modules/v8-to-istanbul": {

View file

@ -21,14 +21,14 @@
},
"dependencies": {
"@adyen/adyen-web": "^6.31.1",
"axios": "^1.13.5",
"axios": "^1.15.0",
"axios-retry": "^3.5.0",
"bootstrap": "^5.3",
"iframe-resizer": "^4.3.9",
"maska": "^2.1.1",
"pinia": "^2.1.4",
"pinia-plugin-persistedstate": "^2.2.0",
"uuid": "^9.0.1",
"uuid": "^14.0.0",
"vee-validate": "^4.5.7",
"vue": "^3.3.4",
"vue-plugin-load-script": "^2.1.0",
@ -59,7 +59,7 @@
"@vue/test-utils": "^2.4.1",
"@vue/vue3-jest": "^27.0.0-alpha.1",
"axe-core": "^4.10.2",
"axios": "^1.13.5",
"axios": "^1.15.0",
"axios-mock-adapter": "^1.21.5",
"babel-jest": "^27.0.6",
"concurrently": "^9.1.2",

View file

@ -14,7 +14,7 @@ import { useMainStore } from '@/store';
import { getPriceOfLineItems } from '@/helpers/price-calculator.js';
import coverageStatuses from '@/constants/coverage-statuses';
import coverageType from '@/constants/coverage-type';
import { containsRecalParts } from '@/helpers/recal-helper';
import { isRecalOrder } from '@/helpers/recal-helper';
jest.mock('@/helpers/layout-helper.js', () => jest.fn());
jest.mock('@/helpers/price-calculator.js', () => ({
@ -34,7 +34,7 @@ jest.mock('@/helpers/text-helper', () => ({
}));
jest.mock('@/helpers/recal-helper.js', () => ({
containsRecalParts: jest.fn()
isRecalOrder: jest.fn()
}));
const SAFELITE_PROVIDER = 'Safelite';
@ -345,7 +345,7 @@ describe('coverageStatement.vue', () => {
});
test('returns true when a part in glassParts requires recalibration and recalibration has been added to order', () => {
// Arrange
containsRecalParts.mockReturnValue(true);
isRecalOrder.mockReturnValue(true);
const mainInitialState = {
order: {
lineItems: {

View file

@ -149,7 +149,7 @@ import { getAvailableLineItems } from '@/helpers/cart-helper';
import coverageStatuses from '@/constants/coverage-statuses';
import coverageType from '@/constants/coverage-type';
import oemEndorsementModal from '@/layouts/coverage-statement/oem-endorsement-modal/oem-endorsement-modal.vue';
import { containsRecalParts } from '@/helpers/recal-helper';
import { isRecalOrder } from '@/helpers/recal-helper';
const RECAL_MODAL_REF_NAME = 'RecalModal';
const CANCEL_CLAIM_REF_NAME = 'CancelClaimModal';
@ -308,13 +308,7 @@ export default {
return this.mainStore.isUnverified;
},
isADAS() {
const { glassParts } = useMainStore().order.lineItems;
const orderContainsRecalPart = containsRecalParts(glassParts);
return (
glassParts !== null
&& !!glassParts.find((part) => part.requiresRecalibration)
&& orderContainsRecalPart
);
return isRecalOrder(this.mainStore.order.lineItems);
},
totalServicePrice() {
return getPriceOfLineItems(this.baseServiceLineItems);

View file

@ -294,7 +294,7 @@ export default {
} else {
glassList = getGlassList(glassPieces);
workType = 'replacement';
if (this.hasRecalibrationPart) {
if (this.hasRecalibrationPart && containsRecalParts(this.submittedOrder.lineItems)) {
if (glassList === 'windshield') {
workType = 'replacement and recalibration';
}
@ -630,8 +630,9 @@ export default {
const repairOrReplace = this.submittedOrder.isRepair ? 'repair' : 'replace';
this.pushEventToGA('confirmation', 'safelite', `${mobileOrInshop}_${repairOrReplace}_${verifiedOrNotVerified}`, true);
const paymentMethodForAnalytics = analyticsPaymentTypeMap.get(this.payment.paymentMethod) ?? 'UNKNOWN';
this.pushEventToGA('order_confirmed', 'payment_type_submitted', paymentMethodForAnalytics, true);
if (this.payment.isPayInAdvance) {
const paymentMethodForAnalytics = analyticsPaymentTypeMap.get(this.payment.paymentMethod);
this.pushEventToGA('payment_page', 'pia_successful', paymentMethodForAnalytics, true);
}

View file

@ -8,6 +8,7 @@
<script>
import { getStringWithCustomValues, processIfStatements } from '@/helpers/cms-content-helper';
import { getGlassList } from '@/helpers/damage-helper';
import { isRecalOrder } from '@/helpers/recal-helper';
import reviewBlock from '@/layouts/payment-method/review-dropdown/review-block/review-block.vue';
export default {
@ -34,12 +35,16 @@ export default {
customValueMap() {
return {
glassList: this.glassList,
isRecalibrationOnOrder: this.isRecalibrationOnOrder
};
},
glassList() {
const glassPieces = this.mainStore.lineItems.glassParts?.map((part) => part.partType.toLowerCase()) ?? [];
return getGlassList(glassPieces);
},
isRecalibrationOnOrder() {
return isRecalOrder(this.mainStore.order.lineItems);
}
},
methods: {
getCmsContentWithCustomValues(widgetName, widgetField) {

View file

@ -119,7 +119,7 @@ export default {
},
mounted() {
showIssLoadingModal(true);
this.pushEventToGA('payment_page', 'Mode', 'Adyen', true);
this.handleAnalyticsEventsOnMounted()
this.initializeAdyen().finally(() => {
showIssLoadingModal(false);
});
@ -584,6 +584,11 @@ export default {
this.$route
);
},
handleAnalyticsEventsOnMounted() {
this.pushEventToGA('payment_page', 'PIA Mode', 'Adyen', true);
const paymentMethod = analyticsPaymentTypeMap.get(this.piaType) ?? 'UNKNOWN';
this.pushEventToGA('payment_method', 'pia', paymentMethod, true);
},
showIssLoadingModal
}
};

View file

@ -9,7 +9,7 @@
<div class="appointment-type-question-text d-flex">
<span
v-if="recalibrationRequired"
class="recal-text">{{ scheduleRecalText }}</span>
class="recal-text mb-4">{{ scheduleRecalText }}</span>
<span
v-if="!requiresInshopRecalibration">{{ appointmentQuestionText }}</span>
</div>
@ -133,6 +133,7 @@ import {
getMobileZipCodeData
} from '@/helpers/service-location-helper';
import { toTitleCase } from '@/helpers/text-helper.js';
import { isRecalOrder } from '@/helpers/recal-helper';
// Import Component
import alert from '@/ux-components/alert/alert.vue';
@ -144,6 +145,7 @@ import serviceZipQuestion from '@/layouts/schedule-page/service-location/service
import widgetFields from '@/constants/cms-widget-fields';
import recalModal from '@/iss-components/recal-modal/recal-modal.vue';
import { getPricedMobileFeePart } from '@/helpers/service-location-helper';
import { processIfStatements } from '@/helpers/cms-content-helper';
const RECAL_MODAL_REF_NAME = 'RecalModal';
@ -241,6 +243,9 @@ export default {
return this.selectedAppointmentType === AppointmentTypeStrings.MOBILE
|| this.selectedAppointmentType === AppointmentTypeStrings.MOBILE_NOT_ITAC_AND_NOT_NOCOMP;
},
isRecalibrationOnOrder() {
return isRecalOrder(this.mainStore.order.lineItems);
},
isServiceableInshop() {
if (this.isRecalibrationServiceableInshop !== null) {
return (this.isGlassServiceableInshop && this.isRecalibrationServiceableInshop);
@ -284,9 +289,11 @@ export default {
},
scheduleRecalText() {
if (this.requiresInshopRecalibration) {
return this.getCmsContent('WhereWouldYouLikeServiceWidget', widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT_2);
const bodyText2 = this.getCmsContent('WhereWouldYouLikeServiceWidget', widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT_2);
return this.processIfStatements(bodyText2, 'custom', this.getCustomValueFromString);
}
return this.getCmsContent('WhereWouldYouLikeServiceWidget', widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT);
const bodyText = this.getCmsContent('WhereWouldYouLikeServiceWidget', widgetFields.CONTENT_GROUP_WIDGET.BODY_TEXT);
return this.processIfStatements(bodyText, 'custom', this.getCustomValueFromString);
}
},
watch: {
@ -343,6 +350,7 @@ export default {
}
},
methods: {
processIfStatements,
async initializeComponent(initialData) {
this.initializingData = true;
await this.setData(initialData);
@ -405,6 +413,14 @@ export default {
getSelectedProvider() {
return useMainStore().order.serviceLocation.provider;
},
getCustomValueFromString(str) {
switch (str) {
case 'isRecalibrationOnOrder':
return this.isRecalibrationOnOrder;
default:
return null;
}
},
async handleInShopZipUpdated(newZip) {
this.zipCode = newZip;
const zipCodeData = await getZipCodeData(this.zipCode);

View file

@ -23,7 +23,7 @@ import partTypeStrings from '@/constants/part-type-strings';
import { useMainStore } from '@/store';
import { getPriceOfLineItem } from '@/helpers/price-calculator';
import { shallowRef } from 'vue';
import { containsRecalParts } from '@/helpers/recal-helper';
import { isRecalOrder } from '@/helpers/recal-helper';
const glassLocations = damageLocationsSelected;
@ -101,7 +101,7 @@ export default {
return modifiedAnswers;
},
isRecalibrationOnOrder() {
return this.mainStore.hasRecalibrationPart && containsRecalParts(this.mainStore.order.lineItems);
return isRecalOrder(this.mainStore.order.lineItems);
},
frontWipersApplicableForTierTwo() {
const frontWipersAreAvailable = this.lineItemsContainsPartType(partTypeStrings.FRONT_WIPER);