Merge pull request #3162 from Safelite/feature/CASH-2564

Feature/cash 2564
This commit is contained in:
kpatel8hs4io 2026-05-04 07:40:23 -04:00 committed by GitHub
commit eb517878d1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 517 additions and 68 deletions

View file

@ -9,8 +9,9 @@ SKIP_CONTENT_SITE="false"
# Experiments Flag
IS_MOBILEFIRST="false"
IS_ADYENPAYMENTS="false"
IS_ADYENPAYMENTS="true"
IS_MULTILOCATIONPOPUP="false"
IS_MSRSPLITPAY="false"
# Base URLs by environment
# qa

View file

@ -2,15 +2,16 @@
# Environment configuration
# Environment type
PLAYWRIGHT_ENV="qa"
PLAYWRIGHT_ENV="QA"
# Skip content site
SKIP_CONTENT_SITE="false"
# Experiments Flag
IS_MOBILEFIRST="false"
IS_ADYENPAYMENTS="false"
IS_ADYENPAYMENTS="true"
IS_MULTILOCATIONPOPUP="false"
IS_MSRSPLITPAY="false"
# Base URLs by environment
# qa

View file

@ -11,6 +11,10 @@ export interface ITestData extends base {
mockFirstInshopCallNoSchedule?: boolean,
handleMobileFirstModal?: boolean,
experiments?: IExperiments
isMSRGlassPart?: boolean,
isMSRZip?: boolean,
isPIAEnabled?: boolean,
isDualRecal?: boolean,
}
@ -19,5 +23,6 @@ export function getDefaultExperimentsData(): IExperiments {
isAdyenPayments: !!process.env.IS_ADYENPAYMENTS && process.env.IS_ADYENPAYMENTS !== "" ? process.env.IS_ADYENPAYMENTS === "true" : false,
isMobileFirst: !!process.env.IS_MOBILEFIRST && process.env.IS_MOBILEFIRST !== "" ? process.env.IS_MOBILEFIRST === "true" : false,
isMultiLocationPopup: !!process.env.IS_MULTILOCATIONPOPUP && process.env.IS_MULTILOCATIONPOPUP !== "" ? process.env.IS_MULTILOCATIONPOPUP === "true" : false,
isMsrSplitPay: !!process.env.IS_MSRSPLITPAY && process.env.IS_MSRSPLITPAY !== "" ? process.env.IS_MSRSPLITPAY === "true" : false,
}
}

View file

@ -1,5 +1,6 @@
export interface IExperiments {
isMobileFirst: boolean,
isAdyenPayments: boolean,
isMultiLocationPopup: boolean
isMultiLocationPopup: boolean,
isMsrSplitPay: boolean
}

View file

@ -19,6 +19,7 @@ export class BasePage {
readonly hamburgerMenu: Locator;
readonly progressBar: Locator;
readonly loaders: Locator;
readonly yellowAlertMessage: Locator;
constructor(page: Page) {
this.page = page;
@ -29,6 +30,7 @@ export class BasePage {
this.hamburgerMenu = this.page.getByRole('button', { name: 'Hamburger Menu (modal window)' });
this.progressBar = this.page.locator('.progress-bar-outer .progress-bar-inner');
this.loaders = this.page.locator('.spinner-border, .loader');
this.yellowAlertMessage = this.page.locator('.alert-warning');
}
async nextPage() {
@ -135,42 +137,30 @@ export class BasePage {
async mockScheduleResponseForFirstInshopCallNoSchedule(customerDetails: ICustomerDetails) {
let fistInshopScheduleCall = true;
// let fistInshopScheduleCall = true;
const apiUrl = `https://digitalapi.${process.env['PLAYWRIGHT_ENV']!.replace('sys', 'test').toLowerCase()}.safelite.io/schedule/api/v1/schedule/shop-time-slots`;
await this.page.route(apiUrl, async (route) => {
if (!fistInshopScheduleCall) {
/*if (!fistInshopScheduleCall) {
return route.continue();
}
// const fmt = (d: Date) => `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,"0")}-${String(d.getDate()).padStart(2,"0")}`;
// const startDate = new Date();
//const beginningOfWeek = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate() - startDate.getDay());
// const endDate = new Date(beginningOfWeek.getFullYear(), beginningOfWeek.getMonth(), beginningOfWeek.getDate() + 13);
// e.g., "2025-07-23"
/*if (route.request().postDataJSON().startDate === fmt(startDate) && route.request().postDataJSON().endDate === fmt(endDate)) {
const response = await route.fetch();
const responseBody = await response.json();
responseBody.days = [];
// Mock the response
await route.fulfill({
response,
body: JSON.stringify(responseBody),
});
}*/
const response = await route.fetch();
const responseBody = await response.json();
responseBody.days = [];
// Remove up to the first five items from the days array, keeping the rest; if empty, leave as is
if (Array.isArray(responseBody.days) && responseBody.days.length > 0) {
responseBody.days = responseBody.days.slice(5);
} else {
responseBody.days = [];
}
// Mock the response
await route.fulfill({
response,
body: JSON.stringify(responseBody),
});
fistInshopScheduleCall = false;
// fistInshopScheduleCall = false;
});
}
@ -252,9 +242,9 @@ export class BasePage {
if (experiments !== undefined) {
experimentsURLExtension += "?cns=all&experiments="
experimentsURLExtension += experiments?.isMobileFirst
/*experimentsURLExtension += experiments?.isMobileFirst
? "MobileFirstAppointment=MobileFirstAppt_V1=MobileFirstAppt_TEST=true"
: "MobileFirstAppointment=MobileFirstAppt_V1=MobileFirstAppt_CONTROL=true";
: "MobileFirstAppointment=MobileFirstAppt_V1=MobileFirstAppt_CONTROL=true";*/
experimentsURLExtension += experiments?.isAdyenPayments
? ",Adyen%20Payments=Adyen%20Payment%20Test=Adyen%20Payment%20(Test)=true"
@ -263,11 +253,15 @@ export class BasePage {
experimentsURLExtension += experiments?.isMultiLocationPopup
? ",MultiLocationPopup=MultiLocationPopup_V1=MultiLocationPopup_TEST=true"
: ",MultiLocationPopup=MultiLocationPopup_V1=MultiLocationPopup_CONTROL=true";
experimentsURLExtension += experiments?.isMsrSplitPay
? ",MSR=MSR_With_Splitpay=YesShowMSR_TEST=true"
: ",MSR=MSR_With_Splitpay=NoShowMSR_CONTROL=true";
} else {
console.log("Url extension without query string");
}
// Convert to HTML encoding before returning
return experimentsURLExtension;
return process.env.PLAYWRIGHT_ENV == 'sys' ? '' : experimentsURLExtension;
}
}

View file

@ -21,7 +21,7 @@ export class HomePage extends BasePage {
readonly viewQuoteButton: Locator;
//Zip Entry
readonly widgetZipEntryField: Locator;
readonly widgetZipEntryInputField: Locator;
readonly getQuoteAndScheduleButton: Locator;
url = process.env['BASE_URL']!;
@ -30,7 +30,7 @@ export class HomePage extends BasePage {
super(page);
this.page = page;
this.letsGetStartedButton = this.page.getByRole('button', { name: 'Let\'s get started' });
this.letsGetStartedButton = this.page.locator('a.zip-submit-button');
this.cusmodalPopup = this.page.locator('#Cusmodalpopup');
this.closePopupButton = this.page.getByRole('button', { name: '×' });
@ -46,7 +46,7 @@ export class HomePage extends BasePage {
this.viewQuoteButton = this.page.locator('#ctaSubmit');
//Zip Entry
this.widgetZipEntryField = this.page.getByRole('textbox', { name: 'Enter service ZIP code' });
this.widgetZipEntryInputField = this.page.locator('input#zipcode');
this.getQuoteAndScheduleButton = this.page.getByLabel('main').getByRole('link', { name: 'Get quote + schedule' });
}
@ -61,7 +61,7 @@ export class HomePage extends BasePage {
async letsGetStarted(zip: string, enterFunnelWithZip: boolean) {
if (enterFunnelWithZip) {
await this.widgetZipEntryField.fill(zip);
await this.widgetZipEntryInputField.fill(zip);
/* await this.letsGetStartedButton.evaluate((element, zip) => {
const currentHref = element.getAttribute('href') || '';
element.setAttribute('href', `${currentHref}?zipCode=${zip}`);

View file

@ -272,9 +272,10 @@ export class PaymentMethodPage extends BasePage {
if (await this.payAtServiceButton.isVisible()) {
await this.payAtServiceButton.click();
} else if (isRecalVehicle) {
await this.recalibrationCheckbox.click();
if (await this.recalibrationCheckbox.isVisible()) {
await this.recalibrationCheckbox.click();
}
}
}
async verifyVAPS(): Promise<void> {
@ -559,8 +560,10 @@ export class PaymentMethodPage extends BasePage {
await this.validateProgressBar(ProgressBarPercentages.PaymentMethodPage);
await this.validatePaymentDetailsPage(testData);
await this.ValidateAfterPayBreakOutSection();
if (testData.isPIAEnabled) {
await this.ValidateAfterPayBreakOutSection();
}
if (isForcedOEM) {
await this.validateOEMPart(isForcedOEM);
}

View file

@ -47,10 +47,10 @@ export class PaypalPage extends BasePage {
await this.page.screenshot({ path: `test-results\\ortoni-data\\paypal-username-${Date.now()}.png`, fullPage: true });
await this.usernameTextBox.fill(paymentDetails!.username!);
await this.nextButton.click();
if (!experiments!.isAdyenPayments){
/*if (!experiments!.isAdyenPayments){
await this.tryAnotherWayButton.click();
await this.usePasswordInsteadButton.click();
}
}*/
await this.passwordTextBox.fill(paymentDetails!.password!);
await this.paypalLoginButton.click();
await this.payWithRadioButton.click();

View file

@ -80,6 +80,15 @@ export class SchedulePage extends BasePage {
async selectLocation(testData: Partial<ITestData>) {
const { appointmentDetails, customerDetails } = testData;
if (testData.isMSRGlassPart || testData.isDualRecal) {
if (testData.isMSRZip) {
expect(await this.mobileButton.isVisible()).toBe(true);
} else {
expect(await this.mobileButton.isVisible()).toBe(false);
expect(await this.yellowAlertMessage.locator('.alert-heading').filter({ hasText: ' We\'re not able to provide mobile service.' }).isVisible()).toBe(true);
}
}
switch(appointmentDetails?.serviceLocation) {
case ServiceLocation.Mobile:
await this.scheduleMobile(testData);

View file

@ -5,6 +5,7 @@ import { ProgressBarPercentages } from 'framework/localTypes/Enums';
import { PaymentMethod } from "framework/localTypes/Enums";
import { step } from 'framework/localTypes/Step';
import { ITestData } from 'framework/TestData';
import { PaymentMethodPage } from './PaymentMethodPage';
export class ServicePackagesPage extends BasePage {
readonly page: Page;
@ -227,6 +228,32 @@ export class ServicePackagesPage extends BasePage {
}
}
async verifyGlassCashQuoteEvent() {
// Get displayed price text for Glass Only package (e.g. "$41.25in 4 interest-free payments\nor $164.99 in single payment")
const expectedGlassOnlyPrice = await this.glassOnlypackagePrice.innerText();
// Extract the single payment amount (e.g. 164.99) from the end of the string using regex
const singlePaymentRegex = /\$([\d,]+\.\d{2})\s*in single payment/;
const match = expectedGlassOnlyPrice.match(singlePaymentRegex);
if (!match) {
throw new Error(`Expected single payment price to be present in: ${expectedGlassOnlyPrice}`);
}
const expectedSinglePayAmount = parseFloat(match[1].replace(',', ''));
// Retrieve the dataLayer from the browser. (Assumes dataLayer is in global scope. Adjust if needed.)
const dataLayer = await this.page.evaluate(() => (window as any).dataLayer);
// Find the first object with a GlassCashQuote property and extract its value.
const glassCashQuote = dataLayer?.find((item: any) => item && item.GlassCashQuote)?.GlassCashQuote;
if (glassCashQuote === undefined || glassCashQuote === null) {
throw new Error("No GlassCashQuote found in dataLayer");
}
// Validate that the GlassCashQuote value matches the extracted expectedSinglePayAmount (with currency float precision)
Soft.expect(Number.parseFloat(glassCashQuote)).toBe(expectedSinglePayAmount);
}
@step("ServicePackagePage >> Select Payment Method and Service Type: ")
async handleServicePackagePage(testData: Partial<ITestData>) {
const { customerDetails, paymentMethod, paymentDetails, servicePackage, isCanNotRecal, isDynamicRecal, hasOemEndorsement, vehicleDamage, appointmentDetails, totalAmount } = testData;
@ -289,6 +316,10 @@ export class ServicePackagesPage extends BasePage {
await this.verifyVehicleParts(vehicleDamage!);
}
if (testData.paymentMethod == PaymentMethod.SelfPay) {
await this.verifyGlassCashQuoteEvent();
}
// Validate backend for OEM endorsement
if (hasOemEndorsement) {
await this.verifyOEMPart();

View file

@ -100,7 +100,8 @@ export default defineConfig({
headless: process.env.CI ? true : false,
screenshot: "only-on-failure",
actionTimeout: 60_000,
navigationTimeout: 60_000
navigationTimeout: 60_000,
bypassCSP: true
},
/* Configure projects for major browsers */

View file

@ -19,12 +19,14 @@ import { ApiResponseInterceptUtil } from 'safelite-playwright-core';
import cashReplaceGlassPromoInshopTests from "./CashReplaceGlassPromoInshop";
import cashReplaceMultiGlassPromoInshopTests from "./CashReplaceMultiGlassPromoInshop";
import cashReplaceStaticInshopTests from "./CashReplaceStaticInshop";
import cashReplaceStaticMobileMSRTests from "./CashReplaceStaticMobileMSR";
import cashReplaceRainDefensePromoInshopTests from "./CashReplaceRainDefensePromoInshop";
import cashReplaceSafeliteCanNotRecalMobileTests from "./CashReplaceSafeliteCanNotRecalMobile";
import cashReplaceVinMobileTests from "./CashReplaceVinMobile";
import cashReplaceWiperDropoffTests from "./CashReplaceWiperDropoff";
import cashReplaceWiperPromoInShopTests from "./CashReplaceWiperPromoInshop";
import insuranceAcuityPaypalTests from "./InsuranceAcuityPaypal";
// import insuranceUSAAMsrTests from "./InsuranceUSAAMsr";
import insuranceITAC21stCenturyTests from "./InsuranceITAC21stCentury";
import insuranceGeicoTests from "./InsuranceGeico";
import insuranceITACOptimizedPriceValidationAllStateTests from "./InsuranceITACOptimizedPriceValidationAllState";
@ -42,6 +44,9 @@ import insuranceBigTruckVerifiedTests from "./InsuranceBigTruckVerified";
import insuranceUnverifiedTests from "./InsuranceUnverified";
import CashReplaceSplitWindshieldTests from "./CashReplaceSplitWindshield";
import insuranceMeemicNearSchoolVerifiedTests from "./InsuranceMeemicNearSchoolVerified";
import cashReplaceDualMobileMSRTests from "./CashReplaceDualMobileMSR";
import cashReplaceDualNonMSRInshopTests from "./CashReplaceDualNonMSRInshop";
const test = getTestObject();
@ -78,12 +83,16 @@ const allStandardTests = [
{ name: "CashReplaceVinMobile", tests: cashReplaceVinMobileTests },
{ name: "CashReplaceWiperDropoff", tests: cashReplaceWiperDropoffTests },
{ name: "CashReplaceStaticInshop", tests: cashReplaceStaticInshopTests },
{ name: "CashReplaceDualMobileMSR", tests: cashReplaceDualMobileMSRTests },
{ name: "CashReplaceDualNonMSRInshop", tests: cashReplaceDualNonMSRInshopTests },
{ name: "CashReplaceStaticMobileMSR", tests: cashReplaceStaticMobileMSRTests },
{ name: "CashReplaceWiperPromoInshop", tests: cashReplaceWiperPromoInShopTests },
{ name: "CashReplaceSwitchToInsuranceProgressiveNoComp", tests: cashReplaceSwitchToInsuranceProgressiveNoCompTests },
{ name: "CashReplaceMobileFirstModal", tests: cashReplaceMobileFirstModalTests },
// { name: "CashReplaceMobileFirstModal", tests: cashReplaceMobileFirstModalTests },
// TODO: Uncomment when QA is ready to run heavy truck tests
// {name: "CashReplaceSplitWindshield", tests: CashReplaceSplitWindshieldTests},
{ name: "InsuranceAcuityPaypal", tests: insuranceAcuityPaypalTests },
// { name: "InsuranceUSAAMsr", tests: insuranceUSAAMsrTests },
{ name: "InsuranceITAC21stCentury", tests: insuranceITAC21stCenturyTests },
{ name: "InsuranceNoCompProgressive", tests: insuranceNoCompProgressiveTests },
// {name: "InsuranceBigTruckVerified", tests: insuranceBigTruckVerifiedTests},

View file

@ -38,7 +38,8 @@ const cashRepairInShopAfterPayData : Partial<ITestData> = {
// Experiments
experiments: {
...getDefaultExperimentsData()
...getDefaultExperimentsData(),
isAdyenPayments: true
}
}

View file

@ -0,0 +1,99 @@
//Imports here
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
import { ServicePackage, PaymentType, PartQuestionType, ServiceLocation } from 'safelite-playwright-core';
import { ITestCase } from '../framework/Typedefs'
import { VehicleLookupType } from 'safelite-playwright-core';
import { getDefaultTestData, setFakerSeedFromTestName } from 'safelite-playwright-core';
import { PaymentMethod } from 'framework/localTypes/Enums';
// Set the seed before generating any data
setFakerSeedFromTestName("CashReplaceDualMobileMSR");
// Now get the test data with the seeded faker
const CashReplaceDualMobileMSRData: Partial<ITestData> = {
...getDefaultTestData(), // Get default data with current seed
// CASH Client
paymentMethod: PaymentMethod.SelfPay,
// Key feature: Premium package with Rain Defense
servicePackage: ServicePackage.Standard,
// Flag for recalibration vehicle
isRecalVehicle: true,
// Override customer details
customerDetails: {
...getDefaultTestData().customerDetails!,
address: {
...getDefaultTestData().customerDetails!.address,
postalCode: '43085'
// postalCode: '21237'
}
},
// Override appointment details
appointmentDetails: {
serviceLocation: ServiceLocation.Mobile,
appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate,
serviceAddress: {
// Use street address from current faker seed
street: "649 High Street",
city: 'Worthington',
state: 'OH',
postalCode: '43085', //
country: 'United States'
},
},
// override part questions
partQuestions: [
{
partQuestionType: PartQuestionType.GeneralQuestion1,
isOnPage: true,
optionToSelect: 'Yes'
}
],
// Override vehicle details
vehicleDetails: {
...getDefaultTestData().vehicleDetails!,
year: '2020',
make: 'Honda',
model: 'Pilot',
style: '4 door utility',
vehicleLookupType: VehicleLookupType.Zip
},
mockFirstInshopCallNoSchedule: true,
isMSRGlassPart: true,
isMSRZip: true,
// No need to override vehicleDamage as it already defaults to WindshieldCrack
// Payment at service
paymentDetails: {
paymentType: PaymentType.PayAtService
},
// Flag for PIA disabled
isPIAEnabled: false,
// Experiments
experiments: {
...getDefaultExperimentsData()
}
}
const cashReplaceDualMobileMSRTests: ITestCase[] = [];
const tc = {
name: `CashReplaceDualMobileMSR`,
tags: ['@E2E', '@CashReplaceDualMobileMSR', '@test_report', '@CASH'],
testData: CashReplaceDualMobileMSRData
};
cashReplaceDualMobileMSRTests.push(tc);
export default cashReplaceDualMobileMSRTests;

View file

@ -0,0 +1,82 @@
//Imports here
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
import { ServicePackage, PaymentType, PartQuestionType, ServiceLocation } from 'safelite-playwright-core';
import { ITestCase } from '../framework/Typedefs'
import { VehicleLookupType } from 'safelite-playwright-core';
import { getDefaultTestData, setFakerSeedFromTestName } from 'safelite-playwright-core';
import { PaymentMethod } from 'framework/localTypes/Enums';
// Set the seed before generating any data
setFakerSeedFromTestName("CashReplaceDualNonMSRInshop");
// Now get the test data with the seeded faker
const CashReplaceDualMobileMSRData: Partial<ITestData> = {
...getDefaultTestData(), // Get default data with current seed
// CASH Client
paymentMethod: PaymentMethod.SelfPay,
// Key feature: Premium package with Rain Defense
servicePackage: ServicePackage.Standard,
// Flag for recalibration vehicle
isRecalVehicle: true,
// Override customer details
customerDetails: {
...getDefaultTestData().customerDetails!,
address: {
...getDefaultTestData().customerDetails!.address,
postalCode: '43085'
// postalCode: '21237'
}
},
// override part questions
partQuestions: [
{
partQuestionType: PartQuestionType.GeneralQuestion1,
isOnPage: true,
optionToSelect: 'Yes'
}
],
// Override vehicle details
vehicleDetails: {
...getDefaultTestData().vehicleDetails!,
year: '2024',
make: 'Subaru',
model: 'Ascent',
style: '4 door utility',
vehicleLookupType: VehicleLookupType.Zip
},
mockFirstInshopCallNoSchedule: true,
isMSRGlassPart: false,
isMSRZip: true,
// Payment at service
paymentDetails: {
paymentType: PaymentType.PayAtService
},
// Flag for PIA disabled
isPIAEnabled: false,
// Experiments
experiments: {
...getDefaultExperimentsData()
}
}
const cashReplaceDualNonMSRInshopTests: ITestCase[] = [];
const tc = {
name: `CashReplaceDualNonMSRInshop`,
tags: ['@E2E', '@CashReplaceDualNonMSRInshop', '@test_report', '@CASH'],
testData: CashReplaceDualMobileMSRData
};
cashReplaceDualNonMSRInshopTests.push(tc);
export default cashReplaceDualNonMSRInshopTests;

View file

@ -35,10 +35,10 @@ const cashReplaceGlassAddressLookupInshopAfterPayData: Partial<ITestData> = {
// Override vehicle details
vehicleDetails: {
...getDefaultTestData().vehicleDetails!,
year: '2013',
make: 'Hyundai',
model: 'Sonata',
style: '4 door sedan',
year: '2024',
make: 'Acura',
model: 'MDX',
style: '4 door utility',
vehicleLookupType: VehicleLookupType.Address
},
@ -48,7 +48,7 @@ const cashReplaceGlassAddressLookupInshopAfterPayData: Partial<ITestData> = {
// Experiments
experiments: {
...getDefaultExperimentsData()
}
}
}
const cashReplaceGlassAddressLookupInshopAfterPayTests: ITestCase[] = [];

View file

@ -35,9 +35,12 @@ const cashReplaceMultiGlassPromoInshopData: Partial<ITestData> = {
make: 'Subaru',
model: 'Outback',
style: '4 door station wagon',
vin: '4S4BSENC4K3221004',
vehicleLookupType: VehicleLookupType.Vin
// vin: '4S4BSENC4K3221004',
vehicleLookupType: VehicleLookupType.Zip
},
// Special flag to skip estimate page
isSkipEstimatePage: true,
// Key feature: multiple damaged glasses
vehicleDamage: [
@ -55,6 +58,15 @@ const cashReplaceMultiGlassPromoInshopData: Partial<ITestData> = {
// Add promo code
promoCode: '20CALL',
},
// override part questions
partQuestions: [
{
partQuestionType: PartQuestionType.GeneralQuestion1,
isOnPage: true,
optionToSelect: 'Yes'
}
],
// Vehicle part questions for multiple glass parts
vehiclePartQuestions: [
@ -62,7 +74,7 @@ const cashReplaceMultiGlassPromoInshopData: Partial<ITestData> = {
partQuestionType: PartQuestionType.WindshieldColor,
isOnPage: true,
optionToSelect: 'Green Tint, Blue Shade',
secondaryQuestionOptionToSelect: 'solar, lane departure warning system, heated glass wiper park, high beam assist, soundproofing'
secondaryQuestionOptionToSelect: 'solar, lane departure warning system, hwp, high beam assist, soundproofing'
},
{
partQuestionType: PartQuestionType.DriverFrontColor,

View file

@ -85,7 +85,7 @@ const cashReplaceMultiSlidingGlassDropoffData: Partial<ITestData> = {
partQuestionType: PartQuestionType.WindshieldColor,
isOnPage: true,
optionToSelect: 'Green Tint',
secondaryQuestionOptionToSelect: 'rain sensor, solar, soundproofing, third visor frit, lane departure warning system, heated glass wiper park, w/combination bracket'
secondaryQuestionOptionToSelect: 'rain sensor, solar, soundproofing, third visor frit, lane departure warning system, hwp, w/combination bracket'
},
{
partQuestionType: PartQuestionType.PassengerFrontColor,

View file

@ -15,19 +15,26 @@ const CashReplaceStaticInshopData: Partial<ITestData> = {
// CASH Client
paymentMethod: PaymentMethod.SelfPay,
// Key feature: Premium package with Rain Defense
servicePackage: ServicePackage.Standard,
// Flag for recalibration vehicle
isRecalVehicle: true,
// Flag for MSR Glass Part
isMSRGlassPart: true,
// Flag for MSR Zip
isMSRZip: false,
// Override customer details
customerDetails: {
...getDefaultTestData().customerDetails!,
address: {
...getDefaultTestData().customerDetails!.address,
postalCode: '43085'
postalCode: '55113' // Non MSR zip
// postalCode: '21237'
}
},
@ -37,34 +44,32 @@ const CashReplaceStaticInshopData: Partial<ITestData> = {
partQuestionType: PartQuestionType.GeneralQuestion1,
isOnPage: true,
optionToSelect: 'Yes'
},
{
partQuestionType: PartQuestionType.GeneralQuestion2,
isOnPage: true,
optionToSelect: 'Yes'
}
],
// Override vehicle details
vehicleDetails: {
...getDefaultTestData().vehicleDetails!,
year: '2022',
make: 'Mazda',
model: 'CX-9',
style: '4 door utility',
vin: '3FA6P0HD8LR234510',
year: '2023',
make: 'Hyundai',
model: 'Elantra',
style: '4 door sedan',
vehicleLookupType: VehicleLookupType.Zip
},
mockFirstInshopCallNoSchedule: true,
// No need to override vehicleDamage as it already defaults to WindshieldCrack
// Payment at service
paymentDetails: {
paymentType: PaymentType.PayAtService
},
// Flag for PIA disabled
isPIAEnabled: false,
// Experiments
experiments: {
...getDefaultExperimentsData()
@ -75,7 +80,7 @@ const cashReplaceStaticInshopTests: ITestCase[] = [];
const tc = {
name: `CashReplaceStaticInshop`,
tags: ['@E2E','@CashReplaceStaticInshop', '@test_report', '@CASH'],
tags: ['@E2E', '@CashReplaceStaticInshop', '@test_report', '@CASH'],
testData: CashReplaceStaticInshopData
};
cashReplaceStaticInshopTests.push(tc);

View file

@ -0,0 +1,92 @@
//Imports here
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
import { ServicePackage, PaymentType, PartQuestionType, ServiceLocation } from 'safelite-playwright-core';
import { ITestCase } from '../framework/Typedefs'
import { VehicleLookupType } from 'safelite-playwright-core';
import { getDefaultTestData, setFakerSeedFromTestName } from 'safelite-playwright-core';
import { PaymentMethod } from 'framework/localTypes/Enums';
// Set the seed before generating any data
setFakerSeedFromTestName("CashReplaceStaticMobileMSR");
// Now get the test data with the seeded faker
const CashReplaceStaticMobileMSRData: Partial<ITestData> = {
...getDefaultTestData(), // Get default data with current seed
// CASH Client
paymentMethod: PaymentMethod.SelfPay,
// Key feature: Premium package with Rain Defense
servicePackage: ServicePackage.Standard,
// Flag for recalibration vehicle
isRecalVehicle: true,
// Override customer details
customerDetails: {
...getDefaultTestData().customerDetails!,
address: {
...getDefaultTestData().customerDetails!.address,
postalCode: '43085'
// postalCode: '21237'
}
},
// override part questions
partQuestions: [
{
partQuestionType: PartQuestionType.GeneralQuestion1,
isOnPage: true,
optionToSelect: 'Yes'
}
],
// Override vehicle details
vehicleDetails: {
...getDefaultTestData().vehicleDetails!,
year: '2023',
make: 'Hyundai',
model: 'Elantra',
style: '4 door sedan',
vin: '3FA6P0HD8LR234510',
vehicleLookupType: VehicleLookupType.Zip
},
mockFirstInshopCallNoSchedule: true,
// No need to override vehicleDamage as it already defaults to WindshieldCrack
// Override appointment details
appointmentDetails: {
serviceLocation: ServiceLocation.Mobile,
appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate,
serviceAddress: {
// Use street address from current faker seed
street: "649 High Street",
city: 'Worthington',
state: 'OH',
postalCode: '43085', //
country: 'United States'
},
},
// Payment at service
paymentDetails: {
paymentType: PaymentType.PayAtService
},
// Experiments
experiments: {
...getDefaultExperimentsData()
}
}
const cashReplaceStaticMobileMSRTests: ITestCase[] = [];
const tc = {
name: `cashReplaceStaticMobileMSR`,
tags: ['@E2E','@cashReplaceStaticMobileMSR', '@test_report', '@CASH'],
testData: CashReplaceStaticMobileMSRData
};
cashReplaceStaticMobileMSRTests.push(tc);
export default cashReplaceStaticMobileMSRTests;

View file

@ -37,6 +37,8 @@ const cashReplaceSwitchToInsuranceProgressiveNoCompData: Partial<ITestData> = {
style: "4 door sedan"
},
isSkipEstimatePage: true,
partQuestions: [
{
partQuestionType: PartQuestionType.GeneralQuestion1,

View file

@ -0,0 +1,101 @@
//Imports here
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
import { ServiceLocation, DamageType, PartQuestionType, VehicleDamage, PaymentType, Flow } from 'safelite-playwright-core';
import { PaymentMethod } from "framework/localTypes/Enums";
import { ITestCase } from '../framework/Typedefs'
import { VehicleLookupType } from 'safelite-playwright-core';
import { getDefaultTestData, setFakerSeedFromTestName } from 'safelite-playwright-core';
// Set the seed based on test name for consistent but unique data
setFakerSeedFromTestName("InsuranceUSAAMsr");
// Now get the test data with the seeded faker
const insuranceUSAAMsrData: Partial<ITestData> = {
...getDefaultTestData(), // Get default data with current seed
// Key feature: Insurance flow with Acuity
paymentMethod: PaymentMethod.Insurance,
// Insurance claim flags
isDuplicateClaim: true,
flow: Flow.Managed,
isUseVehicleOnPolicy: true,
// Override customer details for Kentucky location
customerDetails: {
...getDefaultTestData().customerDetails!,
address: {
street: getDefaultTestData().customerDetails!.address.street,
city: 'Cleaveland',
state: 'Ohio',
postalCode: '44125',
country: 'United States'
}
},
// Insurance claim details
claimDetails: {
client: 'USAA',
policyNumber: 'MOCK900040MSR',
policyDeductible: 100.00,
damageDate: new Date(new Date().setDate(new Date().getDate() - 1)).toLocaleDateString('en-US', {month: '2-digit', day: '2-digit', year: 'numeric'}),
damageCause: DamageType.Rock
},
// Heavy duty truck details with VIN lookup
vehicleDetails: {
...getDefaultTestData().vehicleDetails!,
year: '2023',
make: 'Hyundai',
model: 'Elantra',
style: '4 door sedan'
},
isRecalVehicle: true,
// No need to override vehicleDamage as it already defaults to WindshieldCrack
// Override for mobile service
appointmentDetails: {
serviceLocation: ServiceLocation.Mobile,
appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate,
serviceAddress: {
// Use street address from current faker seed
street: "13300 Carpenter Rd",
city: 'Cleveland',
state: 'OH',
postalCode: '44125',
country: 'United States'
}
},
// Part questions for windshield
partQuestions: [
{
partQuestionType: PartQuestionType.GeneralQuestion1,
isOnPage: true,
optionToSelect: 'Yes'
},
],
// Override payment details (empty because we skip payment method page in insurance flow)
paymentDetails: {
paymentType: PaymentType.PayAtService
},
// Experiments
experiments: {
...getDefaultExperimentsData()
}
}
const insuranceUSAAMsrTests: ITestCase[] = [];
const tc = {
name: `InsuranceUSAAMsr`,
tags: ['@E2E','@InsuranceAcuityPaypal', '@test_report', '@Insurance', '@CASH-1187', '@CASH-848'],
testData: insuranceUSAAMsrData
};
insuranceUSAAMsrTests.push(tc);
export default insuranceUSAAMsrTests;