Merge branch 'develop' into feature/kroell/INSR-8907
# Conflicts: # src/layouts/schedule-page/schedule-page.vue
This commit is contained in:
commit
a9b6e91dc3
84 changed files with 1624 additions and 698 deletions
|
|
@ -14,7 +14,7 @@ resources:
|
||||||
type: github
|
type: github
|
||||||
name: Safelite/AzureDevOps
|
name: Safelite/AzureDevOps
|
||||||
endpoint: Safelite
|
endpoint: Safelite
|
||||||
ref: refs/tags/t5.7.40
|
ref: refs/tags/t5.7.53
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
# - group: Digital-Infrastructure
|
# - group: Digital-Infrastructure
|
||||||
|
|
|
||||||
|
|
@ -272,6 +272,8 @@ stages:
|
||||||
__VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__)
|
__VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__)
|
||||||
__VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__)
|
__VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__)
|
||||||
__VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__)
|
__VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__)
|
||||||
|
__VUE_APP_ADYEN_ENVIRONMENT__: $(__VUE_APP_ADYEN_ENVIRONMENT__)
|
||||||
|
__VUE_APP_ADYEN_CLIENT_KEY__: $(__VUE_APP_ADYEN_CLIENT_KEY__)
|
||||||
indexDeployVariables:
|
indexDeployVariables:
|
||||||
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
|
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
|
||||||
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
|
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
|
||||||
|
|
@ -335,6 +337,8 @@ stages:
|
||||||
__VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__)
|
__VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__)
|
||||||
__VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__)
|
__VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__)
|
||||||
__VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__)
|
__VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__)
|
||||||
|
__VUE_APP_ADYEN_ENVIRONMENT__: $(__VUE_APP_ADYEN_ENVIRONMENT__)
|
||||||
|
__VUE_APP_ADYEN_CLIENT_KEY__: $(__VUE_APP_ADYEN_CLIENT_KEY__)
|
||||||
indexDeployVariables:
|
indexDeployVariables:
|
||||||
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
|
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
|
||||||
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
|
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
|
||||||
|
|
@ -398,6 +402,8 @@ stages:
|
||||||
__VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__)
|
__VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__)
|
||||||
__VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__)
|
__VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__)
|
||||||
__VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__)
|
__VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__)
|
||||||
|
__VUE_APP_ADYEN_ENVIRONMENT__: $(__VUE_APP_ADYEN_ENVIRONMENT__)
|
||||||
|
__VUE_APP_ADYEN_CLIENT_KEY__: $(__VUE_APP_ADYEN_CLIENT_KEY__)
|
||||||
indexDeployVariables:
|
indexDeployVariables:
|
||||||
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
|
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
|
||||||
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
|
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
|
||||||
|
|
@ -461,6 +467,8 @@ stages:
|
||||||
__VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__)
|
__VUE_APP_CUSTOMER_PORTAL_URL__: $(__VUE_APP_CUSTOMER_PORTAL_URL__)
|
||||||
__VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__)
|
__VUE_APP_GOOGLE_PLACES_API_KEY__: $(__VUE_APP_GOOGLE_PLACES_API_KEY__)
|
||||||
__VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__)
|
__VUE_APP_SAFELITE_HOP__: $(__VUE_APP_SAFELITE_HOP__)
|
||||||
|
__VUE_APP_ADYEN_ENVIRONMENT__: $(__VUE_APP_ADYEN_ENVIRONMENT__)
|
||||||
|
__VUE_APP_ADYEN_CLIENT_KEY__: $(__VUE_APP_ADYEN_CLIENT_KEY__)
|
||||||
indexDeployVariables:
|
indexDeployVariables:
|
||||||
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
|
__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__: $(__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__)
|
||||||
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
|
__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__: $(__VUE_APP_GOOGLE_TAG_MANAGER_NOSCRIPT_FRAME_SRC__)
|
||||||
|
|
|
||||||
34
package-lock.json
generated
34
package-lock.json
generated
|
|
@ -3925,9 +3925,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@stylistic/eslint-plugin/node_modules/picomatch": {
|
"node_modules/@stylistic/eslint-plugin/node_modules/picomatch": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
|
||||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
@ -8048,7 +8048,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cosmiconfig/node_modules/yaml": {
|
"node_modules/cosmiconfig/node_modules/yaml": {
|
||||||
"version": "1.10.2",
|
"version": "1.10.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz",
|
||||||
|
"integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
@ -8341,7 +8343,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/cssnano/node_modules/yaml": {
|
"node_modules/cssnano/node_modules/yaml": {
|
||||||
"version": "1.10.2",
|
"version": "1.10.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz",
|
||||||
|
"integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
@ -16002,7 +16006,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-forge": {
|
"node_modules/node-forge": {
|
||||||
"version": "1.3.2",
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "(BSD-3-Clause OR GPL-2.0)",
|
"license": "(BSD-3-Clause OR GPL-2.0)",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
@ -16769,7 +16775,9 @@
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/picomatch": {
|
"node_modules/picomatch": {
|
||||||
"version": "2.3.1",
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
|
||||||
|
"integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
@ -19734,7 +19742,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tinyglobby/node_modules/picomatch": {
|
"node_modules/tinyglobby/node_modules/picomatch": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
|
||||||
|
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
@ -20483,7 +20493,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vite/node_modules/picomatch": {
|
"node_modules/vite/node_modules/picomatch": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
|
||||||
|
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
@ -20565,7 +20577,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/vitest/node_modules/picomatch": {
|
"node_modules/vitest/node_modules/picomatch": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
|
||||||
|
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
||||||
|
|
@ -235,6 +235,7 @@ const defaultAfterpayDetails: IPaymentDetails = {
|
||||||
|
|
||||||
const defaultPaypalDetails: IPaymentDetails = {
|
const defaultPaypalDetails: IPaymentDetails = {
|
||||||
paymentType: PaymentType.Paypal,
|
paymentType: PaymentType.Paypal,
|
||||||
|
username:'Itqatest@safelite.com',
|
||||||
password: 'Safelite1'
|
password: 'Safelite1'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,8 @@ export interface IAppointmentDetails {
|
||||||
serviceAddress?: IAddress, // Used for mobile
|
serviceAddress?: IAddress, // Used for mobile
|
||||||
isVehicleProtected?: boolean // Used for mobile
|
isVehicleProtected?: boolean // Used for mobile
|
||||||
alternateServiceZip?: string // Used for in-shop and drop-off if doing service in a different ZIP
|
alternateServiceZip?: string // Used for in-shop and drop-off if doing service in a different ZIP
|
||||||
|
alternateMobileCity?: string // Used for mobile if doing service in a different city then customers address
|
||||||
|
alternateMobileStreetAddress?: string // Used for mobile if doing service in a different street address then customers address
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPartQuestion {
|
export interface IPartQuestion {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export enum DamageType {
|
||||||
Theft = 'Attempted theft or theft',
|
Theft = 'Attempted theft or theft',
|
||||||
Hail = 'Hailstorm',
|
Hail = 'Hailstorm',
|
||||||
HurricaneStorm = 'Hurricane/storm',
|
HurricaneStorm = 'Hurricane/storm',
|
||||||
Collision = 'Collision',
|
OtherWeather = 'Other weather',
|
||||||
Object = 'Object hit glass',
|
Object = 'Object hit glass',
|
||||||
Other = 'Other/unknown'
|
Other = 'Other/unknown'
|
||||||
}
|
}
|
||||||
|
|
@ -90,7 +90,11 @@ export enum PartQuestionType {
|
||||||
RearWindowColor = 'Rear-Stationary',
|
RearWindowColor = 'Rear-Stationary',
|
||||||
LeatherSeats = 'question-0-1',
|
LeatherSeats = 'question-0-1',
|
||||||
DriverSideColor = 'Driver-SideDoor',
|
DriverSideColor = 'Driver-SideDoor',
|
||||||
LaneKeepAssist = 'question-0-1'
|
LaneKeepAssist = 'question-0-1',
|
||||||
|
GeneralQuestion1 = "question-0-1",
|
||||||
|
GeneralQuestion2 = "question-0-2",
|
||||||
|
GeneralQuestion3 = "question-0-3",
|
||||||
|
GeneralQuestion4 = "question-0-4"
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum PaymentType{
|
export enum PaymentType{
|
||||||
|
|
@ -133,19 +137,23 @@ export enum SideDoorDamage{
|
||||||
|
|
||||||
export enum BailoutCode {
|
export enum BailoutCode {
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
SaveSessionError,
|
SaveSessionError = 1,
|
||||||
VehicleNotFound,
|
VehicleNotFound = 2,
|
||||||
VehicleLookupError,
|
VehicleVinLookupError = 3,
|
||||||
CoverageStatementInvalidState,
|
CoverageStatementInvalidState = 4,
|
||||||
DoNotSeeMyShop,
|
DoNotSeeMyShop = 5,
|
||||||
PricingResponseError,
|
PricingResponseError = 6,
|
||||||
TPANotEnabled,
|
TPANotEnabled = 7,
|
||||||
RequestCallback,
|
RequestCallback = 8,
|
||||||
HeavyTruckVehicle,
|
HeavyTruckVehicle = 9,
|
||||||
NoPartsAvailable,
|
NoPartsAvailable = 10,
|
||||||
PartsServiceError,
|
PartsServiceError = 11,
|
||||||
SafeliteNotTheProvider,
|
SafeliteNotTheProvider = 12,
|
||||||
VehicleYMMSLookupError
|
VehicleYMMSLookupError = 13,
|
||||||
|
ApplicationError = 14,
|
||||||
|
ApiError = 15,
|
||||||
|
RouterError = 16,
|
||||||
|
CoverageCancelledByUser = 17
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum SignatureAlgorithm {
|
export enum SignatureAlgorithm {
|
||||||
|
|
@ -171,3 +179,32 @@ export enum Authentication {
|
||||||
RSATokenEncParamsOneTimeUse = 'RSATokenEncParamsOneTimeUse',
|
RSATokenEncParamsOneTimeUse = 'RSATokenEncParamsOneTimeUse',
|
||||||
Unknown = 'Unknown',
|
Unknown = 'Unknown',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Add validations for the percentages on each page like url validations
|
||||||
|
export enum ProgressBarPercentage {
|
||||||
|
DuplicateCheckPage = '15%',
|
||||||
|
PolicyVehiclesPage = '20%',
|
||||||
|
PolicyEndorsementsPage = '20%',
|
||||||
|
VehicleSelectionPage = '25%',
|
||||||
|
PolicyHolderDetailsPage = '30%',
|
||||||
|
VehicleDamagePage = '35%',
|
||||||
|
PartQuestionsPage = '40%',
|
||||||
|
MoldingQuestionsPage = '45%',
|
||||||
|
VehiclePartsPage = '45%',
|
||||||
|
CapabilityQuestionsPage = '45%',
|
||||||
|
VehicleLookupPage = '45%',
|
||||||
|
VinLookupPage = '50%',
|
||||||
|
LicensePlateLookupPage = '50%',
|
||||||
|
AddressLookupPage = '50%',
|
||||||
|
AddressVehiclesPage = '50%',
|
||||||
|
CoverageStatementPage = '55%',
|
||||||
|
ProviderPreferencePage = '60%',
|
||||||
|
SchedulePage = '70%',
|
||||||
|
ServicePackagesPage = '75%',
|
||||||
|
ContactDetailsPage = '85%',
|
||||||
|
PaymentMethodPage = '95%',
|
||||||
|
PaymentPage = '0%',
|
||||||
|
OrderConfirmationPage = '100%',
|
||||||
|
TpaSearchPage = '80%',
|
||||||
|
TpaSubmitPage = '95%',
|
||||||
|
}
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
export default interface IBailoutFlags {
|
export default interface IBailoutFlags {
|
||||||
isVehicleSelectBailout: boolean,
|
isVehicleSelectBailout: boolean,
|
||||||
isDoNotSeeMyShopBailout: boolean,
|
|
||||||
isTpaNotEnabledBailout: boolean,
|
isTpaNotEnabledBailout: boolean,
|
||||||
isRequestCallbackBailout: boolean,
|
isRequestCallbackBailout: boolean,
|
||||||
isHeavyTruckVehicleBailout: boolean,
|
isHeavyTruckVehicleBailout: boolean,
|
||||||
isPartsServiceErrorBailout: boolean,
|
isPartsServiceErrorBailout: boolean,
|
||||||
isSafeliteNotTheProviderBailout: boolean,
|
isSafeliteNotTheProviderBailout: boolean,
|
||||||
isVehicleLookupBailout: boolean,
|
isVehicleLookupBailout: boolean,
|
||||||
isPriceServiceErrorBailout: boolean
|
isPriceServiceErrorBailout: boolean,
|
||||||
|
isCoverageCancelledByUser: boolean,
|
||||||
|
isAPIErrorBailout: boolean
|
||||||
}
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ export interface ITestData {
|
||||||
clientTag: string,
|
clientTag: string,
|
||||||
isDuplicateClaim: boolean,
|
isDuplicateClaim: boolean,
|
||||||
isPolicyFound: boolean, // Effective difference between advanced and essential
|
isPolicyFound: boolean, // Effective difference between advanced and essential
|
||||||
|
isUnverifiedPolicyAfterVehicleLookup: boolean, // Changing license plate can cause flow to change to unverified from verified
|
||||||
isUseVehicleOnPolicy: boolean, // Should we use the vehicle on the policy?
|
isUseVehicleOnPolicy: boolean, // Should we use the vehicle on the policy?
|
||||||
isVehicleLookupValidations: boolean, // Should we validate vehicle lookup?
|
isVehicleLookupValidations: boolean, // Should we validate vehicle lookup?
|
||||||
isAddressLookupValidations: boolean, // Should we validate address lookup errors?
|
isAddressLookupValidations: boolean, // Should we validate address lookup errors?
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ export default class CcisApiUtil {
|
||||||
createFakeResponse(requestBody: IPostSaveFakeResponseRequestBody) {
|
createFakeResponse(requestBody: IPostSaveFakeResponseRequestBody) {
|
||||||
return axios.post(this.postCreateMockPolicyUrl, requestBody, {
|
return axios.post(this.postCreateMockPolicyUrl, requestBody, {
|
||||||
headers: {
|
headers: {
|
||||||
'X-Mule-Origin-Verify': authToken
|
'X-Mule-Origin-Verify': authToken,
|
||||||
|
'x-Application-Name': 'ISS Playwright'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -21,7 +22,8 @@ export default class CcisApiUtil {
|
||||||
const deleteUrl = `${this.deleteFakeResponseUrl}/${params.accountNumber}/${params.key}/${params.responseType}`;
|
const deleteUrl = `${this.deleteFakeResponseUrl}/${params.accountNumber}/${params.key}/${params.responseType}`;
|
||||||
return axios.delete(deleteUrl, {
|
return axios.delete(deleteUrl, {
|
||||||
headers: {
|
headers: {
|
||||||
'X-Mule-Origin-Verify': authToken
|
'X-Mule-Origin-Verify': authToken,
|
||||||
|
'x-Application-Name': 'ISS Playwright'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ export class AddressLookupPage extends BasePage {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.addressForm = new AddressForm(page);
|
this.addressForm = new AddressForm(page);
|
||||||
this.addressNoMatchTextBox = page.getByText('Your address didn’t return a VIN matchPlease re-enter the information below or');
|
this.addressNoMatchTextBox = page.getByText('Your address didn’t return a VIN match');
|
||||||
this.stateRestrictionsTextBox = page.getByText('State restrictionsLooks like');
|
this.stateRestrictionsTextBox = page.getByText('State restrictionsLooks like');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,34 +1,31 @@
|
||||||
import { Locator, Page } from "@playwright/test";
|
import { Locator, Page } from "@playwright/test";
|
||||||
import { BasePage } from "./BasePage";
|
import { BasePage } from "./BasePage";
|
||||||
import { IPaymentDetails } from "@business-logic/types/CustomerDetails";
|
import { IClaimDetails, IPaymentDetails } from "@business-logic/types/CustomerDetails";
|
||||||
|
import { ServicePackage } from "@business-logic/types/Enums";
|
||||||
|
|
||||||
export class AfterpayPage extends BasePage {
|
export class AfterpayPage extends BasePage {
|
||||||
readonly page: Page;
|
readonly page: Page;
|
||||||
readonly submitButton: Locator;
|
|
||||||
|
|
||||||
// Login
|
|
||||||
readonly passwordTextBox: Locator;
|
readonly passwordTextBox: Locator;
|
||||||
|
readonly submitButton: Locator;
|
||||||
// Card details
|
|
||||||
readonly cardholderNameTextBox: Locator;
|
|
||||||
readonly cardNumberTextBox: Locator;
|
|
||||||
readonly expirationDateTextBox: Locator;
|
|
||||||
readonly cvvTextBox: Locator;
|
|
||||||
|
|
||||||
readonly confirmButton: Locator;
|
readonly confirmButton: Locator;
|
||||||
|
|
||||||
|
readonly selectAfterpayWithInterestButton: Locator;
|
||||||
|
readonly selectAfterpayWithoutInterestButton: Locator;
|
||||||
|
readonly continueAfterpayButton: Locator;
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.passwordTextBox = page.getByRole('textbox', { name: 'Please enter your password' });
|
this.passwordTextBox = page.getByTestId('login-password-input');
|
||||||
this.submitButton = page.getByRole('button', { name: 'Continue' });
|
this.submitButton = page.getByRole('button', { name: 'Continue' });
|
||||||
|
|
||||||
this.cardholderNameTextBox = page.getByTestId('payment-method-cardHolderName-input');
|
|
||||||
this.cardNumberTextBox = page.getByTestId('payment-method-cardNumber-input');
|
|
||||||
this.expirationDateTextBox = page.getByTestId('payment-method-cardExpiry-input');
|
|
||||||
this.cvvTextBox = page.getByTestId('payment-method-cardCvv-input');
|
|
||||||
|
|
||||||
this.confirmButton = page.getByRole('button', { name: 'Confirm' });
|
this.confirmButton = page.getByRole('button', { name: 'Confirm' });
|
||||||
|
|
||||||
|
// Monthly with interest option
|
||||||
|
this.selectAfterpayWithInterestButton = page.getByRole('radio', { name: /month/ });
|
||||||
|
// Biweekly without interest option
|
||||||
|
this.selectAfterpayWithoutInterestButton = page.getByTestId('payment-types-label').filter({ hasText: /every 2 weeks/ });
|
||||||
|
this.continueAfterpayButton = page.getByRole('button', { name: 'Continue' });
|
||||||
}
|
}
|
||||||
|
|
||||||
async login(password: string) {
|
async login(password: string) {
|
||||||
|
|
@ -36,21 +33,28 @@ export class AfterpayPage extends BasePage {
|
||||||
await this.submitButton.click();
|
await this.submitButton.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
async populateCardDetails(paymentDetails: IPaymentDetails) {
|
async executeAfterpayPayment(paymentDetails: IPaymentDetails, claimDetails: IClaimDetails, servicePackage: ServicePackage) {
|
||||||
await this.cardholderNameTextBox.fill('Roberts'); // TODO: Add cardholder name field
|
|
||||||
await this.cardNumberTextBox.fill(paymentDetails.cardNumber!);
|
const confirmButtonOrPaymentOptions = this.confirmButton.or(this.selectAfterpayWithoutInterestButton);
|
||||||
await this.expirationDateTextBox.fill(`${paymentDetails.expirationMonth}/${paymentDetails.expirationYear}`);
|
|
||||||
await this.cvvTextBox.fill(paymentDetails.cvv!);
|
|
||||||
await this.submitButton.click();
|
|
||||||
}
|
|
||||||
|
|
||||||
async executeAfterpayPayment(paymentDetails: IPaymentDetails) {
|
|
||||||
await this.login(paymentDetails.password!);
|
await this.login(paymentDetails.password!);
|
||||||
|
|
||||||
await this.populateCardDetails(paymentDetails);
|
await this.page.locator('div[data-testid=\'loading-icon-svg\']').filter({ visible: true}).first().waitFor({ state: 'hidden' });
|
||||||
|
await confirmButtonOrPaymentOptions.waitFor({ state: 'visible' });
|
||||||
|
|
||||||
|
if (await this.confirmButton.isVisible()) {
|
||||||
|
await this.confirmButton.waitFor({ state: 'attached' });
|
||||||
|
await this.confirmButton.click();
|
||||||
|
} else {
|
||||||
|
// For some orders, user will have 2 options to choose from: monthly with interest or biweekly without interest
|
||||||
|
if (await this.selectAfterpayWithoutInterestButton.isVisible()) {
|
||||||
|
await this.selectAfterpayWithoutInterestButton.click();
|
||||||
|
await this.continueAfterpayButton.click();
|
||||||
|
} else if (await this.selectAfterpayWithInterestButton.isVisible()) {
|
||||||
|
await this.selectAfterpayWithInterestButton.click();
|
||||||
|
await this.continueAfterpayButton.click();
|
||||||
|
}
|
||||||
await this.confirmButton.click();
|
await this.confirmButton.click();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -28,8 +28,7 @@ export class BailoutPage extends BasePage {
|
||||||
await expect.soft(this.firstNameTextBox).toHaveValue(customerDetails.firstName);
|
await expect.soft(this.firstNameTextBox).toHaveValue(customerDetails.firstName);
|
||||||
await expect.soft(this.lastNameTextBox).toHaveValue(customerDetails.lastName);
|
await expect.soft(this.lastNameTextBox).toHaveValue(customerDetails.lastName);
|
||||||
await expect.soft(this.phoneNumberTextBox).toHaveValue(customerDetails.phoneNumber);
|
await expect.soft(this.phoneNumberTextBox).toHaveValue(customerDetails.phoneNumber);
|
||||||
await expect.soft(this.emailAddressTextBox).toHaveValue(customerDetails.email);
|
expect.soft(await this.getBailoutCode()).toEqual(bailoutCode);
|
||||||
await expect.soft(await this.getBailoutCode()).toEqual(bailoutCode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async validateBailoutDetailsNotNull(){
|
async validateBailoutDetailsNotNull(){
|
||||||
|
|
@ -41,7 +40,7 @@ export class BailoutPage extends BasePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
async getBailoutCode() {
|
async getBailoutCode() {
|
||||||
const mainLocalStorage = JSON.parse(await this.page.evaluate('localStorage.getItem(\'main\')'));
|
const mainLocalStorage = JSON.parse(await this.page.evaluate('sessionStorage.getItem(\'main\')'));
|
||||||
const bailoutCode = mainLocalStorage.applicationUser.pageData['bailout-page'].bailoutCode as number;
|
const bailoutCode = mainLocalStorage.applicationUser.pageData['bailout-page'].bailoutCode as number;
|
||||||
return bailoutCode;
|
return bailoutCode;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,8 @@ export class BasePage {
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.continueButton = page.locator('[id="infoBox"]').getByRole('button');
|
this.continueButton = page.locator('button[data-test-id="site-footer-main-button"]')
|
||||||
|
.and(page.locator('button', { hasText: /get\s*started|continue|submit/i }));
|
||||||
this.pageSpinner = page.getByRole('status');
|
this.pageSpinner = page.getByRole('status');
|
||||||
this.buttonLoadSpin = page.getByRole('alert');
|
this.buttonLoadSpin = page.getByRole('alert');
|
||||||
}
|
}
|
||||||
|
|
@ -95,16 +96,16 @@ export class BasePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
async logReferralNumber() {
|
async logReferralNumber() {
|
||||||
let mainLocalStorage = JSON.parse(await this.page.evaluate('localStorage.getItem(\'main\')'));
|
let mainSessionStorage = JSON.parse(await this.page.evaluate('sessionStorage.getItem(\'main\')'));
|
||||||
let referralNumber = mainLocalStorage.order.referralNumber as number;
|
let referralNumber = mainSessionStorage.order.referralNumber as number;
|
||||||
let referralSequenceNumber = mainLocalStorage.order.referralSequenceNumber as number;
|
let referralSequenceNumber = mainSessionStorage.order.referralSequenceNumber as number;
|
||||||
if (referralNumber == null) {
|
if (referralNumber == null) {
|
||||||
for (let i = 1; i <= 20; i++) {
|
for (let i = 1; i <= 20; i++) {
|
||||||
if (!referralNumber == null) break;
|
if (!referralNumber == null) break;
|
||||||
await this.page.waitForTimeout(500);
|
await this.page.waitForTimeout(500);
|
||||||
mainLocalStorage = JSON.parse(await this.page.evaluate('localStorage.getItem(\'main\')'));
|
mainSessionStorage = JSON.parse(await this.page.evaluate('localStorage.getItem(\'main\')'));
|
||||||
referralNumber = mainLocalStorage.order.referralNumber as number;
|
referralNumber = mainSessionStorage.order.referralNumber as number;
|
||||||
referralSequenceNumber = mainLocalStorage.order.referralSequenceNumber as number;
|
referralSequenceNumber = mainSessionStorage.order.referralSequenceNumber as number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,35 +6,57 @@ export class ContactDetailsPage extends BasePage {
|
||||||
readonly page: Page;
|
readonly page: Page;
|
||||||
issPageValue = 'contact-details';
|
issPageValue = 'contact-details';
|
||||||
|
|
||||||
// Contact details form
|
readonly appointmentInformationAlert: Locator;
|
||||||
// TODO: Check if we can consolidate
|
readonly changeZipCodeAlert: Locator;
|
||||||
readonly firstNameTextBox: Locator;
|
|
||||||
readonly lastNameTextBox: Locator;
|
readonly streetAddressTextBox: Locator;
|
||||||
readonly emailAddressTextBox: Locator;
|
readonly apartmentNumberTextBox: Locator;
|
||||||
readonly phoneNumberTextBox: Locator;
|
readonly cityTextBox: Locator;
|
||||||
|
readonly stateTextBox: Locator;
|
||||||
|
readonly zipCodeTextBox: Locator;
|
||||||
|
readonly coveredLocationYesButton: Locator;
|
||||||
|
readonly coveredLocationNoButton: Locator
|
||||||
readonly notesTextBox: Locator;
|
readonly notesTextBox: Locator;
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
|
|
||||||
|
// Alerts
|
||||||
|
this.appointmentInformationAlert = this.page.locator('[class*="widget-name-AppointmentInformationAlertWidget"]');
|
||||||
|
this.changeZipCodeAlert = this.page.locator('[class*="widget-name-ChangeZipCodeAlertWidget"]');
|
||||||
|
|
||||||
// Contact details form
|
// Contact details form
|
||||||
this.firstNameTextBox = this.page.getByRole('textbox', { name: 'First name' });
|
this.streetAddressTextBox = this.page.getByRole('textbox', { name: 'Street address' });
|
||||||
this.lastNameTextBox = this.page.getByRole('textbox', { name: 'Last name' });
|
this.apartmentNumberTextBox = this.page.getByRole('textbox', { name: 'Apartment number or letter (Optional)' });
|
||||||
this.emailAddressTextBox = this.page.getByRole('textbox', { name: 'Email address' });
|
this.cityTextBox = this.page.getByRole('textbox', { name: 'City' });
|
||||||
this.phoneNumberTextBox = this.page.getByRole('textbox', { name: 'Phone number' });
|
this.stateTextBox = this.page.getByRole('textbox', { name: 'state' });
|
||||||
this.notesTextBox = this.page.getByRole('textbox', { name: 'Notes' });
|
this.zipCodeTextBox = this.page.getByRole('textbox', { name: 'ZIP' });
|
||||||
|
this.coveredLocationYesButton = this.page.locator('#vehicleProtectedQuestion-true');
|
||||||
|
this.coveredLocationNoButton = this.page.locator('#vehicleProtectedQuestion-false');
|
||||||
|
this.notesTextBox = this.page.getByRole('textbox', { name: 'technicianNotes' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async validateAlertsAreVisible() {
|
||||||
|
await expect(this.appointmentInformationAlert).toBeVisible();
|
||||||
|
await this.appointmentInformationAlert.click(); //
|
||||||
|
await expect(this.appointmentInformationAlert).toContainText('Please have your vehicle keys or key card available, as your technician needs access inside the vehicle and may need to move your vehicle to complete service.');
|
||||||
|
|
||||||
async getContactDetails() {
|
await expect(this.changeZipCodeAlert).toBeVisible();
|
||||||
const customerDetails: Partial<ICustomerDetails> = {};
|
await this.changeZipCodeAlert.click();
|
||||||
customerDetails.firstName = await this.firstNameTextBox.inputValue();
|
await expect(this.changeZipCodeAlert).toContainText('If your service ZIP code has changed, please go back and update it to ensure we have the correct information for your appointment.');
|
||||||
customerDetails.lastName = await this.lastNameTextBox.inputValue();
|
}
|
||||||
customerDetails.email = await this.emailAddressTextBox.inputValue();
|
|
||||||
customerDetails.phoneNumber = await this.phoneNumberTextBox.inputValue();
|
|
||||||
|
|
||||||
return customerDetails;
|
// TO-DO add method for when checkbox for same as policy address displays
|
||||||
|
|
||||||
|
async fillContactDetails(customerDetails: ICustomerDetails) {
|
||||||
|
await this.streetAddressTextBox.fill(customerDetails.address.street!);
|
||||||
|
await this.cityTextBox.fill(customerDetails.address.city!);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fillAlternateMobileStreetAndCity(alternateMobileStreetAddress: string, alternateMobileCity: string) {
|
||||||
|
await this.streetAddressTextBox.fill(alternateMobileStreetAddress);
|
||||||
|
await this.cityTextBox.fill(alternateMobileCity);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fillNotes(notes?: string) {
|
async fillNotes(notes?: string) {
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,46 @@
|
||||||
import { expect, type Locator, type Page } from '@playwright/test';
|
import { expect, type Locator, type Page } from '@playwright/test';
|
||||||
import { BasePage } from './BasePage';
|
import { BasePage } from './BasePage';
|
||||||
|
import { IClaimDetails, ICustomerDetails } from '@business-logic/types/CustomerDetails';
|
||||||
|
import { defaultTestData, ITestData, VehicleDamage } from 'safelite-playwright-core';
|
||||||
|
|
||||||
export class CoverageStatementPage extends BasePage {
|
export class CoverageStatementPage extends BasePage {
|
||||||
readonly page: Page;
|
readonly page: Page;
|
||||||
readonly scheduleOnlineButton: Locator;
|
|
||||||
readonly cancelMyClaimButton: Locator;
|
readonly cancelMyClaimButton: Locator;
|
||||||
readonly cancelMyClaimConfirm: Locator;
|
readonly cancelMyClaimConfirm: Locator;
|
||||||
readonly deductibleAmount: Locator;
|
readonly deductibleAmount: Locator;
|
||||||
readonly verfiyingCoverageText: Locator;
|
readonly noDeductibleRepairText: Locator; // For essential flow when there is no deductible and repair is covered
|
||||||
readonly continueToScheduleButton: Locator; // For ITAC/NoComp
|
readonly youPayYourDeductibleText: Locator;
|
||||||
|
readonly verifiedCoverageHeader: Locator; // For essential flow when coverage is verified
|
||||||
|
readonly headerForITAC: Locator; // For ITAC when coverage is found
|
||||||
|
readonly headerForNoComp: Locator; // For NoComp when coverage is found
|
||||||
|
readonly unverifiedCoverageHeader: Locator; // For essential flows when verifying deductible
|
||||||
|
readonly oemBullet: Locator; // For OEM bullet when OEM endorsement is present
|
||||||
|
readonly continueSchedulingButton: Locator; // For ITAC/NoComp
|
||||||
|
readonly continueButton: Locator; // For essential flows
|
||||||
issPageValue = 'coverage-statement';
|
issPageValue = 'coverage-statement';
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.scheduleOnlineButton = this.page.getByText('Continue to schedule online');
|
|
||||||
this.cancelMyClaimButton = this.page.getByText('Cancel my claim');
|
|
||||||
this.cancelMyClaimConfirm = this.page.getByText('No, I want to cancel');
|
|
||||||
|
|
||||||
this.deductibleAmount = this.page.getByText('$');
|
this.cancelMyClaimButton = this.page.getByRole('link', { name: "No, I want to cancel" }); // seen for ITAC/NoComp flows
|
||||||
this.verfiyingCoverageText = this.page.getByRole('heading', { name: 'We’re verifying your coverage' });
|
this.cancelMyClaimConfirm = this.page.locator('div.text-center', { hasText: "No, I want to cancel" }); // on modal for cancel claim
|
||||||
this.continueToScheduleButton = page.locator('div[class*="button-content"]', {hasText:'Continue to schedule online'});
|
|
||||||
|
this.deductibleAmount = this.page.locator('.cost-underline');
|
||||||
|
this.noDeductibleRepairText = this.page.getByText('According to your policy, there is no deductible for a repair.'); // no deductible for repair text
|
||||||
|
this.youPayYourDeductibleText = this.page.getByText('You pay your deductible:'); // no deductible for replacement text
|
||||||
|
this.verifiedCoverageHeader = this.page.getByRole('heading', { name: 'We have verified your coverage' });
|
||||||
|
this.unverifiedCoverageHeader = this.page.getByRole('heading', { level: 5, name: "We’re verifying your coverage" });
|
||||||
|
this.headerForITAC = this.page.getByRole('heading', { name: 'Good news! Safelite\'s price is lower than your deductible' });
|
||||||
|
this.headerForNoComp = this.page.getByRole('heading', { name: 'Looks like your policy doesn\'t include comprehensive coverage.\nSafelite can still get you fixed up and safely back on the road.' });
|
||||||
|
this.oemBullet = this.page.getByText('OEM (Original Equipment Manufacturer) glass replacement is included under your policy and will be installed in your vehicle.');
|
||||||
|
|
||||||
|
this.continueSchedulingButton = page.getByRole('button', { name: 'Continue scheduling' }); // continue button for ITAC/NoComp flow
|
||||||
|
this.continueButton = page.getByRole('button', { name: 'Continue' }); // continue button for essential flow
|
||||||
}
|
}
|
||||||
|
|
||||||
async scheduleOnline(){
|
async scheduleOnline(){
|
||||||
await this.scheduleOnlineButton.click();
|
await this.continueSchedulingButton.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
async cancelMyClaim(){
|
async cancelMyClaim(){
|
||||||
|
|
@ -32,11 +48,70 @@ export class CoverageStatementPage extends BasePage {
|
||||||
await this.cancelMyClaimConfirm.click();
|
await this.cancelMyClaimConfirm.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
async validateDeductibleAmount(customer){
|
async handleRepairWithNoDeductibleFlow() {
|
||||||
await expect(this.deductibleAmount). toContainText(`$${customer.deductibleAmount}`, {timeout: 60000});
|
|
||||||
|
if (VehicleDamage.WindshieldOneChip || VehicleDamage.WindshieldTwoChips || VehicleDamage.WindshieldThreeChips) {
|
||||||
|
await expect(this.verifiedCoverageHeader).toBeVisible();
|
||||||
|
await expect(this.noDeductibleRepairText).toBeVisible();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleReplacementOrRepairWithNoDeductibleFlow(claimDetails: IClaimDetails, VehicleDamage){
|
||||||
|
const noDeductibleFlow = claimDetails.policyDeductible === 0;
|
||||||
|
|
||||||
|
if (noDeductibleFlow && VehicleDamage === VehicleDamage.WindshieldOneChip || VehicleDamage.WindshieldTwoChips || VehicleDamage.WindshieldThreeChips) {
|
||||||
|
|
||||||
|
// await expect(this.noDeductibleRepairText).toBeVisible();
|
||||||
|
await this.continueButton.click();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
await expect(this.youPayYourDeductibleText).toBeVisible();
|
||||||
|
await expect(this.deductibleAmount).toContainText(`$0`, {timeout: 60000});
|
||||||
|
await this.continueButton.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleReplacementWithDeductibleFlow(claimDetails: IClaimDetails){
|
||||||
|
const replaceWithDeductibleFlow = claimDetails.policyDeductible! > 0 && claimDetails.policyDeductible !== 9999;
|
||||||
|
|
||||||
|
if (replaceWithDeductibleFlow) {
|
||||||
|
await expect(this.youPayYourDeductibleText).toBeVisible();
|
||||||
|
await expect(this.deductibleAmount).toContainText(`$${claimDetails.policyDeductible?.toLocaleString()}`, {timeout: 60000});
|
||||||
|
|
||||||
|
await this.continueButton.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async handleUnverifiedFlow(claimDetails: IClaimDetails){
|
||||||
|
const unVerifiedCustomer = claimDetails.policyDeductible === -1; // if deductible is -1, we treat it as unverified flow
|
||||||
|
|
||||||
|
if (unVerifiedCustomer) {
|
||||||
|
await expect(this.unverifiedCoverageHeader).toBeVisible();
|
||||||
|
|
||||||
|
await this.continueButton.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleUnverifiedPolicyAfterVehicleLookupFlow(){
|
||||||
|
await expect(this.unverifiedCoverageHeader).toBeVisible();
|
||||||
|
await this.continueButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleITACFlow(){
|
||||||
|
await expect(this.headerForITAC).toBeVisible(); // verify ITAC header is visible
|
||||||
|
|
||||||
|
await this.continueSchedulingButton.click(); // happy path to scheduling for ITAC
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleNoCompFlow(){
|
||||||
|
await expect(this.headerForNoComp).toBeVisible(); // verify NoComp header is visible
|
||||||
|
|
||||||
|
await this.continueSchedulingButton.click(); // happy path to scheduling for NoComp
|
||||||
|
}
|
||||||
|
|
||||||
|
async validateOEMBullet(){
|
||||||
|
await expect(this.oemBullet).toBeVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
async validateUnverifiedText(){
|
|
||||||
await expect(this.verfiyingCoverageText).toBeEnabled();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
@ -12,11 +12,11 @@ export class EndorsementsPage extends BasePage {
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.educatorYesButton = this.page.locator('label[for="schoolProperty-Yes"]');
|
this.educatorYesButton = this.page.locator('label:has(div.button-content:has(span:has-text("Yes")))');
|
||||||
this.educatorNoButton = this.page.locator('label[for="schoolProperty-No"]');
|
this.educatorNoButton = this.page.locator('label:has(div.button-content:has(span:has-text("No")))');
|
||||||
}
|
}
|
||||||
|
|
||||||
async verifyEndorsements(endorsements: IEndorsementDetails[]) {
|
async verifyEndorsements(endorsements: IEndorsementDetails[]) {
|
||||||
for (const endorsement of endorsements) {
|
for (const endorsement of endorsements) {
|
||||||
switch(endorsement.endorsementType) {
|
switch(endorsement.endorsementType) {
|
||||||
case EndorsementType.Educator:
|
case EndorsementType.Educator:
|
||||||
|
|
|
||||||
|
|
@ -6,110 +6,175 @@ import { ITestData } from '@business-logic/types/ITestData';
|
||||||
|
|
||||||
export class OrderConfirmationPage extends BasePage {
|
export class OrderConfirmationPage extends BasePage {
|
||||||
readonly page: Page;
|
readonly page: Page;
|
||||||
|
|
||||||
|
readonly successCheckmark: Locator;
|
||||||
|
readonly successHeader: Locator;
|
||||||
|
|
||||||
readonly serviceText: Locator;
|
readonly serviceText: Locator;
|
||||||
readonly emailText: Locator;
|
readonly workOrderNumberText: Locator;
|
||||||
readonly apptDateText: Locator;
|
readonly confirmationText: Locator;
|
||||||
readonly amountDueText: Locator;
|
readonly appointmentTypeText: Locator;
|
||||||
readonly viewCartButton: Locator;
|
readonly apptDetailsText: Locator;
|
||||||
readonly deductibleText: Locator;
|
readonly deductibleText: Locator;
|
||||||
readonly subtotalText: Locator;
|
readonly subtotalText: Locator;
|
||||||
|
readonly totalAmountDueText: Locator;
|
||||||
|
readonly amountPaidText: Locator;
|
||||||
readonly finalAmountDue: Locator;
|
readonly finalAmountDue: Locator;
|
||||||
readonly cartServicePackageText: Locator;
|
readonly cartLineItemsText: Locator;
|
||||||
|
readonly unverifiedCoverageDeductibleText: Locator;
|
||||||
|
|
||||||
issPageValue = 'order-confirmation';
|
issPageValue = 'order-confirmation';
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.serviceText = this.page.locator('[class="appointment-text text-center lh-base"]');
|
|
||||||
this.emailText = this.page.locator('[class="email-confirmation-text"]');
|
this.successCheckmark = this.page.locator('img[src*="-checkmark.svg"]');
|
||||||
this.apptDateText = this.page.locator('[class="appointment-date-time text-center mt-4"]');
|
this.successHeader = this.page.locator('[class="header-text"]');
|
||||||
this.amountDueText = this.page.getByLabel('expand cart details');
|
|
||||||
this.viewCartButton = this.page.locator('#cart-dropdown-head');
|
this.confirmationText = this.page.locator('[class="subheader-text"]', { hasText: 'Your appointment is on Safelite\'s schedule and your confirmation email is on the way.' });
|
||||||
this.deductibleText = this.page.locator('#deductible-value');
|
this.serviceText = this.page.locator('[class="service-description confirmation-section"]');
|
||||||
this.subtotalText = this.page.locator("#subtotal-value");
|
this.workOrderNumberText = this.page.locator('[class="work-order-description"]');
|
||||||
|
this.appointmentTypeText = this.page.locator('[class="appointment-title"]');
|
||||||
|
this.apptDetailsText = this.page.locator('[class="appointment-details confirmation-section"]');
|
||||||
|
|
||||||
|
// Order details section
|
||||||
|
this.deductibleText = this.page.locator('span#deductible-value, span.deductible-value');
|
||||||
|
this.subtotalText = this.page.locator('#subtotal-value');
|
||||||
|
this.totalAmountDueText = this.page.locator('#total-value');
|
||||||
|
this.amountPaidText = this.page.locator('#amount-paid-value');
|
||||||
this.finalAmountDue = this.page.locator('#bottom-amount-due-value');
|
this.finalAmountDue = this.page.locator('#bottom-amount-due-value');
|
||||||
this.cartServicePackageText = this.page.locator('#cart-service-package');
|
this.cartLineItemsText = this.page.locator('.cart-item-list');
|
||||||
|
this.unverifiedCoverageDeductibleText = this.page.locator('span#deductible-value', { hasText: 'Verifying coverage' });
|
||||||
}
|
}
|
||||||
|
|
||||||
async validateOrderConfirmationPage(testData: Partial<ITestData>) {
|
async validateOrderConfirmationPage(testData: Partial<ITestData>) {
|
||||||
// Destructure data we use
|
// Destructure data we use
|
||||||
const { vehicleDetails, customerDetails, servicePackage, isItac,
|
const { vehicleDetails, customerDetails, servicePackage, isItac,
|
||||||
isNoComp, isPolicyFound, claimDetails, paymentDetails, isUseVehicleOnPolicy } = testData;
|
isNoComp, isPolicyFound, claimDetails, paymentDetails, isUseVehicleOnPolicy } = testData;
|
||||||
await this.serviceText.waitFor({ state: "visible" });
|
|
||||||
await this.logOrderNumber();
|
|
||||||
|
|
||||||
// Grab text
|
// Grab text
|
||||||
const serviceTextValue = await this.serviceText.textContent();
|
const serviceTextValue = await this.serviceText.textContent();
|
||||||
const apptDateValue = await this.apptDateText.textContent();
|
const apptDetailsValue = await this.apptDetailsText.textContent();
|
||||||
const emailTextValue = await this.emailText.textContent();
|
const appointmentTypeValue = await this.appointmentTypeText.textContent();
|
||||||
const servicePackageValue = await this.cartServicePackageText.textContent();
|
|
||||||
const amountDueValue = await this.amountDueText.textContent();
|
|
||||||
const deductibleTextValue = (isItac || isNoComp) ? null : await this.deductibleText.textContent();
|
// Derived conditions
|
||||||
const subtotalTextValue = await this.subtotalText.textContent();
|
const isItacOrNoComp = !!(isItac || isNoComp);
|
||||||
const finalAmountDueValue = await this.finalAmountDue.textContent();
|
const isUnverified = !isPolicyFound;
|
||||||
|
const isUnverifiedPolicyAfterVehicleLookup = testData.isUnverifiedPolicyAfterVehicleLookup === true;
|
||||||
|
const hasPremiumOrStandard =
|
||||||
|
(claimDetails!.policyDeductible >= 0 || !isPolicyFound) &&
|
||||||
|
(servicePackage === ServicePackage.Premium || servicePackage === ServicePackage.Standard);
|
||||||
|
|
||||||
|
const payAtService =
|
||||||
|
(claimDetails!.policyDeductible >= 0 &&
|
||||||
|
paymentDetails?.paymentType === PaymentType.PayAtService) || !paymentDetails?.paymentType;
|
||||||
|
|
||||||
|
const paidWithPIA =
|
||||||
|
claimDetails!.policyDeductible >= 0 &&
|
||||||
|
paymentDetails?.paymentType !== PaymentType.PayAtService;
|
||||||
|
|
||||||
|
// Helper: grab textContent only when the element is expected on-screen
|
||||||
|
const textIf = async (condition: boolean, locator: Locator) =>
|
||||||
|
condition ? await locator.textContent() : null;
|
||||||
|
|
||||||
|
// Grab text content for elements that are expected on-screen
|
||||||
|
const lineItemsValue = await textIf(hasPremiumOrStandard, this.cartLineItemsText);
|
||||||
|
const deductibleTextValue = await textIf(!isItacOrNoComp, this.deductibleText);
|
||||||
|
const subtotalTextValue = await textIf((hasPremiumOrStandard || isItacOrNoComp) && !isUnverified && !isUnverifiedPolicyAfterVehicleLookup, this.subtotalText);
|
||||||
|
const totalAmountDueValue = await textIf((hasPremiumOrStandard && !payAtService) || (isItacOrNoComp && !payAtService) && !isUnverified && !isUnverifiedPolicyAfterVehicleLookup, this.totalAmountDueText);
|
||||||
|
const amountPaidTextValue = await textIf((hasPremiumOrStandard && !payAtService) || (isItacOrNoComp && !payAtService) && !isUnverified && !isUnverifiedPolicyAfterVehicleLookup, this.totalAmountDueText);
|
||||||
|
const finalAmountDueValue = await textIf(hasPremiumOrStandard || isItacOrNoComp || isUnverified || isUnverifiedPolicyAfterVehicleLookup, this.finalAmountDue);
|
||||||
|
const confirmationTextValue = await this.confirmationText.textContent();
|
||||||
|
|
||||||
|
|
||||||
// Extract service package price
|
|
||||||
const servicePackageAmt = Number.parseFloat(servicePackageValue!.split('$')[1].replaceAll(',', ''));
|
|
||||||
|
|
||||||
// General Validations
|
// General Validations
|
||||||
|
expect.soft(this.serviceText).toBeVisible();;
|
||||||
|
expect.soft(this.successHeader).toBeVisible();
|
||||||
|
expect.soft(confirmationTextValue).toContain('Your appointment is on Safelite\'s schedule and your confirmation email is on the way.');
|
||||||
expect.soft(serviceTextValue).toContain(`${vehicleDetails!.year} ${vehicleDetails!.make} ${vehicleDetails!.model}`);
|
expect.soft(serviceTextValue).toContain(`${vehicleDetails!.year} ${vehicleDetails!.make} ${vehicleDetails!.model}`);
|
||||||
expect.soft(apptDateValue).toContain(customerDetails!.apptDate);
|
|
||||||
expect.soft(emailTextValue).toContain(customerDetails!.email);
|
|
||||||
|
|
||||||
// Service package validations
|
// Validate order number and appointment type header
|
||||||
await expect.soft(this.cartServicePackageText).toContainText(`${servicePackage}`)
|
await this.validateOrderNumber();
|
||||||
if ((servicePackage === ServicePackage.Premium && testData.isReplace === true) || servicePackage === ServicePackage.Standard) {
|
await this.validateAppointmentTypeHeader();
|
||||||
expect.soft(servicePackageValue).toContain('New wiper blades');
|
|
||||||
}
|
|
||||||
if (servicePackage === ServicePackage.Premium) {
|
|
||||||
expect.soft(servicePackageValue).toContain('Rain Defense™ treatment');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Price validations
|
// Validate line items
|
||||||
if (servicePackage === ServicePackage.GlassOnly) {
|
if (servicePackage === ServicePackage.Premium) {
|
||||||
expect.soft(servicePackageAmt).toEqual(0);
|
expect.soft(lineItemsValue).toContain('Front advanced beam blades');
|
||||||
|
expect.soft(lineItemsValue).toContain('Safelite Rain Repellent Treatment');
|
||||||
} else {
|
} else {
|
||||||
expect.soft(servicePackageAmt).toBeGreaterThan(0);
|
if (servicePackage === ServicePackage.Standard) {
|
||||||
|
expect.soft(lineItemsValue).toContain('Front advanced beam blades');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPolicyFound && (isUseVehicleOnPolicy ?? true)) {
|
|
||||||
// Extract numbers
|
if (isPolicyFound && (claimDetails!.policyDeductible === 0 && (servicePackage === ServicePackage.GlassOnly))) {
|
||||||
const amountDueAmt = Number.parseFloat(amountDueValue!.split('$')[1].replaceAll(',', ''));
|
const zeroDeductibleText = await this.deductibleText.textContent();
|
||||||
|
expect.soft(zeroDeductibleText).toEqual('$0.00');
|
||||||
|
} else if (isPolicyFound && claimDetails!.policyDeductible > 0 && !(isItac || isNoComp) && servicePackage === ServicePackage.GlassOnly){
|
||||||
|
expect.soft(deductibleTextValue).not.toBeNull();
|
||||||
const deductibleAmt = deductibleTextValue ? Number.parseFloat(deductibleTextValue.split('$')[1].replaceAll(',', '')) : 0;
|
const deductibleAmt = deductibleTextValue ? Number.parseFloat(deductibleTextValue.split('$')[1].replaceAll(',', '')) : 0;
|
||||||
const subtotalAmt = Number.parseFloat(subtotalTextValue!.split('$')[1].replaceAll(',', ''));
|
expect.soft(deductibleAmt).toEqual(claimDetails!.policyDeductible);
|
||||||
subtotalTextValue?.replaceAll(',', '')
|
|
||||||
const finalAmountDueAmt = Number.parseFloat(finalAmountDueValue!.split('$')[1].replaceAll(',', ''));
|
} else if ((isPolicyFound || isItac || (isNoComp && paymentDetails!.paymentType === PaymentType.PayAtService)) && !isUnverifiedPolicyAfterVehicleLookup && finalAmountDueValue !== null && subtotalTextValue !== null) {
|
||||||
|
// Extract numbers
|
||||||
|
const deductibleAmt = deductibleTextValue ? Number.parseFloat(deductibleTextValue.split('$')[1].replaceAll(',', '')) : null;
|
||||||
|
|
||||||
|
const subtotalAmt = subtotalTextValue ? Number.parseFloat(subtotalTextValue!.split('$')[1].replaceAll(',', '')) : null;
|
||||||
|
|
||||||
|
|
||||||
|
//const totalAmountDueAmt = Number.parseFloat(totalAmountDueValue!.split('$')[1].replaceAll(',', ''));
|
||||||
|
const finalAmountDueAmt = finalAmountDueValue ? Number.parseFloat(finalAmountDueValue!.split('$')[1].replaceAll(',', '')) : null;
|
||||||
|
|
||||||
if (!(isItac || isNoComp)) {
|
if (!(isItac || isNoComp)) {
|
||||||
expect.soft(subtotalAmt).toEqual(claimDetails!.policyDeductible + servicePackageAmt);
|
|
||||||
expect.soft(deductibleAmt).toEqual(claimDetails!.policyDeductible);
|
expect.soft(deductibleAmt).toEqual(claimDetails!.policyDeductible);
|
||||||
} else {
|
} else {
|
||||||
expect.soft(subtotalAmt).toBeGreaterThan(0);
|
expect.soft(subtotalAmt).toBeGreaterThan(0);
|
||||||
expect.soft(deductibleAmt).toEqual(0);
|
//expect.soft(deductibleAmt).toEqual(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paymentDetails!.paymentType === PaymentType.PayAtService && (claimDetails!.policyDeductible > 0 || servicePackageAmt > 0)) {
|
if ((paymentDetails!.paymentType === PaymentType.PayAtService) && (claimDetails!.policyDeductible >= 0 && (servicePackage === ServicePackage.Standard || servicePackage === ServicePackage.Premium))) {
|
||||||
// Verify amount due > 0
|
|
||||||
expect.soft(amountDueAmt).toBeGreaterThan(0);
|
|
||||||
expect.soft(finalAmountDueAmt).toBeGreaterThan(0);
|
expect.soft(finalAmountDueAmt).toBeGreaterThan(0);
|
||||||
} else {
|
} else {
|
||||||
// Verify amount due 0
|
const totalAmountDueAmt = Number.parseFloat(totalAmountDueValue!.split('$')[1].replaceAll(',', ''));
|
||||||
expect.soft(amountDueAmt).toEqual(0);
|
const amountPaidValue = Number.parseFloat(amountPaidTextValue!.split('$')[1].replaceAll(',', ''));
|
||||||
|
// Verify amount due 0 usually when PIA is selected
|
||||||
|
expect.soft(amountPaidValue).toEqual(totalAmountDueAmt);
|
||||||
expect.soft(finalAmountDueAmt).toEqual(0);
|
expect.soft(finalAmountDueAmt).toEqual(0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
expect.soft(amountDueValue).toContain('Verifying coverage');
|
// essential flows will have deductible and amount due as "Verifying coverage"
|
||||||
expect.soft(subtotalTextValue).toEqual('Verifying coverage');
|
const verifyingCoverageText = this.unverifiedCoverageDeductibleText;
|
||||||
|
|
||||||
|
expect.soft(verifyingCoverageText).toContainText('Verifying coverage');
|
||||||
expect.soft(finalAmountDueValue).toEqual('Verifying coverage');
|
expect.soft(finalAmountDueValue).toEqual('Verifying coverage');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async logOrderNumber() {
|
async validateOrderNumber() {
|
||||||
const sessionStorage = JSON.parse(await this.page.evaluate('sessionStorage.getItem(\'submittedOrder\')'));
|
const sessionStorage = JSON.parse(await this.page.evaluate('sessionStorage.getItem(\'submittedOrder\')'));
|
||||||
const workOrderNumber = sessionStorage.workOrderNumber;
|
const workOrderNumber = sessionStorage.workOrderNumber;
|
||||||
await test.step(`SessionStorage Work Order Number:${workOrderNumber}`, async () => {
|
const workOrderNumberValue = await this.workOrderNumberText.textContent();
|
||||||
console.log(`SessionStorage Work Order Number:${workOrderNumber}`);
|
expect.soft(workOrderNumberValue).toEqual(workOrderNumber);
|
||||||
});
|
}
|
||||||
|
|
||||||
|
async validateAppointmentTypeHeader() {
|
||||||
|
const sessionStorage = JSON.parse(await this.page.evaluate('sessionStorage.getItem(\'submittedOrder\')'));
|
||||||
|
const appointmentType = sessionStorage.serviceLocation.appointmentType;
|
||||||
|
const appointmentTypeValue = await this.appointmentTypeText.textContent();
|
||||||
|
const apptDetailsValue = await this.apptDetailsText.textContent();
|
||||||
|
|
||||||
|
if (appointmentTypeValue?.includes('going to a Safelite shop') && apptDetailsValue?.includes('Drop off before 9:30 AM')) {
|
||||||
|
expect.soft(appointmentType).toEqual('Dropoff');
|
||||||
|
} else if (appointmentTypeValue?.includes('going to a Safelite shop')) {
|
||||||
|
expect.soft(appointmentType).toEqual('Inshop');
|
||||||
|
} else {
|
||||||
|
expect.soft(appointmentType).toEqual('Mobile');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async validateURL() {
|
async validateURL() {
|
||||||
|
|
|
||||||
|
|
@ -1,60 +1,79 @@
|
||||||
import { expect, type Locator, type Page } from '@playwright/test';
|
import { expect, type Locator, type Page } from '@playwright/test';
|
||||||
import { BasePage } from './BasePage';
|
import { BasePage } from './BasePage';
|
||||||
import { IPaymentDetails } from '@business-logic/types/CustomerDetails';
|
import { IClaimDetails, IPaymentDetails } from '@business-logic/types/CustomerDetails';
|
||||||
import { PaymentType } from '@business-logic/types/Enums';
|
import { PaymentType, ServicePackage } from '@business-logic/types/Enums';
|
||||||
import { PaymentPage } from './PaymentPage';
|
import { PaymentPage } from './PaymentPage';
|
||||||
import { AfterpayPage } from './AfterpayPage';
|
import { AfterpayPage } from './AfterpayPage';
|
||||||
import { PaypalPage } from './PaypalPage';
|
import { PaypalPage } from './PaypalPage';
|
||||||
|
|
||||||
export class PaymentMethodPage extends BasePage {
|
export class PaymentMethodPage extends BasePage {
|
||||||
readonly page: Page;
|
readonly page: Page;
|
||||||
readonly payAtServiceButton: Locator;
|
|
||||||
readonly havePaymentReadyMsg: Locator;
|
|
||||||
readonly payNowButton: Locator;
|
|
||||||
readonly payInFourButton: Locator;
|
|
||||||
readonly paypalButton: Locator;
|
|
||||||
readonly paymentPage: PaymentPage;
|
|
||||||
readonly paypalPage: PaypalPage;
|
readonly paypalPage: PaypalPage;
|
||||||
|
readonly paymentPage: PaymentPage;
|
||||||
|
|
||||||
|
readonly payNowButton: Locator;
|
||||||
|
readonly paypalButton: Locator;
|
||||||
|
readonly payInFourButton: Locator;
|
||||||
|
readonly payAtAppointmentButton: Locator;
|
||||||
|
|
||||||
|
readonly textReminderYesButton: Locator;
|
||||||
|
readonly textReminderNoButton: Locator;
|
||||||
|
readonly continueToCheckoutButton: Locator;
|
||||||
|
readonly submitButton: Locator;
|
||||||
|
|
||||||
issPageValue = 'payment-method';
|
issPageValue = 'payment-method';
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.payAtServiceButton = this.page.locator('[buttonlabel="Pay at my appointment"]'); //this.page.getByText('Pay at time of service');
|
|
||||||
this.havePaymentReadyMsg = this.page.getByText('Please have payment ready during your appointment.'); // it will be displayed when there is no payment option
|
|
||||||
this.payNowButton = this.page.locator('[buttonlabel="Pay now"]');
|
|
||||||
this.payInFourButton = this.page.locator('[buttonlabel="Pay in 4 installments"]');
|
|
||||||
this.paypalButton = this.page.frameLocator('iframe[name="card-frame"]').locator('div[id="paypalParentDiv"]');
|
|
||||||
this.paymentPage = new PaymentPage(page);
|
|
||||||
this.paypalPage = new PaypalPage(page);
|
this.paypalPage = new PaypalPage(page);
|
||||||
|
this.paymentPage = new PaymentPage(page);
|
||||||
|
|
||||||
|
this.payNowButton = this.page.locator('[buttonlabel="Pay now"]'); // credit and paypal options behind this button
|
||||||
|
this.paypalButton = this.page.frameLocator('iframe[name="card-frame"]').locator('div[id="paypalParentDiv"]');
|
||||||
|
this.payInFourButton = this.page.locator('[buttonlabel="Pay in 4 installments"]'); // Afterpay
|
||||||
|
this.payAtAppointmentButton = this.page.locator('[buttonlabel="Pay at my appointment"]');
|
||||||
|
|
||||||
|
this.textReminderYesButton = this.page.locator('div.button-content', { hasText: /^yes$/i });
|
||||||
|
this.textReminderNoButton = this.page.locator('div.button-content', { hasText: 'No' });
|
||||||
|
this.continueToCheckoutButton = this.page.getByRole('button', { name: 'Continue to checkout' });
|
||||||
|
this.submitButton = this.page.getByRole('button', { name: 'Submit' });
|
||||||
}
|
}
|
||||||
|
|
||||||
async executePayment(paymentDetails: IPaymentDetails) {
|
async executePayment(paymentDetails: IPaymentDetails, claimDetails: IClaimDetails, servicePackage: ServicePackage) {
|
||||||
const browserContext = this.page.context();
|
const browserContext = this.page.context();
|
||||||
|
|
||||||
switch (paymentDetails.paymentType) {
|
switch (paymentDetails.paymentType) {
|
||||||
case PaymentType.Credit:
|
case PaymentType.Credit:
|
||||||
await this.selectCreditCard();
|
await this.payNowButton.click();
|
||||||
await this.paymentPage.populateCreditCardDetails(paymentDetails);
|
await this.textReminderYesButton.click();
|
||||||
|
await this.continueToCheckoutButton.click();
|
||||||
|
await this.selectCreditCard(paymentDetails);
|
||||||
break;
|
break;
|
||||||
case PaymentType.Paypal:
|
case PaymentType.Paypal:
|
||||||
|
await this.payNowButton.click();
|
||||||
|
await this.textReminderYesButton.click();
|
||||||
|
await this.continueToCheckoutButton.click();
|
||||||
await this.selectPaypal();
|
await this.selectPaypal();
|
||||||
await this.paypalPage.completePaypalPurchase(paymentDetails);
|
await this.paypalPage.completePaypalPurchase(paymentDetails);
|
||||||
break;
|
break;
|
||||||
case PaymentType.AfterPay:
|
case PaymentType.AfterPay:
|
||||||
await this.payInFourButton.click();
|
await this.payInFourButton.click();
|
||||||
await this.nextPage();
|
await this.textReminderYesButton.click();
|
||||||
|
await this.continueToCheckoutButton.click();
|
||||||
|
|
||||||
// Capture popup
|
// Capture popup
|
||||||
const afterpayPopup = await browserContext.waitForEvent('page');
|
const afterpayPopup = await browserContext.waitForEvent('page');
|
||||||
const afterpayPage = new AfterpayPage(afterpayPopup);
|
const afterpayPage = new AfterpayPage(afterpayPopup);
|
||||||
|
|
||||||
// Execute payment
|
// Execute payment
|
||||||
await afterpayPage.executeAfterpayPayment(paymentDetails);
|
await afterpayPage.executeAfterpayPayment(paymentDetails, claimDetails, servicePackage);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PaymentType.PayAtService:
|
case PaymentType.PayAtService:
|
||||||
await this.selectPayAtService();
|
await this.payAtAppointmentButton.click();
|
||||||
|
await this.textReminderYesButton.click();
|
||||||
|
await this.submitButton.click();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.error('PaymentMethodPage >> Logic for this payment method unimplemented');
|
console.error('PaymentMethodPage >> Logic for this payment method unimplemented');
|
||||||
|
|
@ -63,22 +82,19 @@ export class PaymentMethodPage extends BasePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectPaypal() {
|
async selectPaypal() {
|
||||||
await this.payNowButton.click();
|
|
||||||
await this.nextPage();
|
|
||||||
await this.paypalButton.click();
|
await this.paypalButton.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectCreditCard() {
|
async selectCreditCard(paymentDetails: IPaymentDetails) {
|
||||||
await this.payNowButton.click();
|
await this.paymentPage.populateCreditCardDetails(paymentDetails);
|
||||||
await this.nextPage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectPayAtService() {
|
async selectPayAtAppointment() {
|
||||||
await this.payAtServiceButton.click();
|
await this.payAtAppointmentButton.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
// async validateAmountDue(customer){
|
async submitOrderWithoutPIA() {
|
||||||
// await this.amountDueDropDown.click();
|
await this.textReminderYesButton.click();
|
||||||
// await expect(this.deductibleAmountTextField).toContainText(`${customer.deductibleAmount}`);
|
await this.submitButton.click();
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { type Locator, type Page } from '@playwright/test';
|
import { type Locator, type Page } from '@playwright/test';
|
||||||
import { BasePage } from './BasePage';
|
import { BasePage } from './BasePage';
|
||||||
|
import { AfterpayPage } from './AfterpayPage';
|
||||||
import { IPaymentDetails } from '@business-logic/types/CustomerDetails';
|
import { IPaymentDetails } from '@business-logic/types/CustomerDetails';
|
||||||
|
|
||||||
export class PaymentPage extends BasePage {
|
export class PaymentPage extends BasePage {
|
||||||
|
|
@ -26,8 +27,7 @@ export class PaymentPage extends BasePage {
|
||||||
this.cityTextField = page.frameLocator('iframe[name="card-frame"]').getByRole('textbox', { name: 'City' });
|
this.cityTextField = page.frameLocator('iframe[name="card-frame"]').getByRole('textbox', { name: 'City' });
|
||||||
this.stateDropDown = page.frameLocator('iframe[name="card-frame"]').getByRole('combobox', { name: 'State' });
|
this.stateDropDown = page.frameLocator('iframe[name="card-frame"]').getByRole('combobox', { name: 'State' });
|
||||||
this.billingZipTextField = page.frameLocator('iframe[name="card-frame"]').getByRole('textbox', { name: 'Billing ZIP code' });;
|
this.billingZipTextField = page.frameLocator('iframe[name="card-frame"]').getByRole('textbox', { name: 'Billing ZIP code' });;
|
||||||
this.submitPaymentButton = page.frameLocator('iframe[name="card-frame"]').locator('#buttonContainer');
|
this.submitPaymentButton = page.getByRole('button', { name: 'Submit payment' });
|
||||||
// this.validateURL(this.url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async populateCreditCardDetails(paymentDetails: IPaymentDetails){
|
async populateCreditCardDetails(paymentDetails: IPaymentDetails){
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,33 @@
|
||||||
import { expect, type Locator, type Page } from '@playwright/test';
|
import { expect, type Locator, type Page } from "@playwright/test";
|
||||||
import { BasePage } from './BasePage';
|
import { BasePage } from "./BasePage";
|
||||||
import { IPaymentDetails } from '@business-logic/types/CustomerDetails';
|
import { IPaymentDetails } from "@business-logic/types/CustomerDetails";
|
||||||
|
|
||||||
export class PaypalPage extends BasePage {
|
export class PaypalPage extends BasePage {
|
||||||
readonly page: Page;
|
readonly page: Page;
|
||||||
readonly loginWithPasswordButton: Locator;
|
readonly usernameTextBox: Locator;
|
||||||
readonly passwordTextBox: Locator;
|
readonly nextButton: Locator;
|
||||||
readonly paypalLoginButton: Locator;
|
readonly passwordTextBox: Locator;
|
||||||
readonly completePurchaseButton: Locator;
|
readonly paypalLoginButton: Locator;
|
||||||
|
readonly payButton: Locator;
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.loginWithPasswordButton = page.getByRole('link', { name: 'Log in with a password instead' });
|
this.usernameTextBox = page.locator("#email");
|
||||||
this.passwordTextBox = page.getByPlaceholder('Password');
|
this.nextButton = page.getByRole("button", { name: "Next" });
|
||||||
this.paypalLoginButton = page.getByRole('button', { name: 'Log In', exact: true });
|
this.passwordTextBox = page.getByRole("textbox", { name: "Password" });
|
||||||
this.completePurchaseButton = page.getByTestId('submit-button-initial');
|
this.paypalLoginButton = page.getByRole("button", {
|
||||||
}
|
name: "Log In",
|
||||||
|
exact: true,
|
||||||
|
});
|
||||||
|
this.payButton = page.getByRole("button", { name: "Pay $" });
|
||||||
|
}
|
||||||
|
|
||||||
async completePaypalPurchase(paymentDetails: IPaymentDetails){
|
async completePaypalPurchase(paymentDetails: IPaymentDetails) {
|
||||||
await this.loginWithPasswordButton.click();
|
await this.usernameTextBox.fill(paymentDetails.username!);
|
||||||
await this.passwordTextBox.fill(paymentDetails.password!);
|
await this.nextButton.click();
|
||||||
await this.paypalLoginButton.click();
|
await this.passwordTextBox.fill(paymentDetails.password!);
|
||||||
await this.completePurchaseButton.click();
|
await this.paypalLoginButton.click();
|
||||||
}
|
await this.payButton.click();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,60 @@
|
||||||
import { type Locator, type Page } from '@playwright/test';
|
import { type Locator, type Page } from '@playwright/test';
|
||||||
import { BasePage } from './BasePage';
|
import { BasePage } from './BasePage';
|
||||||
import { ICustomerDetails } from '@business-logic/types/CustomerDetails';
|
import { ICustomerDetails } from '@business-logic/types/CustomerDetails';
|
||||||
import { AddressForm } from './forms/AddressForm';
|
|
||||||
|
|
||||||
export class PolicyHolderDetailsPage extends BasePage {
|
export class PolicyHolderDetailsPage extends BasePage {
|
||||||
readonly page: Page;
|
readonly page: Page;
|
||||||
readonly addressForm: AddressForm;
|
readonly firstNameTextBox: Locator;
|
||||||
|
readonly lastNameTextBox: Locator;
|
||||||
|
readonly addressInputBox: Locator;
|
||||||
|
readonly emailAddressTextBox: Locator;
|
||||||
|
|
||||||
readonly issPageValue = 'policy-holder-details';
|
readonly issPageValue = 'policy-holder-details';
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.addressForm = new AddressForm(page);
|
this.firstNameTextBox = page.locator('#firstNameField');
|
||||||
|
this.lastNameTextBox = page.locator('#lastNameField');
|
||||||
|
this.emailAddressTextBox = page.locator('#emailField');
|
||||||
|
this.addressInputBox = page.locator('input[name="autocomplete"]'); // for essential flows
|
||||||
}
|
}
|
||||||
|
|
||||||
async fillCustomerDetails(customerDetails: ICustomerDetails){
|
async fillCustomerDetails(customerDetails: ICustomerDetails){
|
||||||
await this.addressForm.populateAddress(customerDetails);
|
// Check if firstName field is empty, then fill it
|
||||||
|
const firstNameValue = await this.firstNameTextBox.inputValue();
|
||||||
|
if (!firstNameValue || firstNameValue.trim() === '') {
|
||||||
|
if (customerDetails.firstName) {
|
||||||
|
await this.firstNameTextBox.fill(customerDetails.firstName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if lastName field is empty, then fill it
|
||||||
|
const lastNameValue = await this.lastNameTextBox.inputValue();
|
||||||
|
if (!lastNameValue || lastNameValue.trim() === '') {
|
||||||
|
if (customerDetails.lastName) {
|
||||||
|
await this.lastNameTextBox.fill(customerDetails.lastName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill email address for both essential and advanced flows
|
||||||
|
await this.emailAddressTextBox.fill(customerDetails.email);
|
||||||
|
|
||||||
|
const addressValue = await this.addressInputBox.inputValue();
|
||||||
|
|
||||||
|
// For essential flows, when address fields are not pre-filled
|
||||||
|
if (!addressValue || addressValue.trim() === '') {
|
||||||
|
await this.addressInputBox.click();
|
||||||
|
await this.addressInputBox.fill(customerDetails.address.street);
|
||||||
|
|
||||||
|
// Wait for suggestions to load (Google Places has a slight delay)
|
||||||
|
await this.page.locator('.pac-item').first().waitFor({ state: 'visible', timeout: 5000 });
|
||||||
|
|
||||||
|
// Click the first result
|
||||||
|
await this.page.locator('.pac-item').first().click();
|
||||||
|
|
||||||
|
// Optional: wait for the input to be populated by Google Places
|
||||||
|
await this.addressInputBox.waitFor({ state: 'attached' });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -5,11 +5,14 @@ import { IVehicleDetails } from '@business-logic/types/CustomerDetails';
|
||||||
export class PolicyVehiclesPage extends BasePage {
|
export class PolicyVehiclesPage extends BasePage {
|
||||||
readonly page: Page;
|
readonly page: Page;
|
||||||
issPageValue = 'policy-vehicles';
|
issPageValue = 'policy-vehicles';
|
||||||
|
readonly addAnotherVehicleButton: Locator;
|
||||||
|
readonly selectVehicleOnPolicyButton: Locator;
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
// this.validateURL(this.url);
|
this.addAnotherVehicleButton = this.page.getByText('Add another vehicle');
|
||||||
|
this.selectVehicleOnPolicyButton = this.page.locator(`input[type="radio"][name="policyVehiclesQuestionOption"]`).first();
|
||||||
}
|
}
|
||||||
|
|
||||||
async validateVehicleIsOnPolicy(vehicleDetails: IVehicleDetails) {
|
async validateVehicleIsOnPolicy(vehicleDetails: IVehicleDetails) {
|
||||||
|
|
@ -21,8 +24,9 @@ export class PolicyVehiclesPage extends BasePage {
|
||||||
const vehicleRegExp = new RegExp(`${vehicleDetails.year} .+ ${vehicleDetails.model}`, 'i');
|
const vehicleRegExp = new RegExp(`${vehicleDetails.year} .+ ${vehicleDetails.model}`, 'i');
|
||||||
await this.page.locator('label').filter({hasText: vehicleRegExp}).locator('div').click();
|
await this.page.locator('label').filter({hasText: vehicleRegExp}).locator('div').click();
|
||||||
}
|
}
|
||||||
async selectVehicleNotListed(){
|
|
||||||
await this.page.getByText('Vehicle not listed').click();
|
async addAnotherVehicle(){
|
||||||
|
await this.page.getByRole('button', {name: 'Add another vehicle'}).click();
|
||||||
}
|
}
|
||||||
|
|
||||||
async assertNonServiceableAlertBehavior(){
|
async assertNonServiceableAlertBehavior(){
|
||||||
|
|
|
||||||
|
|
@ -3,48 +3,78 @@ import { BasePage } from './BasePage';
|
||||||
|
|
||||||
export class ProviderPreferencePage extends BasePage {
|
export class ProviderPreferencePage extends BasePage {
|
||||||
readonly page: Page;
|
readonly page: Page;
|
||||||
readonly scheduleWithSafelite: Locator;
|
readonly scheduleNowButton: Locator;
|
||||||
readonly scheduleWithOther: Locator;
|
readonly findAnotherShopButton: Locator;
|
||||||
readonly acknowledgeAdasButton: Locator;
|
|
||||||
|
readonly acknowledgeAdasCheckbox: Locator;
|
||||||
readonly gotItButton: Locator;
|
readonly gotItButton: Locator;
|
||||||
|
readonly tpaRecalModal: Locator;
|
||||||
|
readonly learnMoreLink: Locator;
|
||||||
|
readonly yesButton: Locator;
|
||||||
|
readonly noButton: Locator;
|
||||||
readonly acknowledgeCheckbox: Locator;
|
readonly acknowledgeCheckbox: Locator;
|
||||||
readonly stateLawModalHeading: Locator;
|
readonly tpaRecalModalContinueButton: Locator;
|
||||||
|
readonly stateLawModalText: Locator;
|
||||||
|
readonly stateLawRepairModalText: Locator;
|
||||||
|
readonly stateLawModalOkayButton: Locator;
|
||||||
issPageValue = 'provider-preference';
|
issPageValue = 'provider-preference';
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
// this.scheduleWithSafelite = this.page.locator('div').filter({ hasText: /Schedule online with |Safelite AutoGlass/ }).first();
|
|
||||||
this.scheduleWithSafelite = this.page.getByText(/Schedule online with|Safelite AutoGlass/).first();
|
this.scheduleNowButton = this.page.getByRole('button', { name: 'Schedule now' });
|
||||||
this.scheduleWithOther = this.page.getByText(/Find another shop|Choose my own shop/).first();
|
this.findAnotherShopButton = this.page.getByRole('link', { name: 'Find another shop' });
|
||||||
this.acknowledgeAdasButton = this.page.getByLabel('I acknowledge that my vehicle');
|
|
||||||
this.gotItButton = this.page.getByRole('button', { name: 'Got it' });
|
//Recal modal
|
||||||
this.acknowledgeCheckbox = this.page.locator('#tpaAcknowledgement');
|
this.tpaRecalModal = this.page.locator('#TPARecalModal');
|
||||||
this.stateLawModalHeading = this.page.getByRole('heading').filter({ hasText: /.* State Law/});
|
this.learnMoreLink = this.page.locator('#moreDetails');
|
||||||
|
this.yesButton = this.page.getByText('Yes', { exact: true }); // schedule with Safelite
|
||||||
|
this.noButton = this.page.getByText('No', { exact: true }); // schedule with TPA
|
||||||
|
this.acknowledgeAdasCheckbox = this.page.getByRole('checkbox', { name: /I acknowledge/i })
|
||||||
|
this.tpaRecalModalContinueButton = this.page.locator('#modalbtn', { hasText: 'Continue' });
|
||||||
|
|
||||||
|
// State law modal - is there a difference between repair and replacement modals? need to check
|
||||||
|
this.stateLawModalText = this.page.getByText(/law prohibits us from requiring you.*You have the right to select the motor vehicle repair shop of your choice\./is);
|
||||||
|
this.stateLawRepairModalText = this.page.getByText(/We are prohibited by law from requiring that repairs be done at a specific automotive repair dealer. You are entitled to select the auto body repair shop to repair damage covered by us\./is);
|
||||||
|
this.stateLawModalOkayButton = this.page.getByRole('button', { name: 'Okay' })
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectProvider(isSafelite = true) {
|
async selectProvider(isSafelite = true) {
|
||||||
if (isSafelite) {
|
if (isSafelite) {
|
||||||
await this.scheduleWithSafelite.click();
|
await this.scheduleNowButton.click();
|
||||||
await this.nextPage();
|
await this.nextPage();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
await this.scheduleWithOther.waitFor({ state: 'visible' });
|
await this.findAnotherShopButton.waitFor({ state: 'visible' });
|
||||||
await this.scheduleWithOther.click();
|
await this.findAnotherShopButton.click();
|
||||||
await this.continueButton.click();
|
await this.tpaRecalModal.waitFor({ state: 'visible' });
|
||||||
//if(await this.acknowledgeAdasButton.isEnabled({timeout: 2500})){
|
await this.scheduleTPAWithAdas();
|
||||||
// await this.acknowledgeAdasButton.click();
|
|
||||||
// await this.gotItButton.click();
|
|
||||||
// await this.page.waitForTimeout(1000);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async acknowledgeRecalNotificaiton() {
|
|
||||||
await this.acknowledgeAdasButton.click();
|
async scheduleWithSafeliteADAS() {
|
||||||
await this.gotItButton.click();
|
await this.learnMoreLink.click();
|
||||||
|
await this.yesButton.click();
|
||||||
|
await this.tpaRecalModalContinueButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
async scheduleTPAWithAdas() {
|
||||||
|
await this.learnMoreLink.click();
|
||||||
|
await this.noButton.click();
|
||||||
|
await this.acknowledgeAdasCheckbox.click();
|
||||||
|
await this.tpaRecalModalContinueButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
async scheduleTPAWithoutAdas() {
|
||||||
|
await this.findAnotherShopButton.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
async validateStateLawModalIsVisible() {
|
async validateStateLawModalIsVisible() {
|
||||||
await expect.soft(this.stateLawModalHeading).toBeVisible();
|
await expect.soft(this.stateLawModalText).toBeVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
async validateStateLawRepairModalIsVisible() {
|
||||||
|
await expect.soft(this.stateLawRepairModalText).toBeVisible();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,56 +3,111 @@ import { BasePage } from './BasePage';
|
||||||
import { IAppointmentDetails } from '@business-logic/types/CustomerDetails';
|
import { IAppointmentDetails } from '@business-logic/types/CustomerDetails';
|
||||||
import { formatDate, formatTime } from '@impl/utils/DateUtils';
|
import { formatDate, formatTime } from '@impl/utils/DateUtils';
|
||||||
import { ServiceLocation } from '@business-logic/types/Enums';
|
import { ServiceLocation } from '@business-logic/types/Enums';
|
||||||
|
import { getCustomerDetails, ITestData } from 'safelite-playwright-core';
|
||||||
|
|
||||||
export class SchedulePage extends BasePage {
|
export class SchedulePage extends BasePage {
|
||||||
readonly page: Page;
|
readonly page: Page;
|
||||||
issPageValue = 'schedule-page';
|
issPageValue = 'schedule-page';
|
||||||
readonly firstAvailableDate: Locator;
|
|
||||||
|
readonly inShopButton: Locator;
|
||||||
|
readonly mobileButton: Locator;
|
||||||
|
readonly moreLocationsButton: Locator;
|
||||||
|
readonly zipCodeTextBox: Locator;
|
||||||
|
readonly findButton: Locator;
|
||||||
|
readonly selectAShopOptions: Locator;
|
||||||
|
readonly firstAppointmentButton : Locator;
|
||||||
|
readonly firstAvailableAMDate: Locator;
|
||||||
|
readonly firstAvailablePMDate: Locator;
|
||||||
readonly firstAvailableTime: Locator;
|
readonly firstAvailableTime: Locator;
|
||||||
|
readonly firstAvailabeAMTime: Locator;
|
||||||
readonly modalContinueButton: Locator;
|
readonly modalContinueButton: Locator;
|
||||||
readonly dropOffButton: Locator;
|
readonly dropOffButton: Locator;
|
||||||
readonly dateText: Locator;
|
readonly dateText: Locator;
|
||||||
readonly viewMoreDatesLink: Locator;
|
readonly viewMoreDatesLink: Locator;
|
||||||
|
|
||||||
|
readonly continueButton: Locator;
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.firstAvailableDate = this.page.locator('.selectable-day').locator('nth=0');
|
|
||||||
this.firstAvailableTime = this.page.locator('label').filter({ hasText: /AM|PM/ }).locator('div').locator('nth=0');
|
this.inShopButton = this.page.locator('[buttonlabel="At a Safelite shop"]');
|
||||||
|
this.mobileButton = this.page.locator('[buttonlabel="Have Safelite come to me"]');
|
||||||
|
// For in shop
|
||||||
|
this.moreLocationsButton = this.page.getByRole('button', { name: 'More Locations' });
|
||||||
|
// For mobile
|
||||||
|
this.zipCodeTextBox = this.page.locator('#serviceZipCode');
|
||||||
|
this.findButton = this.page.getByRole('button', { name: 'Find' });
|
||||||
|
// For in-shop and drop off
|
||||||
|
this.selectAShopOptions = this.page.locator('[class="shop-question"]');
|
||||||
|
this.firstAppointmentButton = this.page.locator('#availabilityIndicator').first();
|
||||||
|
this.firstAvailableAMDate = this.page.locator('morning-row-cell has-appointments selected-date').first();
|
||||||
|
this.firstAvailablePMDate = this.page.locator('afternoon-row-cell has-appointments selected-date').first();
|
||||||
|
this.firstAvailableTime = this.page.locator('.time-slot-button').first();
|
||||||
|
this.firstAvailabeAMTime = this.page.locator('.time-slot-button').nth(0);
|
||||||
this.modalContinueButton = this.page.locator('#modalbtn');
|
this.modalContinueButton = this.page.locator('#modalbtn');
|
||||||
this.dropOffButton = this.page.getByText('Drop off your vehicle', { exact: true });
|
this.dropOffButton = this.page.locator('[class="dropoff-label"]');
|
||||||
this.dateText = this.page.locator('[class="modal-header mb-2 mt-2"]');
|
this.dateText = this.page.locator('[class="modal-header mb-2 mt-2"]');
|
||||||
this.viewMoreDatesLink = this.page.getByText(/View more dates/).first();
|
this.viewMoreDatesLink = this.page.getByRole('button', { name: 'More Right arrow icon' });
|
||||||
|
|
||||||
|
this.continueButton = this.page.locator('#stacked').locator('button:has-text("Continue")');
|
||||||
}
|
}
|
||||||
|
|
||||||
async scheduleAppointment(appointmentDetails: IAppointmentDetails) {
|
// Select in shop and schedule
|
||||||
const formattedDate = formatDate(appointmentDetails.appointmentDate!);
|
async scheduleInShop(appointmentDetails?: IAppointmentDetails){
|
||||||
const formattedTime = formatTime(appointmentDetails.appointmentDate!);
|
|
||||||
const dateInput = this.page.locator(`div[id="${formattedDate}"]`);
|
if (appointmentDetails?.serviceLocation === ServiceLocation.InShop) {
|
||||||
const timeButton = this.page.locator(`div[aria-label="${formattedTime}"]`);
|
try {await this.inShopButton.waitFor({ state: 'visible', timeout: 5000 });
|
||||||
if (await dateInput.isVisible()) {
|
await this.inShopButton.isVisible()
|
||||||
await dateInput.click();
|
await this.inShopButton.click();
|
||||||
} else {
|
await (await this.getFirstNonDropOffTimeSlot()).click();
|
||||||
await this.viewMoreDatesLink.click();
|
} catch {
|
||||||
await dateInput.click();
|
await this.inShopButton.isHidden()
|
||||||
|
await (await this.getFirstNonDropOffTimeSlot()).click();
|
||||||
}
|
}
|
||||||
await timeButton.click();
|
} else if (appointmentDetails?.serviceLocation === ServiceLocation.DropOff) {
|
||||||
await this.modalContinueButton.click();
|
if (await this.inShopButton.isVisible()){
|
||||||
}
|
await this.inShopButton.waitFor({ state: 'visible', timeout: 5000 });
|
||||||
|
await this.inShopButton.click();
|
||||||
|
|
||||||
async scheduleFirstAppointment(serviceLocation: ServiceLocation) {
|
if (await this.dropOffButton.isVisible()) {
|
||||||
if (await this.firstAvailableDate.isVisible()) {
|
await this.dropOffButton.waitFor({ state: 'visible', timeout: 5000 });
|
||||||
await this.firstAvailableDate.click();
|
await this.dropOffButton.click()
|
||||||
} else {
|
} else {
|
||||||
await this.viewMoreDatesLink.click();
|
await (await this.getFirstNonDropOffTimeSlot()).click();
|
||||||
while(await this.firstAvailableDate.isHidden()){
|
|
||||||
await this.viewMoreDatesLink.click();
|
|
||||||
}
|
}
|
||||||
await this.firstAvailableDate.click();
|
} else {
|
||||||
|
await (await this.getFirstNonDropOffTimeSlot()).click();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
await this.selectFirstAvailableTime();
|
||||||
}
|
}
|
||||||
|
await this.continueButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
serviceLocation === ServiceLocation.DropOff ? await this.dropOffButton.click() : await this.firstAvailableTime.click();
|
// Select mobile button, enter zip code, click find button, select first available time and continue
|
||||||
await this.modalContinueButton.click();
|
async scheduleMobile(appointmentDetails: IAppointmentDetails){
|
||||||
return (`${await this.dateText.allInnerTexts()}`);
|
await this.mobileButton.click();
|
||||||
|
await this.zipCodeTextBox.fill(appointmentDetails.serviceAddress!.postalCode!);
|
||||||
|
await this.findButton.click();
|
||||||
|
await this.selectFirstAvailableTime();
|
||||||
|
await this.continueButton.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selects the first available time slot but if its not visible, click "More" first to load more dates and times
|
||||||
|
async selectFirstAvailableTime(): Promise<void> {
|
||||||
|
if (await this.firstAvailableTime.isVisible()) {
|
||||||
|
await this.firstAvailableTime.click();
|
||||||
|
} else {
|
||||||
|
await this.viewMoreDatesLink.click();
|
||||||
|
await this.firstAvailableTime.waitFor({ state: 'visible' });
|
||||||
|
await this.firstAvailableTime.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getFirstNonDropOffTimeSlot(): Promise<Locator> {
|
||||||
|
const timeSlots = this.page.locator('.time-slot-button');
|
||||||
|
const nonDropOff = timeSlots.filter({ hasNotText: /Drop & Go/i });
|
||||||
|
return nonDropOff.first();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -18,26 +18,6 @@ export class ServiceLocationPage extends BasePage {
|
||||||
readonly RecalWarningMessage2: Locator;
|
readonly RecalWarningMessage2: Locator;
|
||||||
readonly militaryWarningMessage: Locator;
|
readonly militaryWarningMessage: Locator;
|
||||||
|
|
||||||
// For in-shop and drop off
|
|
||||||
readonly selectAShopOptions: Locator;
|
|
||||||
readonly firstAppointmentButton: Locator;
|
|
||||||
readonly changeZipButton: Locator;
|
|
||||||
readonly updateZipTextBox: Locator;
|
|
||||||
readonly saveZipButton: Locator;
|
|
||||||
|
|
||||||
// For mobile
|
|
||||||
readonly enterServiceAddressButton: Locator;
|
|
||||||
readonly serviceAddressTextBox: Locator;
|
|
||||||
readonly aptNumberTextBox: Locator;
|
|
||||||
readonly cityTextBox: Locator;
|
|
||||||
readonly stateDropDown: Locator;
|
|
||||||
readonly zipCodeTextBox: Locator;
|
|
||||||
readonly vehicleProtectedYesButton: Locator;
|
|
||||||
readonly vehicleProtectedNoButton: Locator;
|
|
||||||
readonly saveAddressButton: Locator;
|
|
||||||
|
|
||||||
issPageValue = 'service-location';
|
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
|
|
@ -52,80 +32,6 @@ export class ServiceLocationPage extends BasePage {
|
||||||
this.RecalWarningMessage2 = this.page.getByText(/advanced safety system recalibration needs to be done in our shop./);
|
this.RecalWarningMessage2 = this.page.getByText(/advanced safety system recalibration needs to be done in our shop./);
|
||||||
this.militaryWarningMessage = this.page.locator('[class*="widget-name-AlertMilitaryBaseZipWidget"]');
|
this.militaryWarningMessage = this.page.locator('[class*="widget-name-AlertMilitaryBaseZipWidget"]');
|
||||||
|
|
||||||
// For in-shop and drop off
|
|
||||||
this.selectAShopOptions = this.page.locator('[class="shop-question"]');
|
|
||||||
// this.firstAppointmentButton = this.page.locator('div').filter({ hasText: /Appts/}).first();
|
|
||||||
this.firstAppointmentButton = this.page.locator('#availabilityIndicator').first();
|
|
||||||
this.changeZipButton = this.page.locator('[id="serviceZipLinkPromptId"]');
|
|
||||||
this.updateZipTextBox = this.page.getByRole('textbox', { name: 'Update your service ZIP code'});
|
|
||||||
this.saveZipButton = this.page.getByRole('button', { name: 'Save ZIP code' });
|
|
||||||
|
|
||||||
|
|
||||||
// For mobile
|
|
||||||
this.enterServiceAddressButton = this.page.getByRole('link', { name: 'Enter your service address' });
|
|
||||||
this.serviceAddressTextBox = this.page.getByRole('textbox', { name: 'Street Address' });
|
|
||||||
this.aptNumberTextBox = this.page.getByRole('textbox', { name: 'Apt. number'});
|
|
||||||
this.cityTextBox = this.page.getByRole('textbox', { name: 'City' });
|
|
||||||
this.stateDropDown = this.page.getByRole('combobox', { name: 'State' });
|
|
||||||
this.zipCodeTextBox = this.page.getByRole('textbox', { name: 'Zip code' });
|
|
||||||
this.vehicleProtectedYesButton = this.page.locator('label').filter({ hasText: 'Yes' }).locator('div');
|
|
||||||
this.vehicleProtectedNoButton = this.page.locator('label').filter({ hasText: 'No' }).locator('div');
|
|
||||||
this.saveAddressButton = this.page.getByRole('button', { name: 'Save Address' });
|
|
||||||
}
|
|
||||||
|
|
||||||
async selectLocation(appointmentDetails: IAppointmentDetails){
|
|
||||||
if (appointmentDetails.alternateServiceZip) {
|
|
||||||
await this.changeZipButton.click();
|
|
||||||
await this.fillAndValidate(this.updateZipTextBox, appointmentDetails.alternateServiceZip);
|
|
||||||
await this.saveZipButton.click();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(appointmentDetails.serviceLocation) {
|
|
||||||
case ServiceLocation.Mobile:
|
|
||||||
await this.scheduleMobile(appointmentDetails);
|
|
||||||
break;
|
|
||||||
case ServiceLocation.InShop:
|
|
||||||
await this.scheduleInShop(appointmentDetails);
|
|
||||||
break;
|
|
||||||
case ServiceLocation.DropOff:
|
|
||||||
await this.scheduleDropOff(appointmentDetails);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async scheduleInShop(appointmentDetails?: IAppointmentDetails) {
|
|
||||||
await this.inShopButton.click();
|
|
||||||
if (appointmentDetails && appointmentDetails.shopAddress) {
|
|
||||||
await this.selectAShopOptions.locator(`[buttonbodycopy="${appointmentDetails.shopAddress}"]`).check();
|
|
||||||
} else {
|
|
||||||
await this.firstAppointmentButton.click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async scheduleMobile(appointmentDetails: IAppointmentDetails){
|
|
||||||
if (appointmentDetails.serviceAddress) {
|
|
||||||
await this.mobileButton.click();
|
|
||||||
await this.enterServiceAddressButton.click();
|
|
||||||
await this.addressForm.populateAddress({ address: appointmentDetails.serviceAddress! });
|
|
||||||
if (faker.datatype.boolean()) {
|
|
||||||
await this.vehicleProtectedYesButton.check();
|
|
||||||
} else {
|
|
||||||
await this.vehicleProtectedNoButton.check();
|
|
||||||
}
|
|
||||||
await this.saveAddressButton.click();
|
|
||||||
} else {
|
|
||||||
console.error('ServiceLocationPage >> Please supply an address')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async scheduleDropOff(appointmentDetails?: IAppointmentDetails){
|
|
||||||
await this.dropOffButton.click();
|
|
||||||
if (appointmentDetails && appointmentDetails.shopAddress) {
|
|
||||||
await this.selectAShopOptions.locator(`[buttonbodycopy="${appointmentDetails.shopAddress}"]`).check();
|
|
||||||
} else {
|
|
||||||
await this.firstAppointmentButton.click();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async validateRecalWarning(){
|
async validateRecalWarning(){
|
||||||
|
|
|
||||||
|
|
@ -6,21 +6,37 @@ export class ServicePackagesPage extends BasePage {
|
||||||
readonly page: Page;
|
readonly page: Page;
|
||||||
readonly standardPackageButton: Locator;
|
readonly standardPackageButton: Locator;
|
||||||
readonly premiumPackageButton: Locator;
|
readonly premiumPackageButton: Locator;
|
||||||
readonly glassOnlyButton: Locator;
|
readonly glassOnlyPackageButton: Locator;
|
||||||
|
readonly wiperModal: Locator;
|
||||||
|
readonly wiperModalCloseButton: Locator;
|
||||||
|
readonly continueButton: Locator;
|
||||||
issPageValue = 'service-packages';
|
issPageValue = 'service-packages';
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.standardPackageButton = this.page.locator('li').filter({ hasText: 'Standard' });
|
this.standardPackageButton = this.page.locator('label[for="ServicePackageQuestion-TierTwo"]'); // standard package
|
||||||
this.premiumPackageButton = this.page.locator('li').filter({ hasText: 'Premium' });
|
this.premiumPackageButton = this.page.locator('label[for="ServicePackageQuestion-TierThree"]'); // premium package
|
||||||
this.glassOnlyButton = this.page.locator('li').filter({ hasText: 'Glass service' });
|
this.glassOnlyPackageButton = this.page.locator('label[for="ServicePackageQuestion-TierOne"]'); // glass only package
|
||||||
|
this.wiperModal = this.page.locator('#FrontWiperModal #modalbtn');
|
||||||
|
this.wiperModalCloseButton = this.page.locator('#FrontWiperModal').getByLabel('Close')
|
||||||
|
this.continueButton = this.page.getByRole('button', { name: 'Continue' });
|
||||||
// this.validateURL(this.url);
|
// this.validateURL(this.url);
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectServicePackage(servicePackage: ServicePackage){
|
async selectServicePackage(servicePackage: ServicePackage){
|
||||||
await this.page.getByText(servicePackage).click();
|
if (servicePackage === ServicePackage.Standard) {
|
||||||
return (`${await this.page.locator('li').filter({ hasText: 'Premium' }).locator('[class="pricing-info"]').allInnerTexts()}`);
|
await this.standardPackageButton.check();
|
||||||
//return (`${await this.page.getByText(servicePackage).locator('[class="pricing-info"]').allInnerTexts()}`);
|
} else if (servicePackage === ServicePackage.Premium) {
|
||||||
|
await this.premiumPackageButton.check();
|
||||||
|
try {await this.wiperModal.waitFor({ state: 'visible', timeout: 5000 });
|
||||||
|
await this.wiperModalCloseButton.click();
|
||||||
|
} catch {
|
||||||
|
await this.continueButton.click();
|
||||||
|
}
|
||||||
|
} else if (servicePackage === ServicePackage.GlassOnly) {
|
||||||
|
await this.glassOnlyPackageButton.check();
|
||||||
|
}
|
||||||
|
await this.continueButton.click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,16 +4,30 @@ import { BasePage } from './BasePage';
|
||||||
export class TpaConfirmationPage extends BasePage {
|
export class TpaConfirmationPage extends BasePage {
|
||||||
readonly page: Page;
|
readonly page: Page;
|
||||||
readonly successMessage: Locator;
|
readonly successMessage: Locator;
|
||||||
|
readonly shopConfirmationMessage: Locator;
|
||||||
readonly issPageValue = 'tpa-confirmation';
|
readonly issPageValue = 'tpa-confirmation';
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.successMessage = page.getByText('Success');
|
this.successMessage = page.getByText('Thank you for submitting your claim; there is one final step.');
|
||||||
|
this.shopConfirmationMessage = page.locator('div.subheader').first()
|
||||||
|
}
|
||||||
|
|
||||||
|
async getTpaShopSelectedName() {
|
||||||
|
const sessionStorage = JSON.parse(await this.page.evaluate('sessionStorage.getItem(\'submittedOrder\')'));
|
||||||
|
const tpaShopSelectedName = sessionStorage.serviceLocation.provider.companyName;
|
||||||
|
return tpaShopSelectedName;
|
||||||
}
|
}
|
||||||
|
|
||||||
async validateSuccessMessage() {
|
async validateSuccessMessage() {
|
||||||
await expect(this.successMessage).toBeVisible();
|
const shopConfirmationMessageText = await this.shopConfirmationMessage.textContent();
|
||||||
}
|
const tpaShopSelectedNameText = await this.getTpaShopSelectedName();
|
||||||
|
|
||||||
|
await this.successMessage.waitFor({ state: 'visible' });
|
||||||
|
await expect(this.successMessage).toBeVisible();
|
||||||
|
expect.soft(shopConfirmationMessageText?.toLowerCase()).toContain(
|
||||||
|
('Your information has been sent to' + ' ' + tpaShopSelectedNameText).toLowerCase()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,20 +4,12 @@ import { BasePage } from './BasePage';
|
||||||
export class TpaSearchPage extends BasePage {
|
export class TpaSearchPage extends BasePage {
|
||||||
readonly page: Page;
|
readonly page: Page;
|
||||||
readonly firstLocationButton: Locator;
|
readonly firstLocationButton: Locator;
|
||||||
readonly doNotSeeMyShopButton: Locator;
|
|
||||||
issPageValue = 'tpa-search';
|
issPageValue = 'tpa-search';
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
// this.firstLocationButton = page.locator("fieldset[aria-labelledby='chooseShop']/span").first();
|
this.firstLocationButton = page.locator('div.button-content').first();
|
||||||
this.firstLocationButton = page.locator("#buttonLabelSpan").first();
|
|
||||||
|
|
||||||
this.doNotSeeMyShopButton = page.getByRole('link', { name: 'I don\'t see my shop' });
|
|
||||||
}
|
|
||||||
|
|
||||||
async selectDoNotSeeMyShop() {
|
|
||||||
await this.doNotSeeMyShopButton.click()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectFirstLocation() {
|
async selectFirstLocation() {
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,29 @@
|
||||||
import { expect, type Locator, type Page } from '@playwright/test';
|
import { expect, type Locator, type Page } from '@playwright/test';
|
||||||
import { BasePage } from './BasePage';
|
import { BasePage } from './BasePage';
|
||||||
|
import { IClaimDetails } from '@business-logic/types/CustomerDetails';
|
||||||
|
|
||||||
export class TpaSubmitPage extends BasePage {
|
export class TpaSubmitPage extends BasePage {
|
||||||
readonly page: Page;
|
readonly page: Page;
|
||||||
readonly deductible: Locator;
|
readonly deductible: Locator;
|
||||||
|
readonly recalAlert: Locator;
|
||||||
|
readonly learnMoreLink: Locator;
|
||||||
|
readonly recalModal: Locator;
|
||||||
|
readonly closeRecalModalButton: Locator;
|
||||||
issPageValue = 'tpa-submit';
|
issPageValue = 'tpa-submit';
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.deductible = page.getByText('Deductible $');
|
this.recalAlert = page.getByRole('alert').filter({ hasText: 'Some vehicle safety features may not work properly.'});
|
||||||
|
this.learnMoreLink = page.getByRole('link', { name: 'Learn more' });
|
||||||
|
this.recalModal = page.getByRole('dialog').filter({ hasText: 'IMPORTANT SERVICE REQUIRED' }).first();
|
||||||
|
this.closeRecalModalButton = page.locator('.modalbtn', { hasText: 'Close' });
|
||||||
|
this.deductible = page.locator('span#deductible-value, span.deductible-value');
|
||||||
}
|
}
|
||||||
|
|
||||||
async validateDeductible(expDeductible) {
|
async validateDeductible(claimDetails: IClaimDetails) {
|
||||||
await expect(this.deductible).toContainText(expDeductible);
|
await expect(this.deductible).toContainText(claimDetails.policyDeductible.toLocaleString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Validate change preferred shop and contact details flows
|
||||||
}
|
}
|
||||||
|
|
@ -4,13 +4,13 @@ import { VehicleDamage } from '@business-logic/types/Enums';
|
||||||
|
|
||||||
export class VehicleDamagePage extends BasePage {
|
export class VehicleDamagePage extends BasePage {
|
||||||
readonly page: Page;
|
readonly page: Page;
|
||||||
readonly windshieldChkBox: Locator;
|
readonly windshieldButton: Locator;
|
||||||
readonly crackButton: Locator;
|
readonly sideDoorButton: Locator;
|
||||||
readonly chipButton: Locator;
|
readonly replaceButton: Locator;
|
||||||
|
readonly repairButton: Locator;
|
||||||
readonly singleWindshieldButton: Locator;
|
readonly singleWindshieldButton: Locator;
|
||||||
readonly splitWindshieldDriverSideButton: Locator;
|
readonly splitWindshieldDriverSideButton: Locator;
|
||||||
readonly splitWindshieldPassengerSideButton: Locator;
|
readonly splitWindshieldPassengerSideButton: Locator;
|
||||||
readonly sideDoorButton: Locator;
|
|
||||||
readonly driverSideButton: Locator;
|
readonly driverSideButton: Locator;
|
||||||
readonly passengerSideButton: Locator;
|
readonly passengerSideButton: Locator;
|
||||||
readonly driverQuarterPanelChkBox: Locator;
|
readonly driverQuarterPanelChkBox: Locator;
|
||||||
|
|
@ -30,9 +30,11 @@ export class VehicleDamagePage extends BasePage {
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.windshieldChkBox = this.page.locator('[buttonlabel="Windshield"]');
|
this.windshieldButton = this.page.locator('[buttonlabel="Windshield"]');
|
||||||
this.crackButton = this.page.locator('[buttonlabel="Crack"]');
|
this.sideDoorButton = this.page.locator('[buttonlabel="Side door"]');
|
||||||
this.chipButton = this.page.locator('[buttonlabel="Chip(s)"]');
|
this.rearWindowChkBox = this.page.locator('[buttonlabel="Rear window"]');
|
||||||
|
this.replaceButton = this.page.locator('div.list-card-content:has-text("Replace")');
|
||||||
|
this.repairButton = this.page.locator('div.list-card-content:has-text("Repair")');
|
||||||
this.singleWindshieldButton = this.page.locator('[buttonlabel="Single windshield"]');
|
this.singleWindshieldButton = this.page.locator('[buttonlabel="Single windshield"]');
|
||||||
this.splitWindshieldDriverSideButton = this.page.locator('[buttonlabel="Split windshield, driver side"]');
|
this.splitWindshieldDriverSideButton = this.page.locator('[buttonlabel="Split windshield, driver side"]');
|
||||||
this.splitWindshieldPassengerSideButton = this.page.locator('[buttonlabel="Split windshield, passenger side"]');
|
this.splitWindshieldPassengerSideButton = this.page.locator('[buttonlabel="Split windshield, passenger side"]');
|
||||||
|
|
@ -55,17 +57,17 @@ export class VehicleDamagePage extends BasePage {
|
||||||
|
|
||||||
async checkSeparateApptsWarning() {
|
async checkSeparateApptsWarning() {
|
||||||
// Select conflict
|
// Select conflict
|
||||||
await this.windshieldChkBox.check();
|
await this.windshieldButton.check();
|
||||||
await this.chipButton.check();
|
await this.repairButton.check();
|
||||||
await this.rearWindowChkBox.check();
|
await this.rearWindowChkBox.check();
|
||||||
|
|
||||||
// Expect warning
|
// Expect warning
|
||||||
await expect.soft(this.separateApptsWarning).toBeAttached();
|
await expect.soft(this.separateApptsWarning).toBeAttached();
|
||||||
|
|
||||||
// Undo changes
|
// Undo changes
|
||||||
await this.crackButton.check();
|
await this.replaceButton.check();
|
||||||
await this.windshieldChkBox.uncheck();
|
await this.windshieldButton.uncheck();
|
||||||
await expect.soft(this.crackButton).not.toBeVisible();
|
await expect.soft(this.replaceButton).not.toBeVisible();
|
||||||
await this.rearWindowChkBox.uncheck();
|
await this.rearWindowChkBox.uncheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,33 +75,33 @@ export class VehicleDamagePage extends BasePage {
|
||||||
for (const damage of vehicleDamage) {
|
for (const damage of vehicleDamage) {
|
||||||
switch(damage) {
|
switch(damage) {
|
||||||
case VehicleDamage.WindshieldOneChip:
|
case VehicleDamage.WindshieldOneChip:
|
||||||
await this.windshieldChkBox.check();
|
await this.windshieldButton.check();
|
||||||
await this.selectChips('1');
|
await this.selectChips('1');
|
||||||
break;
|
break;
|
||||||
case VehicleDamage.WindshieldTwoChips:
|
case VehicleDamage.WindshieldTwoChips:
|
||||||
await this.windshieldChkBox.check();
|
await this.windshieldButton.check();
|
||||||
await this.selectChips('2');
|
await this.selectChips('2');
|
||||||
break;
|
break;
|
||||||
case VehicleDamage.WindshieldThreeChips:
|
case VehicleDamage.WindshieldThreeChips:
|
||||||
await this.windshieldChkBox.check();
|
await this.windshieldButton.check();
|
||||||
await this.selectChips('3');
|
await this.selectChips('3');
|
||||||
break;
|
break;
|
||||||
case VehicleDamage.WindshieldCrack:
|
case VehicleDamage.WindshieldCrack:
|
||||||
await this.windshieldChkBox.check();
|
await this.windshieldButton.check();
|
||||||
await this.selectCrack();
|
await this.selectCrack();
|
||||||
break;
|
break;
|
||||||
case VehicleDamage.WindshieldCrackSingleWindshield:
|
case VehicleDamage.WindshieldCrackSingleWindshield:
|
||||||
await this.windshieldChkBox.check();
|
await this.windshieldButton.check();
|
||||||
await this.selectCrack();
|
await this.selectCrack();
|
||||||
await this.singleWindshieldButton.check();
|
await this.singleWindshieldButton.check();
|
||||||
break;
|
break;
|
||||||
case VehicleDamage.WindshieldCrackDriverSide:
|
case VehicleDamage.WindshieldCrackDriverSide:
|
||||||
await this.windshieldChkBox.check();
|
await this.windshieldButton.check();
|
||||||
await this.selectCrack();
|
await this.selectCrack();
|
||||||
await this.splitWindshieldDriverSideButton.check();
|
await this.splitWindshieldDriverSideButton.check();
|
||||||
break;
|
break;
|
||||||
case VehicleDamage.WindshieldCrackPassengerSide:
|
case VehicleDamage.WindshieldCrackPassengerSide:
|
||||||
await this.windshieldChkBox.check();
|
await this.windshieldButton.check();
|
||||||
await this.selectCrack();
|
await this.selectCrack();
|
||||||
await this.splitWindshieldPassengerSideButton.check();
|
await this.splitWindshieldPassengerSideButton.check();
|
||||||
break;
|
break;
|
||||||
|
|
@ -156,12 +158,12 @@ export class VehicleDamagePage extends BasePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectCrack(){
|
async selectCrack(){
|
||||||
await this.crackButton.check();
|
await this.replaceButton.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectChips(numChips: string){
|
async selectChips(numChips: string){
|
||||||
const numChipsButton = this.page.getByText(numChips, {exact: true});
|
const numChipsButton = this.page.getByText(numChips, {exact: true});
|
||||||
await this.chipButton.check();
|
await this.repairButton.check();
|
||||||
await numChipsButton.check();
|
await numChipsButton.check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export class VehicleLookupLicensePage extends BasePage {
|
||||||
this.licensePlateNumTextBox = page.getByRole('textbox', { name: 'License plate number' });
|
this.licensePlateNumTextBox = page.getByRole('textbox', { name: 'License plate number' });
|
||||||
this.licensePlateStateDrpDwn = page.getByRole('combobox', { name: 'License plate state' });
|
this.licensePlateStateDrpDwn = page.getByRole('combobox', { name: 'License plate state' });
|
||||||
this.plateNoMatchError = page.getByText('Your license plate didn’t return a VIN match.Please re-enter the information');
|
this.plateNoMatchError = page.getByText('Your license plate didn’t return a VIN match.Please re-enter the information');
|
||||||
this.plateMismatchAlert = page.getByRole('alert').locator('div');
|
this.plateMismatchAlert = page.getByText('We found a windshield, but the VIN associated with the license plate you provided is for a');
|
||||||
}
|
}
|
||||||
|
|
||||||
async enterPlateDetails(vehicleDetails: IVehicleDetails, isVehicleLookupValidations = false) {
|
async enterPlateDetails(vehicleDetails: IVehicleDetails, isVehicleLookupValidations = false) {
|
||||||
|
|
@ -26,6 +26,7 @@ export class VehicleLookupLicensePage extends BasePage {
|
||||||
await this.continueButton.click({ timeout: 1000 });
|
await this.continueButton.click({ timeout: 1000 });
|
||||||
await expect(this.plateNoMatchError).toBeVisible();
|
await expect(this.plateNoMatchError).toBeVisible();
|
||||||
await this.licensePlateNumTextBox.fill(vehicleDetails.licensePlateNumber[1]);
|
await this.licensePlateNumTextBox.fill(vehicleDetails.licensePlateNumber[1]);
|
||||||
|
await this.licensePlateStateDrpDwn.selectOption(vehicleDetails.licensePlateState![1]);
|
||||||
await this.continueButton.click({ timeout: 1000 });
|
await this.continueButton.click({ timeout: 1000 });
|
||||||
await expect(this.plateMismatchAlert).toBeVisible();
|
await expect(this.plateMismatchAlert).toBeVisible();
|
||||||
await this.licensePlateNumTextBox.fill(vehicleDetails.licensePlateNumber[2]);
|
await this.licensePlateNumTextBox.fill(vehicleDetails.licensePlateNumber[2]);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ export class VehicleLookupPage extends BasePage {
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.vinLookupButton = page.getByLabel('Provide my VIN manually', { exact: true });
|
this.vinLookupButton = page.getByLabel('Provide my VIN', { exact: true });
|
||||||
this.addressLookupButton = page.getByLabel('Provide my home address', { exact: true });
|
this.addressLookupButton = page.getByLabel('Provide my home address', { exact: true });
|
||||||
this.licenseLookupButton = page.getByLabel('Provide my license plate #', { exact: true });
|
this.licenseLookupButton = page.getByLabel('Provide my license plate #', { exact: true });
|
||||||
this.vinLookupPage = new VinLookupPage(page);
|
this.vinLookupPage = new VinLookupPage(page);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { Page } from "@playwright/test";
|
import { expect, type Locator, type Page } from "@playwright/test";
|
||||||
import { PartQuestionsPage } from "./PartQuestionsPage";
|
import { PartQuestionsPage } from "./PartQuestionsPage";
|
||||||
|
import { IPartQuestion } from '@business-logic/types/CustomerDetails';
|
||||||
|
|
||||||
export default class VehiclePartQuestionsPage extends PartQuestionsPage{
|
export default class VehiclePartQuestionsPage extends PartQuestionsPage{
|
||||||
issPageValue = 'vehicle-parts';
|
issPageValue = 'vehicle-parts';
|
||||||
|
|
@ -7,4 +8,16 @@ export default class VehiclePartQuestionsPage extends PartQuestionsPage{
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async selectPartQuestionResponses(partQuestions: IPartQuestion[]) {
|
||||||
|
for (const pq of partQuestions) {
|
||||||
|
const parentobject=this.page.locator(`fieldset[aria-labelledby="${pq.partQuestionType}"]`);
|
||||||
|
const partQuestionOptionButton = parentobject.locator(`[buttonlabel="${pq.optionToSelect}"]`);
|
||||||
|
await partQuestionOptionButton.nth(0).click();
|
||||||
|
if (pq.secondaryQuestionOptionToSelect != null) {
|
||||||
|
const secondaryQuestionButton = parentobject.getByText(`${pq.secondaryQuestionOptionToSelect}`);
|
||||||
|
await secondaryQuestionButton.nth(1).click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -16,6 +16,7 @@ export class WelcomePage extends BasePage {
|
||||||
readonly city: Locator;
|
readonly city: Locator;
|
||||||
readonly state: Locator;
|
readonly state: Locator;
|
||||||
readonly cookieCloseButton: Locator;
|
readonly cookieCloseButton: Locator;
|
||||||
|
readonly GetStartedButton: Locator;
|
||||||
url = process.env['BASE_URL']! + '/?issPage=welcome-page';
|
url = process.env['BASE_URL']! + '/?issPage=welcome-page';
|
||||||
issPageValue = 'welcome-page';
|
issPageValue = 'welcome-page';
|
||||||
|
|
||||||
|
|
@ -24,13 +25,14 @@ export class WelcomePage extends BasePage {
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.policyNumber = page.getByRole('textbox', { name: 'Policy number' });
|
this.policyNumber = page.getByRole('textbox', { name: 'Policy number' });
|
||||||
this.policyZip = page.getByRole('textbox', { name: 'Policy ZIP' });
|
this.policyZip = page.getByRole('textbox', { name: 'Policy ZIP' });
|
||||||
this.damageDate = page.getByRole('textbox', { name: 'When did the damage occur?<' });
|
this.damageDate = page.locator('#dateOfLossField');
|
||||||
this.damageCause = page.locator('#damageCauseQuestionField');
|
this.damageCause = page.locator('#damageCauseQuestionField');
|
||||||
this.phoneNumber = page.getByRole('textbox', { name: 'Best number to reach you' });
|
this.phoneNumber = page.getByRole('textbox', { name: 'Best number to reach you' });
|
||||||
this.emailAddress = page.getByRole('textbox', { name: 'Email address' });
|
this.emailAddress = page.getByRole('textbox', { name: 'Email address' });
|
||||||
this.city = page.getByRole('textbox', { name: 'In which city did the damage' });
|
this.city = page.getByRole('textbox', { name: 'In which city did the damage' });
|
||||||
this.state = page.locator('select[name="\\38 fdf9dc2e13e430eb57529499dceb3eb"]');
|
this.state = page.locator('select[name="\\38 fdf9dc2e13e430eb57529499dceb3eb"]');
|
||||||
this.cookieCloseButton = page.getByRole('button', { name: 'Close' });
|
this.cookieCloseButton = page.getByRole('button', { name: 'Close' });
|
||||||
|
this.GetStartedButton = page.getByRole('button', { name: 'Get Started' });
|
||||||
}
|
}
|
||||||
|
|
||||||
async goto(clientTag: string) {
|
async goto(clientTag: string) {
|
||||||
|
|
@ -66,18 +68,17 @@ export class WelcomePage extends BasePage {
|
||||||
|
|
||||||
async populatePage(customerDetails: ICustomerDetails, claimDetails: IClaimDetails, isFillCityInfo: boolean) {
|
async populatePage(customerDetails: ICustomerDetails, claimDetails: IClaimDetails, isFillCityInfo: boolean) {
|
||||||
await this.policyNumber.fill(claimDetails.policyNumber);
|
await this.policyNumber.fill(claimDetails.policyNumber);
|
||||||
await this.policyZip.fill(customerDetails.address.postalCode);
|
await this.phoneNumber.fill(customerDetails.phoneNumber);
|
||||||
await this.damageDate.click();
|
await this.damageDate.click();
|
||||||
await this.damageDate.fill(claimDetails.damageDate);
|
await this.damageDate.fill(claimDetails.damageDate);
|
||||||
await this.damageCause.selectOption(claimDetails.damageCause);
|
await this.damageCause.selectOption(claimDetails.damageCause);
|
||||||
await this.damageCause.press('Tab');
|
await this.damageCause.press('Tab');
|
||||||
await this.phoneNumber.fill(customerDetails.phoneNumber);
|
await this.policyZip.fill(customerDetails.address.postalCode);
|
||||||
// Phone number fixed 12/5. Can't start with 1 or 0
|
|
||||||
await this.emailAddress.fill(customerDetails.email);
|
|
||||||
|
|
||||||
if (isFillCityInfo) {
|
if (isFillCityInfo) {
|
||||||
await this.city.fill(customerDetails.address.city);
|
|
||||||
await this.state.selectOption(customerDetails.address.state);
|
await this.state.selectOption(customerDetails.address.state);
|
||||||
|
await this.city.fill(customerDetails.address.city);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -88,6 +88,7 @@ export default defineConfig({
|
||||||
// baseURL: 'http://127.0.0.1:3000',
|
// baseURL: 'http://127.0.0.1:3000',
|
||||||
|
|
||||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||||
|
baseURL: process.env.BASE_URL || 'https://selfservice.test.glassclaim.com',
|
||||||
trace: 'on-first-retry',
|
trace: 'on-first-retry',
|
||||||
headless: process.env.CI ? true : false,
|
headless: process.env.CI ? true : false,
|
||||||
screenshot: "only-on-failure",
|
screenshot: "only-on-failure",
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
import TestCase from "@business-logic/types/TestCase";
|
import TestCase from "@business-logic/types/TestCase";
|
||||||
import { expect, Page } from "@playwright/test";
|
import { expect, Page } from "@playwright/test";
|
||||||
|
import { getDefaultTestData } from "safelite-playwright-core";
|
||||||
import { addSmokeTagToRandomTest, prepareTest, test, TestInfo } from "@business-logic/types/Test";
|
import { addSmokeTagToRandomTest, prepareTest, test, TestInfo } from "@business-logic/types/Test";
|
||||||
import { RuleEngine, ValidationOptions } from "@business-logic/types/RuleEngine";
|
import { RuleEngine, ValidationOptions } from "@business-logic/types/RuleEngine";
|
||||||
import { ICustomerDetails } from "@business-logic/types/CustomerDetails";
|
import { ICustomerDetails } from "@business-logic/types/CustomerDetails";
|
||||||
import essentialHpTestCases from "./0016_EssentialRepairInShop";
|
import essentialHpTestCases from "./0016_EssentialRepairInShop";
|
||||||
import essentialReplaceTestCases from "./0013_EssentialReplace";
|
import essentialReplaceTestCases from "./0013_EssentialReplace";
|
||||||
import { BailoutCode, VehicleDamage, VehicleLookupType } from "@business-logic/types/Enums";
|
import { BailoutCode, ServiceLocation, VehicleDamage, VehicleLookupType } from "@business-logic/types/Enums";
|
||||||
import essentialTpaNotEnabledTestCases from "./0003_EssentialTpaNotEnabledBailout";
|
import essentialTpaNotEnabledTestCases from "./0003_EssentialTpaNotEnabledBailout";
|
||||||
import essentialDoNotSeeShopTestCases from "./0011_EssentialDoNotSeeShopBailout";
|
import essentialDoNotSeeShopTestCases from "./0011_EssentialDoNotSeeShopBailout";
|
||||||
import essentialVehicleNotFoundTestCases from "./0010_EssentialVehicleNotFoundBailout";
|
import essentialVehicleNotFoundTestCases from "./0010_EssentialVehicleNotFoundBailout";
|
||||||
|
|
@ -58,7 +59,7 @@ import advancedScenario0025TestCases from "./advanced/0025a_VehicleByVINUnverifi
|
||||||
import advancedScenario0026aTestCases from "./advanced/0026a_NoDeductibleAdasBailout5";
|
import advancedScenario0026aTestCases from "./advanced/0026a_NoDeductibleAdasBailout5";
|
||||||
import advancedScenario0028aTestCases from "./advanced/0028a_ItacCancelMyClaim";
|
import advancedScenario0028aTestCases from "./advanced/0028a_ItacCancelMyClaim";
|
||||||
import advancedScenario0029aTestCases from "./advanced/0029a_HeavyVehicleBailout";
|
import advancedScenario0029aTestCases from "./advanced/0029a_HeavyVehicleBailout";
|
||||||
import advancedScenario0030aTestCases from "./advanced/0030a_PartsServiceBailout";
|
import advancedScenario0030aTestCases from "./advanced/0030a_APIErrorBailout";
|
||||||
import advancedScenario0031aTestCases from "./advanced/0031a_ReplaceServiceableBigTruck";
|
import advancedScenario0031aTestCases from "./advanced/0031a_ReplaceServiceableBigTruck";
|
||||||
import advancedScenario0032aTestCases from "./advanced/0032a_DeclineNonServiceableBigTruck";
|
import advancedScenario0032aTestCases from "./advanced/0032a_DeclineNonServiceableBigTruck";
|
||||||
|
|
||||||
|
|
@ -382,8 +383,8 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
// Destructure data for easy access
|
// Destructure data for easy access
|
||||||
const { customerDetails, claimDetails, vehicleDetails, vehicleDamage,
|
const { customerDetails, claimDetails, vehicleDetails, vehicleDamage,
|
||||||
appointmentDetails, isSafelite, endorsements,
|
appointmentDetails, isSafelite, endorsements,
|
||||||
partQuestions, paymentDetails, isNoComp, isItac, isRecalNotification,
|
partQuestions, paymentDetails, isNoComp, isItac, isRecalNotification, isUnverifiedPolicyAfterVehicleLookup,
|
||||||
isRecalWarning, servicePackage, hasStateLawPopup, otherVehiclesOnPolicy,
|
isRecalWarning, servicePackage, hasOemEndorsement, hasStateLawPopup, otherVehiclesOnPolicy,
|
||||||
isSeparateApptsWarning, vehiclePartQuestions, editVehicleDetails, isAddressLookupValidations,
|
isSeparateApptsWarning, vehiclePartQuestions, editVehicleDetails, isAddressLookupValidations,
|
||||||
hasMilitaryWarning, capabilityQuestions, isUseVehicleOnPolicy,
|
hasMilitaryWarning, capabilityQuestions, isUseVehicleOnPolicy,
|
||||||
isVehicleLookupValidations, isMoldingQuestion, isNonServiceable, isNonServiceableVin } = testCase.testData;
|
isVehicleLookupValidations, isMoldingQuestion, isNonServiceable, isNonServiceableVin } = testCase.testData;
|
||||||
|
|
@ -401,9 +402,9 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
vehiclePartQuestionsPage, capabilityQuestionsPage, moldingQuestionsPage, addressLookupPage } = testCase.pages;
|
vehiclePartQuestionsPage, capabilityQuestionsPage, moldingQuestionsPage, addressLookupPage } = testCase.pages;
|
||||||
|
|
||||||
// Destructure bailout flags
|
// Destructure bailout flags
|
||||||
const { isVehicleSelectBailout, isDoNotSeeMyShopBailout, isTpaNotEnabledBailout,
|
const { isVehicleSelectBailout, isTpaNotEnabledBailout,
|
||||||
isPartsServiceErrorBailout, isVehicleLookupBailout, isPriceServiceErrorBailout,
|
isAPIErrorBailout, isVehicleLookupBailout, isPriceServiceErrorBailout,
|
||||||
isRequestCallbackBailout } = testCase.testData.bailoutFlags || {};
|
isRequestCallbackBailout, isHeavyTruckVehicleBailout, isCoverageCancelledByUser } = testCase.testData.bailoutFlags || {};
|
||||||
|
|
||||||
const repairTypes: VehicleDamage[] = [
|
const repairTypes: VehicleDamage[] = [
|
||||||
VehicleDamage.WindshieldOneChip,
|
VehicleDamage.WindshieldOneChip,
|
||||||
|
|
@ -420,7 +421,7 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
|
|
||||||
await test.step('WelcomePage >> Populate Customer Details', async () => {
|
await test.step('WelcomePage >> Populate Customer Details', async () => {
|
||||||
await welcomePage.populatePage(customerDetails!, claimDetails!, await welcomePage.hasCityInfo());
|
await welcomePage.populatePage(customerDetails!, claimDetails!, await welcomePage.hasCityInfo());
|
||||||
await welcomePage.nextPage();
|
await welcomePage.GetStartedButton.click();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (testCase.testData.isDuplicateClaim) {
|
if (testCase.testData.isDuplicateClaim) {
|
||||||
|
|
@ -445,26 +446,35 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!(isUseVehicleOnPolicy ?? true)) {
|
if (!(isUseVehicleOnPolicy ?? true)) {
|
||||||
await policyVehiclesPage.selectVehicleNotListed();
|
await policyVehiclesPage.addAnotherVehicle();
|
||||||
await policyVehiclesPage.nextPage();
|
await policyVehiclesPage.nextPage();
|
||||||
await vehicleSelectionPage.selectVehicle(vehicleDetails!);
|
await vehicleSelectionPage.selectVehicle(vehicleDetails!);
|
||||||
await policyVehiclesPage.nextPage();
|
await policyVehiclesPage.nextPage();
|
||||||
|
|
||||||
|
await test.step('PolicyHolderDetailsPage >> Enter customer data', async () => {
|
||||||
|
await policyHolderDetailsPage.validateURL(policyHolderDetailsPage.issPageValue);
|
||||||
|
await policyHolderDetailsPage.fillCustomerDetails(customerDetails!);
|
||||||
|
await policyHolderDetailsPage.nextPage();
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
// Select vehicle
|
// Select vehicle
|
||||||
await policyVehiclesPage.selectVehicle(vehicleDetails!);
|
await policyVehiclesPage.selectVehicle(vehicleDetails!);
|
||||||
|
|
||||||
|
await policyVehiclesPage.nextPage();
|
||||||
|
await policyVehiclesPage.logReferralNumber();
|
||||||
|
|
||||||
|
if (isNonServiceable && isHeavyTruckVehicleBailout) {
|
||||||
|
await bailoutPage.validateURL(bailoutPage.issPageValue);
|
||||||
|
await bailoutPage.validateBailoutDetails(customerDetails!, BailoutCode.HeavyTruckVehicle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isNonServiceable) {
|
if (isNonServiceable) {
|
||||||
await policyVehiclesPage.assertNonServiceableAlertBehavior();
|
await policyVehiclesPage.assertNonServiceableAlertBehavior();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await policyVehiclesPage.nextPage();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isNonServiceable) {
|
if (hasEndorsements) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasEndorsements) {
|
|
||||||
await test.step('EndorsementsPage >> Select Endorsements', async () => {
|
await test.step('EndorsementsPage >> Select Endorsements', async () => {
|
||||||
await endorsementsPage.validateURL(endorsementsPage.issPageValue);
|
await endorsementsPage.validateURL(endorsementsPage.issPageValue);
|
||||||
await endorsementsPage.verifyEndorsements(endorsements);
|
await endorsementsPage.verifyEndorsements(endorsements);
|
||||||
|
|
@ -472,29 +482,22 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
await endorsementsPage.nextPage();
|
await endorsementsPage.nextPage();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
await test.step('PolicyHolderDetailsPage >> Enter customer data', async () => {
|
||||||
} else {
|
await policyHolderDetailsPage.validateURL(policyHolderDetailsPage.issPageValue);
|
||||||
await policyVehiclesPage.logReferralNumber();
|
await policyHolderDetailsPage.fillCustomerDetails(customerDetails!);
|
||||||
await test.step('PolicyHolderDetailsPage >> Enter customer data', async () => {
|
await policyHolderDetailsPage.nextPage();
|
||||||
await policyHolderDetailsPage.validateURL(policyHolderDetailsPage.issPageValue);
|
|
||||||
await policyHolderDetailsPage.fillCustomerDetails(customerDetails!);
|
|
||||||
await policyHolderDetailsPage.nextPage();
|
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isNonServiceable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (isVehicleLookupBailout) {
|
if (isVehicleLookupBailout) {
|
||||||
forceAPIError(page, '/vehicle/api/v1/vehicle/lookup')
|
forceAPIError(page, '/vehicle/api/v1/vehicle/lookup')
|
||||||
}
|
}
|
||||||
|
|
||||||
await test.step('VehicleDetailsPage >> Select Vehicle', async () => {
|
|
||||||
await vehicleSelectionPage.validateURL(vehicleSelectionPage.issPageValue);
|
|
||||||
await vehicleSelectionPage.selectVehicle(vehicleDetails!);
|
|
||||||
if (isNonServiceable) {
|
|
||||||
await vehicleSelectionPage.assertNonServiceableAlertBehavior();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
await vehicleSelectionPage.nextPage();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isNonServiceable) {
|
if (isNonServiceable) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -508,20 +511,21 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (editVehicleDetails) {
|
// Essential flow when policy is not found
|
||||||
isPolicyFound = false; // Flow proceeds as unverified
|
if (isPolicyFound === false) {
|
||||||
testCase.testData.isPolicyFound = false;
|
testCase.testData.isPolicyFound = false;
|
||||||
await test.step('VehicleDamagePage >> Click Edit Vehicle', async () => {
|
|
||||||
await vehicleDamagePage.validateURL(vehicleDamagePage.issPageValue);
|
|
||||||
await vehicleDamagePage.editVehicleButton.click();
|
|
||||||
});
|
|
||||||
|
|
||||||
await test.step('VehicleDetailsPage >> Select edited vehicle', async () => {
|
await test.step('VehicleSelectionPage >> Select vehicle for essential flow', async () => {
|
||||||
await test.step('VehicleDetailsPage >> Select Vehicle', async () => {
|
|
||||||
await vehicleSelectionPage.validateURL(vehicleSelectionPage.issPageValue);
|
await vehicleSelectionPage.validateURL(vehicleSelectionPage.issPageValue);
|
||||||
await vehicleSelectionPage.selectVehicle(editVehicleDetails);
|
await vehicleSelectionPage.selectVehicle(vehicleDetails!);
|
||||||
await vehicleSelectionPage.nextPage();
|
await vehicleSelectionPage.nextPage();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await test.step('PolicyHolderDetailsPage >> Enter customer data', async () => {
|
||||||
|
await policyHolderDetailsPage.validateURL(policyHolderDetailsPage.issPageValue);
|
||||||
|
await policyHolderDetailsPage.fillCustomerDetails(customerDetails!);
|
||||||
|
|
||||||
|
await policyHolderDetailsPage.nextPage();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -534,7 +538,7 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
await vehicleDamagePage.nextPage();
|
await vehicleDamagePage.nextPage();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isPartsServiceErrorBailout) {
|
if (isAPIErrorBailout) {
|
||||||
await test.step('VehicleLookupPage >> Select Lookup Type', async () => {
|
await test.step('VehicleLookupPage >> Select Lookup Type', async () => {
|
||||||
await vehicleLookupPage.validateURL(vehicleLookupPage.issPageValue);
|
await vehicleLookupPage.validateURL(vehicleLookupPage.issPageValue);
|
||||||
await vehicleLookupPage.vehicleLookup(vehicleDetails!);
|
await vehicleLookupPage.vehicleLookup(vehicleDetails!);
|
||||||
|
|
@ -545,9 +549,9 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
forceAPIError(page, '/parts/api/v1/parts')
|
forceAPIError(page, '/parts/api/v1/parts')
|
||||||
await vinLookupPage.nextPage();
|
await vinLookupPage.nextPage();
|
||||||
});
|
});
|
||||||
await test.step('BailoutPage >> Parts Service Error Bailout', async () => {
|
await test.step('BailoutPage >> API error occurred bailout', async () => {
|
||||||
await bailoutPage.validateURL(bailoutPage.issPageValue);
|
await bailoutPage.validateURL(bailoutPage.issPageValue);
|
||||||
await bailoutPage.validateBailoutDetails(customerDetails!, BailoutCode.PartsServiceError);
|
await bailoutPage.validateBailoutDetails(customerDetails!, BailoutCode.ApiError);
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
|
|
@ -584,10 +588,14 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
await test.step('Address Lookup validations >> Vehicle Lookup by address: ' + customerDetails!.address.street, async () => {
|
await test.step('Address Lookup validations >> Vehicle Lookup by address: ' + customerDetails!.address.street, async () => {
|
||||||
if (Array.isArray(vehicleDetails?.address)) {
|
if (Array.isArray(vehicleDetails?.address)) {
|
||||||
await addressLookupPage.validateURL(addressLookupPage.issPageValue);
|
await addressLookupPage.validateURL(addressLookupPage.issPageValue);
|
||||||
await addressLookupPage.validateAddressLookupAlerts(vehicleDetails?.address);
|
await addressLookupPage.validateAddressLookupAlerts(vehicleDetails?.address!);
|
||||||
await addressLookupPage.nextPage();
|
await addressLookupPage.nextPage();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await test.step('Address Vehicles >> Next page', async () => {
|
||||||
|
await addressLookupPage.nextPage();
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
await test.step('VehicleLookupAddressPage >> Lookup by address: ' + customerDetails!.address.street, async () => {
|
await test.step('VehicleLookupAddressPage >> Lookup by address: ' + customerDetails!.address.street, async () => {
|
||||||
await vehicleLookupAddressPage.validateURL(vehicleLookupAddressPage.issPageValue);
|
await vehicleLookupAddressPage.validateURL(vehicleLookupAddressPage.issPageValue);
|
||||||
|
|
@ -627,6 +635,7 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMoldingQuestion) {
|
if (isMoldingQuestion) {
|
||||||
await test.step('Molding Questions Page >> Select Yes', async () => {
|
await test.step('Molding Questions Page >> Select Yes', async () => {
|
||||||
await moldingQuestionsPage.validateURL(moldingQuestionsPage.issPageValue);
|
await moldingQuestionsPage.validateURL(moldingQuestionsPage.issPageValue);
|
||||||
|
|
@ -637,6 +646,7 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
await moldingQuestionsPage.nextPage();
|
await moldingQuestionsPage.nextPage();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (capabilityQuestions && capabilityQuestions.length > 0) {
|
if (capabilityQuestions && capabilityQuestions.length > 0) {
|
||||||
await capabilityQuestionsPage.validateURL(capabilityQuestionsPage.issPageValue);
|
await capabilityQuestionsPage.validateURL(capabilityQuestionsPage.issPageValue);
|
||||||
await capabilityQuestionsPage.validatePartQuestions(capabilityQuestions);
|
await capabilityQuestionsPage.validatePartQuestions(capabilityQuestions);
|
||||||
|
|
@ -645,6 +655,7 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (partQuestions && partQuestions.length > 0) {
|
if (partQuestions && partQuestions.length > 0) {
|
||||||
|
let partQuestionsPage = testCase.pages.partQuestionsPage;
|
||||||
await partQuestionsPage.validateURL(partQuestionsPage.issPageValue);
|
await partQuestionsPage.validateURL(partQuestionsPage.issPageValue);
|
||||||
await partQuestionsPage.validatePartQuestions(partQuestions);
|
await partQuestionsPage.validatePartQuestions(partQuestions);
|
||||||
await partQuestionsPage.selectPartQuestionResponses(partQuestions);
|
await partQuestionsPage.selectPartQuestionResponses(partQuestions);
|
||||||
|
|
@ -653,60 +664,96 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
|
|
||||||
if (vehiclePartQuestions && vehiclePartQuestions.length > 0) {
|
if (vehiclePartQuestions && vehiclePartQuestions.length > 0) {
|
||||||
await vehiclePartQuestionsPage.validateURL(vehiclePartQuestionsPage.issPageValue);
|
await vehiclePartQuestionsPage.validateURL(vehiclePartQuestionsPage.issPageValue);
|
||||||
await vehiclePartQuestionsPage.validatePartQuestions(vehiclePartQuestions);
|
|
||||||
await vehiclePartQuestionsPage.selectPartQuestionResponses(vehiclePartQuestions);
|
await vehiclePartQuestionsPage.selectPartQuestionResponses(vehiclePartQuestions);
|
||||||
await vehiclePartQuestionsPage.nextPage();
|
await vehiclePartQuestionsPage.nextPage();
|
||||||
}
|
}
|
||||||
if (isRequestCallbackBailout) {
|
|
||||||
await test.step('CoverageStatementPage >> Cancel My claim', async () => {
|
if (isCoverageCancelledByUser) {
|
||||||
|
await test.step('CoverageStatementPage >> Cancel my claim', async () => {
|
||||||
await coverageStatementPage.validateURL(coverageStatementPage.issPageValue);
|
await coverageStatementPage.validateURL(coverageStatementPage.issPageValue);
|
||||||
await coverageStatementPage.cancelMyClaim();
|
await coverageStatementPage.cancelMyClaim();
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('BailoutPage >> Request Callback Bailout', async () => {
|
await test.step('BailoutPage >> User canceled claim on ITAC/No Comp coverage statement', async () => {
|
||||||
await bailoutPage.validateURL(bailoutPage.issPageValue);
|
await bailoutPage.validateURL(bailoutPage.issPageValue);
|
||||||
await bailoutPage.validateBailoutDetails(customerDetails!, BailoutCode.RequestCallback);
|
await bailoutPage.validateBailoutDetails(customerDetails!, BailoutCode.CoverageCancelledByUser);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await test.step('CoverageStatementPage >> Next page', async () => {
|
await test.step('CoverageStatementPage >> Next page', async () => {
|
||||||
await coverageStatementPage.validateURL(coverageStatementPage.issPageValue);
|
await coverageStatementPage.validateURL(coverageStatementPage.issPageValue);
|
||||||
// Confirm no coverage
|
|
||||||
if (isPolicyFound && (isItac || isNoComp)) {
|
if (hasOemEndorsement) {
|
||||||
await coverageStatementPage.continueToScheduleButton.click();
|
await coverageStatementPage.validateOEMBullet();
|
||||||
|
}
|
||||||
|
// For essential/unverified flows
|
||||||
|
if (!isPolicyFound) {
|
||||||
|
await coverageStatementPage.handleUnverifiedFlow(claimDetails!);
|
||||||
}
|
}
|
||||||
|
|
||||||
await coverageStatementPage.nextPage();
|
// For No Comp flows
|
||||||
|
if (isPolicyFound && isNoComp === true) {
|
||||||
|
await coverageStatementPage.handleNoCompFlow();
|
||||||
|
}
|
||||||
|
|
||||||
|
// For ITAC flows
|
||||||
|
if (isPolicyFound && isItac === true) {
|
||||||
|
await coverageStatementPage.handleITACFlow();
|
||||||
|
}
|
||||||
|
|
||||||
|
// For replacements with deductible
|
||||||
|
if (isPolicyFound && claimDetails?.policyDeductible! > 0 && claimDetails?.policyDeductible !== 9999 && testCase.testData.isUnverifiedPolicyAfterVehicleLookup !== true) {
|
||||||
|
await coverageStatementPage.handleReplacementWithDeductibleFlow(claimDetails!);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For replacements or repairs with 0 deductible
|
||||||
|
if (isPolicyFound && claimDetails?.policyDeductible === 0) {
|
||||||
|
await coverageStatementPage.handleReplacementOrRepairWithNoDeductibleFlow(claimDetails!, VehicleDamage!);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For unverified policy after vehicle lookup
|
||||||
|
if (isPolicyFound && testCase.testData.isUnverifiedPolicyAfterVehicleLookup === true) {
|
||||||
|
await coverageStatementPage.handleUnverifiedPolicyAfterVehicleLookupFlow();
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (hasStateLawPopup) {
|
if (hasStateLawPopup) {
|
||||||
await test.step('ProviderPreferencePage >> Dismiss state law popup', async () => {
|
await test.step('ProviderPreferencePage >> Dismiss state law popup', async () => {
|
||||||
await providerPreferencePage.validateURL(providerPreferencePage.issPageValue);
|
await providerPreferencePage.validateURL(providerPreferencePage.issPageValue);
|
||||||
await providerPreferencePage.validateStateLawModalIsVisible();
|
if (vehicleDamage!.includes(VehicleDamage.WindshieldCrack)) {
|
||||||
await providerPreferencePage.gotItButton.click();
|
await providerPreferencePage.stateLawModalOkayButton.click();
|
||||||
});
|
} else {
|
||||||
|
await providerPreferencePage.stateLawModalOkayButton.click();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isPolicyFound || !(isItac || isNoComp)) {
|
if (!isPolicyFound || !(isItac || isNoComp) && !isUnverifiedPolicyAfterVehicleLookup) {
|
||||||
await test.step('ProviderPreferencePage >> Select Provider ' + isSafelite ? "Safelite" : "Other shops(Non-Safelite)", async () => {
|
await test.step('ProviderPreferencePage >> Select Provider ' + isSafelite ? "Safelite" : "Other shops(Non-Safelite)", async () => {
|
||||||
await providerPreferencePage.validateURL(providerPreferencePage.issPageValue);
|
await providerPreferencePage.validateURL(providerPreferencePage.issPageValue);
|
||||||
await providerPreferencePage.selectProvider(isSafelite);
|
await providerPreferencePage.selectProvider(isSafelite);
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// validations for Recal warning mesage
|
if (isSafelite && isUnverifiedPolicyAfterVehicleLookup) {
|
||||||
if (isRecalWarning) {
|
await test.step('ProviderPreferencePage >> Select Provider ' + isSafelite ? "Safelite" : "Other shops(Non-Safelite)", async () => {
|
||||||
await serviceLocationPage.validateURL(serviceLocationPage.issPageValue);
|
await providerPreferencePage.validateURL(providerPreferencePage.issPageValue);
|
||||||
await serviceLocationPage.validateRecalWarning();
|
await providerPreferencePage.selectProvider(isSafelite);
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// if isRecalNotifidation flag true additional step to acknowledge Recal notification.
|
if (!isSafelite && isUnverifiedPolicyAfterVehicleLookup) {
|
||||||
if (isRecalNotification) {
|
await test.step('ProviderPreferencePage >> Schedule TPA without Adas', async () => {
|
||||||
await providerPreferencePage.validateURL(providerPreferencePage.issPageValue);
|
await providerPreferencePage.validateURL(providerPreferencePage.issPageValue);
|
||||||
await providerPreferencePage.acknowledgeRecalNotificaiton();
|
await providerPreferencePage.scheduleTPAWithoutAdas();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
// If No-Comp or ITAC, ProviderPreferencePage does not appear
|
// If No-Comp or ITAC, ProviderPreferencePage does not appear
|
||||||
if (!isPolicyFound || !(isItac || isNoComp)) {
|
if (!isPolicyFound || !(isItac || isNoComp) || isUnverifiedPolicyAfterVehicleLookup) {
|
||||||
|
|
||||||
|
|
||||||
if (!isSafelite) {
|
if (!isSafelite) {
|
||||||
|
|
@ -728,16 +775,6 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDoNotSeeMyShopBailout) {
|
|
||||||
await test.step('TpaSearchPage >> Select "Do Not See My Shop"', async () => {
|
|
||||||
await tpaSearchPage.validateURL(tpaSearchPage.issPageValue);
|
|
||||||
await tpaSearchPage.selectDoNotSeeMyShop();
|
|
||||||
});
|
|
||||||
await bailoutPage.validateURL(bailoutPage.issPageValue);
|
|
||||||
await bailoutPage.validateBailoutDetails(customerDetails!, BailoutCode.DoNotSeeMyShop);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await test.step('TpaSearchPage >> TPA Search', async () => {
|
await test.step('TpaSearchPage >> TPA Search', async () => {
|
||||||
await tpaSearchPage.validateURL(tpaSearchPage.issPageValue);
|
await tpaSearchPage.validateURL(tpaSearchPage.issPageValue);
|
||||||
await tpaSearchPage.selectFirstLocation();
|
await tpaSearchPage.selectFirstLocation();
|
||||||
|
|
@ -745,9 +782,12 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('TpaSubmitPage >> TPA Submit', async () => {
|
await test.step('TpaSubmitPage >> TPA Submit', async () => {
|
||||||
// TODO: Validations
|
|
||||||
await tpaSubmitPage.validateURL(tpaSubmitPage.issPageValue);
|
await tpaSubmitPage.validateURL(tpaSubmitPage.issPageValue);
|
||||||
|
if (!isUnverifiedPolicyAfterVehicleLookup) {
|
||||||
|
await tpaSubmitPage.validateDeductible(claimDetails!);
|
||||||
|
} else {
|
||||||
await tpaSubmitPage.nextPage();
|
await tpaSubmitPage.nextPage();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
await test.step('TpaConfirmationPage >> TPA Confirmation', async () => {
|
await test.step('TpaConfirmationPage >> TPA Confirmation', async () => {
|
||||||
|
|
@ -756,43 +796,41 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}}
|
||||||
}
|
|
||||||
|
|
||||||
await test.step('ServiceLocationPage >> Select service location', async () => {
|
|
||||||
await serviceLocationPage.validateURL(serviceLocationPage.issPageValue);
|
|
||||||
await serviceLocationPage.selectLocation(appointmentDetails!);
|
|
||||||
if (hasMilitaryWarning) {
|
|
||||||
await expect.soft(serviceLocationPage.militaryWarningMessage).toBeVisible();
|
|
||||||
}
|
|
||||||
await serviceLocationPage.nextPage();
|
|
||||||
});
|
|
||||||
|
|
||||||
await test.step('SchedulePage >> Select day and time', async () => {
|
await test.step('SchedulePage >> Select day and time', async () => {
|
||||||
await schedulePage.validateURL(schedulePage.issPageValue);
|
await schedulePage.validateURL(schedulePage.issPageValue);
|
||||||
customerDetails!.apptDate = await schedulePage.scheduleFirstAppointment(appointmentDetails!.serviceLocation);
|
|
||||||
});
|
|
||||||
|
|
||||||
await test.step('ContactDetailsPage >> Validate contact details', async () => {
|
if (appointmentDetails?.serviceLocation === ServiceLocation.Mobile) {
|
||||||
const expectedContactDetails: Partial<ICustomerDetails> = {
|
await schedulePage.scheduleMobile(appointmentDetails);
|
||||||
firstName: customerDetails!.firstName,
|
|
||||||
lastName: customerDetails!.lastName,
|
|
||||||
email: customerDetails!.email,
|
|
||||||
phoneNumber: customerDetails!.phoneNumber
|
|
||||||
};
|
|
||||||
await contactDetailsPage.validateURL(contactDetailsPage.issPageValue);
|
|
||||||
const actualContactDetails = await contactDetailsPage.getContactDetails();
|
|
||||||
expect.soft(actualContactDetails).toEqual(expectedContactDetails);
|
|
||||||
|
|
||||||
await contactDetailsPage.fillNotes(customerDetails!.notes);
|
|
||||||
|
|
||||||
if (isPriceServiceErrorBailout) {
|
|
||||||
forceAPIError(page, '/price/api/v1/price/combined-quote');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await contactDetailsPage.nextPage();
|
if (appointmentDetails?.serviceLocation === ServiceLocation.InShop || appointmentDetails?.serviceLocation === ServiceLocation.DropOff) {
|
||||||
|
await schedulePage.scheduleInShop(appointmentDetails);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
await test.step('ServicePackagesPage >> Choose service package', async () => {
|
||||||
|
await servicePackagesPage.validateURL(servicePackagesPage.issPageValue);
|
||||||
|
await servicePackagesPage.selectServicePackage(servicePackage!);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (appointmentDetails?.serviceLocation === ServiceLocation.Mobile) {
|
||||||
|
await test.step('ContactDetailsPage >> Validate contact details', async () => {
|
||||||
|
await contactDetailsPage.validateURL(contactDetailsPage.issPageValue);
|
||||||
|
|
||||||
|
|
||||||
|
await contactDetailsPage.fillContactDetails(customerDetails!);
|
||||||
|
if (appointmentDetails?.alternateMobileCity) {
|
||||||
|
await contactDetailsPage.fillAlternateMobileStreetAndCity(appointmentDetails?.alternateMobileStreetAddress!, appointmentDetails?.alternateMobileCity!);
|
||||||
|
}
|
||||||
|
|
||||||
|
await contactDetailsPage.nextPage();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (isPriceServiceErrorBailout) {
|
if (isPriceServiceErrorBailout) {
|
||||||
await test.step('BailoutPage >> Price Service Error Bailout', async () => {
|
await test.step('BailoutPage >> Price Service Error Bailout', async () => {
|
||||||
await bailoutPage.validateURL(bailoutPage.issPageValue);
|
await bailoutPage.validateURL(bailoutPage.issPageValue);
|
||||||
|
|
@ -801,22 +839,29 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await test.step('ServicePackagesPage >> Choose service package', async () => {
|
|
||||||
await servicePackagesPage.validateURL(servicePackagesPage.issPageValue);
|
|
||||||
customerDetails!.packagePrice = await servicePackagesPage.selectServicePackage(servicePackage!);
|
|
||||||
await servicePackagesPage.nextPage();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (isPolicyFound && (isUseVehicleOnPolicy ?? true) && claimDetails!.policyDeductible > 0) {
|
if (isPolicyFound && (isUseVehicleOnPolicy ?? true) && claimDetails!.policyDeductible > 0) {
|
||||||
await test.step('PaymentMethodPage >> Execute Payment', async () => {
|
await test.step('PaymentMethodPage >> Execute Payment', async () => {
|
||||||
await paymentMethodPage.validateURL(paymentMethodPage.issPageValue);
|
await paymentMethodPage.validateURL(paymentMethodPage.issPageValue);
|
||||||
await paymentMethodPage.executePayment(paymentDetails!);
|
await paymentMethodPage.executePayment(paymentDetails!, claimDetails!, servicePackage!);
|
||||||
await paymentMethodPage.nextPage();
|
await paymentMethodPage.nextPage();
|
||||||
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await test.step('PaymentMethodPage >> Skip to Order Confirmation', async () => {
|
await test.step('PaymentMethodPage >> Skip to Order Confirmation', async () => {
|
||||||
await paymentMethodPage.validateURL(paymentMethodPage.issPageValue);
|
await paymentMethodPage.validateURL(paymentMethodPage.issPageValue);
|
||||||
await paymentMethodPage.nextPage();
|
|
||||||
|
if (isPolicyFound && (isUseVehicleOnPolicy ?? true) && claimDetails!.policyDeductible === 0) {
|
||||||
|
await paymentMethodPage.submitOrderWithoutPIA();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isPolicyFound) {
|
||||||
|
await paymentMethodPage.submitOrderWithoutPIA();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPolicyFound && testCase.testData.isUnverifiedPolicyAfterVehicleLookup === true) {
|
||||||
|
await paymentMethodPage.submitOrderWithoutPIA();
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,10 @@ const essentialReplaceStaticAdasData: Partial<ITestData> = {
|
||||||
phoneNumber: faker.helpers.fromRegExp(/[2-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]/),
|
phoneNumber: faker.helpers.fromRegExp(/[2-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]/),
|
||||||
notes: 'Automated Test',
|
notes: 'Automated Test',
|
||||||
address: {
|
address: {
|
||||||
street: faker.location.streetAddress(),
|
street: "123 Test Road",
|
||||||
city: 'Knoxville',
|
city: 'Columbus',
|
||||||
state: 'Tennessee',
|
state: 'OHIO',
|
||||||
postalCode: '37996',
|
postalCode: '43085',
|
||||||
country: 'United States'
|
country: 'United States'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@ const essentialRepairInShopAcuraData: Partial<ITestData> = {
|
||||||
phoneNumber: faker.helpers.fromRegExp(/[2-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]/),
|
phoneNumber: faker.helpers.fromRegExp(/[2-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]/),
|
||||||
notes: 'Automated Test',
|
notes: 'Automated Test',
|
||||||
address: {
|
address: {
|
||||||
street: faker.location.streetAddress(),
|
street: '200 W. Oak Street',
|
||||||
city: 'Fort Collins',
|
city: 'Fort Collins',
|
||||||
state: 'Colorado',
|
state: 'COLORADO',
|
||||||
postalCode: '80526',
|
postalCode: '80526',
|
||||||
country: 'United States'
|
country: 'United States'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,10 @@ const essentialTpaEnabledData: Partial<ITestData> = {
|
||||||
notes: 'Automated Test',
|
notes: 'Automated Test',
|
||||||
address: {
|
address: {
|
||||||
// street: faker.location.streetAddress(),
|
// street: faker.location.streetAddress(),
|
||||||
street: '134 Woodlands Place',
|
street: '1343 Cameron Ave',
|
||||||
city: 'Dublin',
|
city: 'Lewis Center',
|
||||||
state: 'Florida',
|
state: 'OH',
|
||||||
postalCode: '32040',
|
postalCode: '43035',
|
||||||
country: 'United States'
|
country: 'United States'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -42,10 +42,10 @@ const essentialTpaEnabledData: Partial<ITestData> = {
|
||||||
damageCause: DamageType.Other
|
damageCause: DamageType.Other
|
||||||
},
|
},
|
||||||
vehicleDetails: {
|
vehicleDetails: {
|
||||||
year: '2022',
|
year: '2015',
|
||||||
make: 'Honda',
|
make: 'Honda',
|
||||||
model: 'Civic',
|
model: 'Accord',
|
||||||
style: '4 door hatchback'
|
style: '4 door sedan'
|
||||||
},
|
},
|
||||||
vehicleDamage: [
|
vehicleDamage: [
|
||||||
VehicleDamage.WindshieldThreeChips,
|
VehicleDamage.WindshieldThreeChips,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ const essentialDoNotSeeShopData: Partial<ITestData> = {
|
||||||
partQuestions: undefined,
|
partQuestions: undefined,
|
||||||
isSafelite: false,
|
isSafelite: false,
|
||||||
bailoutFlags: {
|
bailoutFlags: {
|
||||||
isDoNotSeeMyShopBailout: true
|
|
||||||
},
|
},
|
||||||
servicePackage: faker.helpers.enumValue(ServicePackage),
|
servicePackage: faker.helpers.enumValue(ServicePackage),
|
||||||
customerDetails: {
|
customerDetails: {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0001a${faker.string.uuid().substring(0, 6)}`;
|
const policyNumber = `~AutomatedScenario0001a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0001a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0001a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0001Data: Partial<ITestData> = {
|
const advancedScenario0001Data: Partial<ITestData> = {
|
||||||
|
|
@ -31,7 +31,6 @@ const advancedScenario0001Data: Partial<ITestData> = {
|
||||||
isDuplicateClaim: false,
|
isDuplicateClaim: false,
|
||||||
isPolicyFound: true,
|
isPolicyFound: true,
|
||||||
isNoComp: false,
|
isNoComp: false,
|
||||||
hasStateLawPopup: true,
|
|
||||||
endorsements: undefined,
|
endorsements: undefined,
|
||||||
vehiclePartQuestions: [
|
vehiclePartQuestions: [
|
||||||
|
|
||||||
|
|
@ -60,7 +59,7 @@ const advancedScenario0001Data: Partial<ITestData> = {
|
||||||
shopAddress: undefined,
|
shopAddress: undefined,
|
||||||
appointmentDate: nextWeekday
|
appointmentDate: nextWeekday
|
||||||
},
|
},
|
||||||
paymentDetails: ClientData.getDefaultPaypalDetails()//ClientData.getDefaultCreditCardDetails()
|
paymentDetails: ClientData.getDefaultCreditCardDetails()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add validation for deductible/covered amount
|
// TODO: Add validation for deductible/covered amount
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ if ((process.env.ENABLE_MOCK_TESTING ?? 'false') === 'true') {
|
||||||
customerDetails.lastName = 'Cormier';
|
customerDetails.lastName = 'Cormier';
|
||||||
customerDetails.address.street = '69825 W Pine Street';
|
customerDetails.address.street = '69825 W Pine Street';
|
||||||
} else {
|
} else {
|
||||||
policyNumber = `~AutomatedScenario0002a${faker.string.uuid().substring(0, 6)}`;
|
policyNumber = `~AutomatedScenario0002a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`;
|
||||||
};
|
};
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0002a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0002a', customerDetails, policyNumber);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0003a${faker.string.uuid().substring(0,6)}`;
|
const policyNumber = `~AutomatedScenario0003a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`;
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0003a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0003a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0003Data: Partial<ITestData> = {
|
const advancedScenario0003Data: Partial<ITestData> = {
|
||||||
|
|
@ -33,6 +33,7 @@ const advancedScenario0003Data: Partial<ITestData> = {
|
||||||
isDuplicateClaim: false,
|
isDuplicateClaim: false,
|
||||||
isPolicyFound: true,
|
isPolicyFound: true,
|
||||||
isNoComp: false,
|
isNoComp: false,
|
||||||
|
hasOemEndorsement: true,
|
||||||
hasStateLawPopup: false,
|
hasStateLawPopup: false,
|
||||||
endorsements: undefined,
|
endorsements: undefined,
|
||||||
vehiclePartQuestions: [
|
vehiclePartQuestions: [
|
||||||
|
|
@ -44,7 +45,7 @@ const advancedScenario0003Data: Partial<ITestData> = {
|
||||||
{
|
{
|
||||||
partQuestionType: PartQuestionType.PassengerRearColor,
|
partQuestionType: PartQuestionType.PassengerRearColor,
|
||||||
isOnPage: true,
|
isOnPage: true,
|
||||||
optionToSelect: 'Green Tint'
|
optionToSelect: 'Solar, Passenger side, Rear'
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
isSafelite: true,
|
isSafelite: true,
|
||||||
|
|
@ -53,7 +54,7 @@ const advancedScenario0003Data: Partial<ITestData> = {
|
||||||
claimDetails: {
|
claimDetails: {
|
||||||
policyNumber: policyNumber,
|
policyNumber: policyNumber,
|
||||||
policyDeductible: 50,
|
policyDeductible: 50,
|
||||||
damageDate: '2016-01-02',
|
damageDate: '2026-01-02',
|
||||||
damageCause: faker.helpers.enumValue(DamageType)
|
damageCause: faker.helpers.enumValue(DamageType)
|
||||||
},
|
},
|
||||||
policySoap: policySoap,
|
policySoap: policySoap,
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0004a${faker.string.uuid().substring(0, 6)}`;
|
const policyNumber = `~AutomatedScenario0004a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0004a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0004a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0004aData: Partial<ITestData> = {
|
const advancedScenario0004aData: Partial<ITestData> = {
|
||||||
|
|
@ -33,8 +33,7 @@ const advancedScenario0004aData: Partial<ITestData> = {
|
||||||
isNoComp: false,
|
isNoComp: false,
|
||||||
hasStateLawPopup: false,
|
hasStateLawPopup: false,
|
||||||
endorsements: undefined,
|
endorsements: undefined,
|
||||||
vehiclePartQuestions: [
|
partQuestions: [],
|
||||||
],
|
|
||||||
isSafelite: true,
|
isSafelite: true,
|
||||||
servicePackage: faker.helpers.enumValue(ServicePackage),
|
servicePackage: faker.helpers.enumValue(ServicePackage),
|
||||||
customerDetails: customerDetails,
|
customerDetails: customerDetails,
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0005a${faker.string.uuid().substring(0,6)}`;
|
const policyNumber = `~AutomatedScenario0005a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0005a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0005a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0005Data: Partial<ITestData> = {
|
const advancedScenario0005Data: Partial<ITestData> = {
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0006a${faker.string.uuid().substring(0,6)}`;
|
const policyNumber = `~AutomatedScenario0006a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0006a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0006a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0006Data: Partial<ITestData> = {
|
const advancedScenario0006Data: Partial<ITestData> = {
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0007a${faker.string.uuid().substring(0,6)}`;
|
const policyNumber = `~AutomatedScenario0007a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0007a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0007a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0007Data: Partial<ITestData> = {
|
const advancedScenario0007Data: Partial<ITestData> = {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ const nextWeekday = getNextWeekday();
|
||||||
const customerAddress: IAddress = {
|
const customerAddress: IAddress = {
|
||||||
street: faker.location.streetAddress(),
|
street: faker.location.streetAddress(),
|
||||||
city: 'Hamden',
|
city: 'Hamden',
|
||||||
state: 'CT',
|
state: 'CONNECTICUT',
|
||||||
postalCode: '06517',
|
postalCode: '06517',
|
||||||
country: 'United States'
|
country: 'United States'
|
||||||
}
|
}
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0008a${faker.string.uuid().substring(0,6)}`;
|
const policyNumber = `~AutomatedScenario0008a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0008a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0008a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0008Data: Partial<ITestData> = {
|
const advancedScenario0008Data: Partial<ITestData> = {
|
||||||
|
|
@ -33,7 +33,7 @@ const advancedScenario0008Data: Partial<ITestData> = {
|
||||||
isDuplicateClaim: false,
|
isDuplicateClaim: false,
|
||||||
isPolicyFound: true,
|
isPolicyFound: true,
|
||||||
isNoComp: false,
|
isNoComp: false,
|
||||||
hasStateLawPopup: true,
|
hasStateLawPopup: false,
|
||||||
endorsements: undefined,
|
endorsements: undefined,
|
||||||
vehiclePartQuestions: [
|
vehiclePartQuestions: [
|
||||||
// {
|
// {
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0009a${faker.string.uuid().substring(0,6)}`;
|
const policyNumber = `~AutomatedScenario0009a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0009a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0009a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0009Data: Partial<ITestData> = {
|
const advancedScenario0009Data: Partial<ITestData> = {
|
||||||
|
|
@ -38,7 +38,7 @@ const advancedScenario0009Data: Partial<ITestData> = {
|
||||||
{
|
{
|
||||||
endorsementType: EndorsementType.Educator,
|
endorsementType: EndorsementType.Educator,
|
||||||
isOnPolicy: true,
|
isOnPolicy: true,
|
||||||
isClickYes: false
|
isClickYes: true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
vehiclePartQuestions: [
|
vehiclePartQuestions: [
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0010a${faker.string.uuid().substring(0,6)}`;
|
const policyNumber = `~AutomatedScenario0010a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0010a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0010a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0010Data: Partial<ITestData> = {
|
const advancedScenario0010Data: Partial<ITestData> = {
|
||||||
|
|
@ -92,7 +92,7 @@ for (const client of advancedClients) {
|
||||||
const data = {...advancedScenario0010Data};
|
const data = {...advancedScenario0010Data};
|
||||||
data.clientTag = client.clientTag;
|
data.clientTag = client.clientTag;
|
||||||
const tc = new TestCase({
|
const tc = new TestCase({
|
||||||
name: `0010a Advanced Repair No Deductible FL Rear Client: "${client.accountName}"`,
|
name: `0010a Advanced Replace No Deductible FL Rear Client: "${client.accountName}"`,
|
||||||
tags: [`@${client.clientTag}`, `@${client.accountName}`, '@Advanced'],
|
tags: [`@${client.clientTag}`, `@${client.accountName}`, '@Advanced'],
|
||||||
testData: data
|
testData: data
|
||||||
}, undefined, '0010a');
|
}, undefined, '0010a');
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0011a${faker.string.uuid().substring(0, 6)}`;
|
const policyNumber = `~AutomatedScenario0011a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0011a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0011a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0011Data: Partial<ITestData> = {
|
const advancedScenario0011Data: Partial<ITestData> = {
|
||||||
|
|
@ -33,13 +33,13 @@ const advancedScenario0011Data: Partial<ITestData> = {
|
||||||
isDuplicateClaim: false,
|
isDuplicateClaim: false,
|
||||||
isPolicyFound: true,
|
isPolicyFound: true,
|
||||||
isNoComp: false,
|
isNoComp: false,
|
||||||
isItac: true,
|
isItac: false,
|
||||||
hasStateLawPopup: false,
|
hasStateLawPopup: false,
|
||||||
endorsements: [
|
endorsements: [
|
||||||
{
|
{
|
||||||
endorsementType: EndorsementType.Educator,
|
endorsementType: EndorsementType.Educator,
|
||||||
isOnPolicy: true,
|
isOnPolicy: true,
|
||||||
isClickYes: false
|
isClickYes: true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
partQuestions: undefined,
|
partQuestions: undefined,
|
||||||
|
|
@ -48,7 +48,7 @@ const advancedScenario0011Data: Partial<ITestData> = {
|
||||||
customerDetails: customerDetails,
|
customerDetails: customerDetails,
|
||||||
claimDetails: {
|
claimDetails: {
|
||||||
policyNumber: policyNumber,
|
policyNumber: policyNumber,
|
||||||
policyDeductible: 500,
|
policyDeductible: 0,
|
||||||
damageDate: '2023-03-01',
|
damageDate: '2023-03-01',
|
||||||
damageCause: faker.helpers.enumValue(DamageType)
|
damageCause: faker.helpers.enumValue(DamageType)
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0012a${faker.string.uuid().substring(0,6)}`;
|
const policyNumber = `~AutomatedScenario0012a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0012a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0012a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0012Data: Partial<ITestData> = {
|
const advancedScenario0012Data: Partial<ITestData> = {
|
||||||
|
|
@ -48,7 +48,7 @@ const advancedScenario0012Data: Partial<ITestData> = {
|
||||||
customerDetails: customerDetails,
|
customerDetails: customerDetails,
|
||||||
claimDetails: {
|
claimDetails: {
|
||||||
policyNumber: policyNumber,
|
policyNumber: policyNumber,
|
||||||
policyDeductible: 500,
|
policyDeductible: 9999,
|
||||||
damageDate: '2023-09-01',
|
damageDate: '2023-09-01',
|
||||||
damageCause: faker.helpers.enumValue(DamageType)
|
damageCause: faker.helpers.enumValue(DamageType)
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import ClientData from "@business-logic/data/ClientData";
|
import ClientData from "@business-logic/data/ClientData";
|
||||||
import TestCase from "@business-logic/types/TestCase";
|
import TestCase from "@business-logic/types/TestCase";
|
||||||
import { DamageType, EndorsementType, ServiceLocation, ServicePackage, VehicleDamage } from "@business-logic/types/Enums";
|
import { DamageType, EndorsementType, PaymentType, ServiceLocation, ServicePackage, VehicleDamage } from "@business-logic/types/Enums";
|
||||||
import { ITestData } from "@business-logic/types/ITestData"
|
import { ITestData } from "@business-logic/types/ITestData"
|
||||||
import { faker } from "@faker-js/faker";
|
import { faker } from "@faker-js/faker";
|
||||||
import { getNextWeekday } from "@impl/utils/DateUtils";
|
import { getNextWeekday } from "@impl/utils/DateUtils";
|
||||||
|
|
@ -11,9 +11,9 @@ import { IAddress } from "@business-logic/types/IAddress";
|
||||||
const nextWeekday = getNextWeekday();
|
const nextWeekday = getNextWeekday();
|
||||||
const customerAddress: IAddress = {
|
const customerAddress: IAddress = {
|
||||||
street: faker.location.streetAddress(),
|
street: faker.location.streetAddress(),
|
||||||
city: 'Birmingham',
|
city: 'Worthington',
|
||||||
state: 'AL',
|
state: 'OH',
|
||||||
postalCode: '35118',
|
postalCode: '43085',
|
||||||
country: 'United States'
|
country: 'United States'
|
||||||
}
|
}
|
||||||
const customerDetails: ICustomerDetails = {
|
const customerDetails: ICustomerDetails = {
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0013a${faker.string.uuid().substring(0, 6)}`;
|
const policyNumber = `~AutomatedScenario0013a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0013a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0013a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0013Data: Partial<ITestData> = {
|
const advancedScenario0013Data: Partial<ITestData> = {
|
||||||
|
|
@ -33,13 +33,13 @@ const advancedScenario0013Data: Partial<ITestData> = {
|
||||||
isDuplicateClaim: false,
|
isDuplicateClaim: false,
|
||||||
isPolicyFound: true,
|
isPolicyFound: true,
|
||||||
isNoComp: false,
|
isNoComp: false,
|
||||||
isItac: true,
|
isItac: false,
|
||||||
hasStateLawPopup: false,
|
hasStateLawPopup: false,
|
||||||
endorsements: [
|
endorsements: [
|
||||||
{
|
{
|
||||||
endorsementType: EndorsementType.Educator,
|
endorsementType: EndorsementType.Educator,
|
||||||
isOnPolicy: true,
|
isOnPolicy: true,
|
||||||
isClickYes: false
|
isClickYes: true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
vehiclePartQuestions: [
|
vehiclePartQuestions: [
|
||||||
|
|
@ -49,7 +49,7 @@ const advancedScenario0013Data: Partial<ITestData> = {
|
||||||
customerDetails: customerDetails,
|
customerDetails: customerDetails,
|
||||||
claimDetails: {
|
claimDetails: {
|
||||||
policyNumber: policyNumber,
|
policyNumber: policyNumber,
|
||||||
policyDeductible: 9999,
|
policyDeductible: 0,
|
||||||
damageDate: '2023-08-01',
|
damageDate: '2023-08-01',
|
||||||
damageCause: faker.helpers.enumValue(DamageType)
|
damageCause: faker.helpers.enumValue(DamageType)
|
||||||
},
|
},
|
||||||
|
|
@ -68,7 +68,9 @@ const advancedScenario0013Data: Partial<ITestData> = {
|
||||||
serviceAddress: customerAddress,
|
serviceAddress: customerAddress,
|
||||||
appointmentDate: nextWeekday
|
appointmentDate: nextWeekday
|
||||||
},
|
},
|
||||||
paymentDetails: ClientData.getDefaultCreditCardDetails()
|
paymentDetails: {
|
||||||
|
paymentType: PaymentType.PayAtService
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,7 +82,7 @@ for (const client of advancedClients) {
|
||||||
const data = { ...advancedScenario0013Data };
|
const data = { ...advancedScenario0013Data };
|
||||||
data.clientTag = client.clientTag;
|
data.clientTag = client.clientTag;
|
||||||
const tc = new TestCase({
|
const tc = new TestCase({
|
||||||
name: `0013a Advanced ITAC Mobile Client: "${client.accountName}"`,
|
name: `0013a Advanced $0 Deductible with Vaps Mobile Client: "${client.accountName}"`,
|
||||||
tags: [`@${client.clientTag}`, `@${client.accountName}`, '@Advanced'],
|
tags: [`@${client.clientTag}`, `@${client.accountName}`, '@Advanced'],
|
||||||
testData: data
|
testData: data
|
||||||
}, undefined, '0013a');
|
}, undefined, '0013a');
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0014a${faker.string.uuid().substring(0,6)}`;
|
const policyNumber = `~AutomatedScenario0014a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0014a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0014a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0014Data: Partial<ITestData> = {
|
const advancedScenario0014Data: Partial<ITestData> = {
|
||||||
|
|
@ -33,13 +33,13 @@ const advancedScenario0014Data: Partial<ITestData> = {
|
||||||
isDuplicateClaim: false,
|
isDuplicateClaim: false,
|
||||||
isPolicyFound: true,
|
isPolicyFound: true,
|
||||||
isNoComp: true,
|
isNoComp: true,
|
||||||
isRecalWarning: true,
|
isRecalWarning: false,
|
||||||
hasStateLawPopup: false,
|
hasStateLawPopup: false,
|
||||||
endorsements: [
|
endorsements: [
|
||||||
{
|
{
|
||||||
endorsementType: EndorsementType.Educator,
|
endorsementType: EndorsementType.Educator,
|
||||||
isOnPolicy: true,
|
isOnPolicy: true,
|
||||||
isClickYes: true
|
isClickYes: false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
partQuestions: undefined,
|
partQuestions: undefined,
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0015a${faker.string.uuid().substring(0,6)}`;
|
const policyNumber = `~AutomatedScenario0015a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0015a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0015a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0015Data: Partial<ITestData> = {
|
const advancedScenario0015Data: Partial<ITestData> = {
|
||||||
|
|
@ -46,16 +46,16 @@ const advancedScenario0015Data: Partial<ITestData> = {
|
||||||
{
|
{
|
||||||
partQuestionType: PartQuestionType.WindshieldColor,
|
partQuestionType: PartQuestionType.WindshieldColor,
|
||||||
isOnPage: true,
|
isOnPage: true,
|
||||||
optionToSelect: 'Green Tint, Blue Shade'
|
optionToSelect: 'Heated glass, Heated glass Wiper Park'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
partQuestionType: PartQuestionType.DriverFrontColor,
|
partQuestionType: PartQuestionType.DriverFrontColor,
|
||||||
isOnPage: true,
|
isOnPage: true,
|
||||||
optionToSelect: 'Green Tint'
|
optionToSelect: 'Driver side, Front'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
isSafelite: true,
|
isSafelite: true,
|
||||||
servicePackage: faker.helpers.enumValue(ServicePackage),
|
servicePackage: ServicePackage.Premium,
|
||||||
customerDetails: customerDetails,
|
customerDetails: customerDetails,
|
||||||
claimDetails: {
|
claimDetails: {
|
||||||
policyNumber: policyNumber,
|
policyNumber: policyNumber,
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0016a${faker.string.uuid().substring(0,6)}`;
|
const policyNumber = `~AutomatedScenario0016a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0016a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0016a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0016Data: Partial<ITestData> = {
|
const advancedScenario0016Data: Partial<ITestData> = {
|
||||||
|
|
@ -39,38 +39,37 @@ const advancedScenario0016Data: Partial<ITestData> = {
|
||||||
{
|
{
|
||||||
partQuestionType: PartQuestionType.WindshieldColor,
|
partQuestionType: PartQuestionType.WindshieldColor,
|
||||||
isOnPage: true,
|
isOnPage: true,
|
||||||
optionToSelect: 'Green Tint'
|
optionToSelect: 'Solar, Third Visor Frit, soundproofing, Infrared Interlayer'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
partQuestionType: PartQuestionType.DriverFrontColor,
|
partQuestionType: PartQuestionType.DriverFrontColor,
|
||||||
isOnPage: true,
|
isOnPage: true,
|
||||||
optionToSelect: 'Green Tint'
|
optionToSelect: 'Solar, Driver side, Front'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
partQuestionType: PartQuestionType.DriverRearColor,
|
partQuestionType: PartQuestionType.DriverRearColor,
|
||||||
isOnPage: true,
|
isOnPage: true,
|
||||||
optionToSelect: 'Green Tint'
|
optionToSelect: 'Solar, Driver side, Rear'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
partQuestionType: PartQuestionType.DriverVentColor,
|
partQuestionType: PartQuestionType.DriverVentColor,
|
||||||
isOnPage: true,
|
isOnPage: true,
|
||||||
optionToSelect: 'Green Tint',
|
optionToSelect: 'Solar, Driver side, Rear'
|
||||||
secondaryQuestionOptionToSelect: 'solar, driver side, rear'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
partQuestionType: PartQuestionType.PassengerFrontColor,
|
partQuestionType: PartQuestionType.PassengerFrontColor,
|
||||||
isOnPage: true,
|
isOnPage: true,
|
||||||
optionToSelect: 'Green Tint'
|
optionToSelect: 'Solar, Passenger side, Front'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
partQuestionType: PartQuestionType.PassengerRearColor,
|
partQuestionType: PartQuestionType.PassengerRearColor,
|
||||||
isOnPage: true,
|
isOnPage: true,
|
||||||
optionToSelect: 'Green Tint'
|
optionToSelect: 'Solar, Passenger side, Rear'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
partQuestionType: PartQuestionType.RearWindowColor,
|
partQuestionType: PartQuestionType.RearWindowColor,
|
||||||
isOnPage: true,
|
isOnPage: true,
|
||||||
optionToSelect: 'Green Tint'
|
optionToSelect: 'Heated glass, Solar'
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
isSafelite: true,
|
isSafelite: true,
|
||||||
|
|
@ -100,8 +99,8 @@ const advancedScenario0016Data: Partial<ITestData> = {
|
||||||
// VehicleDamage.PassengerVentGlass // TODO: Verify if this is intentionally not in UI
|
// VehicleDamage.PassengerVentGlass // TODO: Verify if this is intentionally not in UI
|
||||||
],
|
],
|
||||||
appointmentDetails: {
|
appointmentDetails: {
|
||||||
serviceLocation: ServiceLocation.Mobile,
|
serviceLocation: ServiceLocation.InShop,
|
||||||
serviceAddress: customerAddress,
|
serviceAddress: undefined,
|
||||||
appointmentDate: nextWeekday
|
appointmentDate: nextWeekday
|
||||||
},
|
},
|
||||||
paymentDetails: ClientData.getDefaultPaypalDetails()
|
paymentDetails: ClientData.getDefaultPaypalDetails()
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0017a${faker.string.uuid().substring(0,6)}`;
|
const policyNumber = `~AutomatedScenario0017a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0017a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0017a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0017Data: Partial<ITestData> = {
|
const advancedScenario0017Data: Partial<ITestData> = {
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0018a${faker.string.uuid().substring(0,6)}`;
|
const policyNumber = `~AutomatedScenario0018a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0018a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0018a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0018Data: Partial<ITestData> = {
|
const advancedScenario0018Data: Partial<ITestData> = {
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ const vehicleDetails: IVehicleDetails = {
|
||||||
style: '4 door sedan'
|
style: '4 door sedan'
|
||||||
};
|
};
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0019a${faker.string.uuid().substring(0,6)}`;
|
const policyNumber = `~AutomatedScenario0019a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0019a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0019a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0019Data: Partial<ITestData> = {
|
const advancedScenario0019Data: Partial<ITestData> = {
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0020a${faker.string.uuid().substring(0,6)}`;
|
const policyNumber = `~AutomatedScenario0020a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0020a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0020a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0020Data: Partial<ITestData> = {
|
const advancedScenario0020Data: Partial<ITestData> = {
|
||||||
|
|
@ -60,12 +60,14 @@ const advancedScenario0020Data: Partial<ITestData> = {
|
||||||
serviceLocation: ServiceLocation.Mobile,
|
serviceLocation: ServiceLocation.Mobile,
|
||||||
serviceAddress: {
|
serviceAddress: {
|
||||||
street: faker.location.streetAddress(),
|
street: faker.location.streetAddress(),
|
||||||
city: 'Goose Creek',
|
city: 'Worthington',
|
||||||
state: 'SC',
|
state: 'OH',
|
||||||
postalCode: '29445',
|
postalCode: '43085',
|
||||||
country: 'US'
|
country: 'US'
|
||||||
},
|
},
|
||||||
alternateServiceZip: '29445',
|
alternateServiceZip: '43085',
|
||||||
|
alternateMobileCity: 'Worthington',
|
||||||
|
alternateMobileStreetAddress: '177 Franklin Ave',
|
||||||
appointmentDate: nextWeekday
|
appointmentDate: nextWeekday
|
||||||
},
|
},
|
||||||
paymentDetails: {
|
paymentDetails: {
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,14 @@ const customerDetails: ICustomerDetails = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0021a${faker.string.uuid().substring(0, 6)}`;
|
const policyNumber = `~AutomatedScenario0021a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0021a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0021a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0021Data: Partial<ITestData> = {
|
const advancedScenario0021Data: Partial<ITestData> = {
|
||||||
clientTag: '',
|
clientTag: '',
|
||||||
isDuplicateClaim: false,
|
isDuplicateClaim: false,
|
||||||
isPolicyFound: true,
|
isPolicyFound: true,
|
||||||
|
isUnverifiedPolicyAfterVehicleLookup: true,
|
||||||
isNoComp: false,
|
isNoComp: false,
|
||||||
hasStateLawPopup: true,
|
hasStateLawPopup: true,
|
||||||
endorsements: undefined,
|
endorsements: undefined,
|
||||||
|
|
@ -54,8 +55,8 @@ const advancedScenario0021Data: Partial<ITestData> = {
|
||||||
model: 'RX 300',
|
model: 'RX 300',
|
||||||
style: undefined,
|
style: undefined,
|
||||||
vehicleLookupType: VehicleLookupType.LicensePlateNumber,
|
vehicleLookupType: VehicleLookupType.LicensePlateNumber,
|
||||||
licensePlateNumber: ['NoPlate753', 'BQ40903','1111'],
|
licensePlateNumber: ['NoPlate753', 'GAH2307','1111'],
|
||||||
licensePlateState: ['Illinois','Illinois','California'],
|
licensePlateState: ['Illinois','Ohio','California'],
|
||||||
},
|
},
|
||||||
vehicleDamage: [
|
vehicleDamage: [
|
||||||
VehicleDamage.WindshieldCrack,
|
VehicleDamage.WindshieldCrack,
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,14 @@ const customerDetails: ICustomerDetails = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0022a${faker.string.uuid().substring(0, 6)}`;
|
const policyNumber = `~AutomatedScenario0022a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0022a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0022a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0022Data: Partial<ITestData> = {
|
const advancedScenario0022Data: Partial<ITestData> = {
|
||||||
clientTag: '',
|
clientTag: '',
|
||||||
isDuplicateClaim: false,
|
isDuplicateClaim: false,
|
||||||
isPolicyFound: true,
|
isPolicyFound: true,
|
||||||
|
isUnverifiedPolicyAfterVehicleLookup: true,
|
||||||
isNoComp: false,
|
isNoComp: false,
|
||||||
hasStateLawPopup: true,
|
hasStateLawPopup: true,
|
||||||
endorsements: undefined,
|
endorsements: undefined,
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,14 @@ const customerDetails: ICustomerDetails = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0023a${faker.string.uuid().substring(0, 6)}`;
|
const policyNumber = `~AutomatedScenario0023a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0023a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0023a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0023Data: Partial<ITestData> = {
|
const advancedScenario0023Data: Partial<ITestData> = {
|
||||||
clientTag: '',
|
clientTag: '',
|
||||||
isDuplicateClaim: false,
|
isDuplicateClaim: false,
|
||||||
isPolicyFound: true,
|
isPolicyFound: true,
|
||||||
|
isUnverifiedPolicyAfterVehicleLookup: true,
|
||||||
isNoComp: false,
|
isNoComp: false,
|
||||||
hasStateLawPopup: true,
|
hasStateLawPopup: true,
|
||||||
endorsements: undefined,
|
endorsements: undefined,
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0024a${faker.string.uuid().substring(0, 6)}`;
|
const policyNumber = `~AutomatedScenario0024a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0024a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0024a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0024Data: Partial<ITestData> = {
|
const advancedScenario0024Data: Partial<ITestData> = {
|
||||||
|
|
@ -50,14 +50,14 @@ const advancedScenario0024Data: Partial<ITestData> = {
|
||||||
policySoap: policySoap,
|
policySoap: policySoap,
|
||||||
vehicleDetails: {
|
vehicleDetails: {
|
||||||
year: '2015',
|
year: '2015',
|
||||||
make: 'Ford',
|
make: 'Audi',
|
||||||
model: 'F Series F150',
|
model: 'A7',
|
||||||
style: '2 door super cab',
|
style: '4 door hatchback',
|
||||||
vehicleLookupType: VehicleLookupType.Address,
|
vehicleLookupType: VehicleLookupType.Address,
|
||||||
address: [
|
address: [
|
||||||
{ street: '9 Test Street', city: 'Columbus', state: 'OH', postalCode: '43220', lastName: 'Test' },
|
{ street: '9 Test Street', city: 'Columbus', state: 'OH', postalCode: '43220', lastName: 'Test' },
|
||||||
{ street: '8621 GREENLEAF AVE', city: 'Whittier', state: 'California', postalCode: '90602', lastName: 'Johnson' },
|
{ street: '8621 GREENLEAF AVE', city: 'Whittier', state: 'California', postalCode: '90602', lastName: 'Johnson' },
|
||||||
{ street: '10212 JEWEL CT', city: 'Conroe', state: 'Texas', postalCode: '77385', lastName: 'Reed' }
|
{ street: '6531 CANYON RANCH', city: 'Frisco', state: 'Texas', postalCode: '75036', lastName: 'TRAINOR' }
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
vehicleDamage: [
|
vehicleDamage: [
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
phoneNumber: '614-531-0031',
|
phoneNumber: '614-531-0031',
|
||||||
notes: 'Automated Test',
|
notes: 'Automated Test',
|
||||||
address: {
|
address: {
|
||||||
street: faker.location.streetAddress(),
|
street: '5273 Berrywood Dr',
|
||||||
city: 'Columbus',
|
city: 'Columbus',
|
||||||
state: 'OH',
|
state: 'OH',
|
||||||
postalCode: '43220',
|
postalCode: '43220',
|
||||||
|
|
@ -23,7 +23,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0025a${faker.string.uuid().substring(0, 6)}`;
|
const policyNumber = `~AutomatedScenario0025a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0025a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0025a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0025Data: Partial<ITestData> = {
|
const advancedScenario0025Data: Partial<ITestData> = {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0026a${faker.string.uuid().substring(0, 6)}`;
|
const policyNumber = `~AutomatedScenario0026a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0026a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0026a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0026aData: Partial<ITestData> = {
|
const advancedScenario0026aData: Partial<ITestData> = {
|
||||||
|
|
@ -35,7 +35,6 @@ const advancedScenario0026aData: Partial<ITestData> = {
|
||||||
isRecalNotification: true,
|
isRecalNotification: true,
|
||||||
endorsements: undefined,
|
endorsements: undefined,
|
||||||
bailoutFlags: {
|
bailoutFlags: {
|
||||||
isDoNotSeeMyShopBailout: true
|
|
||||||
},
|
},
|
||||||
vehiclePartQuestions: [
|
vehiclePartQuestions: [
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0028a${faker.string.uuid().substring(0, 6)}`;
|
const policyNumber = `~AutomatedScenario0028a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0028a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0028a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0028aData: Partial<ITestData> = {
|
const advancedScenario0028aData: Partial<ITestData> = {
|
||||||
|
|
@ -36,7 +36,7 @@ const advancedScenario0028aData: Partial<ITestData> = {
|
||||||
isItac: true,
|
isItac: true,
|
||||||
hasStateLawPopup: false,
|
hasStateLawPopup: false,
|
||||||
bailoutFlags: {
|
bailoutFlags: {
|
||||||
isRequestCallbackBailout: true,
|
isCoverageCancelledByUser: true,
|
||||||
},
|
},
|
||||||
isVehicleSelectBailout: false,
|
isVehicleSelectBailout: false,
|
||||||
endorsements: [
|
endorsements: [
|
||||||
|
|
|
||||||
|
|
@ -23,21 +23,27 @@ const customerDetails: ICustomerDetails = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0029a${faker.string.uuid().substring(0, 6)}`;
|
const policyNumber = `~AutomatedScenario0029a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0029a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0029a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0029Data: Partial<ITestData> = {
|
const advancedScenario0029Data: Partial<ITestData> = {
|
||||||
clientTag: '',
|
clientTag: '',
|
||||||
isDuplicateClaim: false,
|
isDuplicateClaim: false,
|
||||||
isPolicyFound: true,
|
isPolicyFound: true,
|
||||||
|
isUnverifiedPolicyAfterVehicleLookup: true,
|
||||||
|
hasStateLawPopup: true,
|
||||||
isNoComp: false,
|
isNoComp: false,
|
||||||
endorsements: undefined,
|
endorsements: undefined,
|
||||||
|
vehiclePartQuestions: [
|
||||||
|
{
|
||||||
|
partQuestionType: PartQuestionType.WindshieldColor,
|
||||||
|
isOnPage: true,
|
||||||
|
optionToSelect: 'Heated glass, Encap, Asymmetrically Strengthen'
|
||||||
|
},
|
||||||
|
],
|
||||||
isUseVehicleOnPolicy: false,
|
isUseVehicleOnPolicy: false,
|
||||||
servicePackage: faker.helpers.enumValue(ServicePackage),
|
servicePackage: faker.helpers.enumValue(ServicePackage),
|
||||||
customerDetails: customerDetails,
|
customerDetails: customerDetails,
|
||||||
bailoutFlags: {
|
|
||||||
isHeavyTruckVehicleBailout: true,
|
|
||||||
},
|
|
||||||
claimDetails: {
|
claimDetails: {
|
||||||
policyNumber: policyNumber,
|
policyNumber: policyNumber,
|
||||||
policyDeductible: 500,
|
policyDeductible: 500,
|
||||||
|
|
@ -50,7 +56,7 @@ const advancedScenario0029Data: Partial<ITestData> = {
|
||||||
make: 'Freightliner',
|
make: 'Freightliner',
|
||||||
model: '114sd',
|
model: '114sd',
|
||||||
vehicleLookupType: VehicleLookupType.Vin,
|
vehicleLookupType: VehicleLookupType.Vin,
|
||||||
vin: '1FUJG3DV5HHJH2985',
|
vin: '1FVMG3DV5HHJA1388',
|
||||||
},
|
},
|
||||||
vehicleDamage: [
|
vehicleDamage: [
|
||||||
VehicleDamage.WindshieldCrack,
|
VehicleDamage.WindshieldCrack,
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ import { IAddress } from "@business-logic/types/IAddress";
|
||||||
|
|
||||||
const nextWeekday = getNextWeekday();
|
const nextWeekday = getNextWeekday();
|
||||||
const customerAddress: IAddress = {
|
const customerAddress: IAddress = {
|
||||||
street: faker.location.streetAddress(),
|
street: '474 1st St',
|
||||||
city: 'Birmingham',
|
city: 'Lindsay',
|
||||||
state: 'AL',
|
state: 'CA',
|
||||||
postalCode: '35118',
|
postalCode: '93247',
|
||||||
country: 'United States'
|
country: 'United States'
|
||||||
}
|
}
|
||||||
const customerDetails: ICustomerDetails = {
|
const customerDetails: ICustomerDetails = {
|
||||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
address: customerAddress
|
address: customerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0030a${faker.string.uuid().substring(0, 6)}`;
|
const policyNumber = `~AutomatedScenario0030a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0030a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0030a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0030aData: Partial<ITestData> = {
|
const advancedScenario0030aData: Partial<ITestData> = {
|
||||||
|
|
@ -36,7 +36,7 @@ const advancedScenario0030aData: Partial<ITestData> = {
|
||||||
isItac: false,
|
isItac: false,
|
||||||
hasStateLawPopup: false,
|
hasStateLawPopup: false,
|
||||||
bailoutFlags: {
|
bailoutFlags: {
|
||||||
isPartsServiceErrorBailout: true,
|
isAPIErrorBailout: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
vehiclePartQuestions: [
|
vehiclePartQuestions: [
|
||||||
|
|
@ -79,7 +79,7 @@ for (const client of advancedClients) {
|
||||||
const data = { ...advancedScenario0030aData };
|
const data = { ...advancedScenario0030aData };
|
||||||
data.clientTag = client.clientTag;
|
data.clientTag = client.clientTag;
|
||||||
const tc = new TestCase({
|
const tc = new TestCase({
|
||||||
name: `0030a Advanced ITAC Cancel My Claim: "${client.accountName}"`,
|
name: `0030a Advanced API Error Bailout: "${client.accountName}"`,
|
||||||
tags: [`@${client.clientTag}`, `@${client.accountName}`, '@Advanced', '@INSR-2057'],
|
tags: [`@${client.clientTag}`, `@${client.accountName}`, '@Advanced', '@INSR-2057'],
|
||||||
testData: data
|
testData: data
|
||||||
}, undefined, '0030a');
|
}, undefined, '0030a');
|
||||||
|
|
@ -23,7 +23,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0031a${faker.string.uuid().substring(0, 6)}`;
|
const policyNumber = `~AutomatedScenario0031a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0031a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0031a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0031Data: Partial<ITestData> = {
|
const advancedScenario0031Data: Partial<ITestData> = {
|
||||||
|
|
@ -33,19 +33,11 @@ const advancedScenario0031Data: Partial<ITestData> = {
|
||||||
isNoComp: false,
|
isNoComp: false,
|
||||||
hasStateLawPopup: false,
|
hasStateLawPopup: false,
|
||||||
endorsements: undefined,
|
endorsements: undefined,
|
||||||
partQuestions: [
|
|
||||||
{
|
|
||||||
partQuestionType: PartQuestionType.LaneKeepAssist,
|
|
||||||
isOnPage: true,
|
|
||||||
optionToSelect: 'Yes',
|
|
||||||
}
|
|
||||||
],
|
|
||||||
vehiclePartQuestions: [
|
vehiclePartQuestions: [
|
||||||
{
|
{
|
||||||
partQuestionType: PartQuestionType.WindshieldColor,
|
partQuestionType: PartQuestionType.WindshieldColor,
|
||||||
isOnPage: true,
|
isOnPage: true,
|
||||||
optionToSelect: 'Green Tint',
|
optionToSelect: 'One-Piece, With Lane Departure Warning System',
|
||||||
secondaryQuestionOptionToSelect: 'one-piece, w/lane departure warning system',
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
isSafelite: true,
|
isSafelite: true,
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ const customerDetails: ICustomerDetails = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const policyNumber = `~AutomatedScenario0032a${faker.string.uuid().substring(0, 6)}`;
|
const policyNumber = `~AutomatedScenario0032a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0032a', customerDetails, policyNumber);
|
const policySoap = MockPolicyData.getPolicySoapByScenario('0032a', customerDetails, policyNumber);
|
||||||
|
|
||||||
const advancedScenario0032Data: Partial<ITestData> = {
|
const advancedScenario0032Data: Partial<ITestData> = {
|
||||||
|
|
@ -33,6 +33,9 @@ const advancedScenario0032Data: Partial<ITestData> = {
|
||||||
isNoComp: false,
|
isNoComp: false,
|
||||||
hasStateLawPopup: false,
|
hasStateLawPopup: false,
|
||||||
endorsements: undefined,
|
endorsements: undefined,
|
||||||
|
bailoutFlags: {
|
||||||
|
isHeavyTruckVehicleBailout: true,
|
||||||
|
},
|
||||||
vehiclePartQuestions: [
|
vehiclePartQuestions: [
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@
|
||||||
"coverage/api/v1/coverage/register-claim": "0002a_Advanced_Replace_Deductible_Client/coverage/api/v1/coverage/register-claim.json",
|
"coverage/api/v1/coverage/register-claim": "0002a_Advanced_Replace_Deductible_Client/coverage/api/v1/coverage/register-claim.json",
|
||||||
"price/api/v1/price/order-items-with-itac-pricing": "0002a_Advanced_Replace_Deductible_Client/price/api/v1/price/order-items-with-itac-pricing.json",
|
"price/api/v1/price/order-items-with-itac-pricing": "0002a_Advanced_Replace_Deductible_Client/price/api/v1/price/order-items-with-itac-pricing.json",
|
||||||
"location/api/v1/location/providers/75023/Replace/100/550036/true/CR00056707/DW01571GTNNOEM": "0002a_Advanced_Replace_Deductible_Client/location/api/v1/location/providers/75023/Replace/100/550036/true/CR00056707/DW01571GTNNOEM.json",
|
"location/api/v1/location/providers/75023/Replace/100/550036/true/CR00056707/DW01571GTNNOEM": "0002a_Advanced_Replace_Deductible_Client/location/api/v1/location/providers/75023/Replace/100/550036/true/CR00056707/DW01571GTNNOEM.json",
|
||||||
"schedule/api/v1/schedule/shop-time-slots": "0002a_Advanced_Replace_Deductible_Client/schedule/api/v1/schedule/shop-time-slots.json",
|
|
||||||
"location/api/v1/location/alert-reasons/01813": "0002a_Advanced_Replace_Deductible_Client/location/api/v1/location/alert-reasons/01813.json",
|
"location/api/v1/location/alert-reasons/01813": "0002a_Advanced_Replace_Deductible_Client/location/api/v1/location/alert-reasons/01813.json",
|
||||||
"parts/api/v1/parts/rain-repel": "0002a_Advanced_Replace_Deductible_Client/parts/api/v1/parts/rain-repel.json",
|
"parts/api/v1/parts/rain-repel": "0002a_Advanced_Replace_Deductible_Client/parts/api/v1/parts/rain-repel.json",
|
||||||
"price/api/v1/price/combined-quote": "0002a_Advanced_Replace_Deductible_Client/price/api/v1/price/combined-quote.json"
|
"price/api/v1/price/combined-quote": "0002a_Advanced_Replace_Deductible_Client/price/api/v1/price/combined-quote.json"
|
||||||
|
|
|
||||||
|
|
@ -11,22 +11,29 @@ const GaEvents = Object.freeze({
|
||||||
|
|
||||||
const GaCategories = Object.freeze({
|
const GaCategories = Object.freeze({
|
||||||
API_RESPONSE: 'Api_Response',
|
API_RESPONSE: 'Api_Response',
|
||||||
|
CONFIRMATION_CLICKED: "confirmation clicked",
|
||||||
|
CONFIRMATION_CLICKED_INSHOP: "inshop confirmation clicked",
|
||||||
|
CONFIRMATION_CLICKED_MOBILE: "mobile confirmation clicked",
|
||||||
EVOX: 'Evox'
|
EVOX: 'Evox'
|
||||||
});
|
});
|
||||||
|
|
||||||
const GaActions = Object.freeze({
|
const GaActions = Object.freeze({
|
||||||
RESULT: 'Result',
|
|
||||||
CLICKED: 'Clicked',
|
CLICKED: 'Clicked',
|
||||||
|
NO: "no",
|
||||||
|
RESULT: 'Result',
|
||||||
|
SUBMITTED: 'Submitted',
|
||||||
VIF: 'vif',
|
VIF: 'vif',
|
||||||
SUBMITTED: 'Submitted'
|
YES: "yes",
|
||||||
});
|
});
|
||||||
|
|
||||||
const GaLabels = Object.freeze({
|
const GaLabels = Object.freeze({
|
||||||
SUCCESS: 'Success',
|
ADDRESS_LOOKUP: 'Address_Look_up',
|
||||||
ERROR: 'Error',
|
ERROR: 'Error',
|
||||||
LICENSE_PLATE_LOOKUP: 'License_Plate_Look_Up',
|
LICENSE_PLATE_LOOKUP: 'License_Plate_Look_Up',
|
||||||
|
NO: "no",
|
||||||
|
SUCCESS: 'Success',
|
||||||
VIN_LOOKUP: 'Vin_Look_Up',
|
VIN_LOOKUP: 'Vin_Look_Up',
|
||||||
ADDRESS_LOOKUP: 'Address_Look_up'
|
YES: "yes",
|
||||||
});
|
});
|
||||||
|
|
||||||
const ValueToLogTypes = Object.freeze({
|
const ValueToLogTypes = Object.freeze({
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ const experimentUniverses = Object.freeze({
|
||||||
ISS_FUNNEL: 'ISSFunnel',
|
ISS_FUNNEL: 'ISSFunnel',
|
||||||
ISS_FEATURETOGGLE_AREFEES_HIDDEN: 'NextGenISS_FeatureToggle_AreFeesHidden',
|
ISS_FEATURETOGGLE_AREFEES_HIDDEN: 'NextGenISS_FeatureToggle_AreFeesHidden',
|
||||||
ISS_FEATURETOGGLE_AREFEES_OVERRIDDEN: 'NextGenISS_FeatureToggle_AreFeesOverridden',
|
ISS_FEATURETOGGLE_AREFEES_OVERRIDDEN: 'NextGenISS_FeatureToggle_AreFeesOverridden',
|
||||||
|
ISS_MOBILE_FIRST_APPOINTMENTS: 'ISS_Mobile_First_Appointments',
|
||||||
ADYEN_PAYMENT_TEST: 'NextGenAdyenPaymentTest'
|
ADYEN_PAYMENT_TEST: 'NextGenAdyenPaymentTest'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -12,6 +13,9 @@ const experimentSettings = Object.freeze({
|
||||||
ISS_FEATURE_TOGGLE_IS_MOBILE_FEE_OVERRIDDEN: 'OverrideMobileFee',
|
ISS_FEATURE_TOGGLE_IS_MOBILE_FEE_OVERRIDDEN: 'OverrideMobileFee',
|
||||||
ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_HIDDEN: 'HideRecycleFee',
|
ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_HIDDEN: 'HideRecycleFee',
|
||||||
ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_OVERRIDDEN: 'OverrideRecycleFee',
|
ISS_FEATURE_TOGGLE_IS_RECYCLE_FEE_OVERRIDDEN: 'OverrideRecycleFee',
|
||||||
|
ISS_MOBILE_FIRST_MAX_MOBILE_DAYS: 'MaxMobileDays',
|
||||||
|
ISS_MOBILE_FIRST_MAX_PM_MOBILE_DAYS: 'MaxPmMobileDays',
|
||||||
|
ISS_MOBILE_FIRST_SHOW_FIRST_MOBILE_APPOINTMENT: 'ShowMobileFirstAppointment',
|
||||||
ISS_ENABLE_ADYEN_V1: 'ISS_Enable_Adyen_V1'
|
ISS_ENABLE_ADYEN_V1: 'ISS_Enable_Adyen_V1'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,7 @@ export function mapAdyenToIssPaymentMethod(adyenMethod) {
|
||||||
const paymentMethodMap = {
|
const paymentMethodMap = {
|
||||||
["scheme"]: paymentMethods.CREDIT_CARD,
|
["scheme"]: paymentMethods.CREDIT_CARD,
|
||||||
["afterpaytouch_US"]: paymentMethods.AFTERPAY,
|
["afterpaytouch_US"]: paymentMethods.AFTERPAY,
|
||||||
|
["afterpaytouch"]: paymentMethods.AFTERPAY,
|
||||||
["paypal"]: paymentMethods.PAYPAL,
|
["paypal"]: paymentMethods.PAYPAL,
|
||||||
["applepay"]: paymentMethods.APPLEPAY,
|
["applepay"]: paymentMethods.APPLEPAY,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,23 @@ function processZipCodeResults(request) {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getZipCodeData(zipCode) {
|
export async function getAvailabilityRating(
|
||||||
return await processZipCodeResults(useMainStore().validateZip({ zip: zipCode }));
|
startDate,
|
||||||
|
endDate,
|
||||||
|
shopAppointmentType,
|
||||||
|
providerNumber
|
||||||
|
) {
|
||||||
|
// For a given shop provider number and date range, get the appointment time slots available
|
||||||
|
const shopTimeSlots = await useMainStore().getShopTimeSlots(startDate, endDate, shopAppointmentType, providerNumber);
|
||||||
|
|
||||||
|
const numberOfDaysToEvaluate = 2;
|
||||||
|
const isGoodAvailability =
|
||||||
|
shopTimeSlots.data.days.filter((x) => x.timeSlots.length > 0).length
|
||||||
|
>= numberOfDaysToEvaluate;
|
||||||
|
|
||||||
|
const shopStatus = isGoodAvailability ? 'high' : 'low';
|
||||||
|
|
||||||
|
return Promise.resolve(shopStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getMobileZipCodeData(zipCode) {
|
export async function getMobileZipCodeData(zipCode) {
|
||||||
|
|
@ -42,25 +57,6 @@ export async function getPricedMobileFeePart(serviceZipCode) {
|
||||||
return Promise.resolve(pricingResults[0]);
|
return Promise.resolve(pricingResults[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAvailabilityRating(
|
|
||||||
startDate,
|
|
||||||
endDate,
|
|
||||||
shopAppointmentType,
|
|
||||||
providerNumber
|
|
||||||
) {
|
|
||||||
// For a given shop provider number and date range, get the appointment time slots available
|
|
||||||
const shopTimeSlots = await useMainStore().getShopTimeSlots(startDate, endDate, shopAppointmentType, providerNumber);
|
|
||||||
|
|
||||||
const numberOfDaysToEvaluate = 2;
|
|
||||||
const isGoodAvailability =
|
|
||||||
shopTimeSlots.data.days.filter((x) => x.timeSlots.length > 0).length
|
|
||||||
>= numberOfDaysToEvaluate;
|
|
||||||
|
|
||||||
const shopStatus = isGoodAvailability ? 'high' : 'low';
|
|
||||||
|
|
||||||
return Promise.resolve(shopStatus);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function getProviderData() {
|
export function getProviderData() {
|
||||||
const mainStore = useMainStore();
|
const mainStore = useMainStore();
|
||||||
const storeServiceLocation = mainStore.order.serviceLocation;
|
const storeServiceLocation = mainStore.order.serviceLocation;
|
||||||
|
|
@ -73,6 +69,18 @@ export function getProviderData() {
|
||||||
return { storeServiceLocation, isMobileAppointment, storeSelectedProvider, serviceZipCode }
|
return { storeServiceLocation, isMobileAppointment, storeSelectedProvider, serviceZipCode }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getZipCodeData(zipCode) {
|
||||||
|
return await processZipCodeResults(useMainStore().validateZip({ zip: zipCode }));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapTimeSlot(timeSlot, timeOfDay) {
|
||||||
|
return {
|
||||||
|
...timeSlot,
|
||||||
|
isDropoff: timeSlot.id.endsWith('DROP OFF'),
|
||||||
|
timeOfDay
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export async function onProviderChanged() {
|
export async function onProviderChanged() {
|
||||||
const { isMobileAppointment, storeSelectedProvider, serviceZipCode } = getProviderData();
|
const { isMobileAppointment, storeSelectedProvider, serviceZipCode } = getProviderData();
|
||||||
if (!storeSelectedProvider) {
|
if (!storeSelectedProvider) {
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openModal() {
|
openModal() {
|
||||||
|
this.pushEventToGA("existing_claim", "pop_up_displayed", this.mainStore.accountNameForEvents, true);
|
||||||
this.$refs.continueModal.openModal();
|
this.$refs.continueModal.openModal();
|
||||||
},
|
},
|
||||||
setModalStatus(isOpened) {
|
setModalStatus(isOpened) {
|
||||||
|
|
@ -77,9 +78,11 @@ export default {
|
||||||
this.$refs.continueModal.closeModal();
|
this.$refs.continueModal.closeModal();
|
||||||
},
|
},
|
||||||
continueReferral() {
|
continueReferral() {
|
||||||
|
this.pushEventToGA("existing_claim", "finish_claim", this.mainStore.accountNameForEvents, true);
|
||||||
this.$emit('continue-previous-referral');
|
this.$emit('continue-previous-referral');
|
||||||
},
|
},
|
||||||
startNewReferral() {
|
startNewReferral() {
|
||||||
|
this.pushEventToGA("existing_claim", "start_new_claim", this.mainStore.accountNameForEvents, true);
|
||||||
this.$emit('start-new-referral');
|
this.$emit('start-new-referral');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -230,11 +230,15 @@ export default {
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
isSameAsPolicyAddress(newValue) {
|
isSameAsPolicyAddress(newValue) {
|
||||||
|
this.pushEventToGA("mobile_location", "same_as_policy_address", newValue ? "checked" : "unchecked", true);
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
this.copyPolicyAddressToServiceLocation();
|
this.copyPolicyAddressToServiceLocation();
|
||||||
} else {
|
} else {
|
||||||
this.clearAddressFields();
|
this.clearAddressFields();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
isVehicleProtected(newValue) {
|
||||||
|
this.pushEventToGA("mobile_location", "is_vehicle_protected", newValue, true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<suggestTimeslotModal
|
||||||
|
:ref="SUGGEST_TIMESLOT_MODAL_REF_NAME"
|
||||||
|
cmsWidgetName="SuggestTimeslotModal"
|
||||||
|
@confirmAppointmentClicked="autoSelectTimeslotConfirmed" />
|
||||||
<recalAckModal
|
<recalAckModal
|
||||||
ref="recalAckModal"
|
ref="recalAckModal"
|
||||||
cmsWidgetName="RecalAckModalWidget"
|
cmsWidgetName="RecalAckModalWidget"
|
||||||
|
|
@ -88,10 +92,12 @@ import locationAlerts from '@/layouts/schedule-page/location-alerts/location-ale
|
||||||
import datePicker from '@/digital-components/date-picker/date-picker.vue';
|
import datePicker from '@/digital-components/date-picker/date-picker.vue';
|
||||||
import serviceLocation from '@/layouts/schedule-page/service-location/service-location.vue';
|
import serviceLocation from '@/layouts/schedule-page/service-location/service-location.vue';
|
||||||
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
import siteFooter from '@/iss-components/site-footer/site-footer.vue';
|
||||||
|
import suggestTimeslotModal from '@/layouts/schedule-page/suggest-timeslot-modal/suggest-timeslot-modal.vue';
|
||||||
import modal from '@/digital-components/modal/modal.vue';
|
import modal from '@/digital-components/modal/modal.vue';
|
||||||
import recalAckModal from '@/layouts/schedule-page/recal-ack-modal/recal-ack-modal.vue';
|
import recalAckModal from '@/layouts/schedule-page/recal-ack-modal/recal-ack-modal.vue';
|
||||||
|
|
||||||
// Supporting files
|
// Supporting files
|
||||||
|
import { experimentSettings, experimentUniverses } from '@/constants/experiments';
|
||||||
import {
|
import {
|
||||||
AppointmentTypeStrings,
|
AppointmentTypeStrings,
|
||||||
GET_MOBILE_TIME_SLOTS,
|
GET_MOBILE_TIME_SLOTS,
|
||||||
|
|
@ -111,7 +117,9 @@ import settleAllPromises from '@/helpers/layout-helper';
|
||||||
import showIssLoadingModal from '@/helpers/loading-modal-helper.js';
|
import showIssLoadingModal from '@/helpers/loading-modal-helper.js';
|
||||||
import {
|
import {
|
||||||
getPricedMobileFeePart,
|
getPricedMobileFeePart,
|
||||||
getZipCodeData
|
getMobileZipCodeData,
|
||||||
|
getZipCodeData,
|
||||||
|
mapTimeSlot
|
||||||
} from '@/helpers/service-location-helper';
|
} from '@/helpers/service-location-helper';
|
||||||
import { Form } from 'vee-validate';
|
import { Form } from 'vee-validate';
|
||||||
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
import BaseFormMixin from '@/mixins/base-form-mixin.js';
|
||||||
|
|
@ -120,6 +128,7 @@ import { containsRecalParts, anyPartWithRequiresRecalFlag } from '@/helpers/reca
|
||||||
import errorMessages from '@/constants/error-messages';
|
import errorMessages from '@/constants/error-messages';
|
||||||
|
|
||||||
// Define constants
|
// Define constants
|
||||||
|
const SUGGEST_TIMESLOT_MODAL_REF_NAME = 'SuggestTimeslotModal';
|
||||||
const TIME_SLOTS_CALL_DAYS_LIMIT = 15;
|
const TIME_SLOTS_CALL_DAYS_LIMIT = 15;
|
||||||
|
|
||||||
const getAvailableDates = async (
|
const getAvailableDates = async (
|
||||||
|
|
@ -241,6 +250,7 @@ export default {
|
||||||
datePicker,
|
datePicker,
|
||||||
serviceLocation,
|
serviceLocation,
|
||||||
siteFooter,
|
siteFooter,
|
||||||
|
suggestTimeslotModal,
|
||||||
Form,
|
Form,
|
||||||
recalAckModal
|
recalAckModal
|
||||||
},
|
},
|
||||||
|
|
@ -346,9 +356,16 @@ export default {
|
||||||
zipCodeCtu: resultMap.zipCodeData?.zipCodeCtu
|
zipCodeCtu: resultMap.zipCodeData?.zipCodeCtu
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mobileFirstObject = {
|
||||||
|
mobileProviderNumber: resultMap.providers?.mobileProviderNumber,
|
||||||
|
serviceabilityDetails: resultMap.serviceabilityDetails,
|
||||||
|
zipCode: initialServiceLocationObj.zipCode
|
||||||
|
}
|
||||||
|
|
||||||
vm.setCmsContent(resultMap.cmsContent);
|
vm.setCmsContent(resultMap.cmsContent);
|
||||||
vm.$refs.serviceLocation.initializeComponent(serviceLocationData);
|
vm.$refs.serviceLocation.initializeComponent(serviceLocationData);
|
||||||
await vm.setData(resultMap.premiumFeeWithPrice, initialServiceLocationObj);
|
await vm.setData(resultMap.premiumFeeWithPrice, initialServiceLocationObj);
|
||||||
|
await vm.checkMobileFirstExperience(mobileFirstObject);
|
||||||
showIssLoadingModal(false);
|
showIssLoadingModal(false);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
@ -375,6 +392,7 @@ export default {
|
||||||
selectedServiceLocationCity: this.getServiceLocationCity(),
|
selectedServiceLocationCity: this.getServiceLocationCity(),
|
||||||
selectedTimeSlotInfo: this.getSelectedTimeSlotInfo(),
|
selectedTimeSlotInfo: this.getSelectedTimeSlotInfo(),
|
||||||
showDatePickerError: false,
|
showDatePickerError: false,
|
||||||
|
SUGGEST_TIMESLOT_MODAL_REF_NAME,
|
||||||
isAcknowledged: false
|
isAcknowledged: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
@ -471,6 +489,185 @@ export default {
|
||||||
arePagePrerequisitesValid() {
|
arePagePrerequisitesValid() {
|
||||||
return useMainStore().order.serviceLocation.zipCode !== null;
|
return useMainStore().order.serviceLocation.zipCode !== null;
|
||||||
},
|
},
|
||||||
|
async autoSelectTimeslotConfirmed(emittedValue) {
|
||||||
|
if (this.mainStore.isNoComp || this.mainStore.isITAC) {
|
||||||
|
console.log('User is No Comp or ITAC, skipping mobile fee update on auto select timeslot confirmed');
|
||||||
|
// this.mainStore.updateMobileFee(this.mobileFeePart);
|
||||||
|
}
|
||||||
|
|
||||||
|
const providerToUse = {
|
||||||
|
providerNumber: emittedValue.mobileProviderNumber,
|
||||||
|
address: {
|
||||||
|
streetAddress: null,
|
||||||
|
city: null,
|
||||||
|
state: null,
|
||||||
|
zipCode: null,
|
||||||
|
zipCodeCtu: null
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.mainStore.updateServiceLocation({
|
||||||
|
state: emittedValue.zipCodeData.state,
|
||||||
|
zipCode: emittedValue.zipCodeData.zipCode,
|
||||||
|
zipCodeCtu: emittedValue.zipCodeData.zipCodeCtu,
|
||||||
|
appointmentType: AppointmentTypeStrings.MOBILE,
|
||||||
|
provider: providerToUse
|
||||||
|
});
|
||||||
|
|
||||||
|
const timeSlotToUse = {
|
||||||
|
date: emittedValue.date,
|
||||||
|
routeCode: emittedValue.timeSlot.id,
|
||||||
|
startTime: emittedValue.timeSlot.startTime,
|
||||||
|
endTime: emittedValue.timeSlot.endTime,
|
||||||
|
jobMaxMinutes: emittedValue.estimatedServiceMinutesMax.toString(),
|
||||||
|
jobMinMinutes: emittedValue.estimatedServiceMinutesMin.toString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
this.mainStore.saveSchedule(timeSlotToUse);
|
||||||
|
showIssLoadingModal(true);
|
||||||
|
this.$router.navigate(
|
||||||
|
this.navigationScenarios.CLICKED_FORWARD,
|
||||||
|
this.$route
|
||||||
|
);
|
||||||
|
},
|
||||||
|
async checkMobileFirstExperience(mobileFirstObject = {}) {
|
||||||
|
const showMobileFirst = this.getSettingValue(experimentSettings.ISS_MOBILE_FIRST_SHOW_FIRST_MOBILE_APPOINTMENT);
|
||||||
|
if (showMobileFirst) {
|
||||||
|
const pmMobileDaysLimit = this.getSettingValue(experimentSettings.ISS_MOBILE_FIRST_MAX_PM_MOBILE_DAYS);
|
||||||
|
const mobileDaysLimit = this.getSettingValue(experimentSettings.ISS_MOBILE_FIRST_MAX_MOBILE_DAYS);
|
||||||
|
const hasSelectedDate = !!this.getSelectedDate();
|
||||||
|
const isServicableMobile = mobileFirstObject.serviceabilityDetails?.isGlassServiceableMobile;
|
||||||
|
if (!hasSelectedDate && isServicableMobile && mobileFirstObject.mobileProviderNumber && mobileFirstObject.zipCode) {
|
||||||
|
const todayDateObject = new Date();
|
||||||
|
const todayDateString = convertDateToDateString(todayDateObject);
|
||||||
|
const calendarViewDirection = 'future';
|
||||||
|
const initialDays = 15;
|
||||||
|
|
||||||
|
const initialViewStartDate = todayDateString;
|
||||||
|
const initialEndDate = new Date();
|
||||||
|
initialEndDate.setDate(initialEndDate.getDate() + (initialDays - 1));
|
||||||
|
const initialViewEndDate = convertDateToDateString(initialEndDate);
|
||||||
|
const preSelectedDate = this.selectedDate;
|
||||||
|
|
||||||
|
const initialData = await getAvailableDates(
|
||||||
|
initialViewStartDate,
|
||||||
|
initialViewEndDate,
|
||||||
|
AppointmentTypeStrings.MOBILE,
|
||||||
|
mobileFirstObject.mobileProviderNumber,
|
||||||
|
mobileFirstObject.zipCode
|
||||||
|
).then((response) => ({
|
||||||
|
todayDate: todayDateString,
|
||||||
|
initialViewStartDate,
|
||||||
|
initialViewEndDate,
|
||||||
|
calendarViewDirection,
|
||||||
|
initialShopTimeSlotsResponse: response,
|
||||||
|
preSelectedDate,
|
||||||
|
initialDaysLoaded: initialDays,
|
||||||
|
daysFromStart: null
|
||||||
|
}))
|
||||||
|
.catch(() => {
|
||||||
|
return {
|
||||||
|
todayDate: todayDateString,
|
||||||
|
initialViewStartDate,
|
||||||
|
initialViewEndDate,
|
||||||
|
calendarViewDirection,
|
||||||
|
initialShopTimeSlotsResponse: { days: [] },
|
||||||
|
preSelectedDate,
|
||||||
|
initialDaysLoaded: initialDays,
|
||||||
|
daysFromStart: null
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
this.mobileDatesData = initialData;
|
||||||
|
|
||||||
|
const estimatedServiceMinutesMax = initialData.initialShopTimeSlotsResponse?.estimatedServiceMinutesMaximum || 120;
|
||||||
|
const estimatedServiceMinutesMin = initialData.initialShopTimeSlotsResponse?.estimatedServiceMinutesMinimum || 90;
|
||||||
|
|
||||||
|
const retTimeSlotsResponse = [];
|
||||||
|
initialData.initialShopTimeSlotsResponse.days.forEach((selectableDate) => {
|
||||||
|
const dateObjectToPush = {
|
||||||
|
date: selectableDate.date,
|
||||||
|
timeSlots: selectableDate.timeSlots,
|
||||||
|
morningTimeSlots: selectableDate.timeSlots.filter((timeSlot) => {
|
||||||
|
const timeHour = parseInt(timeSlot.startTime.split(':')[0], 10);
|
||||||
|
return timeHour < 12;
|
||||||
|
}).map((timeSlot) => mapTimeSlot(timeSlot, 'morning')),
|
||||||
|
afternoonTimeSlots: selectableDate.timeSlots.filter((timeSlot) => {
|
||||||
|
const timeHour = parseInt(timeSlot.startTime.split(':')[0], 10);
|
||||||
|
return timeHour >= 12;
|
||||||
|
}).map((timeSlot) => mapTimeSlot(timeSlot, 'afternoon')),
|
||||||
|
isSelected: false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (dateObjectToPush.morningTimeSlots.length > 0) {
|
||||||
|
const findIndex = dateObjectToPush.morningTimeSlots.findIndex((timeSlot) => timeSlot.id.endsWith('DROP OFF'));
|
||||||
|
if (findIndex !== -1) {
|
||||||
|
const dropOffSlot = dateObjectToPush.morningTimeSlots.splice(findIndex, 1)[0];
|
||||||
|
dateObjectToPush.morningTimeSlots.unshift(dropOffSlot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dateObjectToPush.afternoonTimeSlots.length > 0) {
|
||||||
|
const findIndex = dateObjectToPush.afternoonTimeSlots.findIndex((timeSlot) => timeSlot.id.endsWith('DROP OFF'));
|
||||||
|
if (findIndex !== -1) {
|
||||||
|
const dropOffSlot = dateObjectToPush.afternoonTimeSlots.splice(findIndex, 1)[0];
|
||||||
|
dateObjectToPush.afternoonTimeSlots.push(dropOffSlot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
retTimeSlotsResponse.push(dateObjectToPush);
|
||||||
|
});
|
||||||
|
|
||||||
|
let dateDifferenceForPmMobile = null;
|
||||||
|
const firstPmMobileDateWithTimeSlots = retTimeSlotsResponse.find((date) => {
|
||||||
|
const hasPmMobileTimeSlots = date.afternoonTimeSlots?.length > 0;
|
||||||
|
if (hasPmMobileTimeSlots && pmMobileDaysLimit) {
|
||||||
|
dateDifferenceForPmMobile = calcDaysBetweenDates(todayDateString, date.date);
|
||||||
|
return dateDifferenceForPmMobile <= pmMobileDaysLimit;
|
||||||
|
}
|
||||||
|
return hasPmMobileTimeSlots;
|
||||||
|
});
|
||||||
|
|
||||||
|
let dateDifferenceForMobile = null;
|
||||||
|
const firstMobileDateWithTimeSlots = retTimeSlotsResponse.find((date) => {
|
||||||
|
const hasMobileTimeSlots = date.morningTimeSlots?.length > 0;
|
||||||
|
const hasPmMobileTimeSlots = date.afternoonTimeSlots?.length > 0;
|
||||||
|
if (hasMobileTimeSlots || hasPmMobileTimeSlots) {
|
||||||
|
if (mobileDaysLimit) {
|
||||||
|
dateDifferenceForMobile = calcDaysBetweenDates(todayDateString, date.date);
|
||||||
|
return mobileDaysLimit && dateDifferenceForMobile <= mobileDaysLimit;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return hasPmMobileTimeSlots;
|
||||||
|
});
|
||||||
|
|
||||||
|
const zipCodeData = await getMobileZipCodeData(mobileFirstObject.zipCode);
|
||||||
|
if ((firstPmMobileDateWithTimeSlots || firstMobileDateWithTimeSlots) && zipCodeData?.isValid) {
|
||||||
|
zipCodeData.zipCode = mobileFirstObject.zipCode;
|
||||||
|
const timeSlotForAutoSelectionMobile = {
|
||||||
|
date: firstPmMobileDateWithTimeSlots ? firstPmMobileDateWithTimeSlots.date : firstMobileDateWithTimeSlots.date,
|
||||||
|
estimatedServiceMinutesMax,
|
||||||
|
estimatedServiceMinutesMin,
|
||||||
|
isRepair: this.mainStore.order.damage.isRepair,
|
||||||
|
mobileProviderNumber: mobileFirstObject.mobileProviderNumber,
|
||||||
|
timeSlot: firstPmMobileDateWithTimeSlots ? firstPmMobileDateWithTimeSlots.afternoonTimeSlots[0]
|
||||||
|
: (firstMobileDateWithTimeSlots.morningTimeSlots[0] || firstMobileDateWithTimeSlots.afternoonTimeSlots[0]),
|
||||||
|
zipCodeData
|
||||||
|
};
|
||||||
|
|
||||||
|
const dateObjectToUse = new Date(`${timeSlotForAutoSelectionMobile.date}T${timeSlotForAutoSelectionMobile.timeSlot.startTime}:00`);
|
||||||
|
timeSlotForAutoSelectionMobile.dateObject = dateObjectToUse;
|
||||||
|
timeSlotForAutoSelectionMobile.dayOfWeek = dateObjectToUse.toLocaleDateString('en-US', { weekday: 'long' });
|
||||||
|
|
||||||
|
const experiment = this.getExperimentByName(experimentUniverses.ISS_MOBILE_FIRST_APPOINTMENTS);
|
||||||
|
if (experiment && !experiment.isExposed) {
|
||||||
|
this.mainStore.logMobileFirstExperimentExposure();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$refs[SUGGEST_TIMESLOT_MODAL_REF_NAME].openModal(timeSlotForAutoSelectionMobile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
async setData(premiumFeeWithPriceResponse, initialServiceLocationObj) {
|
async setData(premiumFeeWithPriceResponse, initialServiceLocationObj) {
|
||||||
this.selectedServiceLocation = initialServiceLocationObj;
|
this.selectedServiceLocation = initialServiceLocationObj;
|
||||||
this.mobilePremiumAppointmentFee = premiumFeeWithPriceResponse
|
this.mobilePremiumAppointmentFee = premiumFeeWithPriceResponse
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,259 @@
|
||||||
|
<template>
|
||||||
|
<div class="suggest-timeslot-modal-container">
|
||||||
|
<modal
|
||||||
|
ref="suggestTimeslotModal"
|
||||||
|
:onModalClosedCallback="onModalClosed">
|
||||||
|
<div>
|
||||||
|
<div class="header">{{ modalHeaderText }}</div>
|
||||||
|
<div class="subheader">{{ modalHeaderSubText }}</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="message"
|
||||||
|
v-html="modalBodyText">
|
||||||
|
</div>
|
||||||
|
<div class="appointment-info"
|
||||||
|
v-html="modalAppointmentInformationText">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer-container">
|
||||||
|
<div>
|
||||||
|
<button type="button" aria-live="polite" aria-label="Confirm Appointment" class="btn btn-danger confirm-appointment"
|
||||||
|
@click="confirmAppointmentClicked">
|
||||||
|
{{ modalCloseButtonText }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button type="button" aria-live="polite" aria-label="See more options" class="btn btn-link see-more-options"
|
||||||
|
@click="seeMoreOptionsClicked">
|
||||||
|
{{ modalFooterSubText }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import modal from '@/digital-components/modal/modal.vue';
|
||||||
|
import {
|
||||||
|
convertDateToTwoDigitDay,
|
||||||
|
getDisplayTextForDurationLength,
|
||||||
|
militaryToTwelveHourTime
|
||||||
|
} from '@/helpers/date-helper';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'suggest-timeslot-modal',
|
||||||
|
components: {
|
||||||
|
modal
|
||||||
|
},
|
||||||
|
emits: ['confirm-appointment-clicked'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
confirmedAppointment: false,
|
||||||
|
timeSlotForAutoSelectionMobile: {}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
cmsWidgetName: {
|
||||||
|
type: String,
|
||||||
|
default: 'SuggestTimeslotModal'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
customAppointmentEstimate() {
|
||||||
|
return getDisplayTextForDurationLength(this.timeSlotForAutoSelectionMobile.estimatedServiceMinutesMin, this.timeSlotForAutoSelectionMobile.estimatedServiceMinutesMax)
|
||||||
|
},
|
||||||
|
customAppointmentWindow() {
|
||||||
|
return `${militaryToTwelveHourTime(this.timeSlotForAutoSelectionMobile?.timeSlot?.startTime)} - ${militaryToTwelveHourTime(this.timeSlotForAutoSelectionMobile?.timeSlot?.endTime)}`;
|
||||||
|
},
|
||||||
|
customDayOfWeek() {
|
||||||
|
return this.timeSlotForAutoSelectionMobile.dayOfWeek ? this.timeSlotForAutoSelectionMobile.dayOfWeek : '';
|
||||||
|
},
|
||||||
|
customDayOfWeekMonthDayYear() {
|
||||||
|
if (!this.timeSlotForAutoSelectionMobile?.date) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const dayOfWeekToUse = this.customDayOfWeek;
|
||||||
|
const year = this.timeSlotForAutoSelectionMobile.dateObject.getFullYear();
|
||||||
|
const month = this.timeSlotForAutoSelectionMobile.dateObject.toLocaleString('en-US', { month: 'long' });
|
||||||
|
const day = convertDateToTwoDigitDay(this.timeSlotForAutoSelectionMobile.dateObject);
|
||||||
|
return `${dayOfWeekToUse}, ${month} ${day}, ${year}`;
|
||||||
|
},
|
||||||
|
modalAppointmentInformationText() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'BodyText2')
|
||||||
|
.replaceAll('{custom:dowMonthDayYear}', this.customDayOfWeekMonthDayYear)
|
||||||
|
.replaceAll('{custom:appointmentEstimate}', this.customAppointmentEstimate)
|
||||||
|
.replaceAll('{custom:appointmentWindow}', this.customAppointmentWindow);
|
||||||
|
},
|
||||||
|
modalBodyText() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'BodyText')
|
||||||
|
.replaceAll('{custom:damageType}', this.timeSlotForAutoSelectionMobile.isRepair ? 'repair' : 'replace',)
|
||||||
|
.replaceAll('{custom:dayOfWeekLong}', this.customDayOfWeek);
|
||||||
|
},
|
||||||
|
modalCloseButtonText() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'FooterText');
|
||||||
|
},
|
||||||
|
modalFooterSubText() {
|
||||||
|
return 'See more options';
|
||||||
|
},
|
||||||
|
modalHeaderSubText() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'SubheaderText');
|
||||||
|
},
|
||||||
|
modalHeaderText() {
|
||||||
|
return this.getCmsContent(this.cmsWidgetName, 'HeaderText');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
confirmAppointmentClicked() {
|
||||||
|
this.confirmedAppointment = true;
|
||||||
|
this.$emit('confirm-appointment-clicked', this.timeSlotForAutoSelectionMobile);
|
||||||
|
this.$refs.suggestTimeslotModal.closeModal();
|
||||||
|
},
|
||||||
|
onModalClosed() {
|
||||||
|
this.pushEvent();
|
||||||
|
this.confirmedAppointment = false;
|
||||||
|
this.timeSlotForAutoSelectionMobile = {};
|
||||||
|
},
|
||||||
|
openModal(timeSlotForAutoSelectionMobile) {
|
||||||
|
this.timeSlotForAutoSelectionMobile = timeSlotForAutoSelectionMobile;
|
||||||
|
this.$refs.suggestTimeslotModal.openModal();
|
||||||
|
},
|
||||||
|
pushEvent() {
|
||||||
|
const gaAction = this.confirmedAppointment ? this.GaActions.YES : this.GaActions.NO;
|
||||||
|
if (this.timeSlotForAutoSelectionMobile && this.timeSlotForAutoSelectionMobile.timeSlot) {
|
||||||
|
this.pushEventToGA(
|
||||||
|
this.GaCategories.CONFIRMATION_CLICKED,
|
||||||
|
gaAction,
|
||||||
|
this.timeSlotForAutoSelectionMobile.timeSlot.startTime +
|
||||||
|
"-" +
|
||||||
|
this.timeSlotForAutoSelectionMobile.timeSlot.endTime +
|
||||||
|
" " +
|
||||||
|
this.timeSlotForAutoSelectionMobile.date,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
seeMoreOptionsClicked() {
|
||||||
|
this.$refs.suggestTimeslotModal.closeModal();
|
||||||
|
},
|
||||||
|
footerButtonClick() {
|
||||||
|
this.$refs.suggestTimeslotModal.closeModal();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.suggest-timeslot-modal-container {
|
||||||
|
.modal {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
:deep(.modal) {
|
||||||
|
.modal-dialog {
|
||||||
|
@include media-breakpoint-up(xs) {
|
||||||
|
width: auto;
|
||||||
|
max-width: unset;
|
||||||
|
}
|
||||||
|
@include media-breakpoint-up(xl) {
|
||||||
|
width: 37.5rem;
|
||||||
|
max-width: 37.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
width: 22rem;
|
||||||
|
max-width: 22rem;
|
||||||
|
padding: 1.5rem 0;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
line-height: 1.5rem;
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-body {
|
||||||
|
padding: 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-footer {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
margin-top: 1rem;
|
||||||
|
color: #db0020;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subheader {
|
||||||
|
color: black;
|
||||||
|
text-align: center;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
line-height: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
color: #525656;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.625rem;
|
||||||
|
|
||||||
|
.emphasize {
|
||||||
|
color: black;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.appointment-info {
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding: 1rem;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
|
||||||
|
.emphasize {
|
||||||
|
color: black;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-right: 0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-container {
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
padding: 0 1.5rem;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
.confirm-appointment {
|
||||||
|
width: 100%;
|
||||||
|
padding: .75rem 0;
|
||||||
|
border-radius: 4.5rem;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.see-more-options {
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
letter-spacing: 0.03em;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1rem;
|
||||||
|
line-height: 1.625rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -68,6 +68,7 @@
|
||||||
:options="DamageCauseOptions"
|
:options="DamageCauseOptions"
|
||||||
disableAutoFill
|
disableAutoFill
|
||||||
:validationRules="rules.damageOption"
|
:validationRules="rules.damageOption"
|
||||||
|
isRequired
|
||||||
placeHolderText="Select an option"
|
placeHolderText="Select an option"
|
||||||
class="form-group" />
|
class="form-group" />
|
||||||
<textboxQuestion
|
<textboxQuestion
|
||||||
|
|
@ -252,6 +253,35 @@ export default {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.mainStore.applicationUser.firstHit) {
|
||||||
|
const isInfoPrefilled = !!(this.mainStore.order.policy.policyNumber
|
||||||
|
&& this.mainStore.order.policy.dateOfLoss
|
||||||
|
&& this.mainStore.order.policy.policyZipCode);
|
||||||
|
|
||||||
|
this.pushEventToGA("policy_info", "info_prefilled", isInfoPrefilled.toString(), true);
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const formRoot = this.$el;
|
||||||
|
const requiredFieldCount = formRoot.querySelectorAll('[aria-required="true"]').length;
|
||||||
|
this.pushEventToGA("policy_info", "required_fields", requiredFieldCount.toString(), true);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.mainStore.applicationUser.firstHit = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Check if we're coming from SFA
|
||||||
|
// eslint-disable-next-line
|
||||||
|
if (false) {
|
||||||
|
this.pushEventToGA("co_branded", "welcome_clicked_cta", "yes_clicked", 0);
|
||||||
|
this.pushEventToGA("visitor_info_welcome", "referring_site", "SFA", null);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.pushEventToGA("visitor_info_welcome", "referring_site", "ClientSite", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pushEventToGA("visitor_info_welcome", "client_name", this.mainStore.accountNameForEvents, null);
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
DamageCauseOptions() {
|
DamageCauseOptions() {
|
||||||
const damageCauseAnswers = this.getCmsContent(
|
const damageCauseAnswers = this.getCmsContent(
|
||||||
|
|
@ -460,6 +490,20 @@ export default {
|
||||||
this.answeredContinueModal = true;
|
this.answeredContinueModal = true;
|
||||||
this.$refs.continueModal.closeModal();
|
this.$refs.continueModal.closeModal();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
'welcomePageModel.policyZipCode': {
|
||||||
|
handler: async function (newZip) {
|
||||||
|
if (newZip.length === 5) {
|
||||||
|
this.pushEventToGA("policy_info", "policy_zip", newZip, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'welcomePageModel.damageCause': function (newCause) {
|
||||||
|
if (newCause) {
|
||||||
|
this.pushEventToGA("policy_info", "cause_of_loss", newCause, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,10 @@ export default {
|
||||||
hasSetting(settingName) {
|
hasSetting(settingName) {
|
||||||
return Object.hasOwn(useMainStore().experimentSettings, settingName);
|
return Object.hasOwn(useMainStore().experimentSettings, settingName);
|
||||||
},
|
},
|
||||||
|
getExperimentByName(experimentName) {
|
||||||
|
const experiment = useMainStore().applicationUser.experiments.find((e) => e.universeName === experimentName);
|
||||||
|
return experiment ? experiment : null;
|
||||||
|
},
|
||||||
getSettingValue(settingName) {
|
getSettingValue(settingName) {
|
||||||
return this.hasSetting(settingName)
|
return this.hasSetting(settingName)
|
||||||
? useMainStore().experimentSettings[settingName]
|
? useMainStore().experimentSettings[settingName]
|
||||||
|
|
|
||||||
|
|
@ -240,7 +240,8 @@ export const getDefaultState = () => ({
|
||||||
triggeredSiteEntry: false, // TODO not in save session
|
triggeredSiteEntry: false, // TODO not in save session
|
||||||
duplicateOrders: [],
|
duplicateOrders: [],
|
||||||
hasSentSaveQuoteEmail: null,
|
hasSentSaveQuoteEmail: null,
|
||||||
coverageLookupAttempts: 0
|
coverageLookupAttempts: 0,
|
||||||
|
firstHit: true
|
||||||
},
|
},
|
||||||
issConfig: {
|
issConfig: {
|
||||||
clientName: 'Generic Insurance', // this is the default and will be overriden by the client's name
|
clientName: 'Generic Insurance', // this is the default and will be overriden by the client's name
|
||||||
|
|
@ -446,7 +447,8 @@ export const useMainStore = defineStore({
|
||||||
.map((x) => x.settings)
|
.map((x) => x.settings)
|
||||||
.reduce((r, c) => Object.assign(r, c), {}) ?? {},
|
.reduce((r, c) => Object.assign(r, c), {}) ?? {},
|
||||||
originalDeductible: (state) => (state.order.damage.isRepair ? state.order.originalDeductible.repair : state.order.originalDeductible.replace),
|
originalDeductible: (state) => (state.order.damage.isRepair ? state.order.originalDeductible.repair : state.order.originalDeductible.replace),
|
||||||
currentDeductible: (state) => (state.order.damage.isRepair ? state.order.currentDeductible.repair : state.order.currentDeductible.replace)
|
currentDeductible: (state) => (state.order.damage.isRepair ? state.order.currentDeductible.repair : state.order.currentDeductible.replace),
|
||||||
|
accountNameForEvents: (state) => state.issConfig.clientName.replaceAll(" ", "").replaceAll("&", "amp")
|
||||||
},
|
},
|
||||||
actions:
|
actions:
|
||||||
{
|
{
|
||||||
|
|
@ -2632,6 +2634,9 @@ export const useMainStore = defineStore({
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
logMobileFirstExperimentExposure() {
|
||||||
|
this.logExperimentIfExists(issPageValues.SCHEDULE_PAGE, experimentUniverses.ISS_MOBILE_FIRST_APPOINTMENTS);
|
||||||
|
},
|
||||||
logWelcomePageExperiments(issPage) {
|
logWelcomePageExperiments(issPage) {
|
||||||
this.logExperimentIfExists(issPage, experimentUniverses.ISS_FEATURETOGGLE_AREFEES_HIDDEN);
|
this.logExperimentIfExists(issPage, experimentUniverses.ISS_FEATURETOGGLE_AREFEES_HIDDEN);
|
||||||
this.logExperimentIfExists(issPage, experimentUniverses.ISS_FEATURETOGGLE_AREFEES_OVERRIDDEN);
|
this.logExperimentIfExists(issPage, experimentUniverses.ISS_FEATURETOGGLE_AREFEES_OVERRIDDEN);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ process.env.VUE_APP_CURRENT_ENVIRONMENT = "__VUE_APP_CURRENT_ENVIRONMENT__";
|
||||||
process.env.VUE_APP_CUSTOMER_PORTAL_URL = '__VUE_APP_CUSTOMER_PORTAL_URL__';
|
process.env.VUE_APP_CUSTOMER_PORTAL_URL = '__VUE_APP_CUSTOMER_PORTAL_URL__';
|
||||||
process.env.VUE_APP_GOOGLE_PLACES_API_KEY = "__VUE_APP_GOOGLE_PLACES_API_KEY__";
|
process.env.VUE_APP_GOOGLE_PLACES_API_KEY = "__VUE_APP_GOOGLE_PLACES_API_KEY__";
|
||||||
process.env.VUE_APP_SAFELITE_HOP = "__VUE_APP_SAFELITE_HOP__";
|
process.env.VUE_APP_SAFELITE_HOP = "__VUE_APP_SAFELITE_HOP__";
|
||||||
|
process.env.VUE_APP_ADYEN_ENVIRONMENT = '__VUE_APP_ADYEN_ENVIRONMENT__';
|
||||||
|
process.env.VUE_APP_ADYEN_CLIENT_KEY = '__VUE_APP_ADYEN_CLIENT_KEY__';
|
||||||
|
|
||||||
// GA & GTM
|
// GA & GTM
|
||||||
process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY = "__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__";
|
process.env.VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY = "__VUE_APP_GOOGLE_TAG_MANAGER_SCRIPT_BODY__";
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue