Merge branch 'CASH-1326-header-updates' of https://github.com/Safelite/DigitalConsumer.FixMyGlass into CASH-1326-header-updates

This commit is contained in:
Bryan Mauger 2025-08-04 12:21:06 -04:00
commit fe0c71c331
10 changed files with 191 additions and 85 deletions

View file

@ -27,4 +27,3 @@ ADMIN_SERVICE_API_URL="https://issadminapi.dev.sagaws.net/iss-admin/api/v1/"
# API authentication (replace with actual value when running tests) # API authentication (replace with actual value when running tests)
CCIS_API_AUTH="undefined" CCIS_API_AUTH="undefined"

View file

@ -131,24 +131,24 @@ export class BasePage {
} }
async validateProgressBar(progressPercentage: string, timeout: number = 60000) { async validateProgressBar(progressPercentage: string, timeout: number = 60000) {
// This section has been commented out until progress bar work is completed for parity.
// await waitUntil(async () => {
await waitUntil(async () => { // let loaderElements = await this.page.locator('button .loader, .buy-loader, timeout, .modal-loader').all();
let loaderElements = await this.page.locator('button .loader, .buy-loader, timeout, .modal-loader').all(); // return !(await Promise.any(loaderElements.map(el => el.isVisible())).catch(() => false));
return !(await Promise.any(loaderElements.map(el => el.isVisible())).catch(() => false)); // });
});
// Take a screenshot of the page before validating the progress bar // // Take a screenshot of the page before validating the progress bar
await this.page.screenshot({ path: `test-results\\ortoni-data\\progress-bar-${Date.now()}.png`, fullPage: true }); // await this.page.screenshot({ path: `test-results\\ortoni-data\\progress-bar-${Date.now()}.png`, fullPage: true });
// Wait until the progress bar element is attached and visible // // Wait until the progress bar element is attached and visible
const actualProgressPercentage = await this.progressBar.evaluate( // const actualProgressPercentage = await this.progressBar.evaluate(
async (element) => { // async (element) => {
await new Promise(resolve => setTimeout(resolve, 200)); // await new Promise(resolve => setTimeout(resolve, 200));
return element.style.width || "Not Found"; // return element.style.width || "Not Found";
} // }
); // );
Soft.expect(actualProgressPercentage).toBe(progressPercentage); // Soft.expect(actualProgressPercentage).toBe(progressPercentage);
console.log(`Progress Bar Percentage: Actual - ${actualProgressPercentage} vs Expected - ${progressPercentage}`); // console.log(`Progress Bar Percentage: Actual - ${actualProgressPercentage} vs Expected - ${progressPercentage}`);
} }
} }

View file

@ -95,7 +95,7 @@ const cashReplaceMultiGlassMobileTests: ITestCase[] = [];
const tc = { const tc = {
name: `CashReplaceMultiGlassMobile`, name: `CashReplaceMultiGlassMobile`,
tags: ['@E2E','@CashReplaceMultiGlassMobile', '@test_report', '@CASH'], tags: ['@E2E','@CashReplaceMultiGlassMobile', '@test_report', '@CASH', '@CASH-1182'],
testData: cashReplaceMultiGlassMobileData testData: cashReplaceMultiGlassMobileData
}; };
cashReplaceMultiGlassMobileTests.push(tc); cashReplaceMultiGlassMobileTests.push(tc);

View file

@ -77,7 +77,7 @@ const cashReplaceSafeliteCanNotRecalMobileTests: ITestCase[] = [];
const tc = { const tc = {
name: `CashReplaceSafeliteCanNotRecalMobile`, name: `CashReplaceSafeliteCanNotRecalMobile`,
tags: ['@E2E','@CashReplaceSafeliteCanNotRecalMobile', '@test_report', '@CASH'], tags: ['@E2E','@CashReplaceSafeliteCanNotRecalMobile', '@test_report', '@CASH', '@CASH-1182'],
testData: cashReplaceSafeliteCanNotRecalMobileData testData: cashReplaceSafeliteCanNotRecalMobileData
}; };
cashReplaceSafeliteCanNotRecalMobileTests.push(tc); cashReplaceSafeliteCanNotRecalMobileTests.push(tc);

View file

@ -66,7 +66,7 @@ const cashReplaceVinMobileTests: ITestCase[] = [];
const tc = { const tc = {
name: `CashReplaceVinMobile`, name: `CashReplaceVinMobile`,
tags: ['@E2E','@CashReplaceVinMobile', '@test_report', '@CASH'], tags: ['@E2E','@CashReplaceVinMobile', '@test_report', '@CASH', '@CASH-1182'],
testData: cashReplaceVinMobileData testData: cashReplaceVinMobileData
}; };
cashReplaceVinMobileTests.push(tc); cashReplaceVinMobileTests.push(tc);

View file

@ -1025,6 +1025,8 @@ export default {
flex-grow: 0; flex-grow: 0;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: flex-start;
text-align: left;
.duration-text-block { .duration-text-block {
text-align: left; text-align: left;
@ -1108,7 +1110,7 @@ export default {
grid-area: 1 / 1 / 2 / 5; grid-area: 1 / 1 / 2 / 5;
font-family: UrbanistBold; font-family: UrbanistBold;
color: $black; color: $black;
justify-content: center; justify-content: left;
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
.legend { .legend {
@ -1468,19 +1470,8 @@ export default {
display: flex; display: flex;
max-width: 100%; max-width: 100%;
flex-wrap: wrap; flex-wrap: wrap;
gap: 0 0.5rem;
& > div { & > div {
flex: 0 0 calc(50% - 0.25rem);
}
}
:deep(.button-question.is-mobile-appointment) {
.button-inner-wrapper > div {
flex: 0 0 100%;
}
}
:deep(.button-question.is-drop-off-appointment) {
.button-inner-wrapper > div {
flex: 0 0 100%; flex: 0 0 100%;
} }
} }

View file

@ -5,22 +5,6 @@
<div class="container page-container-grouped-styles"> <div class="container page-container-grouped-styles">
<div class="row"> <div class="row">
<div class="col-12 col-md-10 col-lg-8 col-xl-7"> <div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" class="mt-4" />
<serviceZipModalQuestion
editScreenReaderTextCmsWidgetName="ScreenReaderZipEditWidget"
v-model="serviceZipCodeQuestion"
ref="serviceZipCodeQuestion"
:carId="carId"
:isVehicleHeavyTruck="isVehicleHeavyTruck"
:mobileFeePart="mobileFeePart"
@updated-mobile-fee-part="setMobileFeePart"
@updated-recycle-fee-part="setRecycleFeePart"
@updated-serviceability="setServiceabilityDetails"
@updated-contains-military-base="setContainsMilitaryBase"
@updated-bill-to-account-number="setBillToAccountNumber"
@service-zip-changed-from-modal="onServiceZipChanged"
linkWidgetName="ServiceZipLinkWidget"
modalWidgetName="ServiceZipModalWidget" />
<alert <alert
ref="alertMilitaryBaseZip" ref="alertMilitaryBaseZip"
class="my-5" class="my-5"
@ -62,6 +46,7 @@
</div> </div>
<div class="row appointment-type"> <div class="row appointment-type">
<div class="col-12 col-md-10 col-lg-8 col-xl-7"> <div class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader cmsWidgetName="ScheduleYourServiceWidget" class="mt-4" />
<appointmentTypeQuestion <appointmentTypeQuestion
v-model="appointmentTypeFromAppointmentTypeQuestion" v-model="appointmentTypeFromAppointmentTypeQuestion"
v-show="isAppointmentTypeDisplayed" v-show="isAppointmentTypeDisplayed"
@ -77,21 +62,43 @@
labelBold="true" /> labelBold="true" />
</div> </div>
</div> </div>
<div
v-if="appointmentType && appointmentType === appointmentTypeStrings.MOBILE"
class="col-12 col-md-10 col-lg-8 col-xl-7">
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" class="mt-4" />
<serviceZipModalQuestion
editScreenReaderTextCmsWidgetName="ScreenReaderZipEditWidget"
v-model="serviceZipCodeQuestion"
ref="serviceZipCodeQuestion"
:carId="carId"
:isVehicleHeavyTruck="isVehicleHeavyTruck"
:mobileFeePart="mobileFeePart"
@updated-mobile-fee-part="setMobileFeePart"
@updated-recycle-fee-part="setRecycleFeePart"
@updated-serviceability="setServiceabilityDetails"
@updated-contains-military-base="setContainsMilitaryBase"
@updated-bill-to-account-number="setBillToAccountNumber"
@service-zip-changed-from-modal="onServiceZipChanged"
linkWidgetName="ServiceZipLinkWidget"
modalWidgetName="ServiceZipModalWidget" />
</div>
<div <div
class="row your-shop-location" class="row your-shop-location"
v-if="appointmentType && appointmentType !== appointmentTypeStrings.MOBILE"> v-if="appointmentType && appointmentType !== appointmentTypeStrings.MOBILE">
<div class="col-12 col-md-10 col-lg-8 col-xl-7"> <div class="col-12 col-md-10 col-lg-8 col-xl-7">
<button-question <div>
class="shop-question-button" <shopLocation
ref="buttonQuestion" v-if="
:answers="selectedShopAnswer" appointmentType && appointmentType !== appointmentTypeStrings.MOBILE
:modelValue="selectedProvider?.providerNumber" "
:isMultiSelect="false" :selectedShop="selectedShopAnswer"
:readonly="true" :selectedProviderNumberFromParent="selectedProvider?.providerNumber"
:questionText="questionText" :shopProviderDataFromParent="shopProviderData"
buttonTypeString="shopListButton" :zipCodeFromParent="zipCode"
:buttonTypeObject="shopListButton" :isShopQuestionDisplayed="isShopQuestionDisplayed"
groupName="chooseShop" /> @shop-selected="onShopSelected"
@updated-serviceability="setServiceabilityDetails" />
</div>
<div> <div>
<textBlock <textBlock
v-if="mobileFeeApplies && isMobileSelected" v-if="mobileFeeApplies && isMobileSelected"
@ -100,14 +107,6 @@
typeStyle="caption" typeStyle="caption"
class="ps-4 pe-4 mt-4" /> class="ps-4 pe-4 mt-4" />
</div> </div>
<shopQuestionPopup
v-if="isShopQuestionDisplayed"
:selectedProviderNumberFromParent="selectedProvider?.providerNumber"
:shopProviderDataFromParent="shopProviderData"
@shop-selected="onShopSelected"
@updated-serviceability="setServiceabilityDetails"
:zipCodeFromParent="zipCode"
cmsWidgetName="YourSafeliteShopWidget" />
<contentGroupModal ref="RecalModal" cmsWidgetName="RecalModal" /> <contentGroupModal ref="RecalModal" cmsWidgetName="RecalModal" />
</div> </div>
@ -158,9 +157,8 @@ import alert from "@/ux-components/alert/alert";
import serviceZipModalQuestion from "@/layouts/service-location/service-zip-modal-question/service-zip-modal-question"; import serviceZipModalQuestion from "@/layouts/service-location/service-zip-modal-question/service-zip-modal-question";
import appointmentTypeQuestion from "@/layouts/service-location/appointment-type-question/appointment-type-question"; import appointmentTypeQuestion from "@/layouts/service-location/appointment-type-question/appointment-type-question";
import shopQuestion from "@/layouts/service-location/shop-question/shop-question"; import shopQuestion from "@/layouts/service-location/shop-question/shop-question";
import shopQuestionPopup from "@/layouts/service-location/shop-question/shop-question-popup";
import buttonQuestion from "@/digital-components/button-question/button-question.vue";
import shopListButton from "@/layouts/service-location/shop-question/shop-list-button/shop-list-button"; import shopListButton from "@/layouts/service-location/shop-question/shop-list-button/shop-list-button";
import shopLocation from "@/layouts/schedule/shop-location/shop-location";
import funnelHeader from "@/fmg-components/funnel-header/funnel-header"; import funnelHeader from "@/fmg-components/funnel-header/funnel-header";
import navbar from "@/fmg-components/nav-bar/nav-bar"; import navbar from "@/fmg-components/nav-bar/nav-bar";
@ -769,21 +767,15 @@ export default {
const zipCode = this.selectedProvider.address.zipCode; const zipCode = this.selectedProvider.address.zipCode;
const distanceInMiles = provider ? Math.round(provider.distanceInMiles * 2) / 2 : 0; const distanceInMiles = provider ? Math.round(provider.distanceInMiles * 2) / 2 : 0;
return [ return {
{ city: `${city}`,
buttonLabel: `${city}`, distance: `${distanceInMiles} mi`,
buttonLabelSubCopy: `${distanceInMiles} mi`, address1: `${streetAddress}`,
buttonBodyCopy: `${streetAddress}, ${city}, ${state} ${zipCode}`, address2: `${city}, ${state} ${zipCode}`,
additionalButtonData: this.additionalButtonData, };
value: this.selectedProvider.providerNumber,
},
];
} }
return []; return [];
}, },
questionText() {
return this.getCmsContent("YourSafeliteShopWidget", "QuestionText");
},
appointmentTypeStrings() { appointmentTypeStrings() {
return AppointmentTypeStrings; return AppointmentTypeStrings;
}, },
@ -1740,8 +1732,7 @@ export default {
serviceZipModalQuestion, serviceZipModalQuestion,
appointmentTypeQuestion, appointmentTypeQuestion,
contentGroupModal, contentGroupModal,
shopQuestionPopup, shopLocation,
buttonQuestion,
}, },
}; };
</script> </script>
@ -1793,4 +1784,9 @@ export default {
background: $blue-100; background: $blue-100;
box-shadow: 0 0 0 1px $primary; box-shadow: 0 0 0 1px $primary;
} }
.container .row .col-12 .alert-success .alert-heading {
color: $black;
font-weight: 600;
}
</style> </style>

View file

@ -0,0 +1,120 @@
<template>
<div id="shop-location">
<textBlock :customText="questionText" typeStyle="button-question" />
<div>
<div>
<label v-for="addressItem in addressDetails" :key="addressItem">
{{ addressItem }}
</label>
</div>
<div>
<label>{{ selectedShop.distance }}</label>
</div>
</div>
<shopQuestionPopup
v-if="isShopQuestionDisplayed"
:selectedProviderNumberFromParent="selectedProviderNumberFromParent"
:shopProviderDataFromParent="shopProviderDataFromParent"
:zipCodeFromParent="zipCodeFromParent"
@shop-selected="onShopSelected"
@updated-serviceability="setServiceabilityDetails"
cmsWidgetName="YourSafeliteShopWidget" />
</div>
</template>
<script>
import textBlock from "@/digital-components/text-block/text-block";
import shopQuestionPopup from "@/layouts/service-location/shop-question/shop-question-popup";
export default {
name: "shopLocation",
props: {
selectedShop: {
type: Object,
default: () => ({
city: null,
distance: null,
address1: null,
address2: null,
}),
},
isShopQuestionDisplayed: {
type: Boolean,
default: false,
},
selectedProviderNumberFromParent: {
type: String,
default: null,
},
shopProviderDataFromParent: {
type: Object,
default: () => ({}),
},
zipCodeFromParent: {
type: String,
default: null,
},
},
computed: {
questionText() {
return this.getCmsContent("YourSafeliteShopWidget", "QuestionText");
},
addressDetails() {
const { distance, ...addressDetails } = this.selectedShop;
return addressDetails;
},
},
components: {
textBlock,
shopQuestionPopup,
},
methods: {
onShopSelected(shopQuestionPopUpData) {
this.$emit("shop-selected", shopQuestionPopUpData);
},
setServiceabilityDetails(serviceabilityDetails) {
this.$emit("updated-serviceability", serviceabilityDetails);
},
},
};
</script>
<style lang="scss" scoped>
#shop-location {
& > div {
display: flex;
justify-content: space-between;
& > div {
display: flex;
flex-direction: column;
label {
font-size: 0.875rem;
}
}
}
& > div.shop-question {
width: 172px;
}
}
</style>
<style lang="scss">
#shop-location {
& > div.shop-question {
width: fit-content;
background-color: $blue;
border-radius: $border-radius-pill;
padding: 0.75rem 3rem;
a {
text-decoration: none;
color: $white;
font-weight: $font-weight-600;
line-height: 1.5rem;
}
}
}
</style>

View file

@ -90,7 +90,7 @@ export default {
position: relative; position: relative;
background: $white; background: $white;
transition: all 150ms linear; transition: all 150ms linear;
border-radius: $border-radius-lg; border-radius: $border-radius-pill;
border: 1px solid $gray-500; border: 1px solid $gray-500;
width: 100%; width: 100%;
outline: none; outline: none;

View file

@ -28,7 +28,7 @@
position: relative; position: relative;
z-index: 5; z-index: 5;
@include box-shadow-hover($blue-300); @include box-shadow-hover($blue-300);
border-radius: 0.5rem; border-radius: $border-radius-pill;
} }
} }
} }