Merge branch 'develop' into dependabot/npm_and_yarn/multi-75e6bc5210
This commit is contained in:
commit
8544592a5b
141 changed files with 4290 additions and 3920 deletions
|
|
@ -13,6 +13,8 @@ const environmentVariables = {
|
||||||
['__VUE_APP_SAFELITE_HOP__']: "https://sv2-safelitehop-dev.safelite.com/fmgCheckoutShared.aspx",
|
['__VUE_APP_SAFELITE_HOP__']: "https://sv2-safelitehop-dev.safelite.com/fmgCheckoutShared.aspx",
|
||||||
['__VUE_APP_SESSION_TIMEOUT_MINUTES__']: 30,
|
['__VUE_APP_SESSION_TIMEOUT_MINUTES__']: 30,
|
||||||
['__VUE_APP_SOLARWINDS_MONITORING_SCRIPT__']: "",
|
['__VUE_APP_SOLARWINDS_MONITORING_SCRIPT__']: "",
|
||||||
|
['__VUE_APP_ADYEN_ENVIRONMENT__']: "test",
|
||||||
|
['__VUE_APP_ADYEN_CLIENT_KEY__']: "test_WYGT4F5ZT5BRRL5MPWHK6QLYOIXZXROD",
|
||||||
};
|
};
|
||||||
|
|
||||||
const keysOnly = Object.keys(environmentVariables);
|
const keysOnly = Object.keys(environmentVariables);
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ module.exports = {
|
||||||
},
|
},
|
||||||
transformIgnorePatterns: ["'/node_modules/(?!vee-validate)"],
|
transformIgnorePatterns: ["'/node_modules/(?!vee-validate)"],
|
||||||
moduleFileExtensions: ["js", "vue"],
|
moduleFileExtensions: ["js", "vue"],
|
||||||
modulePathIgnorePatterns: ["vin-lookup"],
|
|
||||||
collectCoverageFrom: [
|
collectCoverageFrom: [
|
||||||
"src/**/*.{js,vue}",
|
"src/**/*.{js,vue}",
|
||||||
"!src/main.js",
|
"!src/main.js",
|
||||||
|
|
@ -33,11 +32,7 @@ module.exports = {
|
||||||
"!src/layouts/payment-pia-return/*.vue", // Temp test exclusion while in development
|
"!src/layouts/payment-pia-return/*.vue", // Temp test exclusion while in development
|
||||||
"!src/layouts/insurance/*.vue", // Temp test exclusion while in development
|
"!src/layouts/insurance/*.vue", // Temp test exclusion while in development
|
||||||
"!src/layouts/insurance-company/*.vue", // Temp test exclusion while in development
|
"!src/layouts/insurance-company/*.vue", // Temp test exclusion while in development
|
||||||
"!src/layouts/schedule/**/*.vue", // Temp test exclusion while in development
|
|
||||||
"!src/digital-components/date-picker/**/*.vue", // Temp test exclusion while in development
|
"!src/digital-components/date-picker/**/*.vue", // Temp test exclusion while in development
|
||||||
|
|
||||||
"!src/**/*-june-2025.vue", // Exclude these temporary files for CASH-845 project
|
|
||||||
|
|
||||||
"!src/layouts/insurance-company/insurance-company-question/*.vue", // Temp test exclusion while in development
|
"!src/layouts/insurance-company/insurance-company-question/*.vue", // Temp test exclusion while in development
|
||||||
"!src/experiment-components/*.vue",
|
"!src/experiment-components/*.vue",
|
||||||
// END
|
// END
|
||||||
|
|
@ -45,7 +40,7 @@ module.exports = {
|
||||||
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
|
testMatch: ["**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)"],
|
||||||
coverageThreshold: {
|
coverageThreshold: {
|
||||||
global: {
|
global: {
|
||||||
statements: 64,
|
statements: 68,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Uncomment this to avoid the massive amount of warnings we are getting for onSubmit and onInvalidSubmit
|
// Uncomment this to avoid the massive amount of warnings we are getting for onSubmit and onInvalidSubmit
|
||||||
|
|
|
||||||
41
package-lock.json
generated
41
package-lock.json
generated
|
|
@ -8,6 +8,7 @@
|
||||||
"name": "Safelite",
|
"name": "Safelite",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@adyen/adyen-web": "^6.27.0",
|
||||||
"@iframe-resizer/child": "^5.3.3",
|
"@iframe-resizer/child": "^5.3.3",
|
||||||
"axios": "^0.30.2",
|
"axios": "^0.30.2",
|
||||||
"bootstrap": "^5.3.3",
|
"bootstrap": "^5.3.3",
|
||||||
|
|
@ -59,6 +60,18 @@
|
||||||
"node": "8 || 9 || 10 || 11 || 12 || 13 || 14 || 15 || 16 || 17 || 18 || 19 || 20 || 21 || 22"
|
"node": "8 || 9 || 10 || 11 || 12 || 13 || 14 || 15 || 16 || 17 || 18 || 19 || 20 || 21 || 22"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@adyen/adyen-web": {
|
||||||
|
"version": "6.27.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@adyen/adyen-web/-/adyen-web-6.27.0.tgz",
|
||||||
|
"integrity": "sha512-6E6hqEkMkoY/FevjO53zhgeCWMt+i/PDc11MX6eVM7Fvd+Sdgc9cIwTBz+NKIXs4ZerG6n2gd+ZIZEywqF/aBQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/applepayjs": "14.0.9",
|
||||||
|
"@types/googlepay": "0.7.8",
|
||||||
|
"classnames": "2.5.1",
|
||||||
|
"preact": "10.22.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@ampproject/remapping": {
|
"node_modules/@ampproject/remapping": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
|
||||||
|
|
@ -3173,6 +3186,12 @@
|
||||||
"node": ">=10.13.0"
|
"node": ">=10.13.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/applepayjs": {
|
||||||
|
"version": "14.0.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/applepayjs/-/applepayjs-14.0.9.tgz",
|
||||||
|
"integrity": "sha512-xEprYbb0TEP/XIiDPbVnTYpDai8fTFpsQfVSfTd81Is2GOMUy7ie019eyX6Mz2ECxfjoUVKaiGSL577roIeHCg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/babel__core": {
|
"node_modules/@types/babel__core": {
|
||||||
"version": "7.20.5",
|
"version": "7.20.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
|
||||||
|
|
@ -3328,6 +3347,12 @@
|
||||||
"@types/send": "*"
|
"@types/send": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/googlepay": {
|
||||||
|
"version": "0.7.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/googlepay/-/googlepay-0.7.8.tgz",
|
||||||
|
"integrity": "sha512-EHl7G7jIeit/Px/fi/Du/19SZDvqrRhy0DjJX40Vzs/97m3sro9mzVyAYNC0pfzpWGDY+zPjtTLEfhV+OYWUcQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/graceful-fs": {
|
"node_modules/@types/graceful-fs": {
|
||||||
"version": "4.1.9",
|
"version": "4.1.9",
|
||||||
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
|
||||||
|
|
@ -5789,6 +5814,12 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/classnames": {
|
||||||
|
"version": "2.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
|
||||||
|
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/clean-css": {
|
"node_modules/clean-css": {
|
||||||
"version": "5.3.3",
|
"version": "5.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
|
||||||
|
|
@ -13681,6 +13712,16 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/preact": {
|
||||||
|
"version": "10.22.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/preact/-/preact-10.22.1.tgz",
|
||||||
|
"integrity": "sha512-jRYbDDgMpIb5LHq3hkI0bbl+l/TQ9UnkdQ0ww+lp+4MMOdqaUYdFc5qeyP+IV8FAd/2Em7drVPeKdQxsiWCf/A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/preact"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/prelude-ls": {
|
"node_modules/prelude-ls": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@adyen/adyen-web": "^6.27.0",
|
||||||
"@iframe-resizer/child": "^5.3.3",
|
"@iframe-resizer/child": "^5.3.3",
|
||||||
"axios": "^0.30.2",
|
"axios": "^0.30.2",
|
||||||
"bootstrap": "^5.3.3",
|
"bootstrap": "^5.3.3",
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,11 @@
|
||||||
PLAYWRIGHT_ENV="qa"
|
PLAYWRIGHT_ENV="qa"
|
||||||
|
|
||||||
# Skip content site
|
# Skip content site
|
||||||
SKIP_CONTENT_SITE=false
|
SKIP_CONTENT_SITE="false"
|
||||||
|
|
||||||
|
# Experiments Flag
|
||||||
|
IS_MOBILEFIRST="false"
|
||||||
|
IS_ADYENPAYMENTS="false"
|
||||||
|
|
||||||
# Base URLs by environment
|
# Base URLs by environment
|
||||||
# qa
|
# qa
|
||||||
|
|
@ -13,7 +17,8 @@ BASE_URL="https://www-qa2.safelite.com/"
|
||||||
# local version of FMG (after running the local server)
|
# local version of FMG (after running the local server)
|
||||||
# BASE_URL="http://localhost:8080/fmg/"
|
# BASE_URL="http://localhost:8080/fmg/"
|
||||||
# qa with skipToInsurance Turned Off
|
# qa with skipToInsurance Turned Off
|
||||||
# BASE_URL="https://fixmyglassqa.safelite.com/?cns=all&experiments=ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_VinAndEmailOptional=true,NextGen_IGQSkipToInsurance=NextGen_IGQSkipToInsurance_V1=NextGen_IGQSkipToInsurance_CONTROL=true"
|
# BASE_URL="https://fixmyglassqa.safelite.com/?cns=all&experiments=ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_VinAndEmailOptional=true"
|
||||||
|
|
||||||
# sys
|
# sys
|
||||||
# BASE_URL="https://www-test2.safelite.com/fmg/?fmgPage=vehicle"
|
# BASE_URL="https://www-test2.safelite.com/fmg/?fmgPage=vehicle"
|
||||||
# dev
|
# dev
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,20 @@
|
||||||
PLAYWRIGHT_ENV="qa"
|
PLAYWRIGHT_ENV="qa"
|
||||||
|
|
||||||
# Skip content site
|
# Skip content site
|
||||||
SKIP_CONTENT_SITE=false
|
SKIP_CONTENT_SITE="false"
|
||||||
|
|
||||||
|
# Experiments Flag
|
||||||
|
IS_MOBILEFIRST="false"
|
||||||
|
IS_ADYENPAYMENTS="false"
|
||||||
|
|
||||||
# Base URLs by environment
|
# Base URLs by environment
|
||||||
# qa
|
# qa
|
||||||
# BASE_URL="https://www-qa2.safelite.com/"
|
BASE_URL="https://www-qa2.safelite.com/"
|
||||||
# local version of FMG (after running the local server)
|
# local version of FMG (after running the local server)
|
||||||
# BASE_URL="http://localhost:8080/fmg/"
|
# BASE_URL="http://localhost:8080/fmg/"
|
||||||
# qa with skipToInsurance Turned Off
|
# qa with skipToInsurance Turned Off
|
||||||
BASE_URL="https://www-qa2.safelite.com/?&experiments=ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_VinAndEmailOptional=true"
|
# BASE_URL="https://www-qa2.safelite.com/?&experiments=ConceptFunnel=ConceptFunnel_V1=ConceptFunnel_VinAndEmailOptional=true"
|
||||||
|
|
||||||
# sys
|
# sys
|
||||||
# BASE_URL="https://www-test2.safelite.com/fmg/?fmgPage=vehicle"
|
# BASE_URL="https://www-test2.safelite.com/fmg/?fmgPage=vehicle"
|
||||||
# dev
|
# dev
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,22 @@
|
||||||
import { ITestData as base } from 'safelite-playwright-core'
|
import { ITestData as base, getDefaultTestData } from 'safelite-playwright-core'
|
||||||
import { PaymentMethod } from './localTypes/Enums'
|
import { PaymentMethod } from './localTypes/Enums'
|
||||||
|
import { IExperiments } from './localTypes/IExperiments';
|
||||||
|
|
||||||
export interface ITestData extends base {
|
export interface ITestData extends base {
|
||||||
// Put any project-specific data here. Anything useful to other Safelite projects should be submitted as a pull request to safelite-playwright-core.
|
// Put any project-specific data here. Anything useful to other Safelite projects should be submitted as a pull request to safelite-playwright-core.
|
||||||
paymentMethod: PaymentMethod
|
paymentMethod: PaymentMethod,
|
||||||
isOptedInForTextMessages: boolean
|
isOptedInForTextMessages: boolean,
|
||||||
totalAmount?: number
|
totalAmount?: number,
|
||||||
}
|
isForcedOEM?: boolean,
|
||||||
|
mockFirstInshopCallNoSchedule?: boolean,
|
||||||
|
handleMobileFirstModal?: boolean,
|
||||||
|
experiments?: IExperiments
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getDefaultExperimentsData(): IExperiments {
|
||||||
|
return {
|
||||||
|
isAdyenPayments: !!process.env.IS_ADYENPAYMENTS && process.env.IS_ADYENPAYMENTS !== "" ? process.env.IS_ADYENPAYMENTS === "true" : false,
|
||||||
|
isMobileFirst: !!process.env.IS_MOBILEFIRST && process.env.IS_MOBILEFIRST !== "" ? process.env.IS_MOBILEFIRST === "true" : false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import { CCPolicyInfoPage } from "../pages/CCPolicyInfoPage"
|
||||||
import { DuplicateCheckPage } from "../pages/DuplicateCheckPage"
|
import { DuplicateCheckPage } from "../pages/DuplicateCheckPage"
|
||||||
import { PolicyVehiclesPage } from "../pages/PolicyVehiclesPage"
|
import { PolicyVehiclesPage } from "../pages/PolicyVehiclesPage"
|
||||||
import { PolicyInfoSubmittedPage } from "../pages/PolicyInfoSubmittedPage"
|
import { PolicyInfoSubmittedPage } from "../pages/PolicyInfoSubmittedPage"
|
||||||
|
import { HeritageProblemGlassQuestionsPage } from "../pages/HeritageProblemGlassQuestionsPage"
|
||||||
import RecalibrationInfoPage from "../pages/RecalibrationInfoPage"
|
import RecalibrationInfoPage from "../pages/RecalibrationInfoPage"
|
||||||
import { CoverageStatementPage } from "../pages/CoverageStatementPage"
|
import { CoverageStatementPage } from "../pages/CoverageStatementPage"
|
||||||
import { VerifyDetailsPage } from "../pages/VerifyDetailsPage"
|
import { VerifyDetailsPage } from "../pages/VerifyDetailsPage"
|
||||||
|
|
@ -48,6 +49,7 @@ export interface ITestPages {
|
||||||
paymentMethodPage: PaymentMethodPage,
|
paymentMethodPage: PaymentMethodPage,
|
||||||
policyInfoSubmittedPage: PolicyInfoSubmittedPage,
|
policyInfoSubmittedPage: PolicyInfoSubmittedPage,
|
||||||
policyVehiclesPage: PolicyVehiclesPage,
|
policyVehiclesPage: PolicyVehiclesPage,
|
||||||
|
heritageProblemGlassQuestionsPage: HeritageProblemGlassQuestionsPage,
|
||||||
recalibrationInfoPage: RecalibrationInfoPage,
|
recalibrationInfoPage: RecalibrationInfoPage,
|
||||||
schedulePage: SchedulePage,
|
schedulePage: SchedulePage,
|
||||||
mobileDetailsPage: MobileDetailsPage,
|
mobileDetailsPage: MobileDetailsPage,
|
||||||
|
|
@ -83,6 +85,7 @@ export const createTestPages: TestPagesFactory<ITestPages> = (page: Page) => {
|
||||||
paymentMethodPage: new PaymentMethodPage(page),
|
paymentMethodPage: new PaymentMethodPage(page),
|
||||||
policyInfoSubmittedPage: new PolicyInfoSubmittedPage(page),
|
policyInfoSubmittedPage: new PolicyInfoSubmittedPage(page),
|
||||||
policyVehiclesPage: new PolicyVehiclesPage(page),
|
policyVehiclesPage: new PolicyVehiclesPage(page),
|
||||||
|
heritageProblemGlassQuestionsPage: new HeritageProblemGlassQuestionsPage(page),
|
||||||
recalibrationInfoPage: new RecalibrationInfoPage(page),
|
recalibrationInfoPage: new RecalibrationInfoPage(page),
|
||||||
schedulePage: new SchedulePage(page),
|
schedulePage: new SchedulePage(page),
|
||||||
mobileDetailsPage: new MobileDetailsPage(page),
|
mobileDetailsPage: new MobileDetailsPage(page),
|
||||||
|
|
|
||||||
4
playwright-tests/framework/localTypes/IExperiments.ts
Normal file
4
playwright-tests/framework/localTypes/IExperiments.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
export interface IExperiments {
|
||||||
|
isMobileFirst: boolean,
|
||||||
|
isAdyenPayments: boolean
|
||||||
|
}
|
||||||
|
|
@ -18,6 +18,7 @@ export class BasePage {
|
||||||
readonly buttonLoadSpin: Locator;
|
readonly buttonLoadSpin: Locator;
|
||||||
readonly hamburgerMenu: Locator;
|
readonly hamburgerMenu: Locator;
|
||||||
readonly progressBar: Locator;
|
readonly progressBar: Locator;
|
||||||
|
readonly loaders: Locator;
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
this.page = page;
|
this.page = page;
|
||||||
|
|
@ -27,6 +28,7 @@ export class BasePage {
|
||||||
this.buttonLoadSpin = page.getByRole('alert');
|
this.buttonLoadSpin = page.getByRole('alert');
|
||||||
this.hamburgerMenu = this.page.getByRole('button', { name: 'Hamburger Menu (modal window)' });
|
this.hamburgerMenu = this.page.getByRole('button', { name: 'Hamburger Menu (modal window)' });
|
||||||
this.progressBar = this.page.locator('.progress-bar-outer .progress-bar-inner');
|
this.progressBar = this.page.locator('.progress-bar-outer .progress-bar-inner');
|
||||||
|
this.loaders = this.page.locator('.spinner-border, .loader');
|
||||||
}
|
}
|
||||||
|
|
||||||
async nextPage() {
|
async nextPage() {
|
||||||
|
|
@ -131,6 +133,47 @@ export class BasePage {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async mockScheduleResponseForFirstInshopCallNoSchedule(customerDetails: ICustomerDetails) {
|
||||||
|
let fistInshopScheduleCall = true;
|
||||||
|
|
||||||
|
const apiUrl = `https://digitalapi.${process.env['PLAYWRIGHT_ENV']!.replace('sys', 'test').toLowerCase()}.safelite.io/schedule/api/v1/schedule/shop-time-slots`;
|
||||||
|
await this.page.route(apiUrl, async (route) => {
|
||||||
|
if (!fistInshopScheduleCall) {
|
||||||
|
return route.continue();
|
||||||
|
}
|
||||||
|
|
||||||
|
// const fmt = (d: Date) => `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,"0")}-${String(d.getDate()).padStart(2,"0")}`;
|
||||||
|
// const startDate = new Date();
|
||||||
|
//const beginningOfWeek = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate() - startDate.getDay());
|
||||||
|
// const endDate = new Date(beginningOfWeek.getFullYear(), beginningOfWeek.getMonth(), beginningOfWeek.getDate() + 13);
|
||||||
|
// e.g., "2025-07-23"
|
||||||
|
/*if (route.request().postDataJSON().startDate === fmt(startDate) && route.request().postDataJSON().endDate === fmt(endDate)) {
|
||||||
|
const response = await route.fetch();
|
||||||
|
const responseBody = await response.json();
|
||||||
|
|
||||||
|
responseBody.days = [];
|
||||||
|
// Mock the response
|
||||||
|
await route.fulfill({
|
||||||
|
response,
|
||||||
|
body: JSON.stringify(responseBody),
|
||||||
|
});
|
||||||
|
}*/
|
||||||
|
|
||||||
|
const response = await route.fetch();
|
||||||
|
const responseBody = await response.json();
|
||||||
|
|
||||||
|
responseBody.days = [];
|
||||||
|
|
||||||
|
// Mock the response
|
||||||
|
await route.fulfill({
|
||||||
|
response,
|
||||||
|
body: JSON.stringify(responseBody),
|
||||||
|
});
|
||||||
|
fistInshopScheduleCall = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async getRepairPartsTotal(testData: Partial<ITestData>) {
|
async getRepairPartsTotal(testData: Partial<ITestData>) {
|
||||||
const apiUrl = `https://digitalapi.${process.env['PLAYWRIGHT_ENV']!.replace('sys', 'test').toLowerCase()}.safelite.io/price/api/v1/price/order-items`;
|
const apiUrl = `https://digitalapi.${process.env['PLAYWRIGHT_ENV']!.replace('sys', 'test').toLowerCase()}.safelite.io/price/api/v1/price/order-items`;
|
||||||
await this.page.on('response', async (response) => {
|
await this.page.on('response', async (response) => {
|
||||||
|
|
@ -169,4 +212,58 @@ export class BasePage {
|
||||||
Soft.expect(actualProgressPercentage).toBe(progressPercentage);
|
Soft.expect(actualProgressPercentage).toBe(progressPercentage);
|
||||||
console.log(`Progress Bar Percentage: Actual - ${actualProgressPercentage} vs Expected - ${progressPercentage}`);
|
console.log(`Progress Bar Percentage: Actual - ${actualProgressPercentage} vs Expected - ${progressPercentage}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async waitForPageOrComponentload(): Promise<void> {
|
||||||
|
await Promise.all([
|
||||||
|
(async () => {
|
||||||
|
const loaderCount = await this.loaders.count();
|
||||||
|
if (loaderCount > 0) {
|
||||||
|
for (let i = 0; i < loaderCount; i++) {
|
||||||
|
await this.loaders.nth(i).waitFor({ state: 'hidden' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})(),
|
||||||
|
this.page.waitForLoadState('load'),
|
||||||
|
this.page.waitForLoadState('networkidle')
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async validateOEMPart(isOEM: boolean): Promise<void> {
|
||||||
|
if (isOEM!) {
|
||||||
|
// Get Vuex state from localStorage
|
||||||
|
const vuexState = JSON.parse(await this.page.evaluate('localStorage.getItem(\'vuex\')'));
|
||||||
|
|
||||||
|
// Validate the presence of an OEM part
|
||||||
|
if (vuexState.order?.lineItems?.glassParts?.length > 0) {
|
||||||
|
const firstGlassPartNumber = vuexState.order.lineItems.glassParts[0].partNumber;
|
||||||
|
|
||||||
|
await expect(firstGlassPartNumber.includes("OEM")).toBe(true);
|
||||||
|
} else {
|
||||||
|
throw new Error("No glass parts found in the order");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async buildExperimentUrl(testData: Partial<ITestData>): Promise<string> {
|
||||||
|
|
||||||
|
let experimentsURLExtension = "";
|
||||||
|
|
||||||
|
const { experiments } = testData;
|
||||||
|
|
||||||
|
if (experiments !== undefined) {
|
||||||
|
experimentsURLExtension += "?cns=all&experiments="
|
||||||
|
experimentsURLExtension += experiments?.isMobileFirst
|
||||||
|
? "MobileFirstAppointment=MobileFirstAppt_V1=MobileFirstAppt_TEST=true"
|
||||||
|
: "MobileFirstAppointment=MobileFirstAppt_V1=MobileFirstAppt_CONTROL=true";
|
||||||
|
|
||||||
|
experimentsURLExtension += experiments?.isAdyenPayments
|
||||||
|
? ",Adyen%20Payments=Adyen%20Payment%20Test=Adyen%20Payment%20(Test)"
|
||||||
|
: ",Adyen%20Payments=Adyen%20Payment%20Test=CyberSource%20(Control)";
|
||||||
|
} else {
|
||||||
|
console.log("Url extension without query string");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to HTML encoding before returning
|
||||||
|
return experimentsURLExtension;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
42
playwright-tests/pages/HeritageProblemGlassQuestionsPage.ts
Normal file
42
playwright-tests/pages/HeritageProblemGlassQuestionsPage.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { expect, type Locator, type Page } from '@playwright/test';
|
||||||
|
import { InsuranceBasePage } from './InsuranceBasePage';
|
||||||
|
import { ITestData } from 'framework/TestData';
|
||||||
|
import { step } from 'framework/localTypes/Step';
|
||||||
|
|
||||||
|
export class HeritageProblemGlassQuestionsPage extends InsuranceBasePage {
|
||||||
|
readonly provideVinManuallyButton: Locator;
|
||||||
|
readonly provideLicensePlateButton: Locator;
|
||||||
|
readonly provideHomeAddressButton: Locator;
|
||||||
|
readonly continueOnVinPopUpButton: Locator;
|
||||||
|
readonly dontShareVinButton: Locator;
|
||||||
|
|
||||||
|
readonly yestoGlassQuestionButton: Locator;
|
||||||
|
readonly notoGlassQuestionButton: Locator;
|
||||||
|
readonly continueButton: Locator;
|
||||||
|
|
||||||
|
|
||||||
|
constructor(page: Page) {
|
||||||
|
super(page);
|
||||||
|
|
||||||
|
this.provideVinManuallyButton = page.locator('label[for="VINManually"]');
|
||||||
|
this.provideLicensePlateButton = page.locator('label[for="licensePlate"]');
|
||||||
|
this.provideHomeAddressButton = page.locator('label[for="HomeAddress"]');
|
||||||
|
this.continueOnVinPopUpButton = page.locator('button:has-text("Continue")');
|
||||||
|
this.dontShareVinButton = page.getByRole('button', { name: "I would rather not share my VIN" });
|
||||||
|
|
||||||
|
this.yestoGlassQuestionButton = page.locator('label:has-text("Yes")');
|
||||||
|
this.notoGlassQuestionButton = page.locator('label:has-text("No")');
|
||||||
|
this.continueButton = page.locator('button[type="submit"].btn-success.nav-continue');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@step("HeritageProblemGlassQuestionsPage >> Handle VIN popup and answer glass question on heritage")
|
||||||
|
// Handles OEM scenario with vehicle that has only one glass question
|
||||||
|
async handleHeritageProblemGlassQuestionsPage(testData: Partial<ITestData>){
|
||||||
|
|
||||||
|
await this.dontShareVinButton.click();
|
||||||
|
await this.yestoGlassQuestionButton.click();
|
||||||
|
await this.continueButton.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import test, { expect, type Locator, type Page } from '@playwright/test';
|
import test, { expect, type Locator, type Page } from '@playwright/test';
|
||||||
import { BasePage } from './BasePage';
|
import { BasePage } from './BasePage';
|
||||||
|
import { ITestData } from 'framework/TestData';
|
||||||
|
|
||||||
export class HomePage extends BasePage {
|
export class HomePage extends BasePage {
|
||||||
|
|
||||||
|
|
@ -30,7 +31,7 @@ export class HomePage extends BasePage {
|
||||||
super(page);
|
super(page);
|
||||||
|
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.letsGetStartedButton = this.page.locator('.hero-content #zipCodeTextboxButton');
|
this.letsGetStartedButton = this.page.locator('#zipCodeTextboxButton');
|
||||||
this.cusmodalPopup = this.page.locator('#Cusmodalpopup');
|
this.cusmodalPopup = this.page.locator('#Cusmodalpopup');
|
||||||
this.closePopupButton = this.page.getByRole('button', { name: '×' });
|
this.closePopupButton = this.page.getByRole('button', { name: '×' });
|
||||||
|
|
||||||
|
|
@ -47,12 +48,13 @@ export class HomePage extends BasePage {
|
||||||
|
|
||||||
//Zip Entry
|
//Zip Entry
|
||||||
this.enterServiceZipTextBox = this.page.locator('#zipCodeTextbox');
|
this.enterServiceZipTextBox = this.page.locator('#zipCodeTextbox');
|
||||||
this.zipEntryLetsGetStartedButton = this.page.locator('#zipCodeTextboxButton');
|
this.zipEntryLetsGetStartedButton = this.page.locator('#zipCodeTextbox');
|
||||||
this.getQuoteAndScheduleButton = this.page.getByLabel('main').getByRole('link', { name: 'Get quote + schedule' });
|
this.getQuoteAndScheduleButton = this.page.getByLabel('main').getByRole('link', { name: 'Get quote + schedule' });
|
||||||
}
|
}
|
||||||
|
|
||||||
async goto() {
|
async goto(testData: Partial<ITestData>) {
|
||||||
await this.page.goto(process.env['BASE_URL']!);
|
const experimentUrlExtension = await this.buildExperimentUrl(testData);
|
||||||
|
await this.page.goto(process.env['BASE_URL']! + experimentUrlExtension);
|
||||||
}
|
}
|
||||||
|
|
||||||
async isCurrentVariant(): Promise<boolean> {
|
async isCurrentVariant(): Promise<boolean> {
|
||||||
|
|
@ -61,10 +63,11 @@ export class HomePage extends BasePage {
|
||||||
|
|
||||||
async letsGetStarted(zip: string, enterFunnelWithZip: boolean) {
|
async letsGetStarted(zip: string, enterFunnelWithZip: boolean) {
|
||||||
if (enterFunnelWithZip) {
|
if (enterFunnelWithZip) {
|
||||||
await this.letsGetStartedButton.evaluate((element, zip) => {
|
await this.zipEntryLetsGetStartedButton.fill(zip);
|
||||||
|
/* await this.letsGetStartedButton.evaluate((element, zip) => {
|
||||||
const currentHref = element.getAttribute('href') || '';
|
const currentHref = element.getAttribute('href') || '';
|
||||||
element.setAttribute('href', `${currentHref}&zipCode=${zip}`);
|
element.setAttribute('href', `${currentHref}?zipCode=${zip}`);
|
||||||
}, zip);
|
}, zip);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait until modal pop up opens and close pop up
|
// Wait until modal pop up opens and close pop up
|
||||||
|
|
@ -74,6 +77,4 @@ export class HomePage extends BasePage {
|
||||||
}
|
}
|
||||||
await this.letsGetStartedButton.click();
|
await this.letsGetStartedButton.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -81,9 +81,9 @@ export class LookupPage extends BasePage {
|
||||||
|
|
||||||
// Map of expected messages by lookup type
|
// Map of expected messages by lookup type
|
||||||
const expectedMessages = {
|
const expectedMessages = {
|
||||||
'address': "Your address didn't return a VIN match.Please re-enter the information below or provide your VIN in a different way.",
|
'address': "Your address didn't return a VIN match.Please re-enter the information below or provide your VIN in a different way.",
|
||||||
'license plate': "Your license plate didn’t return a VIN match.Please re-enter the information above or provide your VIN in a different way.",
|
'license plate': "Your license plate didn’t return a VIN match.Please re-enter the information above or provide your VIN in a different way.",
|
||||||
'VIN': "Your VIN didn’t return a vehicle matchPlease re-enter your VIN or we can look up your VIN for you.",
|
'VIN': "Your VIN didn’t return a vehicle matchPlease re-enter your VIN or we can look up your VIN for you.",
|
||||||
'ZIP code': "Your ZIP code didn't return a match.Please re-enter the information above or provide your VIN in a different way."
|
'ZIP code': "Your ZIP code didn't return a match.Please re-enter the information above or provide your VIN in a different way."
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -106,19 +106,19 @@ export class LookupPage extends BasePage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleZipValidation(testData: Partial<ITestData>, zip: string, lookupType: VehicleLookupType, alertFlags?: IAlertFlags): Promise<boolean> {
|
async handleZipValidation(testData: Partial<ITestData>): Promise<boolean> {
|
||||||
|
|
||||||
let { vehicleDamage } = testData;
|
let { customerDetails,vehicleDamage, vehicleDetails, alertFlags } = testData;
|
||||||
// Only proceed with validation if alertFlags is provided
|
// Only proceed with validation if alertFlags is provided
|
||||||
if (alertFlags) {
|
if (alertFlags) {
|
||||||
if (alertFlags.isUnserviceableZip) {
|
if (alertFlags.isUnserviceableZip) {
|
||||||
await this.checkForUnserviceableZipAlertMessage(zip);
|
await this.checkForUnserviceableZipAlertMessage(customerDetails!.address.postalCode!);
|
||||||
throw new TestSuccessAlert('Unserviceable ZIP validation successful.');
|
throw new TestSuccessAlert('Unserviceable ZIP validation successful.');
|
||||||
} else if (alertFlags.isInvalidZip) {
|
} else if (alertFlags.isInvalidZip) {
|
||||||
await this.checkForInvalidZipAlertMessage();
|
await this.checkForInvalidZipAlertMessage();
|
||||||
throw new TestSuccessAlert('Invalid ZIP validation successful.');
|
throw new TestSuccessAlert('Invalid ZIP validation successful.');
|
||||||
} else if (alertFlags.isVinNotFound) {
|
} else if (alertFlags.isVinNotFound) {
|
||||||
await this.checkForVinNotFoundAlertMessage(lookupType);
|
await this.checkForVinNotFoundAlertMessage(vehicleDetails!.vehicleLookupType!);
|
||||||
throw new TestSuccessAlert('Vin not found validation successful.');
|
throw new TestSuccessAlert('Vin not found validation successful.');
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ export class OrderConfirmationPage extends BasePage {
|
||||||
async validateOrderConfirmationPage(testData: Partial<ITestData>) {
|
async validateOrderConfirmationPage(testData: Partial<ITestData>) {
|
||||||
// Destructure data we use
|
// Destructure data we use
|
||||||
const { vehicleDetails, customerDetails, servicePackage, isCashInsuranceFlow,
|
const { vehicleDetails, customerDetails, servicePackage, isCashInsuranceFlow,
|
||||||
isPolicyFound, claimDetails, paymentDetails, isUseVehicleOnPolicy, paymentMethod, isPolicyUnverified } = testData;
|
isPolicyFound, claimDetails, paymentDetails, isUseVehicleOnPolicy, paymentMethod, isPolicyUnverified} = testData;
|
||||||
await this.serviceText.waitFor({ state: "visible" });
|
await this.serviceText.waitFor({ state: "visible" });
|
||||||
|
|
||||||
Soft.expect((await this.getActualAppointmentSummary()).map(item => item.toLowerCase())).toEqual((await this.getExpectedAppointmentSummary(testData)).map(item => item.toLowerCase()));
|
Soft.expect((await this.getActualAppointmentSummary()).map(item => item.toLowerCase())).toEqual((await this.getExpectedAppointmentSummary(testData)).map(item => item.toLowerCase()));
|
||||||
|
|
@ -108,7 +108,7 @@ export class OrderConfirmationPage extends BasePage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFormattedAppointmentDate(appointmentDate: string) {
|
/*async getFormattedAppointmentDate(appointmentDate: string) {
|
||||||
|
|
||||||
// Parse the original date
|
// Parse the original date
|
||||||
let parsedAppointmentDate = new Date(`${appointmentDate}` + 'T00:00:00');
|
let parsedAppointmentDate = new Date(`${appointmentDate}` + 'T00:00:00');
|
||||||
|
|
@ -116,6 +116,24 @@ export class OrderConfirmationPage extends BasePage {
|
||||||
// Format the new date as a string
|
// Format the new date as a string
|
||||||
let updatedAppointmentDate = parsedAppointmentDate.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' });
|
let updatedAppointmentDate = parsedAppointmentDate.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' });
|
||||||
return updatedAppointmentDate;
|
return updatedAppointmentDate;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
async getFormattedAppointmentDate(appointmentDate: string) {
|
||||||
|
let formattedAppointmentDate: string;
|
||||||
|
|
||||||
|
switch (true) {
|
||||||
|
case /^\d{4}-\d{2}-\d{2}$/.test(appointmentDate):
|
||||||
|
let parsedAppointmentDate = new Date(`${appointmentDate}` + 'T00:00:00');
|
||||||
|
formattedAppointmentDate = parsedAppointmentDate.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric' });
|
||||||
|
break;
|
||||||
|
case /[A-Za-z]+,\s+[A-Za-z]+\s+\d{1,2}/.test(appointmentDate):
|
||||||
|
formattedAppointmentDate = appointmentDate;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error('Unsupported date format: ' + appointmentDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return formattedAppointmentDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
async toggleOrderDetailsSection() {
|
async toggleOrderDetailsSection() {
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ export class PartQuestionsPage extends BasePage {
|
||||||
} else {
|
} else {
|
||||||
await expect(partQuestionOptions).not.toBeAttached();
|
await expect(partQuestionOptions).not.toBeAttached();
|
||||||
}
|
}
|
||||||
|
await this.selectPartQuestionResponses(partQuestions!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -65,7 +66,6 @@ export class PartQuestionsPage extends BasePage {
|
||||||
|
|
||||||
await this.validateProgressBar(ProgressBarPercentages.PartQuestionsPage);
|
await this.validateProgressBar(ProgressBarPercentages.PartQuestionsPage);
|
||||||
await this.validatePartQuestions(partQuestions!);
|
await this.validatePartQuestions(partQuestions!);
|
||||||
await this.selectPartQuestionResponses(partQuestions!);
|
|
||||||
await this.nextPage();
|
await this.nextPage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -487,7 +487,7 @@ export class PaymentMethodPage extends BasePage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFormattedAppointmentDate(appointmentDate: string) {
|
/*async getFormattedAppointmentDate(appointmentDate: string) {
|
||||||
|
|
||||||
// Parse the original date
|
// Parse the original date
|
||||||
let parsedAppointmentDate = new Date(`${appointmentDate}` + 'T00:00:00');
|
let parsedAppointmentDate = new Date(`${appointmentDate}` + 'T00:00:00');
|
||||||
|
|
@ -495,16 +495,48 @@ export class PaymentMethodPage extends BasePage {
|
||||||
// Format the new date as a string
|
// Format the new date as a string
|
||||||
let updatedAppointmentDate = parsedAppointmentDate.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
|
let updatedAppointmentDate = parsedAppointmentDate.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
|
||||||
return updatedAppointmentDate;
|
return updatedAppointmentDate;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
async getFormattedAppointmentDate(appointmentDate: string) {
|
||||||
|
let formattedAppointmentDate: Date;
|
||||||
|
const now = new Date();
|
||||||
|
|
||||||
|
switch (true) {
|
||||||
|
case /^\d{4}-\d{2}-\d{2}$/.test(appointmentDate):
|
||||||
|
formattedAppointmentDate = new Date(appointmentDate + 'T00:00:00');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case /[A-Za-z]+,\s+[A-Za-z]+\s+\d{1,2}/.test(appointmentDate):
|
||||||
|
const [, month, day] = appointmentDate.match(/[A-Za-z]+,\s+([A-Za-z]+)\s+(\d{1,2})/) || [];
|
||||||
|
formattedAppointmentDate = new Date(`${month} ${day}, ${now.getFullYear()}`);
|
||||||
|
if (formattedAppointmentDate < now) formattedAppointmentDate.setFullYear(now.getFullYear() + 1); // rollover
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Error('Unsupported date format: ' + appointmentDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return formattedAppointmentDate.toLocaleDateString('en-US', {
|
||||||
|
weekday: 'long',
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@step("PaymentMethodPage >> Select Payment Method: ")
|
@step("PaymentMethodPage >> Select Payment Method: ")
|
||||||
async handlePaymentMethodPage(testData: Partial<ITestData>) {
|
async handlePaymentMethodPage(testData: Partial<ITestData>) {
|
||||||
const { servicePackage, isRecalVehicle, paymentDetails } = testData;
|
const { servicePackage, isRecalVehicle, paymentDetails, isForcedOEM } = testData;
|
||||||
|
|
||||||
await this.validateProgressBar(ProgressBarPercentages.PaymentMethodPage);
|
await this.validateProgressBar(ProgressBarPercentages.PaymentMethodPage);
|
||||||
await this.validatePaymentDetailsPage(testData);
|
await this.validatePaymentDetailsPage(testData);
|
||||||
await this.ValidateAfterPayBreakOutSection();
|
await this.ValidateAfterPayBreakOutSection();
|
||||||
|
|
||||||
|
if (isForcedOEM) {
|
||||||
|
await this.validateOEMPart(isForcedOEM);
|
||||||
|
}
|
||||||
|
|
||||||
// Verify VAPS wipers on backend for standard and premium packages
|
// Verify VAPS wipers on backend for standard and premium packages
|
||||||
if (servicePackage === ServicePackage.Standard || servicePackage === ServicePackage.Premium) {
|
if (servicePackage === ServicePackage.Standard || servicePackage === ServicePackage.Premium) {
|
||||||
await this.verifyVAPS();
|
await this.verifyVAPS();
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ export class PaypalPage extends BasePage {
|
||||||
this.paypalLoginButton = page.getByRole('button', { name: 'Log In', exact: true });
|
this.paypalLoginButton = page.getByRole('button', { name: 'Log In', exact: true });
|
||||||
this.completePurchaseButton = page.getByTestId('submit-button-initial')
|
this.completePurchaseButton = page.getByTestId('submit-button-initial')
|
||||||
this.payWithRadioButton = page.getByRole('button').filter({ hasText: 'Pay with' });
|
this.payWithRadioButton = page.getByRole('button').filter({ hasText: 'Pay with' });
|
||||||
this.payButton = page.locator('#one-time-cta');
|
this.payButton = page.locator('footer #one-time-cta');
|
||||||
this.tryAnotherWayButton = page.getByRole('button', { name: 'Try another way' });
|
this.tryAnotherWayButton = page.getByRole('button', { name: 'Try another way' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,6 +41,8 @@ export class PaypalPage extends BasePage {
|
||||||
await this.paypalLoginButton.click();
|
await this.paypalLoginButton.click();
|
||||||
await this.completePurchaseButton.click();
|
await this.completePurchaseButton.click();
|
||||||
} else {
|
} else {
|
||||||
|
await this.usernameTextBox.waitFor({ state: 'visible' });
|
||||||
|
await this.page.screenshot({ path: `test-results\\ortoni-data\\paypal-username-${Date.now()}.png`, fullPage: true });
|
||||||
await this.usernameTextBox.fill(paymentDetails.username!);
|
await this.usernameTextBox.fill(paymentDetails.username!);
|
||||||
await this.nextButton.click();
|
await this.nextButton.click();
|
||||||
await this.tryAnotherWayButton.click();
|
await this.tryAnotherWayButton.click();
|
||||||
|
|
@ -48,8 +50,8 @@ export class PaypalPage extends BasePage {
|
||||||
await this.passwordTextBox.fill(paymentDetails.password!);
|
await this.passwordTextBox.fill(paymentDetails.password!);
|
||||||
await this.paypalLoginButton.click();
|
await this.paypalLoginButton.click();
|
||||||
await this.payWithRadioButton.click();
|
await this.payWithRadioButton.click();
|
||||||
await this.page.waitForTimeout(2000); // wait for 2 seconds to ensure the Pay button is clickable
|
await this.page.waitForTimeout(2000);
|
||||||
await this.payButton.dblclick();
|
await this.payButton.dblclick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -35,6 +35,11 @@ export class SchedulePage extends BasePage {
|
||||||
readonly timeSlots: Locator;
|
readonly timeSlots: Locator;
|
||||||
readonly allDayDropOffButton: Locator;
|
readonly allDayDropOffButton: Locator;
|
||||||
readonly pickATimeButton: Locator;
|
readonly pickATimeButton: Locator;
|
||||||
|
readonly mobileFirstModalCloseButton: Locator;
|
||||||
|
readonly yesButtonRecalAckModal: Locator;
|
||||||
|
readonly noButtonRecalAckModal: Locator;
|
||||||
|
readonly continueButtonRecalAckModal: Locator;
|
||||||
|
readonly mobileFirstModal: Locator;
|
||||||
|
|
||||||
constructor(page: Page) {
|
constructor(page: Page) {
|
||||||
super(page);
|
super(page);
|
||||||
|
|
@ -65,6 +70,11 @@ export class SchedulePage extends BasePage {
|
||||||
this.viewMoreDatesLink = this.page.getByText(/View more dates/).first();
|
this.viewMoreDatesLink = this.page.getByText(/View more dates/).first();
|
||||||
this.appointmentDuration = this.page.locator('.duration-text-block');
|
this.appointmentDuration = this.page.locator('.duration-text-block');
|
||||||
this.timeSlots = this.page.locator('fieldset:has(>legend#chooseTimeSlot) label').filter({ visible: true});
|
this.timeSlots = this.page.locator('fieldset:has(>legend#chooseTimeSlot) label').filter({ visible: true});
|
||||||
|
this.mobileFirstModalCloseButton = this.page.locator('#mobile-first-modal-container .btn-close');
|
||||||
|
this.yesButtonRecalAckModal = this.page.locator("label[buttonlabel='Yes']");
|
||||||
|
this.noButtonRecalAckModal = this.page.locator("label[buttonlabel='No']");
|
||||||
|
this.continueButtonRecalAckModal = this.page.locator("#recal-ack-modal-container .modal-footer button");
|
||||||
|
this.mobileFirstModal = this.page.locator("#mobile-first-modal-container");
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectLocation(testData: Partial<ITestData>) {
|
async selectLocation(testData: Partial<ITestData>) {
|
||||||
|
|
@ -96,6 +106,7 @@ export class SchedulePage extends BasePage {
|
||||||
await this.safeliteShopsList.first().click();
|
await this.safeliteShopsList.first().click();
|
||||||
// Click the save location button
|
// Click the save location button
|
||||||
await this.saveLocationButton.click();
|
await this.saveLocationButton.click();
|
||||||
|
await this.waitForPageOrComponentload();
|
||||||
}
|
}
|
||||||
|
|
||||||
// await this.inShopButton.click();
|
// await this.inShopButton.click();
|
||||||
|
|
@ -225,12 +236,42 @@ export class SchedulePage extends BasePage {
|
||||||
return formattedTimeSlot;
|
return formattedTimeSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async handleMobileFirstPopUp(testData: Partial<ITestData>) {
|
||||||
|
|
||||||
|
const { customerDetails } = testData;
|
||||||
|
customerDetails!.apptDate = (await this.mobileFirstModal.locator('li', { hasText: 'Date:' }).innerText()).replace('Date:', '').trim();
|
||||||
|
customerDetails!.apptTime = (await this.mobileFirstModal.locator('li', { hasText: 'Appointment window:' }).innerText()).replace('Appointment window:', 'arriving between').trim();
|
||||||
|
customerDetails!.apptDuration = (await this.mobileFirstModal.locator('li', { hasText: 'Estimate length:' }).innerText()).replace('Estimate length:', '').trim();
|
||||||
|
|
||||||
|
await this.mobileFirstModal.getByRole("button", { name: 'Confirm appointment'}).click();
|
||||||
|
}
|
||||||
|
|
||||||
@step("SchedulePage >> Schedule appointment: ")
|
@step("SchedulePage >> Schedule appointment: ")
|
||||||
async handleSchedulePage(testData: Partial<ITestData>) {
|
async handleSchedulePage(testData: Partial<ITestData>) {
|
||||||
const { appointmentDetails } = testData;
|
const { appointmentDetails, isCanNotRecal, experiments, handleMobileFirstModal } = testData;
|
||||||
|
await this.waitForPageOrComponentload();
|
||||||
await this.validateProgressBar(ProgressBarPercentages.SchedulePage);
|
await this.validateProgressBar(ProgressBarPercentages.SchedulePage);
|
||||||
|
|
||||||
|
if (handleMobileFirstModal) {
|
||||||
|
return await this.handleMobileFirstPopUp(testData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (experiments?.isMobileFirst && await this.mobileFirstModalCloseButton.isVisible()) {
|
||||||
|
await this.mobileFirstModalCloseButton.click();
|
||||||
|
}
|
||||||
await this.selectLocation(testData);
|
await this.selectLocation(testData);
|
||||||
|
|
||||||
|
if (experiments?.isMobileFirst && await this.mobileFirstModalCloseButton.isVisible({timeout: 5000})) {
|
||||||
|
await this.page.waitForTimeout(1000);
|
||||||
|
await this.mobileFirstModalCloseButton.dblclick();
|
||||||
|
}
|
||||||
|
|
||||||
await this.scheduleFirstAppointment(testData);
|
await this.scheduleFirstAppointment(testData);
|
||||||
|
|
||||||
await this.nextPage();
|
await this.nextPage();
|
||||||
|
if (isCanNotRecal) {
|
||||||
|
await this.yesButtonRecalAckModal.click();
|
||||||
|
await this.continueButtonRecalAckModal.click();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ export class ServicePackagesPage extends BasePage {
|
||||||
this.promoCodeTextbox = this.page.getByLabel('Enter a promo code');
|
this.promoCodeTextbox = this.page.getByLabel('Enter a promo code');
|
||||||
this.applyPromoButton = this.page.getByRole('button', { name: 'Apply promo code' });
|
this.applyPromoButton = this.page.getByRole('button', { name: 'Apply promo code' });
|
||||||
this.repeatedClicksModalCloseButton = this.page.locator('.QSISlider').locator('img[src*=\'close\']');
|
this.repeatedClicksModalCloseButton = this.page.locator('.QSISlider').locator('img[src*=\'close\']');
|
||||||
this.afterPayBanner = this.page.locator('#afterpay-banner');
|
this.afterPayBanner = this.page.locator('div.afterpay-modal-banner');
|
||||||
this.glassOnlypackagePrice = this.page.locator('fieldset:has(legend#ServicePackageQuestion) label').filter({ hasText: 'Glass service only' }).locator('.pricing-info');
|
this.glassOnlypackagePrice = this.page.locator('fieldset:has(legend#ServicePackageQuestion) label').filter({ hasText: 'Glass service only' }).locator('.pricing-info');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -298,6 +298,10 @@ export class ServicePackagesPage extends BasePage {
|
||||||
await this.mockScheduleResponseForEarlyBird(customerDetails!);
|
await this.mockScheduleResponseForEarlyBird(customerDetails!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (testData.mockFirstInshopCallNoSchedule) {
|
||||||
|
await this.mockScheduleResponseForFirstInshopCallNoSchedule(testData.customerDetails!);
|
||||||
|
}
|
||||||
|
|
||||||
await this.nextPage();
|
await this.nextPage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -12,9 +12,9 @@ export class ServiceZipPage extends LookupPage {
|
||||||
|
|
||||||
@step("ZipLookupPage >> Lookup by service ZIP: ")
|
@step("ZipLookupPage >> Lookup by service ZIP: ")
|
||||||
async handleServiceZipPage(testData: Partial<ITestData>) {
|
async handleServiceZipPage(testData: Partial<ITestData>) {
|
||||||
const { customerDetails, vehicleDetails, alertFlags } = testData;
|
const { customerDetails } = testData;
|
||||||
await this.validateProgressBar(ProgressBarPercentages.ServiceZipPage);
|
await this.validateProgressBar(ProgressBarPercentages.ServiceZipPage);
|
||||||
await this.enterZip(customerDetails!.address.postalCode!);
|
await this.enterZip(customerDetails!.address.postalCode!);
|
||||||
await this.handleZipValidation(testData, customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
|
await this.handleZipValidation(testData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -29,10 +29,10 @@ export class VehicleLookupAddressPage extends LookupPage {
|
||||||
|
|
||||||
@step("VehicleLookupAddressPage >> Lookup by address: ")
|
@step("VehicleLookupAddressPage >> Lookup by address: ")
|
||||||
async handleVehicleLookupAddressPage(testData: Partial<ITestData>) {
|
async handleVehicleLookupAddressPage(testData: Partial<ITestData>) {
|
||||||
const { customerDetails, vehicleDetails, alertFlags } = testData;
|
const { customerDetails, vehicleDetails } = testData;
|
||||||
|
|
||||||
await this.validateProgressBar(ProgressBarPercentages.VehicleLookupAddressPage);
|
await this.validateProgressBar(ProgressBarPercentages.VehicleLookupAddressPage);
|
||||||
await this.lookupVehicleByAddress(customerDetails!, vehicleDetails!);
|
await this.lookupVehicleByAddress(customerDetails!, vehicleDetails!);
|
||||||
await this.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
|
await this.handleZipValidation(testData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -34,11 +34,11 @@ export class VehicleLookupLicensePage extends LookupPage {
|
||||||
|
|
||||||
@step("VehicleLookupLicensePage >> Lookup by license plate: ")
|
@step("VehicleLookupLicensePage >> Lookup by license plate: ")
|
||||||
async handleVehicleLookupLicensePage(testData: Partial<ITestData>) {
|
async handleVehicleLookupLicensePage(testData: Partial<ITestData>) {
|
||||||
const { customerDetails, vehicleDetails, alertFlags } = testData;
|
const { customerDetails, vehicleDetails } = testData;
|
||||||
|
|
||||||
await this.validateProgressBar(ProgressBarPercentages.VehicleLookupLicensePage);
|
await this.validateProgressBar(ProgressBarPercentages.VehicleLookupLicensePage);
|
||||||
await this.enterPlateDetails(vehicleDetails!);
|
await this.enterPlateDetails(vehicleDetails!);
|
||||||
await this.enterZip(customerDetails!.address.postalCode!);
|
await this.enterZip(customerDetails!.address.postalCode!);
|
||||||
await this.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
|
await this.handleZipValidation(testData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -24,11 +24,11 @@ export class VinLookupPage extends LookupPage {
|
||||||
|
|
||||||
@step("VinLookupPage >> Lookup by VIN: ")
|
@step("VinLookupPage >> Lookup by VIN: ")
|
||||||
async handleVehicleLookupVinPage(testData: Partial<ITestData>) {
|
async handleVehicleLookupVinPage(testData: Partial<ITestData>) {
|
||||||
const { customerDetails, vehicleDetails, alertFlags } = testData;
|
const { customerDetails, vehicleDetails } = testData;
|
||||||
let vin: string;
|
let vin: string;
|
||||||
|
|
||||||
if (Array.isArray(vehicleDetails?.vin)) {
|
if (Array.isArray(vehicleDetails?.vin)) {
|
||||||
vin = vehicleDetails.vin[0];
|
vin = vehicleDetails!.vin[0];
|
||||||
} else {
|
} else {
|
||||||
vin = vehicleDetails?.vin || '';
|
vin = vehicleDetails?.vin || '';
|
||||||
}
|
}
|
||||||
|
|
@ -36,6 +36,6 @@ export class VinLookupPage extends LookupPage {
|
||||||
await this.validateProgressBar(ProgressBarPercentages.VinLookupPage);
|
await this.validateProgressBar(ProgressBarPercentages.VinLookupPage);
|
||||||
await this.enterVin(vin);
|
await this.enterVin(vin);
|
||||||
await this.enterZip(customerDetails!.address.postalCode!);
|
await this.enterZip(customerDetails!.address.postalCode!);
|
||||||
await this.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
|
await this.handleZipValidation(testData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -57,7 +57,7 @@ export class AddressForm extends BasePage {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
await this.page.hover(".pac-container .pac-item");
|
await this.addressSuggestionList.hover();
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
await this.addressSuggestionList.click(); // Select the first suggestion
|
await this.addressSuggestionList.click(); // Select the first suggestion
|
||||||
//await this.streetAddressTextBox.press('Tab'); // Move focus to ZIP code field
|
//await this.streetAddressTextBox.press('Tab'); // Move focus to ZIP code field
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ export default defineConfig({
|
||||||
/* Retry on CI only */
|
/* Retry on CI only */
|
||||||
retries: process.env.CI ? 1 : 0,
|
retries: process.env.CI ? 1 : 0,
|
||||||
/* Opt out of parallel tests on CI. */
|
/* Opt out of parallel tests on CI. */
|
||||||
workers: process.env.CI ? 4 : 5,
|
workers: process.env.CI ? 4 : 3,
|
||||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||||
reporter: process.env.CI? [
|
reporter: process.env.CI? [
|
||||||
['junit'],
|
['junit'],
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { Page } from "@playwright/test";
|
import { Browser, Page } from "@playwright/test";
|
||||||
import { addSmokeTagToRandomTest, Flow, ServiceLocation } from 'safelite-playwright-core';
|
import { addSmokeTagToRandomTest, Flow, ServiceLocation } from 'safelite-playwright-core';
|
||||||
import { ValidationOptions } from 'safelite-playwright-core';
|
import { ValidationOptions } from 'safelite-playwright-core';
|
||||||
import heavyTruckTests from "./alert-validation/alert0001_HeavyTruck";
|
import heavyTruckTests from "./alert-validation/alert0001_HeavyTruck";
|
||||||
|
|
@ -18,6 +18,7 @@ import cashReplaceGlassLicensePlateLookupInshopPaypalTests from "./CashReplaceGl
|
||||||
import { ApiResponseInterceptUtil } from 'safelite-playwright-core';
|
import { ApiResponseInterceptUtil } from 'safelite-playwright-core';
|
||||||
import cashReplaceGlassPromoInshopTests from "./CashReplaceGlassPromoInshop";
|
import cashReplaceGlassPromoInshopTests from "./CashReplaceGlassPromoInshop";
|
||||||
import cashReplaceMultiGlassPromoInshopTests from "./CashReplaceMultiGlassPromoInshop";
|
import cashReplaceMultiGlassPromoInshopTests from "./CashReplaceMultiGlassPromoInshop";
|
||||||
|
import cashReplaceStaticInshopTests from "./CashReplaceStaticInshop";
|
||||||
import cashReplaceRainDefensePromoInshopTests from "./CashReplaceRainDefensePromoInshop";
|
import cashReplaceRainDefensePromoInshopTests from "./CashReplaceRainDefensePromoInshop";
|
||||||
import cashReplaceSafeliteCanNotRecalMobileTests from "./CashReplaceSafeliteCanNotRecalMobile";
|
import cashReplaceSafeliteCanNotRecalMobileTests from "./CashReplaceSafeliteCanNotRecalMobile";
|
||||||
import cashReplaceVinMobileTests from "./CashReplaceVinMobile";
|
import cashReplaceVinMobileTests from "./CashReplaceVinMobile";
|
||||||
|
|
@ -28,8 +29,10 @@ import insuranceITAC21stCenturyTests from "./InsuranceITAC21stCentury";
|
||||||
import insuranceGeicoTests from "./InsuranceGeico";
|
import insuranceGeicoTests from "./InsuranceGeico";
|
||||||
import insuranceITACOptimizedPriceValidationAllStateTests from "./InsuranceITACOptimizedPriceValidationAllState";
|
import insuranceITACOptimizedPriceValidationAllStateTests from "./InsuranceITACOptimizedPriceValidationAllState";
|
||||||
import insuranceNoCompProgressiveTests from "./InsuranceNoCompProgressive";
|
import insuranceNoCompProgressiveTests from "./InsuranceNoCompProgressive";
|
||||||
|
import insuranceOEMAllstateTests from "./InsuranceOEMAllState";
|
||||||
import cashRepairInShopAfterPayTests from "./CashRepairInShopAfterPay";
|
import cashRepairInShopAfterPayTests from "./CashRepairInShopAfterPay";
|
||||||
import cashRepairInShopPayPalTests from "./CashRepairInShopPayPal";
|
import cashRepairInShopPayPalTests from "./CashRepairInShopPayPal";
|
||||||
|
import cashReplaceMobileFirstModalTests from "./CashReplaceMobileFirstModal";
|
||||||
import cashReplaceMultiSlidingGlassDropoffTests from "./CashReplaceMultiSlidingGlassDropoff";
|
import cashReplaceMultiSlidingGlassDropoffTests from "./CashReplaceMultiSlidingGlassDropoff";
|
||||||
import cashReplaceMultiGlassMobileTests from "./CashReplaceMultiGlassMobile";
|
import cashReplaceMultiGlassMobileTests from "./CashReplaceMultiGlassMobile";
|
||||||
import { getTestObject, TestCase, prepareTest, RuleEngine, TestInfo } from 'framework/Typedefs';
|
import { getTestObject, TestCase, prepareTest, RuleEngine, TestInfo } from 'framework/Typedefs';
|
||||||
|
|
@ -60,32 +63,35 @@ addSmokeTagToRandomTest(splitWindshieldTests);
|
||||||
|
|
||||||
// Standard test scenarios
|
// Standard test scenarios
|
||||||
const allStandardTests = [
|
const allStandardTests = [
|
||||||
{name: "CashRepairMobileCreditCard", tests: cashRepairMobileCCTests},
|
{ name: "CashRepairMobileCreditCard", tests: cashRepairMobileCCTests },
|
||||||
{name: "CashRepairInShopAfterPay", tests: cashRepairInShopAfterPayTests},
|
{ name: "CashRepairInShopAfterPay", tests: cashRepairInShopAfterPayTests },
|
||||||
{name: "CashRepairInShopPayPal", tests: cashRepairInShopPayPalTests},
|
{ name: "CashRepairInShopPayPal", tests: cashRepairInShopPayPalTests },
|
||||||
{name: "CashReplaceDynamicRecalMobile", tests: cashReplaceDynamicRecalMobileTests},
|
{ name: "CashReplaceDynamicRecalMobile", tests: cashReplaceDynamicRecalMobileTests },
|
||||||
{name: "CashReplaceGlassAddressLookupInshopAfterPay", tests: cashReplaceGlassAddressLookupInshopAfterPayTests},
|
{ name: "CashReplaceGlassAddressLookupInshopAfterPay", tests: cashReplaceGlassAddressLookupInshopAfterPayTests },
|
||||||
{name: "CashReplaceGlassLicensePlateLookupInshopPaypal", tests: cashReplaceGlassLicensePlateLookupInshopPaypalTests},
|
{ name: "CashReplaceGlassLicensePlateLookupInshopPaypal", tests: cashReplaceGlassLicensePlateLookupInshopPaypalTests },
|
||||||
{name: "CashReplaceGlassPromoInShop", tests: cashReplaceGlassPromoInshopTests},
|
{ name: "CashReplaceGlassPromoInShop", tests: cashReplaceGlassPromoInshopTests },
|
||||||
{name: "CashReplaceMultiGlassPromoInShop", tests: cashReplaceMultiGlassPromoInshopTests},
|
{ name: "CashReplaceMultiGlassPromoInShop", tests: cashReplaceMultiGlassPromoInshopTests },
|
||||||
{name: "CashReplaceMultiSlidingGlassDropoff",tests: cashReplaceMultiSlidingGlassDropoffTests},
|
{ name: "CashReplaceMultiSlidingGlassDropoff", tests: cashReplaceMultiSlidingGlassDropoffTests },
|
||||||
{name: "CashReplaceMultiGlassMobile",tests: cashReplaceMultiGlassMobileTests},
|
{ name: "CashReplaceMultiGlassMobile", tests: cashReplaceMultiGlassMobileTests },
|
||||||
{name: "CashReplaceRainDefensePromoInshop", tests: cashReplaceRainDefensePromoInshopTests},
|
{ name: "CashReplaceRainDefensePromoInshop", tests: cashReplaceRainDefensePromoInshopTests },
|
||||||
{name: "CashReplaceSafeliteCanNotRecalMobile", tests: cashReplaceSafeliteCanNotRecalMobileTests},
|
{ name: "CashReplaceSafeliteCanNotRecalMobile", tests: cashReplaceSafeliteCanNotRecalMobileTests },
|
||||||
{name: "CashReplaceVinMobile", tests: cashReplaceVinMobileTests},
|
{ name: "CashReplaceVinMobile", tests: cashReplaceVinMobileTests },
|
||||||
{name: "CashReplaceWiperDropoff", tests: cashReplaceWiperDropoffTests},
|
{ name: "CashReplaceWiperDropoff", tests: cashReplaceWiperDropoffTests },
|
||||||
{name: "CashReplaceWiperPromoInshop", tests: cashReplaceWiperPromoInShopTests},
|
{ name: "CashReplaceStaticInshop", tests: cashReplaceStaticInshopTests },
|
||||||
{name: "CashReplaceSwitchToInsuranceProgressiveNoComp", tests: cashReplaceSwitchToInsuranceProgressiveNoCompTests},
|
{ name: "CashReplaceWiperPromoInshop", tests: cashReplaceWiperPromoInShopTests },
|
||||||
|
{ name: "CashReplaceSwitchToInsuranceProgressiveNoComp", tests: cashReplaceSwitchToInsuranceProgressiveNoCompTests },
|
||||||
|
{ name: "CashReplaceMobileFirstModal", tests: cashReplaceMobileFirstModalTests },
|
||||||
// TODO: Uncomment when QA is ready to run heavy truck tests
|
// TODO: Uncomment when QA is ready to run heavy truck tests
|
||||||
// {name: "CashReplaceSplitWindshield", tests: CashReplaceSplitWindshieldTests},
|
// {name: "CashReplaceSplitWindshield", tests: CashReplaceSplitWindshieldTests},
|
||||||
{name: "InsuranceAcuityPaypal", tests: insuranceAcuityPaypalTests},
|
{ name: "InsuranceAcuityPaypal", tests: insuranceAcuityPaypalTests },
|
||||||
{name: "InsuranceITAC21stCentury", tests: insuranceITAC21stCenturyTests},
|
{ name: "InsuranceITAC21stCentury", tests: insuranceITAC21stCenturyTests },
|
||||||
{name: "InsuranceNoCompProgressive", tests: insuranceNoCompProgressiveTests},
|
{ name: "InsuranceNoCompProgressive", tests: insuranceNoCompProgressiveTests },
|
||||||
// {name: "InsuranceBigTruckVerified", tests: insuranceBigTruckVerifiedTests},
|
// {name: "InsuranceBigTruckVerified", tests: insuranceBigTruckVerifiedTests},
|
||||||
{name: "InsuranceUnverified", tests: insuranceUnverifiedTests},
|
{ name: "InsuranceOEMAllstate", tests: insuranceOEMAllstateTests },
|
||||||
|
{ name: "InsuranceUnverified", tests: insuranceUnverifiedTests },
|
||||||
// {name: "InsuranceGeico", tests: insuranceGeicoTests},
|
// {name: "InsuranceGeico", tests: insuranceGeicoTests},
|
||||||
// {name: "InsuranceITACOptimizedPriceValidationAllState", tests: insuranceITACOptimizedPriceValidationAllStateTests}
|
// {name: "InsuranceITACOptimizedPriceValidationAllState", tests: insuranceITACOptimizedPriceValidationAllStateTests}
|
||||||
{name: "InsuranceMeemicNearSchoolVerified", tests: insuranceMeemicNearSchoolVerifiedTests},
|
{ name: "InsuranceMeemicNearSchoolVerified", tests: insuranceMeemicNearSchoolVerifiedTests },
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -138,13 +144,13 @@ async function run(page: Page, testInfo: TestInfo): Promise<void> {
|
||||||
try {
|
try {
|
||||||
await testInfo.testCase.setup();
|
await testInfo.testCase.setup();
|
||||||
testInfo.testCase.setupPages(page, createTestPages);
|
testInfo.testCase.setupPages(page, createTestPages);
|
||||||
await testInfo.testCase.pages.homePage.goto();
|
await testInfo.testCase.pages.homePage.goto(testInfo.testCase.testData);
|
||||||
await runWorkflow(page, testInfo.testCase);
|
await runWorkflow(page, testInfo.testCase);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Catch successful alert tests and log message
|
// Catch successful alert tests and log message
|
||||||
if (error instanceof TestSuccessAlert) {
|
if (error instanceof TestSuccessAlert) {
|
||||||
console.log(error.message);
|
console.log(error.message);
|
||||||
// Catch and throw other errors
|
// Catch and throw other errors
|
||||||
} else {
|
} else {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
@ -173,11 +179,11 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
page.on('response', apiResponseInterceptUtil.handleInterceptResponse);
|
page.on('response', apiResponseInterceptUtil.handleInterceptResponse);
|
||||||
|
|
||||||
// Destructure test data for easier access
|
// Destructure test data for easier access
|
||||||
const {
|
const {
|
||||||
paymentMethod, customerDetails, vehicleDetails, vehicleDamage,
|
paymentMethod, customerDetails, vehicleDetails, vehicleDamage,
|
||||||
paymentDetails, partQuestions, isEnterFunnelWithZip, capabilityQuestions,
|
paymentDetails, partQuestions, isEnterFunnelWithZip, capabilityQuestions,
|
||||||
vehiclePartQuestions, moldingQuestions, isSkipEstimatePage
|
vehiclePartQuestions, moldingQuestions, isSkipEstimatePage
|
||||||
} = testCase.testData;
|
} = testCase.testData;
|
||||||
|
|
||||||
// Check if the vehicle damage includes a windshield crack
|
// Check if the vehicle damage includes a windshield crack
|
||||||
const hasWindshieldCrack = vehicleDamage!.some(damage =>
|
const hasWindshieldCrack = vehicleDamage!.some(damage =>
|
||||||
|
|
@ -191,7 +197,7 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
//============================= TEST WORKFLOW STEPS =============================
|
//============================= TEST WORKFLOW STEPS =============================
|
||||||
|
|
||||||
// Use Environment Variable to decide whether or not we want to skip content site aka home page
|
// Use Environment Variable to decide whether or not we want to skip content site aka home page
|
||||||
if (process.env.SKIP_CONTENT_SITE == "false") {
|
if (process.env.SKIP_CONTENT_SITE == "false") {
|
||||||
await test.step('HomePage >> Lets Get Started', async () => {
|
await test.step('HomePage >> Lets Get Started', async () => {
|
||||||
let homePage = testCase.pages.homePage;
|
let homePage = testCase.pages.homePage;
|
||||||
console.log(`Customer for this test: ${customerDetails?.firstName} ${customerDetails?.lastName}`);
|
console.log(`Customer for this test: ${customerDetails?.firstName} ${customerDetails?.lastName}`);
|
||||||
|
|
@ -209,6 +215,16 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
console.log(`Customer for this test: ${customerDetails?.firstName} ${customerDetails?.lastName}`);
|
console.log(`Customer for this test: ${customerDetails?.firstName} ${customerDetails?.lastName}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (page.url().includes('ServiceDetails.aspx')) {
|
||||||
|
// Take a screenshot for diagnostics
|
||||||
|
await page.screenshot({ path: `test-results\\ortoni-data\\service-details-detected-${Date.now()}.png`, fullPage: true });
|
||||||
|
console.log("ServiceDetails.aspx detected");
|
||||||
|
await page.goBack();
|
||||||
|
await page.reload();
|
||||||
|
let homePage = testCase.pages.homePage;
|
||||||
|
await homePage.letsGetStarted(customerDetails?.address.postalCode!, !!isEnterFunnelWithZip!);
|
||||||
|
}
|
||||||
|
|
||||||
// Handle vehicle selection page
|
// Handle vehicle selection page
|
||||||
let vehicleSelectionPage = testCase.pages.vehicleSelectionPage;
|
let vehicleSelectionPage = testCase.pages.vehicleSelectionPage;
|
||||||
await vehicleSelectionPage.handleVehicleSelectionPage(testCase.testData);
|
await vehicleSelectionPage.handleVehicleSelectionPage(testCase.testData);
|
||||||
|
|
@ -221,24 +237,24 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
if (hasWindshieldCrack && !isSkipEstimatePage) {
|
if (hasWindshieldCrack && !isSkipEstimatePage) {
|
||||||
let estimatePage = testCase.pages.estimatePage;
|
let estimatePage = testCase.pages.estimatePage;
|
||||||
await estimatePage.handleEstimatePage(testCase.testData);
|
await estimatePage.handleEstimatePage(testCase.testData);
|
||||||
|
|
||||||
// Handle different vehicle lookup methods
|
// Handle different vehicle lookup methods
|
||||||
switch (vehicleDetails!.vehicleLookupType!) {
|
switch (vehicleDetails!.vehicleLookupType!) {
|
||||||
case VehicleLookupType.Address:
|
case VehicleLookupType.Address:
|
||||||
let vehicleLookupAddressPage = testCase.pages.vehicleLookupAddressPage;
|
let vehicleLookupAddressPage = testCase.pages.vehicleLookupAddressPage;
|
||||||
await vehicleLookupAddressPage.handleVehicleLookupAddressPage(testCase.testData);
|
await vehicleLookupAddressPage.handleVehicleLookupAddressPage(testCase.testData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VehicleLookupType.LicensePlateNumber:
|
case VehicleLookupType.LicensePlateNumber:
|
||||||
let vehicleLookupLicensePage = testCase.pages.vehicleLookupLicensePage;
|
let vehicleLookupLicensePage = testCase.pages.vehicleLookupLicensePage;
|
||||||
await vehicleLookupLicensePage.handleVehicleLookupLicensePage(testCase.testData);
|
await vehicleLookupLicensePage.handleVehicleLookupLicensePage(testCase.testData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VehicleLookupType.Vin:
|
case VehicleLookupType.Vin:
|
||||||
let vinLookupPage = testCase.pages.vinLookupPage;
|
let vinLookupPage = testCase.pages.vinLookupPage;
|
||||||
await vinLookupPage.handleVehicleLookupVinPage(testCase.testData);
|
await vinLookupPage.handleVehicleLookupVinPage(testCase.testData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VehicleLookupType.Zip:
|
case VehicleLookupType.Zip:
|
||||||
let serviceZipPage = testCase.pages.serviceZipPage;
|
let serviceZipPage = testCase.pages.serviceZipPage;
|
||||||
await serviceZipPage.handleServiceZipPage(testCase.testData);
|
await serviceZipPage.handleServiceZipPage(testCase.testData);
|
||||||
|
|
@ -255,7 +271,7 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
let partQuestionsPage = testCase.pages.partQuestionsPage;
|
let partQuestionsPage = testCase.pages.partQuestionsPage;
|
||||||
await partQuestionsPage.handlePartQuestionsPage(testCase.testData);
|
await partQuestionsPage.handlePartQuestionsPage(testCase.testData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle molding questions if applicable
|
// Handle molding questions if applicable
|
||||||
if (moldingQuestions && moldingQuestions.length > 0) {
|
if (moldingQuestions && moldingQuestions.length > 0) {
|
||||||
let moldingQuestionsPage = testCase.pages.moldingQuestionsPage;
|
let moldingQuestionsPage = testCase.pages.moldingQuestionsPage;
|
||||||
|
|
@ -279,14 +295,14 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
await servicePackagesPage.handleServicePackagePage(testCase.testData);
|
await servicePackagesPage.handleServicePackagePage(testCase.testData);
|
||||||
|
|
||||||
//============================= INSURANCE FLOW =============================`
|
//============================= INSURANCE FLOW =============================`
|
||||||
|
|
||||||
// Insurance flow - if user selected Insurance as Payment Method
|
// Insurance flow - if user selected Insurance as Payment Method
|
||||||
if (paymentMethod == PaymentMethod.Insurance) {
|
if (paymentMethod == PaymentMethod.Insurance) {
|
||||||
await handleInsuranceFlow(testCase);
|
await handleInsuranceFlow(testCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================= SERVICE SCHEDULING =============================
|
//============================= SERVICE SCHEDULING =============================
|
||||||
|
|
||||||
// Select service location
|
// Select service location
|
||||||
// let serviceLocationPage = testCase.pages.serviceLocationPage;
|
// let serviceLocationPage = testCase.pages.serviceLocationPage;
|
||||||
// await serviceLocationPage.handleServiceLocationPage(testCase.testData);
|
// await serviceLocationPage.handleServiceLocationPage(testCase.testData);
|
||||||
|
|
@ -305,7 +321,7 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
await contactDetailsPage.handleContactDetailsPage(testCase.testData);
|
await contactDetailsPage.handleContactDetailsPage(testCase.testData);
|
||||||
|
|
||||||
//============================= PAYMENT PROCESSING =============================
|
//============================= PAYMENT PROCESSING =============================
|
||||||
|
|
||||||
// Handle payment
|
// Handle payment
|
||||||
let paymentMethodPage = testCase.pages.paymentMethodPage;
|
let paymentMethodPage = testCase.pages.paymentMethodPage;
|
||||||
await paymentMethodPage.handlePaymentMethodPage(testCase.testData);
|
await paymentMethodPage.handlePaymentMethodPage(testCase.testData);
|
||||||
|
|
@ -316,84 +332,90 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================= ORDER CONFIRMATION =============================
|
//============================= ORDER CONFIRMATION =============================
|
||||||
|
|
||||||
// Validate order confirmation
|
// Validate order confirmation
|
||||||
let orderConfirmationPage = testCase.pages.orderConfirmationPage;
|
let orderConfirmationPage = testCase.pages.orderConfirmationPage;
|
||||||
await orderConfirmationPage.verifyOrderConfirmationPage(testCase.testData);
|
await orderConfirmationPage.verifyOrderConfirmationPage(testCase.testData);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function handleInsuranceFlow(testCase: TestCase) {
|
async function handleInsuranceFlow(testCase: TestCase) {
|
||||||
const { isPolicyFound, isPolicyDriver, endorsements, isRecalVehicle, isCashInsuranceFlow, flow } = testCase.testData;
|
const { isPolicyFound, isPolicyDriver, endorsements, isRecalVehicle, isCashInsuranceFlow, isForcedOEM, flow } = testCase.testData;
|
||||||
|
|
||||||
// Check if the insurance policy has endorsements
|
|
||||||
const hasEndorsements = endorsements && endorsements.length > 0;
|
|
||||||
|
|
||||||
// Handle insurance company page
|
// Check if the insurance policy has endorsements
|
||||||
let insuranceCompanyPage = testCase.pages.insuranceCompanyPage;
|
const hasEndorsements = endorsements && endorsements.length > 0;
|
||||||
await insuranceCompanyPage.handleInsuranceCompanyPage(testCase.testData);
|
|
||||||
|
|
||||||
// Handle ccPolicyInfoPage
|
// Handle insurance company page
|
||||||
let ccPolicyInfoPage = testCase.pages.ccPolicyInfoPage;
|
let insuranceCompanyPage = testCase.pages.insuranceCompanyPage;
|
||||||
await ccPolicyInfoPage.handleCCPolicyInfoPage(testCase.testData);
|
await insuranceCompanyPage.handleInsuranceCompanyPage(testCase.testData);
|
||||||
|
|
||||||
let duplicateCheckPage = testCase.pages.duplicateCheckPage;
|
// Handle OEM scenario
|
||||||
if (duplicateCheckPage.page.url().includes('DuplicateCheck.aspx')) {
|
if (isForcedOEM) {
|
||||||
await duplicateCheckPage.handleDuplicateCheckPage(testCase.testData);
|
// User should be on heritage problem glass questions page after selecting Allstate on insurance company page
|
||||||
|
let HeritageProblemGlassQuestionsPage = testCase.pages.heritageProblemGlassQuestionsPage;
|
||||||
|
await HeritageProblemGlassQuestionsPage.handleHeritageProblemGlassQuestionsPage(testCase.testData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle ccPolicyInfoPage
|
||||||
|
let ccPolicyInfoPage = testCase.pages.ccPolicyInfoPage;
|
||||||
|
await ccPolicyInfoPage.handleCCPolicyInfoPage(testCase.testData);
|
||||||
|
|
||||||
|
let duplicateCheckPage = testCase.pages.duplicateCheckPage;
|
||||||
|
if (duplicateCheckPage.page.url().includes('DuplicateCheck.aspx')) {
|
||||||
|
await duplicateCheckPage.handleDuplicateCheckPage(testCase.testData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flow === Flow.Managed) {
|
||||||
|
let policyVehiclesPage = testCase.pages.policyVehiclesPage;
|
||||||
|
await policyVehiclesPage.handlePolicyVehiclesPage(testCase.testData);
|
||||||
|
|
||||||
|
// Handle policy driver selection if applicable
|
||||||
|
if (isPolicyDriver) {
|
||||||
|
let policyDriverPage = testCase.pages.policyDriverPage;
|
||||||
|
await policyDriverPage.handlePolicyDriverPage(testCase.testData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( flow === Flow.Managed ) {
|
// Handle endorsements if applicable
|
||||||
let policyVehiclesPage = testCase.pages.policyVehiclesPage;
|
if (hasEndorsements) {
|
||||||
await policyVehiclesPage.handlePolicyVehiclesPage(testCase.testData);
|
let endorsementsPage = testCase.pages.endorsementsPage;
|
||||||
|
await endorsementsPage.handleEndorsementsPage(testCase.testData);
|
||||||
// Handle policy driver selection if applicable
|
|
||||||
if (isPolicyDriver) {
|
|
||||||
let policyDriverPage = testCase.pages.policyDriverPage;
|
|
||||||
await policyDriverPage.handlePolicyDriverPage(testCase.testData);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle endorsements if applicable
|
|
||||||
if (hasEndorsements) {
|
|
||||||
let endorsementsPage = testCase.pages.endorsementsPage;
|
|
||||||
await endorsementsPage.handleEndorsementsPage(testCase.testData);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
//Handle verify details page
|
|
||||||
let verifyDetailsPage = testCase.pages.verifyDetailsPage;
|
|
||||||
await verifyDetailsPage.handleVerifyDetailsPage(testCase.testData);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
// Handle Policy info submitted page
|
//Handle verify details page
|
||||||
let policyInfoSubmittedPage = testCase.pages.policyInfoSubmittedPage;
|
let verifyDetailsPage = testCase.pages.verifyDetailsPage;
|
||||||
await policyInfoSubmittedPage.handlePolicyInfoSubmittedPage();
|
await verifyDetailsPage.handleVerifyDetailsPage(testCase.testData);
|
||||||
|
}
|
||||||
|
|
||||||
if(isRecalVehicle)
|
// Handle Policy info submitted page
|
||||||
{
|
let policyInfoSubmittedPage = testCase.pages.policyInfoSubmittedPage;
|
||||||
let recalibrationInfoPage = testCase.pages.recalibrationInfoPage;
|
await policyInfoSubmittedPage.handlePolicyInfoSubmittedPage();
|
||||||
await recalibrationInfoPage.handleRecalibrationInfoPage();
|
|
||||||
|
if (isRecalVehicle) {
|
||||||
|
let recalibrationInfoPage = testCase.pages.recalibrationInfoPage;
|
||||||
|
await recalibrationInfoPage.handleRecalibrationInfoPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
//handle coveraage statement page
|
||||||
|
let coverageStatementPage = testCase.pages.coverageStatementPage;
|
||||||
|
await coverageStatementPage.handleCoverageStatementPage(testCase.testData);
|
||||||
|
|
||||||
|
// Handle scenario where user selected Cash to Insurance and needs to go back through the flow
|
||||||
|
// right now we are choosing pay at appointment as payment method for this scenario
|
||||||
|
if (isCashInsuranceFlow) {
|
||||||
|
// Schedule appointment
|
||||||
|
let schedulePage = testCase.pages.schedulePage;
|
||||||
|
await schedulePage.handleSchedulePage(testCase.testData);
|
||||||
|
|
||||||
|
if (testCase.testData.appointmentDetails?.serviceLocation === ServiceLocation.Mobile) {
|
||||||
|
let mobileDetailsPage = testCase.pages.mobileDetailsPage;
|
||||||
|
await mobileDetailsPage.handleMobileDetailsPage(testCase.testData);
|
||||||
}
|
}
|
||||||
|
//customer dertails
|
||||||
|
let contactDetailsPage = testCase.pages.contactDetailsPage;
|
||||||
|
await contactDetailsPage.nextPage();
|
||||||
|
|
||||||
//handle coveraage statement page
|
//paymentmethods
|
||||||
let coverageStatementPage = testCase.pages.coverageStatementPage;
|
let paymentMethodPage = testCase.pages.paymentMethodPage;
|
||||||
await coverageStatementPage.handleCoverageStatementPage(testCase.testData);
|
await paymentMethodPage.nextPage();
|
||||||
|
}
|
||||||
// Handle scenario where user selected Cash to Insurance and needs to go back through the flow
|
|
||||||
// right now we are choosing pay at appointment as payment method for this scenario
|
|
||||||
if (isCashInsuranceFlow) {
|
|
||||||
// Schedule appointment
|
|
||||||
let schedulePage = testCase.pages.schedulePage;
|
|
||||||
await schedulePage.handleSchedulePage(testCase.testData);
|
|
||||||
|
|
||||||
if (testCase.testData.appointmentDetails?.serviceLocation === ServiceLocation.Mobile) {
|
|
||||||
let mobileDetailsPage = testCase.pages.mobileDetailsPage;
|
|
||||||
await mobileDetailsPage.handleMobileDetailsPage(testCase.testData);
|
|
||||||
}
|
|
||||||
//customer dertails
|
|
||||||
let contactDetailsPage = testCase.pages.contactDetailsPage;
|
|
||||||
await contactDetailsPage.nextPage();
|
|
||||||
|
|
||||||
//paymentmethods
|
|
||||||
let paymentMethodPage = testCase.pages.paymentMethodPage;
|
|
||||||
await paymentMethodPage.nextPage();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { VehicleDamage, ServiceLocation, ServicePackage } from 'safelite-playwright-core';
|
import { VehicleDamage, ServiceLocation, ServicePackage } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { ClientData } from 'safelite-playwright-core';
|
import { ClientData } from 'safelite-playwright-core';
|
||||||
|
|
@ -34,7 +34,12 @@ const cashRepairInShopAfterPayData : Partial<ITestData> = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Use predefined payment data
|
// Use predefined payment data
|
||||||
paymentDetails: ClientData.getDefaultAfterpayDetails()
|
paymentDetails: ClientData.getDefaultAfterpayDetails(),
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cashRepairInShopAfterPayTests: ITestCase[] = [];
|
const cashRepairInShopAfterPayTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { VehicleDamage, ServicePackage } from 'safelite-playwright-core';
|
import { VehicleDamage, ServicePackage } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { ClientData } from 'safelite-playwright-core';
|
import { ClientData } from 'safelite-playwright-core';
|
||||||
|
|
@ -35,7 +35,12 @@ const cashRepairInShopPayPalData : Partial<ITestData> = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Use predefined payment data
|
// Use predefined payment data
|
||||||
paymentDetails: ClientData.getDefaultPaypalDetails()
|
paymentDetails: ClientData.getDefaultPaypalDetails(),
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cashRepairInShopPayPalTests: ITestCase[] = [];
|
const cashRepairInShopPayPalTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { VehicleDamage, ServiceLocation } from 'safelite-playwright-core';
|
import { VehicleDamage, ServiceLocation } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { ClientData } from 'safelite-playwright-core';
|
import { ClientData } from 'safelite-playwright-core';
|
||||||
|
|
@ -48,7 +48,12 @@ const cashRepairMobileCCData : Partial<ITestData> = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Use predefined payment data
|
// Use predefined payment data
|
||||||
paymentDetails: ClientData.getDefaultCreditCardDetails()
|
paymentDetails: ClientData.getDefaultCreditCardDetails(),
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cashRepairMobileCCTests: ITestCase[] = [];
|
const cashRepairMobileCCTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { ServiceLocation, PaymentType } from 'safelite-playwright-core';
|
import { ServiceLocation, ServicePackage, PaymentType } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { VehicleLookupType } from 'safelite-playwright-core';
|
import { VehicleLookupType } from 'safelite-playwright-core';
|
||||||
import { getDefaultTestData, setFakerSeedFromTestName } from 'safelite-playwright-core';
|
import { getDefaultTestData, setFakerSeedFromTestName } from 'safelite-playwright-core';
|
||||||
|
|
@ -29,7 +29,8 @@ const cashReplaceDynamicRecalMobileData: Partial<ITestData> = {
|
||||||
postalCode: '21237'
|
postalCode: '21237'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
servicePackage: ServicePackage.Premium,
|
||||||
// Override vehicle details
|
// Override vehicle details
|
||||||
vehicleDetails: {
|
vehicleDetails: {
|
||||||
...getDefaultTestData().vehicleDetails!,
|
...getDefaultTestData().vehicleDetails!,
|
||||||
|
|
@ -59,7 +60,14 @@ const cashReplaceDynamicRecalMobileData: Partial<ITestData> = {
|
||||||
|
|
||||||
// Override payment details
|
// Override payment details
|
||||||
paymentDetails: {
|
paymentDetails: {
|
||||||
paymentType: PaymentType.PayAtService
|
paymentType: PaymentType.PayAtService,
|
||||||
|
// promoCode: 'digitalrain'
|
||||||
|
promoCode: 'rain50'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { VehicleLookupType } from 'safelite-playwright-core';
|
import { VehicleLookupType } from 'safelite-playwright-core';
|
||||||
import { ClientData } from 'safelite-playwright-core';
|
import { ClientData } from 'safelite-playwright-core';
|
||||||
|
|
@ -43,7 +43,12 @@ const cashReplaceGlassAddressLookupInshopAfterPayData: Partial<ITestData> = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Override payment details
|
// Override payment details
|
||||||
paymentDetails: ClientData.getDefaultAfterpayDetails()
|
paymentDetails: ClientData.getDefaultAfterpayDetails(),
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cashReplaceGlassAddressLookupInshopAfterPayTests: ITestCase[] = [];
|
const cashReplaceGlassAddressLookupInshopAfterPayTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { VehicleLookupType } from 'safelite-playwright-core';
|
import { VehicleLookupType } from 'safelite-playwright-core';
|
||||||
import { ClientData } from 'safelite-playwright-core';
|
import { ClientData } from 'safelite-playwright-core';
|
||||||
|
|
@ -42,7 +42,12 @@ const cashReplaceGlassLicensePlateLookupInshopPaypalData: Partial<ITestData> = {
|
||||||
// No need to override vehicleDamage as it already defaults to WindshieldCrack
|
// No need to override vehicleDamage as it already defaults to WindshieldCrack
|
||||||
|
|
||||||
// Override payment details to use PayPal
|
// Override payment details to use PayPal
|
||||||
paymentDetails: ClientData.getDefaultPaypalDetails()
|
paymentDetails: ClientData.getDefaultPaypalDetails(),
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cashReplaceGlassLicensePlateLookupInshopPaypalTests: ITestCase[] = [];
|
const cashReplaceGlassLicensePlateLookupInshopPaypalTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { PaymentType } from 'safelite-playwright-core';
|
import { PaymentType } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { VehicleLookupType } from 'safelite-playwright-core';
|
import { VehicleLookupType } from 'safelite-playwright-core';
|
||||||
|
|
@ -55,6 +55,11 @@ const cashReplaceGlassPromoInshopData: Partial<ITestData> = {
|
||||||
paymentType: PaymentType.PayAtService,
|
paymentType: PaymentType.PayAtService,
|
||||||
// Add promo code - key feature of this test
|
// Add promo code - key feature of this test
|
||||||
promoCode: '20CALL',
|
promoCode: '20CALL',
|
||||||
|
},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
85
playwright-tests/tests/CashReplaceMobileFirstModal.ts
Normal file
85
playwright-tests/tests/CashReplaceMobileFirstModal.ts
Normal file
|
|
@ -0,0 +1,85 @@
|
||||||
|
//Imports here
|
||||||
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
|
import { ServiceLocation, ServicePackage, PaymentType, PartQuestionType } from 'safelite-playwright-core';
|
||||||
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
|
import { VehicleLookupType } from 'safelite-playwright-core';
|
||||||
|
import { getDefaultTestData, setFakerSeedFromTestName } from 'safelite-playwright-core';
|
||||||
|
import { PaymentMethod } from 'framework/localTypes/Enums';
|
||||||
|
|
||||||
|
// Set the seed before generating any data
|
||||||
|
setFakerSeedFromTestName("CashReplaceMobileFirstModal");
|
||||||
|
|
||||||
|
// Now get the test data with the seeded faker
|
||||||
|
const cashReplaceMobileFirstModalData: Partial<ITestData> = {
|
||||||
|
...getDefaultTestData(), // Get default data with current seed
|
||||||
|
|
||||||
|
// CASH Client
|
||||||
|
paymentMethod: PaymentMethod.SelfPay,
|
||||||
|
|
||||||
|
customerDetails: {
|
||||||
|
...getDefaultTestData().customerDetails!,
|
||||||
|
address: {
|
||||||
|
...getDefaultTestData().customerDetails!.address,
|
||||||
|
postalCode: '91761'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
servicePackage: ServicePackage.GlassOnly,
|
||||||
|
// Override vehicle details
|
||||||
|
vehicleDetails: {
|
||||||
|
...getDefaultTestData().vehicleDetails!,
|
||||||
|
year: '2018',
|
||||||
|
make: 'Honda',
|
||||||
|
model: 'Accord',
|
||||||
|
style: '4 door sedan',
|
||||||
|
},
|
||||||
|
|
||||||
|
handleMobileFirstModal: true,
|
||||||
|
|
||||||
|
partQuestions: [
|
||||||
|
{
|
||||||
|
partQuestionType: PartQuestionType.GeneralQuestion1,
|
||||||
|
isOnPage: true,
|
||||||
|
optionToSelect: 'Yes'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
mockFirstInshopCallNoSchedule: true,
|
||||||
|
// No need to override vehicleDamage as it already defaults to WindshieldCrack
|
||||||
|
|
||||||
|
// Override appointment details
|
||||||
|
appointmentDetails: {
|
||||||
|
serviceLocation: ServiceLocation.Mobile,
|
||||||
|
appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate,
|
||||||
|
serviceAddress: {
|
||||||
|
// Use street address from current faker seed
|
||||||
|
street: "2064 S Sultana Ave",
|
||||||
|
city: 'Ontario',
|
||||||
|
state: 'CA',
|
||||||
|
postalCode: '91761',
|
||||||
|
country: 'United States'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Override payment details
|
||||||
|
paymentDetails: {
|
||||||
|
paymentType: PaymentType.PayAtService
|
||||||
|
},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData(),
|
||||||
|
isMobileFirst: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cashReplaceMobileFirstModal: ITestCase[] = [];
|
||||||
|
|
||||||
|
const tc = {
|
||||||
|
name: `CashReplaceMobileFirstModal`,
|
||||||
|
tags: ['@E2E','@CashReplaceMobileFirstModal', '@test_report', '@CASH'],
|
||||||
|
testData: cashReplaceMobileFirstModalData
|
||||||
|
};
|
||||||
|
cashReplaceMobileFirstModal.push(tc);
|
||||||
|
|
||||||
|
export default cashReplaceMobileFirstModal;
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { VehicleDamage, PartQuestionType, PaymentType, ServicePackage, ServiceLocation } from 'safelite-playwright-core';
|
import { VehicleDamage, PartQuestionType, PaymentType, ServicePackage, ServiceLocation } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { VehicleLookupType } from 'safelite-playwright-core';
|
import { VehicleLookupType } from 'safelite-playwright-core';
|
||||||
|
|
@ -88,7 +88,12 @@ const cashReplaceMultiGlassMobileData: Partial<ITestData> = {
|
||||||
optionToSelect: 'Gray Tint Privacy',
|
optionToSelect: 'Gray Tint Privacy',
|
||||||
secondaryQuestionOptionToSelect: 'solar, passenger side, encap, chrome molding'
|
secondaryQuestionOptionToSelect: 'solar, passenger side, encap, chrome molding'
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cashReplaceMultiGlassMobileTests: ITestCase[] = [];
|
const cashReplaceMultiGlassMobileTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { VehicleDamage, PartQuestionType, PaymentType } from 'safelite-playwright-core';
|
import { VehicleDamage, PartQuestionType, PaymentType } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { VehicleLookupType } from 'safelite-playwright-core';
|
import { VehicleLookupType } from 'safelite-playwright-core';
|
||||||
|
|
@ -94,7 +94,12 @@ const cashReplaceMultiGlassPromoInshopData: Partial<ITestData> = {
|
||||||
optionToSelect: 'Green Tint',
|
optionToSelect: 'Green Tint',
|
||||||
secondaryQuestionOptionToSelect: 'heated glass, solar, antenna, manual liftgate, 1 hole'
|
secondaryQuestionOptionToSelect: 'heated glass, solar, antenna, manual liftgate, 1 hole'
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cashReplaceMultiGlassPromoInshopTests: ITestCase[] = [];
|
const cashReplaceMultiGlassPromoInshopTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { VehicleDamage, PartQuestionType, PaymentType, ServicePackage, ServiceLocation } from 'safelite-playwright-core';
|
import { VehicleDamage, PartQuestionType, PaymentType, ServicePackage, ServiceLocation } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { VehicleLookupType } from 'safelite-playwright-core';
|
import { VehicleLookupType } from 'safelite-playwright-core';
|
||||||
|
|
@ -35,7 +35,7 @@ const cashReplaceMultiSlidingGlassDropoffData: Partial<ITestData> = {
|
||||||
appointmentDetails: {
|
appointmentDetails: {
|
||||||
serviceLocation: ServiceLocation.DropOff,
|
serviceLocation: ServiceLocation.DropOff,
|
||||||
appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate,
|
appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate,
|
||||||
shopAddress: "6826 sawmill rd, Columbus, OH 43235"
|
shopAddress: "1343 cameron ave, lewis center, oh 43035"
|
||||||
},
|
},
|
||||||
|
|
||||||
// Override vehicle details
|
// Override vehicle details
|
||||||
|
|
@ -105,7 +105,12 @@ const cashReplaceMultiSlidingGlassDropoffData: Partial<ITestData> = {
|
||||||
optionToSelect: 'Gray Tint Privacy',
|
optionToSelect: 'Gray Tint Privacy',
|
||||||
secondaryQuestionOptionToSelect: 'heated glass, solar, slider, power, kit'
|
secondaryQuestionOptionToSelect: 'heated glass, solar, slider, power, kit'
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cashReplaceMultiSlidingGlassDropoffTests: ITestCase[] = [];
|
const cashReplaceMultiSlidingGlassDropoffTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { ServicePackage, PaymentType } from 'safelite-playwright-core';
|
import { ServicePackage, PaymentType } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { VehicleLookupType } from 'safelite-playwright-core';
|
import { VehicleLookupType } from 'safelite-playwright-core';
|
||||||
|
|
@ -50,6 +50,11 @@ const cashReplaceRainDefensePromoInshopData: Partial<ITestData> = {
|
||||||
// Rain Defense promo code
|
// Rain Defense promo code
|
||||||
promoCode: 'rd50'
|
promoCode: 'rd50'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cashReplaceRainDefensePromoInshopTests: ITestCase[] = [];
|
const cashReplaceRainDefensePromoInshopTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { ServiceLocation, PartQuestionType, PaymentType } from 'safelite-playwright-core';
|
import { ServiceLocation, PartQuestionType, PaymentType } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { VehicleLookupType } from 'safelite-playwright-core';
|
import { VehicleLookupType } from 'safelite-playwright-core';
|
||||||
|
|
@ -70,7 +70,12 @@ const cashReplaceSafeliteCanNotRecalMobileData: Partial<ITestData> = {
|
||||||
isOnPage: true,
|
isOnPage: true,
|
||||||
optionToSelect: 'Yes'
|
optionToSelect: 'Yes'
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cashReplaceSafeliteCanNotRecalMobileTests: ITestCase[] = [];
|
const cashReplaceSafeliteCanNotRecalMobileTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { PartQuestionType, PaymentType, VehicleDamage } from 'safelite-playwright-core';
|
import { PartQuestionType, PaymentType, VehicleDamage } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { VehicleLookupType } from 'safelite-playwright-core';
|
import { VehicleLookupType } from 'safelite-playwright-core';
|
||||||
|
|
@ -59,6 +59,11 @@ const CashReplaceSplitWindshieldData: Partial<ITestData> = {
|
||||||
// Override payment details
|
// Override payment details
|
||||||
paymentDetails: {
|
paymentDetails: {
|
||||||
paymentType: PaymentType.PayAtService
|
paymentType: PaymentType.PayAtService
|
||||||
|
},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
83
playwright-tests/tests/CashReplaceStaticInshop.ts
Normal file
83
playwright-tests/tests/CashReplaceStaticInshop.ts
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
//Imports here
|
||||||
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
|
import { ServicePackage, PaymentType, PartQuestionType } from 'safelite-playwright-core';
|
||||||
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
|
import { VehicleLookupType } from 'safelite-playwright-core';
|
||||||
|
import { getDefaultTestData, setFakerSeedFromTestName } from 'safelite-playwright-core';
|
||||||
|
import { PaymentMethod } from 'framework/localTypes/Enums';
|
||||||
|
|
||||||
|
// Set the seed before generating any data
|
||||||
|
setFakerSeedFromTestName("CashReplaceStaticInshop");
|
||||||
|
|
||||||
|
// Now get the test data with the seeded faker
|
||||||
|
const CashReplaceStaticInshopData: Partial<ITestData> = {
|
||||||
|
...getDefaultTestData(), // Get default data with current seed
|
||||||
|
|
||||||
|
// CASH Client
|
||||||
|
paymentMethod: PaymentMethod.SelfPay,
|
||||||
|
|
||||||
|
// Key feature: Premium package with Rain Defense
|
||||||
|
servicePackage: ServicePackage.Standard,
|
||||||
|
|
||||||
|
// Flag for recalibration vehicle
|
||||||
|
isRecalVehicle: true,
|
||||||
|
|
||||||
|
// Override customer details
|
||||||
|
customerDetails: {
|
||||||
|
...getDefaultTestData().customerDetails!,
|
||||||
|
address: {
|
||||||
|
...getDefaultTestData().customerDetails!.address,
|
||||||
|
postalCode: '43085'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// override part questions
|
||||||
|
partQuestions: [
|
||||||
|
{
|
||||||
|
partQuestionType: PartQuestionType.GeneralQuestion1,
|
||||||
|
isOnPage: true,
|
||||||
|
optionToSelect: 'Yes'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
partQuestionType: PartQuestionType.GeneralQuestion2,
|
||||||
|
isOnPage: true,
|
||||||
|
optionToSelect: 'Yes'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// Override vehicle details
|
||||||
|
vehicleDetails: {
|
||||||
|
...getDefaultTestData().vehicleDetails!,
|
||||||
|
year: '2022',
|
||||||
|
make: 'Mazda',
|
||||||
|
model: 'CX-9',
|
||||||
|
style: '4 door utility',
|
||||||
|
vin: '3FA6P0HD8LR234510',
|
||||||
|
vehicleLookupType: VehicleLookupType.Zip
|
||||||
|
},
|
||||||
|
|
||||||
|
mockFirstInshopCallNoSchedule: true,
|
||||||
|
|
||||||
|
// No need to override vehicleDamage as it already defaults to WindshieldCrack
|
||||||
|
|
||||||
|
// Payment at service
|
||||||
|
paymentDetails: {
|
||||||
|
paymentType: PaymentType.PayAtService
|
||||||
|
},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cashReplaceStaticInshopTests: ITestCase[] = [];
|
||||||
|
|
||||||
|
const tc = {
|
||||||
|
name: `CashReplaceStaticInshop`,
|
||||||
|
tags: ['@E2E','@CashReplaceStaticInshop', '@test_report', '@CASH'],
|
||||||
|
testData: CashReplaceStaticInshopData
|
||||||
|
};
|
||||||
|
cashReplaceStaticInshopTests.push(tc);
|
||||||
|
|
||||||
|
export default cashReplaceStaticInshopTests;
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { Flow, ServiceLocation } from "safelite-playwright-core";
|
import { Flow, ServiceLocation } from "safelite-playwright-core";
|
||||||
import { DamageType, PartQuestionType, PaymentType } from 'safelite-playwright-core'
|
import { DamageType, PartQuestionType, PaymentType } from 'safelite-playwright-core'
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
|
|
@ -70,7 +70,10 @@ const cashReplaceSwitchToInsuranceProgressiveNoCompData: Partial<ITestData> = {
|
||||||
appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate,
|
appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create and register the test case
|
// Create and register the test case
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { AppointmentTimeslot, ServiceLocation, PaymentType } from 'safelite-playwright-core';
|
import { AppointmentTimeslot, ServiceLocation, PaymentType } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { VehicleLookupType } from 'safelite-playwright-core';
|
import { VehicleLookupType } from 'safelite-playwright-core';
|
||||||
|
|
@ -60,6 +60,11 @@ const cashReplaceVinMobileData: Partial<ITestData> = {
|
||||||
paymentDetails: {
|
paymentDetails: {
|
||||||
paymentType: PaymentType.PayAtService
|
paymentType: PaymentType.PayAtService
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cashReplaceVinMobileTests: ITestCase[] = [];
|
const cashReplaceVinMobileTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { ServicePackage, ServiceLocation, PartQuestionType, PaymentType } from 'safelite-playwright-core';
|
import { ServicePackage, ServiceLocation, PartQuestionType, PaymentType } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { VehicleLookupType } from 'safelite-playwright-core';
|
import { VehicleLookupType } from 'safelite-playwright-core';
|
||||||
|
|
@ -66,10 +66,15 @@ const cashReplaceWiperDropoffData: Partial<ITestData> = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
partQuestionType: PartQuestionType.GeneralQuestion2,
|
partQuestionType: PartQuestionType.GeneralQuestion2,
|
||||||
isOnPage: false,
|
isOnPage: true,
|
||||||
optionToSelect: 'Yes'
|
optionToSelect: 'Yes'
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const cashReplaceWiperDropoffTests: ITestCase[] = [];
|
const cashReplaceWiperDropoffTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { ServicePackage, ServiceLocation, PaymentType } from 'safelite-playwright-core';
|
import { ServicePackage, ServiceLocation, PaymentType } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { VehicleLookupType } from 'safelite-playwright-core';
|
import { VehicleLookupType } from 'safelite-playwright-core';
|
||||||
|
|
@ -46,6 +46,11 @@ const cashReplaceWiperPromoInShopData: Partial<ITestData> = {
|
||||||
paymentType: PaymentType.PayAtService,
|
paymentType: PaymentType.PayAtService,
|
||||||
// Specific wiper promo code
|
// Specific wiper promo code
|
||||||
promoCode: '1WIPER0',
|
promoCode: '1WIPER0',
|
||||||
|
},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { ServiceLocation, DamageType, PartQuestionType, VehicleDamage, PaymentType, Flow } from 'safelite-playwright-core';
|
import { ServiceLocation, DamageType, PartQuestionType, VehicleDamage, PaymentType, Flow } from 'safelite-playwright-core';
|
||||||
import { PaymentMethod } from "framework/localTypes/Enums";
|
import { PaymentMethod } from "framework/localTypes/Enums";
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
|
|
@ -83,7 +83,12 @@ const insuranceAcuityPaypalData: Partial<ITestData> = {
|
||||||
],
|
],
|
||||||
|
|
||||||
// Override payment details (empty because we skip payment method page in insurance flow)
|
// Override payment details (empty because we skip payment method page in insurance flow)
|
||||||
paymentDetails: {}
|
paymentDetails: {},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const insuranceAcuityPaypalTests: ITestCase[] = [];
|
const insuranceAcuityPaypalTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { ServiceLocation, DamageType, PaymentType, PartQuestionType } from 'safelite-playwright-core';
|
import { ServiceLocation, DamageType, PaymentType, PartQuestionType } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { PaymentMethod } from "framework/localTypes/Enums";
|
import { PaymentMethod } from "framework/localTypes/Enums";
|
||||||
|
|
@ -67,7 +67,12 @@ const insuranceBigTruckVerifiedData: Partial<ITestData> = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Override payment details (empty because we skip payment method page in insurance flow)
|
// Override payment details (empty because we skip payment method page in insurance flow)
|
||||||
paymentDetails: {}
|
paymentDetails: {},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const insuranceBigTruckVerifiedTests: ITestCase[] = [];
|
const insuranceBigTruckVerifiedTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { ServiceLocation, DamageType, Flow } from 'safelite-playwright-core';
|
import { ServiceLocation, DamageType, Flow } from 'safelite-playwright-core';
|
||||||
import { PaymentMethod } from "framework/localTypes/Enums";
|
import { PaymentMethod } from "framework/localTypes/Enums";
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
|
|
@ -64,7 +64,12 @@ const insuranceGeicoData: Partial<ITestData> = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Override payment details (empty because we skip payment method page in insurance flow)
|
// Override payment details (empty because we skip payment method page in insurance flow)
|
||||||
paymentDetails: {}
|
paymentDetails: {},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const insuranceGeicoTests: ITestCase[] = [];
|
const insuranceGeicoTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { ServiceLocation, DamageType, PartQuestionType, Flow } from 'safelite-playwright-core';
|
import { ServiceLocation, DamageType, PartQuestionType, Flow } from 'safelite-playwright-core';
|
||||||
import { PaymentMethod } from "framework/localTypes/Enums";
|
import { PaymentMethod } from "framework/localTypes/Enums";
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
|
|
@ -68,7 +68,12 @@ const insuranceITAC21stCenturyData: Partial<ITestData> = {
|
||||||
isOnPage: true,
|
isOnPage: true,
|
||||||
optionToSelect: 'Yes'
|
optionToSelect: 'Yes'
|
||||||
},
|
},
|
||||||
]
|
],
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const insuranceITAC21stCenturyTests: ITestCase[] = [];
|
const insuranceITAC21stCenturyTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { VehicleDamage, ServiceLocation, DamageType, Flow } from 'safelite-playwright-core';
|
import { VehicleDamage, ServiceLocation, DamageType, Flow } from 'safelite-playwright-core';
|
||||||
import { PaymentMethod } from "framework/localTypes/Enums";
|
import { PaymentMethod } from "framework/localTypes/Enums";
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
|
|
@ -65,7 +65,12 @@ const insuranceITACOptimizedPriceValidationAllStateData: Partial<ITestData> = {
|
||||||
appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate
|
appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate
|
||||||
},
|
},
|
||||||
// Override payment details (empty because we skip payment method page in insurance flow)
|
// Override payment details (empty because we skip payment method page in insurance flow)
|
||||||
paymentDetails: {}
|
paymentDetails: {},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const insuranceITACOptimizedPriceValidationAllStateTests: ITestCase[] = [];
|
const insuranceITACOptimizedPriceValidationAllStateTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { ServiceLocation, DamageType, Flow, PartQuestionType, LossLocation } from 'safelite-playwright-core';
|
import { ServiceLocation, DamageType, Flow, PartQuestionType, LossLocation } from 'safelite-playwright-core';
|
||||||
import { PaymentMethod } from "framework/localTypes/Enums";
|
import { PaymentMethod } from "framework/localTypes/Enums";
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
|
|
@ -62,7 +62,12 @@ const insuranceMeemicNearSchoolVerifiedData: Partial<ITestData> = {
|
||||||
],
|
],
|
||||||
|
|
||||||
// Override payment details (empty because we skip payment method page in insurance flow)
|
// Override payment details (empty because we skip payment method page in insurance flow)
|
||||||
paymentDetails: {}
|
paymentDetails: {},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const insuranceMeemicNearSchoolVerifiedTests: ITestCase[] = [];
|
const insuranceMeemicNearSchoolVerifiedTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { ServiceLocation, DamageType, PaymentType, PartQuestionType, Flow } from 'safelite-playwright-core';
|
import { ServiceLocation, DamageType, PaymentType, PartQuestionType, Flow } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { PaymentMethod } from "framework/localTypes/Enums";
|
import { PaymentMethod } from "framework/localTypes/Enums";
|
||||||
|
|
@ -32,10 +32,11 @@ const insuranceNoCompProgressiveData: Partial<ITestData> = {
|
||||||
lastName: 'SCHATZ',
|
lastName: 'SCHATZ',
|
||||||
address: {
|
address: {
|
||||||
...getDefaultTestData().customerDetails!.address,
|
...getDefaultTestData().customerDetails!.address,
|
||||||
city: 'Slidell',
|
// city: 'Slidell',
|
||||||
state: 'Louisiana',
|
// state: 'Louisiana',
|
||||||
postalCode: '70458'
|
// postalCode: '70458'
|
||||||
}
|
postalCode: '43085'
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -71,12 +72,17 @@ const insuranceNoCompProgressiveData: Partial<ITestData> = {
|
||||||
// Override for in-shop appointment
|
// Override for in-shop appointment
|
||||||
appointmentDetails: {
|
appointmentDetails: {
|
||||||
serviceLocation: ServiceLocation.InShop,
|
serviceLocation: ServiceLocation.InShop,
|
||||||
shopAddress: '56705 Garrett Road, Slidell, LA 70458',
|
// shopAddress: '56705 Garrett Road, Slidell, LA 70458',
|
||||||
appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate
|
appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate
|
||||||
},
|
},
|
||||||
|
|
||||||
// Override payment details (empty because we skip payment method page in insurance flow)
|
// Override payment details (empty because we skip payment method page in insurance flow)
|
||||||
paymentDetails: {}
|
paymentDetails: {},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const insuranceNoCompProgressiveTests: ITestCase[] = [];
|
const insuranceNoCompProgressiveTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
93
playwright-tests/tests/InsuranceOEMAllState.ts
Normal file
93
playwright-tests/tests/InsuranceOEMAllState.ts
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
//Imports here
|
||||||
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
|
import { ServiceLocation, DamageType, PaymentType, PartQuestionType } from 'safelite-playwright-core';
|
||||||
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
|
import { PaymentMethod } from "framework/localTypes/Enums";
|
||||||
|
import { VehicleLookupType } from 'safelite-playwright-core';
|
||||||
|
import { getDefaultTestData, setFakerSeedFromTestName } from 'safelite-playwright-core';
|
||||||
|
|
||||||
|
// Set the seed based on test name for consistent but unique data
|
||||||
|
setFakerSeedFromTestName("InsuranceOEMAllstate");
|
||||||
|
|
||||||
|
// Now get the test data with the seeded faker
|
||||||
|
const insuranceOEMAllstateData: Partial<ITestData> = {
|
||||||
|
...getDefaultTestData(), // Get default data with current seed
|
||||||
|
|
||||||
|
// Key feature: Insurance flow with GEICO
|
||||||
|
paymentMethod: PaymentMethod.Insurance,
|
||||||
|
|
||||||
|
// Insurance claim flags
|
||||||
|
isPolicyFound: false,
|
||||||
|
isPolicyUnverified: true,
|
||||||
|
isRecalVehicle: true,
|
||||||
|
isForcedOEM: true,
|
||||||
|
|
||||||
|
// Override customer details with specific name and California location
|
||||||
|
customerDetails: {
|
||||||
|
...getDefaultTestData().customerDetails!,
|
||||||
|
firstName: 'Jane',
|
||||||
|
lastName: 'OEMTest',
|
||||||
|
address: {
|
||||||
|
...getDefaultTestData().customerDetails!.address,
|
||||||
|
city: 'Richmond',
|
||||||
|
state: 'Virginia',
|
||||||
|
postalCode: '23219'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// Insurance claim details
|
||||||
|
claimDetails: {
|
||||||
|
client: 'Allstate',
|
||||||
|
policyNumber: 'MockOEMTest',
|
||||||
|
policyDeductible: "Unverified",
|
||||||
|
policyZip: '43085',
|
||||||
|
damageDate: new Date(new Date().setDate(new Date().getDate() - 1)).toLocaleDateString('en-US', {month: '2-digit', day: '2-digit', year: 'numeric'}),
|
||||||
|
damageCause: DamageType.Rock
|
||||||
|
},
|
||||||
|
|
||||||
|
// Hyundai vehicle details with VIN lookup
|
||||||
|
vehicleDetails: {
|
||||||
|
...getDefaultTestData().vehicleDetails!,
|
||||||
|
year: '2024',
|
||||||
|
make: 'Jeep',
|
||||||
|
model: 'Wrangler',
|
||||||
|
style: '4 door utility',
|
||||||
|
vehicleLookupType: VehicleLookupType.Zip,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Part questions related to recalibration
|
||||||
|
partQuestions: [
|
||||||
|
{
|
||||||
|
partQuestionType: PartQuestionType.GeneralQuestion1,
|
||||||
|
isOnPage: true,
|
||||||
|
optionToSelect: 'Yes'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
// Override for in-shop appointment
|
||||||
|
appointmentDetails: {
|
||||||
|
serviceLocation: ServiceLocation.InShop,
|
||||||
|
shopAddress: '5719 Brandt Pike, Dayton, OH 45424',
|
||||||
|
appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate
|
||||||
|
},
|
||||||
|
|
||||||
|
// Override payment details (empty because we skip payment method page in insurance flow)
|
||||||
|
paymentDetails: {},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const insuranceOEMAllstateTests: ITestCase[] = [];
|
||||||
|
|
||||||
|
const tc = {
|
||||||
|
name: `InsuranceOEMAllstate`,
|
||||||
|
tags: ['@E2E','@InsuranceOEMAllstate', '@test_report', '@Insurance'],
|
||||||
|
testData: insuranceOEMAllstateData
|
||||||
|
};
|
||||||
|
insuranceOEMAllstateTests.push(tc);
|
||||||
|
|
||||||
|
export default insuranceOEMAllstateTests;
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//Imports here
|
//Imports here
|
||||||
import { ITestData } from 'framework/TestData'
|
import { ITestData, getDefaultExperimentsData } from 'framework/TestData'
|
||||||
import { ServiceLocation, DamageType, PaymentType, PartQuestionType } from 'safelite-playwright-core';
|
import { ServiceLocation, DamageType, PaymentType, PartQuestionType } from 'safelite-playwright-core';
|
||||||
import { ITestCase } from '../framework/Typedefs'
|
import { ITestCase } from '../framework/Typedefs'
|
||||||
import { PaymentMethod } from "framework/localTypes/Enums";
|
import { PaymentMethod } from "framework/localTypes/Enums";
|
||||||
|
|
@ -72,7 +72,12 @@ const insuranceUnverifiedData: Partial<ITestData> = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// Override payment details (empty because we skip payment method page in insurance flow)
|
// Override payment details (empty because we skip payment method page in insurance flow)
|
||||||
paymentDetails: {}
|
paymentDetails: {},
|
||||||
|
|
||||||
|
// Experiments
|
||||||
|
experiments: {
|
||||||
|
...getDefaultExperimentsData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const insuranceUnverifiedTests: ITestCase[] = [];
|
const insuranceUnverifiedTests: ITestCase[] = [];
|
||||||
|
|
|
||||||
|
|
@ -75,10 +75,10 @@ const lookupTypesToTest: LookupTestCase[] = [
|
||||||
},
|
},
|
||||||
customerDetails: {
|
customerDetails: {
|
||||||
address: {
|
address: {
|
||||||
street: '4076 Spectacle Drive',
|
street: '4219 Turpin Ln',
|
||||||
city: 'Columbus',
|
city: 'Columbus',
|
||||||
state: 'OH',
|
state: 'OH',
|
||||||
postalCode: '59261',
|
postalCode: '43230',
|
||||||
country: 'United States'
|
country: 'United States'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en-US">
|
<html lang="en-US">
|
||||||
<head>
|
<head>
|
||||||
|
<meta name="robots" content="noindex" />
|
||||||
<script>
|
<script>
|
||||||
window.dataLayer = [{}];
|
window.dataLayer = [{}];
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -545,7 +545,6 @@
|
||||||
{ path: '/parts/parts-or-questions', method: 'POST', body: {"carId":"CR00046193","glassPieces":[{"location":"Windshield","name":"Single"}],"zip":"43015","vin":null,"serviceType":null,"referralSeqNumber":environmentContext.referralNumber,"AppName":"FixMyGlass"} },
|
{ path: '/parts/parts-or-questions', method: 'POST', body: {"carId":"CR00046193","glassPieces":[{"location":"Windshield","name":"Single"}],"zip":"43015","vin":null,"serviceType":null,"referralSeqNumber":environmentContext.referralNumber,"AppName":"FixMyGlass"} },
|
||||||
{ path: '/parts/wipers/CR00046193/43015', method: 'GET' },
|
{ path: '/parts/wipers/CR00046193/43015', method: 'GET' },
|
||||||
{ path: '/parts/mobile-premium-fee/Cash/Replace', method: 'GET' },
|
{ path: '/parts/mobile-premium-fee/Cash/Replace', method: 'GET' },
|
||||||
{ path: '/parts/service-package-discount', method: 'POST', body: {"glassPieces":[{"location":"Windshield","name":"Single"}],"damageType":"Replace","AppName":"FixMyGlass"} },
|
|
||||||
{ path: '/parts/mobile-fee/?serviceType=Install&facilityType=Mobile&parentAccountNumber=167132&billToAccountNumber=87291&providerNumber=03357&isItacOptimized=false&zipCode=43015', method: 'GET' },
|
{ path: '/parts/mobile-fee/?serviceType=Install&facilityType=Mobile&parentAccountNumber=167132&billToAccountNumber=87291&providerNumber=03357&isItacOptimized=false&zipCode=43015', method: 'GET' },
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ const GaCategories = {
|
||||||
EVOX: "Evox",
|
EVOX: "Evox",
|
||||||
APPOINTMENT: "Appointment",
|
APPOINTMENT: "Appointment",
|
||||||
SERVICE_LOCATION: "service-location",
|
SERVICE_LOCATION: "service-location",
|
||||||
|
CONFIRMATION_CLICKED: "confirmation clicked",
|
||||||
|
RECAL_DISCLAIMER: "Recalibration disclaimer",
|
||||||
};
|
};
|
||||||
|
|
||||||
const GaActions = {
|
const GaActions = {
|
||||||
|
|
@ -26,6 +28,9 @@ const GaActions = {
|
||||||
MOBILE_AVAILABLE: "mobile_available",
|
MOBILE_AVAILABLE: "mobile_available",
|
||||||
SHOPS_FIRST_DISPLAYED: "shops_first_displayed",
|
SHOPS_FIRST_DISPLAYED: "shops_first_displayed",
|
||||||
MORE_LOCATIONS_CLICKED: "more_locations_clicked",
|
MORE_LOCATIONS_CLICKED: "more_locations_clicked",
|
||||||
|
YES: "yes",
|
||||||
|
NO: "no",
|
||||||
|
ACKNOWLEDGED: "Acknowledged",
|
||||||
};
|
};
|
||||||
|
|
||||||
const GaLabels = {
|
const GaLabels = {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ const applicationConfig = {
|
||||||
PIA_ERROR_URL:
|
PIA_ERROR_URL:
|
||||||
location.protocol + "//" + location.host + "/fmg/payment-pia-return?src=concept-funnel",
|
location.protocol + "//" + location.host + "/fmg/payment-pia-return?src=concept-funnel",
|
||||||
CONFIRMATION_URL: location.protocol + "//" + location.host + "/fmg/confirmation",
|
CONFIRMATION_URL: location.protocol + "//" + location.host + "/fmg/confirmation",
|
||||||
|
PIA_ADYEN_RETURN_URL: location.protocol + "//" + location.host + "/fmg/virtual/payment/return",
|
||||||
GOOGLE_CALENDAR: "https://www.google.com/calendar/render?action=TEMPLATE",
|
GOOGLE_CALENDAR: "https://www.google.com/calendar/render?action=TEMPLATE",
|
||||||
YAHOO_CALENDAR: "https://calendar.yahoo.com/?v=60",
|
YAHOO_CALENDAR: "https://calendar.yahoo.com/?v=60",
|
||||||
OUTLOOK_CALENDAR:
|
OUTLOOK_CALENDAR:
|
||||||
|
|
@ -31,6 +32,8 @@ const applicationConfig = {
|
||||||
COOKIE_NAME_LENGTH_MAX_LIMIT: 44,
|
COOKIE_NAME_LENGTH_MAX_LIMIT: 44,
|
||||||
SESSION_TIMEOUT_MINUTES: process.env.__VUE_APP_SESSION_TIMEOUT_MINUTES__,
|
SESSION_TIMEOUT_MINUTES: process.env.__VUE_APP_SESSION_TIMEOUT_MINUTES__,
|
||||||
RETURN_USER_PAGE: "/fmg/return-user",
|
RETURN_USER_PAGE: "/fmg/return-user",
|
||||||
|
ADYEN_CLIENT_KEY: process.env.__VUE_APP_ADYEN_CLIENT_KEY__,
|
||||||
|
ADYEN_ENVIRONMENT: process.env.__VUE_APP_ADYEN_ENVIRONMENT__,
|
||||||
};
|
};
|
||||||
|
|
||||||
export { applicationConfig };
|
export { applicationConfig };
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ const cartItemCategories = {
|
||||||
GLASS_PARTS: "glassParts",
|
GLASS_PARTS: "glassParts",
|
||||||
SUPPORTING_ITEMS: "supportingItems",
|
SUPPORTING_ITEMS: "supportingItems",
|
||||||
PROMOS: "promos",
|
PROMOS: "promos",
|
||||||
SERVICE_PACKAGE_DISCOUNT: "servicePackageDiscount",
|
QUOTE_PAGE_DISCOUNT: "quotePageDiscount",
|
||||||
};
|
};
|
||||||
|
|
||||||
export { cartItemCategories };
|
export { cartItemCategories };
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const cartItemTypes = {
|
||||||
PROMOS: "PROMOS",
|
PROMOS: "PROMOS",
|
||||||
EARLY_BIRD: "EARLY BIRD",
|
EARLY_BIRD: "EARLY BIRD",
|
||||||
SUPPLIES_REPAIR: "SUPPLIES-REPAIR",
|
SUPPLIES_REPAIR: "SUPPLIES-REPAIR",
|
||||||
SERVICE_PACKAGE_DISCOUNT: "SERVICE PACKAGE DISCOUNT",
|
QUOTE_PAGE_DISCOUNT: "QUOTE PAGE DISCOUNT",
|
||||||
DONATION: "DONATION",
|
DONATION: "DONATION",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,10 +76,6 @@ const endpoints = {
|
||||||
url: "/parts/api/v1/parts/pricing-by-day-part-number",
|
url: "/parts/api/v1/parts/pricing-by-day-part-number",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
},
|
},
|
||||||
GetServicePackageDiscountPart: {
|
|
||||||
url: "/parts/api/v1/parts/service-package-discount",
|
|
||||||
method: "POST",
|
|
||||||
},
|
|
||||||
GetServiceabilityDetails: {
|
GetServiceabilityDetails: {
|
||||||
url: "/location/api/v1/location/serviceability-details",
|
url: "/location/api/v1/location/serviceability-details",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
|
|
@ -124,6 +120,14 @@ const endpoints = {
|
||||||
url: "/order/api/v1/order/save-session/fmg",
|
url: "/order/api/v1/order/save-session/fmg",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
},
|
},
|
||||||
|
SubmitOrder: {
|
||||||
|
url: "/order/api/v1/order/submit-order",
|
||||||
|
method: "POST",
|
||||||
|
},
|
||||||
|
SubmitOrderForPia: {
|
||||||
|
url: "/order/api/v1/order/submit-order-for-pia",
|
||||||
|
method: "POST",
|
||||||
|
},
|
||||||
LoadSession: {
|
LoadSession: {
|
||||||
url: "/order/api/v1/order/load-session",
|
url: "/order/api/v1/order/load-session",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
|
@ -154,7 +158,7 @@ const endpoints = {
|
||||||
},
|
},
|
||||||
TaxOrderItems: {
|
TaxOrderItems: {
|
||||||
url: "/price/api/v1/price/taxed-order-items",
|
url: "/price/api/v1/price/taxed-order-items",
|
||||||
method: "GET",
|
method: "POST",
|
||||||
},
|
},
|
||||||
LogExperimentExposureIfAssigned: {
|
LogExperimentExposureIfAssigned: {
|
||||||
url: "/experiments/api/v1/experiments/log-exposure",
|
url: "/experiments/api/v1/experiments/log-exposure",
|
||||||
|
|
@ -208,6 +212,18 @@ const endpoints = {
|
||||||
url: "/order/api/v1/order/add-donation-part",
|
url: "/order/api/v1/order/add-donation-part",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
},
|
},
|
||||||
|
GetOemAfterMarketParts: {
|
||||||
|
url: "/parts/api/v1/parts/oem-after-market-parts",
|
||||||
|
method: "POST",
|
||||||
|
},
|
||||||
|
InitializeAdyenPayment: {
|
||||||
|
url: "/payment/api/v1/payment/payment/session/initialize-session",
|
||||||
|
method: "POST",
|
||||||
|
},
|
||||||
|
GetAdyenSessionResult: {
|
||||||
|
url: "/payment/api/v1/payment/payment/session/session-result",
|
||||||
|
method: "POST",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export { endpoints };
|
export { endpoints };
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ const experimentSettings = {
|
||||||
SUPPRESS_VIN_CAPTURE: "SuppressVinCapture",
|
SUPPRESS_VIN_CAPTURE: "SuppressVinCapture",
|
||||||
DISPLAY_AVAILABILITY_INDICATORS: "DisplayAvailabilityIndicators",
|
DISPLAY_AVAILABILITY_INDICATORS: "DisplayAvailabilityIndicators",
|
||||||
PIA_EXPERIENCE: "PIA Experience",
|
PIA_EXPERIENCE: "PIA Experience",
|
||||||
|
CONDITIONAL_PROVIDER_NUMBERS: "ConditionalProviderNumbers",
|
||||||
|
CONDITIONAL_PROVIDER_NUMBERS_2: "ConditionalProviderNumbers2",
|
||||||
|
CONDITIONAL_PROVIDER_SHUTOFF_DATE: "ConditionalProviderShutoffDate",
|
||||||
PIA_INSURANCE: "DisplayPIAInsurance",
|
PIA_INSURANCE: "DisplayPIAInsurance",
|
||||||
SUBMIT_ORDER_ENABLE_PIA: "SubmitOrder_Enable_PIA",
|
SUBMIT_ORDER_ENABLE_PIA: "SubmitOrder_Enable_PIA",
|
||||||
IS_EMAIL_OPTIONAL: "isEmailOptional",
|
IS_EMAIL_OPTIONAL: "isEmailOptional",
|
||||||
|
|
@ -33,6 +36,11 @@ const experimentSettings = {
|
||||||
SHOW_PM_MOBILE_DAYS: "Show_PMmobileDays",
|
SHOW_PM_MOBILE_DAYS: "Show_PMmobileDays",
|
||||||
SHOW_NO_PM_MOBILE_DAYS: "Show_NoPMmobileDays",
|
SHOW_NO_PM_MOBILE_DAYS: "Show_NoPMmobileDays",
|
||||||
SHOW_NO_MOBILE_AVAILABLE_DAYS: "Show_NoMobileAvailableDays",
|
SHOW_NO_MOBILE_AVAILABLE_DAYS: "Show_NoMobileAvailableDays",
|
||||||
|
SHOW_MOBILE_FIRST_POPUP_REPAIR: "Show_Mobile_First_Popup_Repair",
|
||||||
|
SHOW_MOBILE_FIRST_POPUP_REPLACE_WITHOUT_MSR: "Show_Mobile_First_Popup_Replace_Without_MSR",
|
||||||
|
SHOW_MOBILE_FIRST_POPUP_REPLACE_WITH_MSR: "Show_Mobile_First_Popup_Replace_With_MSR",
|
||||||
|
OFFER_OEM: "OfferOem",
|
||||||
|
USE_ADYEN_PAYMENT: "UseAdyenPayment",
|
||||||
};
|
};
|
||||||
|
|
||||||
const experimentTriggers = {
|
const experimentTriggers = {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,9 @@ const partTypeStrings = {
|
||||||
REPAIR_FEE: "REPAIR FEE",
|
REPAIR_FEE: "REPAIR FEE",
|
||||||
EARLY_BIRD: "EARLY BIRD",
|
EARLY_BIRD: "EARLY BIRD",
|
||||||
SERVICE_PACKAGE_DISCOUNT: "SERVICE PACKAGE DISCOUNT",
|
SERVICE_PACKAGE_DISCOUNT: "SERVICE PACKAGE DISCOUNT",
|
||||||
|
QUOTE_PAGE_DISCOUNT: "QUOTE PAGE DISCOUNT",
|
||||||
DONATION: "DONATION",
|
DONATION: "DONATION",
|
||||||
|
WINDSHIELD: "WINDSHIELD",
|
||||||
};
|
};
|
||||||
|
|
||||||
export { partTypeStrings };
|
export { partTypeStrings };
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,10 @@ export const pageProgressMapper = {
|
||||||
percent: 30,
|
percent: 30,
|
||||||
step: 1,
|
step: 1,
|
||||||
},
|
},
|
||||||
|
"policy-info": {
|
||||||
|
percent: 55,
|
||||||
|
step: 2,
|
||||||
|
},
|
||||||
quote: {
|
quote: {
|
||||||
percent: 60,
|
percent: 60,
|
||||||
step: 2,
|
step: 2,
|
||||||
|
|
@ -80,6 +84,10 @@ export const pageProgressMapper = {
|
||||||
percent: 98.5,
|
percent: 98.5,
|
||||||
step: 4,
|
step: 4,
|
||||||
},
|
},
|
||||||
|
"payment-adyen": {
|
||||||
|
percent: 98.5,
|
||||||
|
step: 4,
|
||||||
|
},
|
||||||
confirmation: {
|
confirmation: {
|
||||||
percent: 100,
|
percent: 100,
|
||||||
step: 4,
|
step: 4,
|
||||||
|
|
|
||||||
105
src/constants/quote-page-discounts.js
Normal file
105
src/constants/quote-page-discounts.js
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
import { packageNames } from "./package-names";
|
||||||
|
import { partTypeStrings } from "./part-type-strings";
|
||||||
|
|
||||||
|
export const quotePageDiscountTable = [
|
||||||
|
// Repair
|
||||||
|
{
|
||||||
|
name: "Repair Glass Only",
|
||||||
|
experimentCode: "Show_GlassOnly_Repair_Discount",
|
||||||
|
partNumber: "GL RPR CSH PKG",
|
||||||
|
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
|
||||||
|
description: "GLASS RPR GEOTARGET DISC",
|
||||||
|
packageLevel: packageNames.TIER_ONE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Repair Standard",
|
||||||
|
experimentCode: "Show_Standard_Repair_Discount",
|
||||||
|
partNumber: "STD RPR CSH PKG",
|
||||||
|
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
|
||||||
|
description: "STD RPR GEOTARGET DISC",
|
||||||
|
packageLevel: packageNames.TIER_TWO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Repair Premium",
|
||||||
|
experimentCode: "Show_Premium_Repair_Discount",
|
||||||
|
partNumber: "PRM RPR CSH PKG",
|
||||||
|
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
|
||||||
|
description: "PREM RPR GEOTARGET DISC",
|
||||||
|
packageLevel: packageNames.TIER_THREE,
|
||||||
|
},
|
||||||
|
// Replace - No recal
|
||||||
|
{
|
||||||
|
name: "Replace Glass Only",
|
||||||
|
experimentCode: "Show_GlassOnly_Replace_Discount",
|
||||||
|
partNumber: "GL RPL CSH PKG",
|
||||||
|
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
|
||||||
|
description: "GLASS RPL GEOTARGET DISC",
|
||||||
|
packageLevel: packageNames.TIER_ONE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Replace Standard",
|
||||||
|
experimentCode: "Show_Standard_Replace_Discount",
|
||||||
|
partNumber: "STD RPL CSH PKG",
|
||||||
|
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
|
||||||
|
description: "STD RPL GEOTARGET DISC",
|
||||||
|
packageLevel: packageNames.TIER_TWO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Replace Premium",
|
||||||
|
experimentCode: "Show_Premium_Replace_Discount",
|
||||||
|
partNumber: "PRM RPL CSH PKG",
|
||||||
|
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
|
||||||
|
description: "PREM RPL GEOTARGET DISC",
|
||||||
|
packageLevel: packageNames.TIER_THREE,
|
||||||
|
},
|
||||||
|
// Replace - with recal
|
||||||
|
{
|
||||||
|
name: "Recal Glass Only",
|
||||||
|
experimentCode: "Show_GlassOnly_Recal_Discount",
|
||||||
|
partNumber: "GL RCL CSH PKG",
|
||||||
|
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
|
||||||
|
description: "GLASS RCL GEOTARGET DISC",
|
||||||
|
packageLevel: packageNames.TIER_ONE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Recal Standard",
|
||||||
|
experimentCode: "Show_Standard_Recal_Discount",
|
||||||
|
partNumber: "STD RCL CSH PKG",
|
||||||
|
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
|
||||||
|
description: "STD RCL GEOTARGET DISC",
|
||||||
|
packageLevel: packageNames.TIER_TWO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Recal Premium",
|
||||||
|
experimentCode: "Show_Premium_Recal_Discount",
|
||||||
|
partNumber: "PRM RCL CSH PKG",
|
||||||
|
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
|
||||||
|
description: "PREM RCL GEOTARGET DISC",
|
||||||
|
packageLevel: packageNames.TIER_THREE,
|
||||||
|
},
|
||||||
|
// Replace - Curve Tempered
|
||||||
|
{
|
||||||
|
name: "Curve Tempered Glass Only",
|
||||||
|
experimentCode: "Show_GlassOnly_Replace_CT_Discount",
|
||||||
|
partNumber: "GL CT CSH PKG",
|
||||||
|
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
|
||||||
|
description: "GLASS CT GEOTARGET DISC",
|
||||||
|
packageLevel: packageNames.TIER_ONE,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Curve Tempered Standard",
|
||||||
|
experimentCode: "Show_Standard_Replace_CT_Discount",
|
||||||
|
partNumber: "STD CT CSH PKG",
|
||||||
|
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
|
||||||
|
description: "STD CT GEOTARGET DISC",
|
||||||
|
packageLevel: packageNames.TIER_TWO,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Curve Tempered Premium",
|
||||||
|
experimentCode: "Show_Premium_Replace_CT_Discount",
|
||||||
|
partNumber: "PRM CT CSH PKG",
|
||||||
|
partType: partTypeStrings.QUOTE_PAGE_DISCOUNT,
|
||||||
|
description: "PREM CT GEOTARGET DISC",
|
||||||
|
packageLevel: packageNames.TIER_THREE,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
@ -11,6 +11,8 @@ const PREMIUM_FEE_PART_TYPE = "EARLY BIRD";
|
||||||
|
|
||||||
const PRICING_BY_DAY_PART_TYPE = "PREMAPPT GEN";
|
const PRICING_BY_DAY_PART_TYPE = "PREMAPPT GEN";
|
||||||
|
|
||||||
|
const RECAL_ACK_YES = "Yes";
|
||||||
|
|
||||||
const RouteCodeFlags = {
|
const RouteCodeFlags = {
|
||||||
ALL_DAY_DROP_OFF: "ALL DAY DROP OFF",
|
ALL_DAY_DROP_OFF: "ALL DAY DROP OFF",
|
||||||
OVERNIGHT_DROP_OFF: "OVERNIGHT DROP OFF",
|
OVERNIGHT_DROP_OFF: "OVERNIGHT DROP OFF",
|
||||||
|
|
@ -31,4 +33,5 @@ export {
|
||||||
PRICING_BY_DAY_PART_TYPE,
|
PRICING_BY_DAY_PART_TYPE,
|
||||||
RouteCodeFlags,
|
RouteCodeFlags,
|
||||||
cmsWidgetFieldMappings,
|
cmsWidgetFieldMappings,
|
||||||
|
RECAL_ACK_YES,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ const storeActions = {
|
||||||
GET_ALERT_REASONS_BY_CTU: "getAlertReasonsByCtu",
|
GET_ALERT_REASONS_BY_CTU: "getAlertReasonsByCtu",
|
||||||
GET_PARTS_OR_QUESTIONS: "getPartsOrQuestions",
|
GET_PARTS_OR_QUESTIONS: "getPartsOrQuestions",
|
||||||
GET_PARTS: "getParts",
|
GET_PARTS: "getParts",
|
||||||
|
GET_OEM_AFTERMARKET_PARTS: "getOemAfterMarketParts",
|
||||||
GET_WIPERS: "getWipers",
|
GET_WIPERS: "getWipers",
|
||||||
GET_RAIN_REPEL: "getRainRepel",
|
GET_RAIN_REPEL: "getRainRepel",
|
||||||
GET_SUPPORTING_ITEMS: "getSupportingItems",
|
GET_SUPPORTING_ITEMS: "getSupportingItems",
|
||||||
|
|
@ -32,7 +33,6 @@ const storeActions = {
|
||||||
GET_MOLDING_QUESTIONS: "getMoldingQuestions",
|
GET_MOLDING_QUESTIONS: "getMoldingQuestions",
|
||||||
GET_MOBILE_FEE_PART: "getMobileFeePart",
|
GET_MOBILE_FEE_PART: "getMobileFeePart",
|
||||||
GET_PRICING_BY_DAY_PART: "getPricingByDayPart",
|
GET_PRICING_BY_DAY_PART: "getPricingByDayPart",
|
||||||
GET_SERVICE_PACKAGE_DISCOUNT_PART: "getServicePackageDiscountPart",
|
|
||||||
GET_SERVICEABILITY_DETAILS: "getServiceabilityDetails",
|
GET_SERVICEABILITY_DETAILS: "getServiceabilityDetails",
|
||||||
GET_SHOP_TIME_SLOTS: "getShopTimeSlots",
|
GET_SHOP_TIME_SLOTS: "getShopTimeSlots",
|
||||||
GET_MOBILE_TIME_SLOTS: "getMobileTimeSlots",
|
GET_MOBILE_TIME_SLOTS: "getMobileTimeSlots",
|
||||||
|
|
@ -111,6 +111,8 @@ const storeActions = {
|
||||||
SAVE_PAYPAL_TOKEN: "savePaypalToken",
|
SAVE_PAYPAL_TOKEN: "savePaypalToken",
|
||||||
SAVE_NEXTGEN_SETTLED_AMOUNT: "saveNextGenSettledAmount",
|
SAVE_NEXTGEN_SETTLED_AMOUNT: "saveNextGenSettledAmount",
|
||||||
SAVE_IS_RECAL_ACK_OPT_IN: "saveIsRecalAckOptIn",
|
SAVE_IS_RECAL_ACK_OPT_IN: "saveIsRecalAckOptIn",
|
||||||
|
SAVE_IS_RECAL_ACKNOWLEDGED_FOR_SCHEDULING: "saveIsRecalAcknowledgedForScheduling",
|
||||||
|
SAVE_IS_OEM_GLASS_SELECTED: "saveIsOemGlassSelected",
|
||||||
SAVE_IS_MSR_FEE_APPLICABLE: "saveIsMSRFeeApplicable",
|
SAVE_IS_MSR_FEE_APPLICABLE: "saveIsMSRFeeApplicable",
|
||||||
|
|
||||||
CREATE_SUBMITTED_STATE: "createSubmittedState",
|
CREATE_SUBMITTED_STATE: "createSubmittedState",
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,8 @@ const storeMutations = {
|
||||||
LOCK_TOKEN: "updateLockToken",
|
LOCK_TOKEN: "updateLockToken",
|
||||||
UPDATE_SETTLED_TENDER_AMOUNT: "updateSettledTenderAmount",
|
UPDATE_SETTLED_TENDER_AMOUNT: "updateSettledTenderAmount",
|
||||||
UPDATE_IS_RECAL_ACK_OPT_IN: "updateIsRecalAckOptIn",
|
UPDATE_IS_RECAL_ACK_OPT_IN: "updateIsRecalAckOptIn",
|
||||||
|
UPDATE_IS_RECAL_ACKNOWLEDGED_FOR_SCHEDULING: "updateIsRecalAcknowledgedForScheduling",
|
||||||
|
UPDATE_IS_OEM_GLASS_SELECTED: "updateIsOemGlassSelected",
|
||||||
UPDATE_IS_MSR_FEE_APPLICABLE: "updateIsMSRFeeApplicable",
|
UPDATE_IS_MSR_FEE_APPLICABLE: "updateIsMSRFeeApplicable",
|
||||||
UPDATE_CASH_PRICE_SUBTOTAL: "updateCashPriceSubTotal",
|
UPDATE_CASH_PRICE_SUBTOTAL: "updateCashPriceSubTotal",
|
||||||
|
|
||||||
|
|
@ -117,6 +119,7 @@ const storeMutations = {
|
||||||
UPDATE_EXTERNAL_PARAMETER_SERVICE_PACKAGE: "updateExternalParameterServicePackage",
|
UPDATE_EXTERNAL_PARAMETER_SERVICE_PACKAGE: "updateExternalParameterServicePackage",
|
||||||
UPDATE_EXTERNAL_PARAMETER_SOURCE: "updateExternalParameterSource",
|
UPDATE_EXTERNAL_PARAMETER_SOURCE: "updateExternalParameterSource",
|
||||||
UPDATE_EXTERNAL_PARAMETER_PHONE_NUMBER: "updateExternalParameterPhoneNumber",
|
UPDATE_EXTERNAL_PARAMETER_PHONE_NUMBER: "updateExternalParameterPhoneNumber",
|
||||||
|
UPDATE_EXTERNAL_PARAMETER_QS_STASH: "updateExternalParameterQsStash",
|
||||||
|
|
||||||
//RESET EXTERNAL_PARAMETER MUTATIONS
|
//RESET EXTERNAL_PARAMETER MUTATIONS
|
||||||
RESET_EXTERNAL_PARAMETER_VEHICLE_STATE: "resetExternalParameterVehicleState",
|
RESET_EXTERNAL_PARAMETER_VEHICLE_STATE: "resetExternalParameterVehicleState",
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,17 +1,18 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="date-picker text-center"
|
class="date-picker text-center"
|
||||||
:class="`${calendarViewDirection} calendar-2025 ${showPricingByDayClass}`">
|
:class="`${calendarViewDirection} calendar-2025 ${showPricingByDayClass} ${loadingStatus === 'reinitial' ? 'loading-reinitial' : ''}`">
|
||||||
<fieldset id="date-picker-fieldset" ref="datePickerFieldset">
|
<fieldset id="date-picker-fieldset" ref="datePickerFieldset">
|
||||||
<legend class="sr-only">Select a day and time</legend>
|
<legend class="sr-only">Select a day and time</legend>
|
||||||
<div
|
<div
|
||||||
v-for="month in months"
|
v-for="(month, i) in months"
|
||||||
:key="`${month.monthLabel}-${month.yearNum?.toString()}`"
|
:key="`${month.monthLabel}-${month.yearNum?.toString()}`"
|
||||||
:id="`${month.monthLabel}-${month.yearNum?.toString()}`"
|
:id="`${month.monthLabel}-${month.yearNum?.toString()}`"
|
||||||
class="calendar-grid-container"
|
class="calendar-grid-container month"
|
||||||
:class="[
|
:class="[
|
||||||
hideSomeDaysForInitialView ? 'partial-month-initial-view' : '',
|
hideSomeDaysForInitialView ? 'partial-month-initial-view' : '',
|
||||||
month.monthClass,
|
month.monthClass,
|
||||||
|
i === 0 ? 'first-month-shown' : '',
|
||||||
]">
|
]">
|
||||||
<div class="month-year body-small d-flex align-items-center">
|
<div class="month-year body-small d-flex align-items-center">
|
||||||
{{ month.monthLabel }} {{ month.yearNum?.toString() }}
|
{{ month.monthLabel }} {{ month.yearNum?.toString() }}
|
||||||
|
|
@ -114,7 +115,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<loader
|
<loader
|
||||||
:class="[!isLoading ? 'date-picker-hidden' : '']"
|
class="date-picker-loader"
|
||||||
|
:class="[loadingStatus !== 'none' ? 'show-loader' : '']"
|
||||||
loaderColor="blue"
|
loaderColor="blue"
|
||||||
loaderPosition="center" />
|
loaderPosition="center" />
|
||||||
<div class="row form-test-error" id="date-of-month-error">
|
<div class="row form-test-error" id="date-of-month-error">
|
||||||
|
|
@ -125,7 +127,7 @@
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-link view-more-dates"
|
class="btn btn-link view-more-dates"
|
||||||
id="viewMoreDates"
|
id="viewMoreDates"
|
||||||
:disabled="isLoading"
|
:disabled="loadingStatus !== 'none'"
|
||||||
@click="showAnotherMonth">
|
@click="showAnotherMonth">
|
||||||
View more dates
|
View more dates
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -160,7 +162,6 @@ export default {
|
||||||
name: "datePicker",
|
name: "datePicker",
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isLoading: true,
|
|
||||||
months: null,
|
months: null,
|
||||||
disableViewMoreDatesButton: false,
|
disableViewMoreDatesButton: false,
|
||||||
hideSomeDaysForInitialView: null,
|
hideSomeDaysForInitialView: null,
|
||||||
|
|
@ -169,7 +170,10 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
customComponentId: String,
|
customComponentId: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
selectableDatesSetting: {
|
selectableDatesSetting: {
|
||||||
type: String,
|
type: String,
|
||||||
validator(value) {
|
validator(value) {
|
||||||
|
|
@ -200,6 +204,10 @@ export default {
|
||||||
pricingByDayUpcharge: Number,
|
pricingByDayUpcharge: Number,
|
||||||
isPricingByDayExperiment: Boolean,
|
isPricingByDayExperiment: Boolean,
|
||||||
isMobileSelected: Boolean,
|
isMobileSelected: Boolean,
|
||||||
|
loadingStatus: {
|
||||||
|
type: String,
|
||||||
|
default: "none",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const uuid = uuidv4();
|
const uuid = uuidv4();
|
||||||
|
|
@ -281,7 +289,7 @@ export default {
|
||||||
if (event.screenX === 0 && event.screenY === 0) {
|
if (event.screenX === 0 && event.screenY === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$emit("date-clicked", date);
|
this.$emit("date-selected", date);
|
||||||
},
|
},
|
||||||
getWeekStartDate(dateString) {
|
getWeekStartDate(dateString) {
|
||||||
const date = convertDateStringToDate(dateString);
|
const date = convertDateStringToDate(dateString);
|
||||||
|
|
@ -324,9 +332,9 @@ export default {
|
||||||
let preSelectedDateMonthEnd = this.getMonthEnd(
|
let preSelectedDateMonthEnd = this.getMonthEnd(
|
||||||
preSelectedDate.replace("-mobile", "")
|
preSelectedDate.replace("-mobile", "")
|
||||||
);
|
);
|
||||||
let weekIncludesPreSelectedMonthEnd = false;
|
let monthEndsByThisWeek = false;
|
||||||
let i = 0;
|
let i = 0;
|
||||||
while (!weekIncludesPreSelectedMonthEnd) {
|
while (!monthEndsByThisWeek && i < 52) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
weekStartDate = this.getNextWeekSunday(weekEndDate);
|
weekStartDate = this.getNextWeekSunday(weekEndDate);
|
||||||
weekEndDate = this.getWeekEndDate(weekStartDate);
|
weekEndDate = this.getWeekEndDate(weekStartDate);
|
||||||
|
|
@ -338,7 +346,12 @@ export default {
|
||||||
preSelectedDateMonthEnd === weekEndDate
|
preSelectedDateMonthEnd === weekEndDate
|
||||||
) {
|
) {
|
||||||
weekEndDate = preSelectedDateMonthEnd;
|
weekEndDate = preSelectedDateMonthEnd;
|
||||||
weekIncludesPreSelectedMonthEnd = true;
|
monthEndsByThisWeek = true;
|
||||||
|
} else if (preSelectedDateMonthEnd < weekEndDate) {
|
||||||
|
// Additional case: if month ends before this week (but not necessarily during it),
|
||||||
|
// still cut the loop here, but don't truncate the week.
|
||||||
|
|
||||||
|
monthEndsByThisWeek = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
weeks.push({
|
weeks.push({
|
||||||
|
|
@ -466,7 +479,7 @@ export default {
|
||||||
const response = config.getSelectableDatesCallback({
|
const response = config.getSelectableDatesCallback({
|
||||||
startDateString: initialViewStartDate,
|
startDateString: initialViewStartDate,
|
||||||
endDateString: initialViewEndDate,
|
endDateString: initialViewEndDate,
|
||||||
providerNumber: config.providerNumber,
|
inshopProviderNumber: config.inshopProviderNumber,
|
||||||
zipCode: config.zipCode,
|
zipCode: config.zipCode,
|
||||||
includeMobileTimeSlots: config.includeMobileTimeSlots,
|
includeMobileTimeSlots: config.includeMobileTimeSlots,
|
||||||
includeInshopTimeSlots: config.includeInshopTimeSlots,
|
includeInshopTimeSlots: config.includeInshopTimeSlots,
|
||||||
|
|
@ -489,7 +502,6 @@ export default {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
async setCalendarData(config = {}) {
|
async setCalendarData(config = {}) {
|
||||||
this.isLoading = true;
|
|
||||||
this.selectableDatesInshop = [];
|
this.selectableDatesInshop = [];
|
||||||
this.selectableDatesMobile = [];
|
this.selectableDatesMobile = [];
|
||||||
this.months = [];
|
this.months = [];
|
||||||
|
|
@ -541,7 +553,6 @@ export default {
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
this.months = months;
|
this.months = months;
|
||||||
this.isLoading = false;
|
|
||||||
|
|
||||||
if (config.preSelectedDate) {
|
if (config.preSelectedDate) {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
|
@ -729,7 +740,6 @@ export default {
|
||||||
},
|
},
|
||||||
async showAnotherMonth() {
|
async showAnotherMonth() {
|
||||||
if (!this.months) return;
|
if (!this.months) return;
|
||||||
this.isLoading = true;
|
|
||||||
let monthToShow;
|
let monthToShow;
|
||||||
let monthStartDate;
|
let monthStartDate;
|
||||||
|
|
||||||
|
|
@ -774,7 +784,6 @@ export default {
|
||||||
monthToShowDates[monthToShowDates.length - 1].inputValue
|
monthToShowDates[monthToShowDates.length - 1].inputValue
|
||||||
);
|
);
|
||||||
|
|
||||||
this.isLoading = false;
|
|
||||||
this.hideSomeDaysForInitialView = false; // if hid days on initial partial view, this will reveal those days
|
this.hideSomeDaysForInitialView = false; // if hid days on initial partial view, this will reveal those days
|
||||||
monthToShow.monthClass = monthToShow.monthClass.replace(" month-hidden", "");
|
monthToShow.monthClass = monthToShow.monthClass.replace(" month-hidden", "");
|
||||||
this.scrollToElement(monthToShow.monthString);
|
this.scrollToElement(monthToShow.monthString);
|
||||||
|
|
@ -787,7 +796,6 @@ export default {
|
||||||
},
|
},
|
||||||
async updateSelectableDates(monthStart, monthEnd) {
|
async updateSelectableDates(monthStart, monthEnd) {
|
||||||
const moreSelectableDates = await this.getMoreDatesCallback(monthStart, monthEnd);
|
const moreSelectableDates = await this.getMoreDatesCallback(monthStart, monthEnd);
|
||||||
|
|
||||||
moreSelectableDates.inshopTimeSlotsData.days.forEach((selectableDate) => {
|
moreSelectableDates.inshopTimeSlotsData.days.forEach((selectableDate) => {
|
||||||
const index = this.selectableDatesInshop.findIndex(
|
const index = this.selectableDatesInshop.findIndex(
|
||||||
(dateObj) => dateObj.date === selectableDate.date
|
(dateObj) => dateObj.date === selectableDate.date
|
||||||
|
|
@ -846,12 +854,6 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
isLoading(newValue) {
|
|
||||||
// if done loading dates, then set to first available date
|
|
||||||
if (newValue === false && this.firstAvailableSelectableDate) {
|
|
||||||
this.selectedDate = this.firstAvailableSelectableDate;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
modelValue(newValue) {
|
modelValue(newValue) {
|
||||||
this.resetField({
|
this.resetField({
|
||||||
value: newValue,
|
value: newValue,
|
||||||
|
|
@ -872,9 +874,14 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.date-picker-hidden {
|
.date-picker-loader {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
max-height: 0;
|
max-height: 0;
|
||||||
|
|
||||||
|
&.show-loader {
|
||||||
|
opacity: 1;
|
||||||
|
max-height: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.date-picker {
|
.date-picker {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
@ -903,12 +910,12 @@ export default {
|
||||||
height: 1.5rem;
|
height: 1.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.calendar-grid-container {
|
.month {
|
||||||
margin: 0 auto 1rem auto;
|
margin: 0 auto 1rem auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
transition:
|
transition:
|
||||||
height ease 2s,
|
height ease 1s,
|
||||||
opacity ease 2s;
|
max-height ease 1s;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(7, 1fr);
|
grid-template-columns: repeat(7, 1fr);
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
@ -1157,7 +1164,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.past {
|
.past {
|
||||||
.calendar-grid-container {
|
.month {
|
||||||
.month-year {
|
.month-year {
|
||||||
grid-area: 1 / 1 / 2 / 6;
|
grid-area: 1 / 1 / 2 / 6;
|
||||||
}
|
}
|
||||||
|
|
@ -1214,7 +1221,7 @@ export default {
|
||||||
}
|
}
|
||||||
// new calendar styling overrides
|
// new calendar styling overrides
|
||||||
&.calendar-2025 {
|
&.calendar-2025 {
|
||||||
.calendar-grid-container .grid-item {
|
.month .grid-item {
|
||||||
margin: 0 0 0.15rem 0;
|
margin: 0 0 0.15rem 0;
|
||||||
}
|
}
|
||||||
.month-year {
|
.month-year {
|
||||||
|
|
@ -1316,6 +1323,33 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.loading-reinitial {
|
||||||
|
.month {
|
||||||
|
opacity: 0;
|
||||||
|
max-height: 0;
|
||||||
|
}
|
||||||
|
.month.first-month-shown {
|
||||||
|
opacity: 1;
|
||||||
|
max-height: none;
|
||||||
|
|
||||||
|
.grid-item.radio-wrapper.selectable-day {
|
||||||
|
input[type="radio"]:checked + label,
|
||||||
|
label {
|
||||||
|
background-color: $white;
|
||||||
|
border: none;
|
||||||
|
color: initial;
|
||||||
|
cursor: default;
|
||||||
|
&:hover {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
font-family: UrbanistRegular;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
:deep(.timeslots .button-inner-wrapper) {
|
:deep(.timeslots .button-inner-wrapper) {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,10 @@ export default {
|
||||||
return this.staticBackdrop ? "static" : "true";
|
return this.staticBackdrop ? "static" : "true";
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
unmounted() {
|
||||||
|
// remove any modal effects before leaving page (e.g. user hits browser back button)
|
||||||
|
this.closeModal();
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
modalButtonMain,
|
modalButtonMain,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
// ***************************************************************
|
||||||
|
// This file wraps the Salesforce generated code.
|
||||||
|
// See the comment below for where you need to paste in the Salesforce generated code.
|
||||||
|
// You may also need to modify the script tag src located in salesforce-webchat.vue to point to the correct Salesforce instance.
|
||||||
|
// ***************************************************************
|
||||||
|
|
||||||
function setupCustomSettings(
|
function setupCustomSettings(
|
||||||
modifyEmbeddedSvcCallback,
|
modifyEmbeddedSvcCallback,
|
||||||
|
|
@ -7,90 +12,38 @@ function setupCustomSettings(
|
||||||
onWebchatCloseCallback
|
onWebchatCloseCallback
|
||||||
) {
|
) {
|
||||||
modifyEmbeddedSvcCallback();
|
modifyEmbeddedSvcCallback();
|
||||||
embedded_svc.addEventHandler("onSettingsCallCompleted", finishedLoadingCallback);
|
window.addEventListener("onEmbeddedMessagingButtonCreated", finishedLoadingCallback);
|
||||||
embedded_svc.addEventHandler("afterMaximize", onWebchatOpenCallback);
|
window.addEventListener("onEmbeddedMessagingWindowMaximized", onWebchatOpenCallback);
|
||||||
embedded_svc.addEventHandler("afterDestroy", onWebchatCloseCallback);
|
window.addEventListener("onEmbeddedMessagingWindowClosed", onWebchatCloseCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
The code below is generated from salesforce but modified in the following ways:
|
|
||||||
* Only the javascript inside the second <script> tag in the provided salesforce code is copy pasted
|
|
||||||
* CSS is not copied in
|
|
||||||
* First <script> tag loading in the file from the CDN is not copied in
|
|
||||||
* Copy the entire contents of the second <script> tag inside the initializeSalesforceWebchatForDev
|
|
||||||
method and add a call to setupCustomSettings before the 'embedded_svc.init()' method is called
|
|
||||||
|
|
||||||
Actual call to paste in:
|
|
||||||
setupCustomSettings(
|
|
||||||
modifyEmbeddedSvcCallback,
|
|
||||||
finishedLoadingCallback,
|
|
||||||
onWebchatOpenCallback,
|
|
||||||
onWebchatCloseCallback
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
|
|
||||||
export function initializeSalesforceWebchatForDev(
|
export function initializeSalesforceWebchatForDev(
|
||||||
modifyEmbeddedSvcCallback,
|
modifyEmbeddedSvcCallback,
|
||||||
finishedLoadingCallback,
|
finishedLoadingCallback,
|
||||||
onWebchatOpenCallback,
|
onWebchatOpenCallback,
|
||||||
onWebchatCloseCallback
|
onWebchatCloseCallback
|
||||||
) {
|
) {
|
||||||
var initESW = function (gslbBaseURL) {
|
setupCustomSettings(
|
||||||
embedded_svc.settings.displayHelpButton = true; //Or false
|
modifyEmbeddedSvcCallback,
|
||||||
embedded_svc.settings.language = ""; //For example, enter 'en' or 'en-US'
|
finishedLoadingCallback,
|
||||||
//embedded_svc.settings.defaultMinimizedText = '...'; //(Defaults to Chat with an Expert)
|
onWebchatOpenCallback,
|
||||||
//embedded_svc.settings.disabledMinimizedText = '...'; //(Defaults to Agent Offline)
|
onWebchatCloseCallback
|
||||||
//embedded_svc.settings.loadingText = ''; //(Defaults to Loading)
|
);
|
||||||
//embedded_svc.settings.storageDomain = 'yourdomain.com'; //(Sets the domain for your deployment so that visitors can navigate subdomains during a chat session)
|
// START OF SALESFORCE GENERATED CODE
|
||||||
// Settings for Chat
|
// Copy in the contents of the first <script> tag inside the initEmbeddedMessaging() method
|
||||||
//embedded_svc.settings.directToButtonRouting = function(prechatFormData) {
|
try {
|
||||||
// Dynamically changes the button ID based on what the visitor enters in the pre-chat form.
|
embeddedservice_bootstrap.settings.language = "en_US"; // For example, enter 'en' or 'en-US'
|
||||||
// Returns a valid button ID.
|
|
||||||
//};
|
|
||||||
//embedded_svc.settings.prepopulatedPrechatFields = {}; //Sets the auto-population of pre-chat form fields
|
|
||||||
//embedded_svc.settings.fallbackRouting = []; //An array of button IDs, user IDs, or userId_buttonId
|
|
||||||
//embedded_svc.settings.offlineSupportMinimizedText = '...'; //(Defaults to Contact Us)
|
|
||||||
|
|
||||||
embedded_svc.settings.enabledFeatures = ["LiveAgent"];
|
embeddedservice_bootstrap.init(
|
||||||
embedded_svc.settings.entryFeature = "LiveAgent";
|
|
||||||
|
|
||||||
setupCustomSettings(
|
|
||||||
modifyEmbeddedSvcCallback,
|
|
||||||
finishedLoadingCallback,
|
|
||||||
onWebchatOpenCallback,
|
|
||||||
onWebchatCloseCallback
|
|
||||||
);
|
|
||||||
|
|
||||||
embedded_svc.init(
|
|
||||||
"https://safelite2--dev.sandbox.my.salesforce.com",
|
|
||||||
"https://safelite2--dev.sandbox.my.salesforce-sites.com/chat",
|
|
||||||
gslbBaseURL,
|
|
||||||
"00D6s0000008r6A",
|
"00D6s0000008r6A",
|
||||||
"Sales_Central_Snap_in",
|
"Sales_Central_TFN",
|
||||||
|
"https://safelite2--dev.sandbox.my.site.com/ESWSalesCentralTFN1755660094477",
|
||||||
{
|
{
|
||||||
baseLiveAgentContentURL:
|
scrt2URL: "https://safelite2--dev.sandbox.my.salesforce-scrt.com",
|
||||||
"https://c.la12s-core1.sfdc-8tgtt5.salesforceliveagent.com/content",
|
|
||||||
deploymentId: "572Wr0000017xKX",
|
|
||||||
buttonId: "573Wr000000CpgH",
|
|
||||||
baseLiveAgentURL: "https://d.la12s-core1.sfdc-8tgtt5.salesforceliveagent.com/chat",
|
|
||||||
eswLiveAgentDevName:
|
|
||||||
"EmbeddedServiceLiveAgent_Parent04IWr000003yKq9MAE_1961681659a",
|
|
||||||
isOfflineSupportEnabled: false,
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
} catch (err) {
|
||||||
|
console.error("Error loading Embedded Messaging: ", err);
|
||||||
if (!window.embedded_svc) {
|
|
||||||
var s = document.createElement("script");
|
|
||||||
s.setAttribute(
|
|
||||||
"src",
|
|
||||||
"https://safelite2--dev.sandbox.my.salesforce.com/embeddedservice/5.0/esw.min.js"
|
|
||||||
);
|
|
||||||
s.onload = function () {
|
|
||||||
initESW(null);
|
|
||||||
};
|
|
||||||
document.body.appendChild(s);
|
|
||||||
} else {
|
|
||||||
initESW("https://service.force.com");
|
|
||||||
}
|
}
|
||||||
|
// END OF SALESFORCE GENERATED CODE
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
// ***************************************************************
|
||||||
|
// This file wraps the Salesforce generated code.
|
||||||
|
// See the comment below for where you need to paste in the Salesforce generated code.
|
||||||
|
// You may also need to modify the script tag src located in salesforce-webchat.vue to point to the correct Salesforce instance.
|
||||||
|
// ***************************************************************
|
||||||
|
|
||||||
function setupCustomSettings(
|
function setupCustomSettings(
|
||||||
modifyEmbeddedSvcCallback,
|
modifyEmbeddedSvcCallback,
|
||||||
|
|
@ -7,91 +12,39 @@ function setupCustomSettings(
|
||||||
onWebchatCloseCallback
|
onWebchatCloseCallback
|
||||||
) {
|
) {
|
||||||
modifyEmbeddedSvcCallback();
|
modifyEmbeddedSvcCallback();
|
||||||
embedded_svc.addEventHandler("onSettingsCallCompleted", finishedLoadingCallback);
|
window.addEventListener("onEmbeddedMessagingButtonCreated", finishedLoadingCallback);
|
||||||
embedded_svc.addEventHandler("afterMaximize", onWebchatOpenCallback);
|
window.addEventListener("onEmbeddedMessagingWindowMaximized", onWebchatOpenCallback);
|
||||||
embedded_svc.addEventHandler("afterDestroy", onWebchatCloseCallback);
|
window.addEventListener("onEmbeddedMessagingWindowClosed", onWebchatCloseCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
The code below is generated from salesforce but modified in the following ways:
|
|
||||||
* Only the javascript inside the second <script> tag in the provided salesforce code is copy pasted
|
|
||||||
* CSS is not copied in
|
|
||||||
* First <script> tag loading in the file from the CDN is not copied in
|
|
||||||
* Copy the entire contents of the second <script> tag inside the initializeSalesforceWebchatForDev
|
|
||||||
method and add a call to setupCustomSettings before the 'embedded_svc.init()' method is called
|
|
||||||
|
|
||||||
Actual call to paste in:
|
|
||||||
setupCustomSettings(
|
|
||||||
modifyEmbeddedSvcCallback,
|
|
||||||
finishedLoadingCallback,
|
|
||||||
onWebchatOpenCallback,
|
|
||||||
onWebchatCloseCallback
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
|
|
||||||
export function initializeSalesforceWebchatForProd(
|
export function initializeSalesforceWebchatForProd(
|
||||||
modifyEmbeddedSvcCallback,
|
modifyEmbeddedSvcCallback,
|
||||||
finishedLoadingCallback,
|
finishedLoadingCallback,
|
||||||
onWebchatOpenCallback,
|
onWebchatOpenCallback,
|
||||||
onWebchatCloseCallback
|
onWebchatCloseCallback
|
||||||
) {
|
) {
|
||||||
var initESW = function (gslbBaseURL) {
|
setupCustomSettings(
|
||||||
let embedded_svc = window.embedded_svc;
|
modifyEmbeddedSvcCallback,
|
||||||
embedded_svc.settings.displayHelpButton = true; //Or false
|
finishedLoadingCallback,
|
||||||
embedded_svc.settings.language = ""; //For example, enter 'en' or 'en-US'
|
onWebchatOpenCallback,
|
||||||
|
onWebchatCloseCallback
|
||||||
|
);
|
||||||
|
|
||||||
//embedded_svc.settings.defaultMinimizedText = '...'; //(Defaults to Chat with an Expert)
|
// START OF SALESFORCE GENERATED CODE
|
||||||
//embedded_svc.settings.disabledMinimizedText = '...'; //(Defaults to Agent Offline)
|
// Copy in the contents of the first <script> tag inside the initEmbeddedMessaging() method
|
||||||
|
try {
|
||||||
|
embeddedservice_bootstrap.settings.language = "en_US"; // For example, enter 'en' or 'en-US'
|
||||||
|
|
||||||
//embedded_svc.settings.loadingText = ''; //(Defaults to Loading)
|
embeddedservice_bootstrap.init(
|
||||||
//embedded_svc.settings.storageDomain = 'yourdomain.com'; //(Sets the domain for your deployment so that visitors can navigate subdomains during a chat session)
|
|
||||||
|
|
||||||
// Settings for Chat
|
|
||||||
//embedded_svc.settings.directToButtonRouting = function(prechatFormData) {
|
|
||||||
// Dynamically changes the button ID based on what the visitor enters in the pre-chat form.
|
|
||||||
// Returns a valid button ID.
|
|
||||||
//};
|
|
||||||
//embedded_svc.settings.prepopulatedPrechatFields = {}; //Sets the auto-population of pre-chat form fields
|
|
||||||
//embedded_svc.settings.fallbackRouting = []; //An array of button IDs, user IDs, or userId_buttonId
|
|
||||||
//embedded_svc.settings.offlineSupportMinimizedText = '...'; //(Defaults to Contact Us)
|
|
||||||
|
|
||||||
embedded_svc.settings.enabledFeatures = ["LiveAgent"];
|
|
||||||
embedded_svc.settings.entryFeature = "LiveAgent";
|
|
||||||
|
|
||||||
setupCustomSettings(
|
|
||||||
modifyEmbeddedSvcCallback,
|
|
||||||
finishedLoadingCallback,
|
|
||||||
onWebchatOpenCallback,
|
|
||||||
onWebchatCloseCallback
|
|
||||||
);
|
|
||||||
|
|
||||||
embedded_svc.init(
|
|
||||||
"https://safelite2.my.salesforce.com",
|
|
||||||
"https://safelite2.my.salesforce-sites.com/chat",
|
|
||||||
gslbBaseURL,
|
|
||||||
"00D3t000004nvsT",
|
"00D3t000004nvsT",
|
||||||
"Sales_Central_Snap_in",
|
"Sales_Central_TFN",
|
||||||
|
"https://safelite2.my.site.com/ESWSalesCentralTFN1769108630294",
|
||||||
{
|
{
|
||||||
baseLiveAgentContentURL:
|
scrt2URL: "https://safelite2.my.salesforce-scrt.com",
|
||||||
"https://c.la13-core2.sfdc-lywfpd.salesforceliveagent.com/content",
|
|
||||||
deploymentId: "5723t0000008wWB",
|
|
||||||
buttonId: "5733t000000D90z",
|
|
||||||
baseLiveAgentURL: "https://d.la13-core2.sfdc-lywfpd.salesforceliveagent.com/chat",
|
|
||||||
eswLiveAgentDevName:
|
|
||||||
"EmbeddedServiceLiveAgent_Parent04I3t000000Cq0SEAS_188de1871ea",
|
|
||||||
isOfflineSupportEnabled: false,
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
} catch (err) {
|
||||||
|
console.error("Error loading Embedded Messaging: ", err);
|
||||||
if (!window.embedded_svc) {
|
|
||||||
var s = document.createElement("script");
|
|
||||||
s.setAttribute("src", "https://safelite2.my.salesforce.com/embeddedservice/5.0/esw.min.js");
|
|
||||||
s.onload = function () {
|
|
||||||
initESW(null);
|
|
||||||
};
|
|
||||||
document.body.appendChild(s);
|
|
||||||
} else {
|
|
||||||
initESW("https://service.force.com");
|
|
||||||
}
|
}
|
||||||
|
// END OF SALESFORCE GENERATED CODE
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
|
// ***************************************************************
|
||||||
|
// This file wraps the Salesforce generated code.
|
||||||
|
// See the comment below for where you need to paste in the Salesforce generated code.
|
||||||
|
// You may also need to modify the script tag src located in salesforce-webchat.vue to point to the correct Salesforce instance.
|
||||||
|
// ***************************************************************
|
||||||
|
|
||||||
function setupCustomSettings(
|
function setupCustomSettings(
|
||||||
modifyEmbeddedSvcCallback,
|
modifyEmbeddedSvcCallback,
|
||||||
|
|
@ -7,93 +12,38 @@ function setupCustomSettings(
|
||||||
onWebchatCloseCallback
|
onWebchatCloseCallback
|
||||||
) {
|
) {
|
||||||
modifyEmbeddedSvcCallback();
|
modifyEmbeddedSvcCallback();
|
||||||
embedded_svc.addEventHandler("onSettingsCallCompleted", finishedLoadingCallback);
|
window.addEventListener("onEmbeddedMessagingButtonCreated", finishedLoadingCallback);
|
||||||
embedded_svc.addEventHandler("afterMaximize", onWebchatOpenCallback);
|
window.addEventListener("onEmbeddedMessagingWindowMaximized", onWebchatOpenCallback);
|
||||||
embedded_svc.addEventHandler("afterDestroy", onWebchatCloseCallback);
|
window.addEventListener("onEmbeddedMessagingWindowClosed", onWebchatCloseCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
The code below is generated from salesforce but modified in the following ways:
|
|
||||||
* Only the javascript inside the second <script> tag in the provided salesforce code is copy pasted
|
|
||||||
* CSS is not copied in
|
|
||||||
* First <script> tag loading in the file from the CDN is not copied in
|
|
||||||
* Copy the entire contents of the second <script> tag inside the initializeSalesforceWebchatForQa
|
|
||||||
method and add a call to setupCustomSettings before the 'embedded_svc.init()' method is called
|
|
||||||
|
|
||||||
Actual call to paste in:
|
|
||||||
setupCustomSettings(
|
|
||||||
modifyEmbeddedSvcCallback,
|
|
||||||
finishedLoadingCallback,
|
|
||||||
onWebchatOpenCallback,
|
|
||||||
onWebchatCloseCallback
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
|
|
||||||
export function initializeSalesforceWebchatForQa(
|
export function initializeSalesforceWebchatForQa(
|
||||||
modifyEmbeddedSvcCallback,
|
modifyEmbeddedSvcCallback,
|
||||||
finishedLoadingCallback,
|
finishedLoadingCallback,
|
||||||
onWebchatOpenCallback,
|
onWebchatOpenCallback,
|
||||||
onWebchatCloseCallback
|
onWebchatCloseCallback
|
||||||
) {
|
) {
|
||||||
var initESW = function (gslbBaseURL) {
|
setupCustomSettings(
|
||||||
embedded_svc.settings.displayHelpButton = true; //Or false
|
modifyEmbeddedSvcCallback,
|
||||||
embedded_svc.settings.language = ""; //For example, enter 'en' or 'en-US'
|
finishedLoadingCallback,
|
||||||
|
onWebchatOpenCallback,
|
||||||
|
onWebchatCloseCallback
|
||||||
|
);
|
||||||
|
// START OF SALESFORCE GENERATED CODE
|
||||||
|
// Copy in the contents of the first <script> tag inside the initEmbeddedMessaging() method
|
||||||
|
try {
|
||||||
|
embeddedservice_bootstrap.settings.language = "en_US"; // For example, enter 'en' or 'en-US'
|
||||||
|
|
||||||
//embedded_svc.settings.defaultMinimizedText = '...'; //(Defaults to Chat with an Expert)
|
embeddedservice_bootstrap.init(
|
||||||
//embedded_svc.settings.disabledMinimizedText = '...'; //(Defaults to Agent Offline)
|
"00DTI000005x7c7",
|
||||||
|
"Sales_Central_TFN",
|
||||||
//embedded_svc.settings.loadingText = ''; //(Defaults to Loading)
|
"https://safelite2--qa.sandbox.my.site.com/ESWSalesCentralTFN1768832680884",
|
||||||
//embedded_svc.settings.storageDomain = 'yourdomain.com'; //(Sets the domain for your deployment so that visitors can navigate subdomains during a chat session)
|
|
||||||
|
|
||||||
// Settings for Chat
|
|
||||||
//embedded_svc.settings.directToButtonRouting = function(prechatFormData) {
|
|
||||||
// Dynamically changes the button ID based on what the visitor enters in the pre-chat form.
|
|
||||||
// Returns a valid button ID.
|
|
||||||
//};
|
|
||||||
//embedded_svc.settings.prepopulatedPrechatFields = {}; //Sets the auto-population of pre-chat form fields
|
|
||||||
//embedded_svc.settings.fallbackRouting = []; //An array of button IDs, user IDs, or userId_buttonId
|
|
||||||
//embedded_svc.settings.offlineSupportMinimizedText = '...'; //(Defaults to Contact Us)
|
|
||||||
|
|
||||||
embedded_svc.settings.enabledFeatures = ["LiveAgent"];
|
|
||||||
embedded_svc.settings.entryFeature = "LiveAgent";
|
|
||||||
|
|
||||||
setupCustomSettings(
|
|
||||||
modifyEmbeddedSvcCallback,
|
|
||||||
finishedLoadingCallback,
|
|
||||||
onWebchatOpenCallback,
|
|
||||||
onWebchatCloseCallback
|
|
||||||
);
|
|
||||||
|
|
||||||
embedded_svc.init(
|
|
||||||
"https://safelite2--safeliteua.sandbox.my.salesforce.com",
|
|
||||||
"https://safelite2--safeliteua.sandbox.my.salesforce-sites.com/chat",
|
|
||||||
gslbBaseURL,
|
|
||||||
"00DDJ000000HRqO",
|
|
||||||
"Sales_Central_Snap_in",
|
|
||||||
{
|
{
|
||||||
baseLiveAgentContentURL:
|
scrt2URL: "https://safelite2--qa.sandbox.my.salesforce-scrt.com",
|
||||||
"https://c.la12s-core1.sfdc-8tgtt5.salesforceliveagent.com/content",
|
|
||||||
deploymentId: "572DJ00000001j3",
|
|
||||||
buttonId: "573DJ00000001ur",
|
|
||||||
baseLiveAgentURL: "https://d.la12s-core1.sfdc-8tgtt5.salesforceliveagent.com/chat",
|
|
||||||
eswLiveAgentDevName:
|
|
||||||
"EmbeddedServiceLiveAgent_Parent04IDJ0000008OZk2AM_1883057c9a6",
|
|
||||||
isOfflineSupportEnabled: false,
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
} catch (err) {
|
||||||
|
console.error("Error loading Embedded Messaging: ", err);
|
||||||
if (!window.embedded_svc) {
|
|
||||||
var s = document.createElement("script");
|
|
||||||
s.setAttribute(
|
|
||||||
"src",
|
|
||||||
"https://safelite2--safeliteua.sandbox.my.salesforce.com/embeddedservice/5.0/esw.min.js"
|
|
||||||
);
|
|
||||||
s.onload = function () {
|
|
||||||
initESW(null);
|
|
||||||
};
|
|
||||||
document.body.appendChild(s);
|
|
||||||
} else {
|
|
||||||
initESW("https://service.force.com");
|
|
||||||
}
|
}
|
||||||
|
// END OF SALESFORCE GENERATED CODE
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
/* eslint-disable */
|
||||||
|
// ***************************************************************
|
||||||
|
// This file wraps the Salesforce generated code.
|
||||||
|
// See the comment below for where you need to paste in the Salesforce generated code.
|
||||||
|
// You may also need to modify the script tag src located in salesforce-webchat.vue to point to the correct Salesforce instance.
|
||||||
|
// ***************************************************************
|
||||||
|
|
||||||
|
function setupCustomSettings(
|
||||||
|
modifyEmbeddedSvcCallback,
|
||||||
|
finishedLoadingCallback,
|
||||||
|
onWebchatOpenCallback,
|
||||||
|
onWebchatCloseCallback
|
||||||
|
) {
|
||||||
|
modifyEmbeddedSvcCallback();
|
||||||
|
window.addEventListener("onEmbeddedMessagingButtonCreated", finishedLoadingCallback);
|
||||||
|
window.addEventListener("onEmbeddedMessagingWindowMaximized", onWebchatOpenCallback);
|
||||||
|
window.addEventListener("onEmbeddedMessagingWindowClosed", onWebchatCloseCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function initializeSalesforceWebchatForSys(
|
||||||
|
modifyEmbeddedSvcCallback,
|
||||||
|
finishedLoadingCallback,
|
||||||
|
onWebchatOpenCallback,
|
||||||
|
onWebchatCloseCallback
|
||||||
|
) {
|
||||||
|
setupCustomSettings(
|
||||||
|
modifyEmbeddedSvcCallback,
|
||||||
|
finishedLoadingCallback,
|
||||||
|
onWebchatOpenCallback,
|
||||||
|
onWebchatCloseCallback
|
||||||
|
);
|
||||||
|
|
||||||
|
// START OF SALESFORCE GENERATED CODE
|
||||||
|
// Copy in the contents of the first <script> tag inside the initEmbeddedMessaging() method
|
||||||
|
try {
|
||||||
|
embeddedservice_bootstrap.settings.language = "en_US"; // For example, enter 'en' or 'en-US'
|
||||||
|
|
||||||
|
embeddedservice_bootstrap.init(
|
||||||
|
"00DcY0000067qKz",
|
||||||
|
"Sales_Central_TFN",
|
||||||
|
"https://safelite2--sys.sandbox.my.site.com/ESWSalesCentralTFN1767797265631",
|
||||||
|
{
|
||||||
|
scrt2URL: "https://safelite2--sys.sandbox.my.salesforce-scrt.com",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error loading Embedded Messaging: ", err);
|
||||||
|
}
|
||||||
|
// END OF SALESFORCE GENERATED CODE
|
||||||
|
}
|
||||||
|
|
@ -2,10 +2,20 @@ import { shallowMount } from "@vue/test-utils";
|
||||||
import salesforceWebchat from "./salesforce-webchat.vue";
|
import salesforceWebchat from "./salesforce-webchat.vue";
|
||||||
import * as devHelper from "./salesforce-helper-dev";
|
import * as devHelper from "./salesforce-helper-dev";
|
||||||
import * as qaHelper from "./salesforce-helper-qa";
|
import * as qaHelper from "./salesforce-helper-qa";
|
||||||
|
import * as sysHelper from "./salesforce-helper-sys";
|
||||||
import * as prodHelper from "./salesforce-helper-prod";
|
import * as prodHelper from "./salesforce-helper-prod";
|
||||||
import { applicationConfig } from "../../constants/application-config";
|
import { applicationConfig } from "../../constants/application-config";
|
||||||
|
|
||||||
describe("salesforceWebchat.vue", () => {
|
describe("salesforceWebchat.vue", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
window.embeddedservice_bootstrap = {
|
||||||
|
settings: {},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
delete window.embeddedservice_bootstrap;
|
||||||
|
});
|
||||||
it("renders correctly", () => {
|
it("renders correctly", () => {
|
||||||
const wrapper = shallowMount(salesforceWebchat);
|
const wrapper = shallowMount(salesforceWebchat);
|
||||||
expect(wrapper.exists()).toBe(true);
|
expect(wrapper.exists()).toBe(true);
|
||||||
|
|
@ -14,7 +24,7 @@ describe("salesforceWebchat.vue", () => {
|
||||||
it("has the correct default data", () => {
|
it("has the correct default data", () => {
|
||||||
const wrapper = shallowMount(salesforceWebchat);
|
const wrapper = shallowMount(salesforceWebchat);
|
||||||
expect(wrapper.vm.$data).toEqual({
|
expect(wrapper.vm.$data).toEqual({
|
||||||
isAgentAvailable: false,
|
isWebchatLoaded: false,
|
||||||
isWebchatOpen: false,
|
isWebchatOpen: false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -37,6 +47,12 @@ describe("salesforceWebchat.vue", () => {
|
||||||
wrapper.vm.initializeSalesforceWebchat();
|
wrapper.vm.initializeSalesforceWebchat();
|
||||||
expect(mockQa).toHaveBeenCalled();
|
expect(mockQa).toHaveBeenCalled();
|
||||||
|
|
||||||
|
applicationConfig.CURRENT_ENVIRONMENT = "SysTest";
|
||||||
|
wrapper = shallowMount(salesforceWebchat);
|
||||||
|
const mockSys = jest.spyOn(sysHelper, "initializeSalesforceWebchatForSys");
|
||||||
|
wrapper.vm.initializeSalesforceWebchat();
|
||||||
|
expect(mockSys).toHaveBeenCalled();
|
||||||
|
|
||||||
applicationConfig.CURRENT_ENVIRONMENT = "Dev";
|
applicationConfig.CURRENT_ENVIRONMENT = "Dev";
|
||||||
wrapper = shallowMount(salesforceWebchat);
|
wrapper = shallowMount(salesforceWebchat);
|
||||||
const mockDev = jest.spyOn(devHelper, "initializeSalesforceWebchatForDev");
|
const mockDev = jest.spyOn(devHelper, "initializeSalesforceWebchatForDev");
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
// Supporting files
|
// Supporting files
|
||||||
import { initializeSalesforceWebchatForDev } from "./salesforce-helper-dev";
|
import { initializeSalesforceWebchatForDev } from "./salesforce-helper-dev";
|
||||||
import { initializeSalesforceWebchatForQa } from "./salesforce-helper-qa";
|
import { initializeSalesforceWebchatForQa } from "./salesforce-helper-qa";
|
||||||
|
import { initializeSalesforceWebchatForSys } from "./salesforce-helper-sys";
|
||||||
import { initializeSalesforceWebchatForProd } from "./salesforce-helper-prod";
|
import { initializeSalesforceWebchatForProd } from "./salesforce-helper-prod";
|
||||||
import { applicationConfig } from "@/constants/application-config";
|
import { applicationConfig } from "@/constants/application-config";
|
||||||
import { webchatHelper } from "@/helpers/webchat-helper";
|
import { webchatHelper } from "@/helpers/webchat-helper";
|
||||||
|
|
@ -16,7 +17,7 @@ export default {
|
||||||
mixins: [analyticsMixin],
|
mixins: [analyticsMixin],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isAgentAvailable: false,
|
isWebchatLoaded: false,
|
||||||
isWebchatOpen: false,
|
isWebchatOpen: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
@ -33,32 +34,13 @@ export default {
|
||||||
mounted() {
|
mounted() {
|
||||||
// Load in script from salesforce CDN
|
// Load in script from salesforce CDN
|
||||||
const script = document.createElement("script");
|
const script = document.createElement("script");
|
||||||
script.src = "https://service.force.com/embeddedservice/5.0/esw.min.js";
|
script.src = this.webChatScriptSrc;
|
||||||
script.onload = this.initializeSalesforceWebchat;
|
script.onload = this.initializeSalesforceWebchat;
|
||||||
document.body.appendChild(script);
|
document.body.appendChild(script);
|
||||||
|
|
||||||
// Notify funnel-header about Salesforce chat open/close state
|
|
||||||
this._salesforceChatOpenObserver = new MutationObserver(() => {
|
|
||||||
const isOpen = !!document.querySelector(".embeddedServiceSidebar");
|
|
||||||
window.dispatchEvent(
|
|
||||||
new CustomEvent("salesforce-chat-visibility", { detail: { open: isOpen } })
|
|
||||||
);
|
|
||||||
});
|
|
||||||
this._salesforceChatOpenObserver.observe(document.body, {
|
|
||||||
childList: true,
|
|
||||||
subtree: true,
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
// Clean up event listeners and observers
|
// Clean up event listeners and observers
|
||||||
window.removeEventListener(
|
|
||||||
"salesforce-chat-visibility",
|
|
||||||
this._handleSalesforceChatVisibility
|
|
||||||
);
|
|
||||||
window.removeEventListener("sierra-chat-transfer", this._handleSierraToSalesforceTransfer);
|
window.removeEventListener("sierra-chat-transfer", this._handleSierraToSalesforceTransfer);
|
||||||
if (this._salesforceChatOpenObserver) {
|
|
||||||
this._salesforceChatOpenObserver.disconnect();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initializeSalesforceWebchat() {
|
initializeSalesforceWebchat() {
|
||||||
|
|
@ -72,7 +54,6 @@ export default {
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case "QA":
|
case "QA":
|
||||||
case "SysTest":
|
|
||||||
initializeSalesforceWebchatForQa(
|
initializeSalesforceWebchatForQa(
|
||||||
this.modifyEmbeddedSvcCallback,
|
this.modifyEmbeddedSvcCallback,
|
||||||
this.finishedLoadingCallback,
|
this.finishedLoadingCallback,
|
||||||
|
|
@ -80,8 +61,17 @@ export default {
|
||||||
this.onWebchatCloseCallback
|
this.onWebchatCloseCallback
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case "SysTest":
|
||||||
|
initializeSalesforceWebchatForSys(
|
||||||
|
this.modifyEmbeddedSvcCallback,
|
||||||
|
this.finishedLoadingCallback,
|
||||||
|
this.onWebchatOpenCallback,
|
||||||
|
this.onWebchatCloseCallback
|
||||||
|
);
|
||||||
|
break;
|
||||||
case "Dev":
|
case "Dev":
|
||||||
case "Localhost":
|
case "Localhost":
|
||||||
|
default:
|
||||||
initializeSalesforceWebchatForDev(
|
initializeSalesforceWebchatForDev(
|
||||||
this.modifyEmbeddedSvcCallback,
|
this.modifyEmbeddedSvcCallback,
|
||||||
this.finishedLoadingCallback,
|
this.finishedLoadingCallback,
|
||||||
|
|
@ -92,16 +82,13 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
modifyEmbeddedSvcCallback() {
|
modifyEmbeddedSvcCallback() {
|
||||||
window.embedded_svc.settings.avatarImgURL = require("@/assets/img/salesforce-webchat/avatar_webchat.png");
|
window.embeddedservice_bootstrap.settings.hideChatButtonOnLoad = true;
|
||||||
window.embedded_svc.settings.prechatBackgroundImgURL = require("@/assets/img/salesforce-webchat/safelite_logo_webchat.png");
|
window.addEventListener("onEmbeddedMessagingConversationStarted", () => {
|
||||||
window.embedded_svc.settings.smallCompanyLogoImgURL = require("@/assets/img/salesforce-webchat/minimized_chat_bubble_webchat.png");
|
|
||||||
window.embedded_svc.settings.displayHelpButton = false;
|
|
||||||
window.embedded_svc.addEventHandler("onChatEstablished", () => {
|
|
||||||
this.pushEventForChatsToGA("support_chat", "chat_opened", "Live Agent", true);
|
this.pushEventForChatsToGA("support_chat", "chat_opened", "Live Agent", true);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
finishedLoadingCallback(data) {
|
finishedLoadingCallback(data) {
|
||||||
this.isAgentAvailable = data.isAgentAvailable;
|
this.isWebchatLoaded = true;
|
||||||
this.updateShouldShowWebchatButton();
|
this.updateShouldShowWebchatButton();
|
||||||
},
|
},
|
||||||
onWebchatOpenCallback() {
|
onWebchatOpenCallback() {
|
||||||
|
|
@ -117,16 +104,35 @@ export default {
|
||||||
updateShouldShowWebchatButton() {
|
updateShouldShowWebchatButton() {
|
||||||
this.webchatGlobalNonpersistedState.showWebchatButton =
|
this.webchatGlobalNonpersistedState.showWebchatButton =
|
||||||
!this.hideSalesforceWebchatLaunchButton &&
|
!this.hideSalesforceWebchatLaunchButton &&
|
||||||
this.isAgentAvailable &&
|
this.isWebchatLoaded &&
|
||||||
!this.isWebchatOpen;
|
!this.isWebchatOpen;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {},
|
computed: {
|
||||||
|
webChatScriptSrc() {
|
||||||
|
// These URLs are from the src tag on the script tag in the Salesforce generated code.
|
||||||
|
switch (applicationConfig.CURRENT_ENVIRONMENT) {
|
||||||
|
case "Prod":
|
||||||
|
return "https://safelite2.my.site.com/ESWSalesCentralTFN1769108630294/assets/js/bootstrap.min.js";
|
||||||
|
case "QA":
|
||||||
|
return "https://safelite2--qa.sandbox.my.site.com/ESWSalesCentralTFN1768832680884/assets/js/bootstrap.min.js";
|
||||||
|
case "SysTest":
|
||||||
|
return "https://safelite2--sys.sandbox.my.site.com/ESWSalesCentralTFN1767797265631/assets/js/bootstrap.min.js";
|
||||||
|
case "Dev":
|
||||||
|
case "Localhost":
|
||||||
|
default:
|
||||||
|
return "https://safelite2--dev.sandbox.my.site.com/ESWSalesCentralTFN1755660094477/assets/js/bootstrap.min.js";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
components: {},
|
components: {},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
.embedded-messaging > .embeddedMessagingFrame[class~="isMaximized"] {
|
||||||
|
z-index: 9999 !important;
|
||||||
|
}
|
||||||
.dockableContainer {
|
.dockableContainer {
|
||||||
&.showDockableContainer {
|
&.showDockableContainer {
|
||||||
color: $gray-600;
|
color: $gray-600;
|
||||||
|
|
|
||||||
|
|
@ -59,14 +59,6 @@ describe("sierraWebchat.vue", () => {
|
||||||
expect(window.sierraChat.closeChatModal).toHaveBeenCalled();
|
expect(window.sierraChat.closeChatModal).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("dispatches sierra-chat-closed on handleSierraOnClose", () => {
|
|
||||||
const eventSpy = jest.spyOn(window, "dispatchEvent");
|
|
||||||
wrapper.vm.createSierraConfig().onClose();
|
|
||||||
expect(eventSpy).toHaveBeenCalledWith(
|
|
||||||
expect.objectContaining({ type: "sierra-chat-closed" })
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("dispatches sierra-chat-transfer on handleSierraOnTransfer", () => {
|
it("dispatches sierra-chat-transfer on handleSierraOnTransfer", () => {
|
||||||
const eventSpy = jest.spyOn(window, "dispatchEvent");
|
const eventSpy = jest.spyOn(window, "dispatchEvent");
|
||||||
const transfer = {
|
const transfer = {
|
||||||
|
|
@ -77,25 +69,4 @@ describe("sierraWebchat.vue", () => {
|
||||||
expect.objectContaining({ type: "sierra-chat-transfer" })
|
expect.objectContaining({ type: "sierra-chat-transfer" })
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("handles sierra-chat-transfer event and starts Salesforce chat with prepopulated fields", () => {
|
|
||||||
const transfer = {
|
|
||||||
data: {
|
|
||||||
first_name: "A",
|
|
||||||
last_name: "B",
|
|
||||||
email: "a@b.com",
|
|
||||||
chat_summary: "summary",
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const event = new CustomEvent("sierra-chat-transfer", { detail: transfer });
|
|
||||||
window.dispatchEvent(event);
|
|
||||||
expect(window.sierraChat.closeChatModal).toHaveBeenCalled();
|
|
||||||
expect(window.embedded_svc.settings.prepopulatedPrechatFields).toEqual({
|
|
||||||
FirstName: "A",
|
|
||||||
LastName: "B",
|
|
||||||
Email: "a@b.com",
|
|
||||||
Subject: "summary",
|
|
||||||
});
|
|
||||||
expect(window.embedded_svc.liveAgentAPI.startChat).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,20 @@ import analyticsMixin from "@/mixins/analytics-mixin";
|
||||||
import store from "@/store";
|
import store from "@/store";
|
||||||
import { routeData } from "@/router/constants/routes";
|
import { routeData } from "@/router/constants/routes";
|
||||||
import { deepClone } from "@/helpers/object-helper";
|
import { deepClone } from "@/helpers/object-helper";
|
||||||
|
import { webchatHelper } from "@/helpers/webchat-helper";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "sierraWebchat",
|
name: "sierraWebchat",
|
||||||
mixins: [analyticsMixin],
|
mixins: [analyticsMixin],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
transferInProgress: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
const { webchatGlobalNonpersistedState, launchWebchat } = webchatHelper();
|
||||||
|
return { webchatGlobalNonpersistedState, launchWebchat };
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
openSierraChatModal() {
|
openSierraChatModal() {
|
||||||
const sierra = window.sierraChat || window.sierra || window.SierraChat;
|
const sierra = window.sierraChat || window.sierra || window.SierraChat;
|
||||||
|
|
@ -35,11 +45,18 @@ export default {
|
||||||
display: "corner",
|
display: "corner",
|
||||||
onLoad: () => this.openSierraChatModal(),
|
onLoad: () => this.openSierraChatModal(),
|
||||||
onOpen: () => {},
|
onOpen: () => {},
|
||||||
onClose: () => window.dispatchEvent(new CustomEvent("sierra-chat-closed")),
|
onClose: () => {
|
||||||
onTransfer: (transfer) =>
|
if (!this.transferInProgress) {
|
||||||
|
this.webchatGlobalNonpersistedState.showWebchatButton = true;
|
||||||
|
this.transferInProgress = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onTransfer: (transfer) => {
|
||||||
|
this.transferInProgress = true;
|
||||||
window.dispatchEvent(
|
window.dispatchEvent(
|
||||||
new CustomEvent("sierra-chat-transfer", { detail: transfer })
|
new CustomEvent("sierra-chat-transfer", { detail: transfer })
|
||||||
),
|
);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
getSierraContext() {
|
getSierraContext() {
|
||||||
|
|
@ -138,10 +155,7 @@ export default {
|
||||||
}
|
}
|
||||||
// Pass data to Salesforce chat if available
|
// Pass data to Salesforce chat if available
|
||||||
const transfer = event.detail;
|
const transfer = event.detail;
|
||||||
if (
|
if (window.embeddedservice_bootstrap && window.embeddedservice_bootstrap.prechatAPI) {
|
||||||
window.embedded_svc &&
|
|
||||||
typeof window.embedded_svc.bootstrapEmbeddedService === "function"
|
|
||||||
) {
|
|
||||||
if (
|
if (
|
||||||
transfer &&
|
transfer &&
|
||||||
transfer.data &&
|
transfer.data &&
|
||||||
|
|
@ -149,51 +163,22 @@ export default {
|
||||||
transfer.data.last_name &&
|
transfer.data.last_name &&
|
||||||
transfer.data.email
|
transfer.data.email
|
||||||
) {
|
) {
|
||||||
window.embedded_svc.settings.prepopulatedPrechatFields = {
|
window.embeddedservice_bootstrap.prechatAPI.setHiddenPrechatFields({
|
||||||
|
ScarlettAISummary: transfer.data.chat_summary,
|
||||||
FirstName: transfer.data.first_name,
|
FirstName: transfer.data.first_name,
|
||||||
LastName: transfer.data.last_name,
|
LastName: transfer.data.last_name,
|
||||||
Email: transfer.data.email,
|
Email: transfer.data.email,
|
||||||
Subject: transfer.data.chat_summary,
|
});
|
||||||
};
|
|
||||||
window.embedded_svc.settings.extraPrechatFormDetails = [
|
|
||||||
{
|
|
||||||
label: "Scarlett AI Summary",
|
|
||||||
value: transfer.data.chat_summary,
|
|
||||||
transcriptFields: ["Scarlett_AI_Summary__c"],
|
|
||||||
displayToAgent: true,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
if (
|
|
||||||
window.embedded_svc.liveAgentAPI &&
|
|
||||||
typeof window.embedded_svc.liveAgentAPI.startChat === "function"
|
|
||||||
) {
|
|
||||||
window.embedded_svc.liveAgentAPI.startChat();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
window.embedded_svc.bootstrapEmbeddedService();
|
this.webchatGlobalNonpersistedState.shouldLaunchSierra = false;
|
||||||
|
this.launchWebchat();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
window.addEventListener("sierra-chat-transfer", this._handleSierraTransfer);
|
window.addEventListener("sierra-chat-transfer", this._handleSierraTransfer);
|
||||||
|
|
||||||
// Notify funnel-header about Sierra chat open/close state
|
|
||||||
this._sierraChatContainerObserver = new MutationObserver(() => {
|
|
||||||
const isOpen = !!document.querySelector("[data-sierra-chat-container]");
|
|
||||||
window.dispatchEvent(
|
|
||||||
new CustomEvent("sierra-chat-visibility", { detail: { open: isOpen } })
|
|
||||||
);
|
|
||||||
});
|
|
||||||
this._sierraChatContainerObserver.observe(document.body, {
|
|
||||||
childList: true,
|
|
||||||
subtree: true,
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
window.removeEventListener("launch-sierra-webchat", this.triggerSierraChat);
|
window.removeEventListener("launch-sierra-webchat", this.triggerSierraChat);
|
||||||
window.removeEventListener("sierra-chat-transfer", this._handleSierraTransfer);
|
window.removeEventListener("sierra-chat-transfer", this._handleSierraTransfer);
|
||||||
if (this._sierraChatContainerObserver) {
|
|
||||||
this._sierraChatContainerObserver.disconnect();
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -145,9 +145,7 @@ export default {
|
||||||
return "$" + decimalPrice.toFixed(2);
|
return "$" + decimalPrice.toFixed(2);
|
||||||
},
|
},
|
||||||
hasPackageDiscount() {
|
hasPackageDiscount() {
|
||||||
return (
|
return this.additionalButtonData.hasDiscount && this.additionalButtonData.Text;
|
||||||
this.additionalButtonData.servicePackageDiscount && this.additionalButtonData.Text
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,11 @@
|
||||||
class="package-label pricing-by-day-pkg-lbl"
|
class="package-label pricing-by-day-pkg-lbl"
|
||||||
:class="[
|
:class="[
|
||||||
this.buttonLabelSubCopy ? 'has-subheader' : '',
|
this.buttonLabelSubCopy ? 'has-subheader' : '',
|
||||||
!this.additionalButtonData.servicePackageDiscount ? 'adjust-top' : '',
|
!this.additionalButtonData.hasDiscount ? 'adjust-top' : '',
|
||||||
]"
|
]"
|
||||||
for="testradio">
|
for="testradio">
|
||||||
<div class="package-specs">
|
<div class="package-specs">
|
||||||
<div v-if="this.additionalButtonData.servicePackageDiscount" class="row">
|
<div v-if="this.additionalButtonData.hasDiscount" class="row">
|
||||||
<div class="col md-6">
|
<div class="col md-6">
|
||||||
<p class="m-0">
|
<p class="m-0">
|
||||||
<span v-html="this.buttonLabel"></span>
|
<span v-html="this.buttonLabel"></span>
|
||||||
|
|
@ -84,10 +84,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="
|
v-if="this.additionalButtonData.hasDiscount && this.additionalButtonData.Text"
|
||||||
this.additionalButtonData.servicePackageDiscount &&
|
|
||||||
this.additionalButtonData.Text
|
|
||||||
"
|
|
||||||
class="special-save-box">
|
class="special-save-box">
|
||||||
<span v-html="this.additionalButtonData.Text"></span>
|
<span v-html="this.additionalButtonData.Text"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,7 @@ import { cartItemCategories } from "@/constants/cart-item-categories";
|
||||||
import { cartItemTypes } from "@/constants/cart-item-types";
|
import { cartItemTypes } from "@/constants/cart-item-types";
|
||||||
import { coverageStatus, cartItemTypesCoveredByInsurance } from "@/constants/insurance";
|
import { coverageStatus, cartItemTypesCoveredByInsurance } from "@/constants/insurance";
|
||||||
import { experimentSettings } from "@/constants/experiments";
|
import { experimentSettings } from "@/constants/experiments";
|
||||||
|
import { quotePageDiscountTable } from "@/constants/quote-page-discounts";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "cart",
|
name: "cart",
|
||||||
|
|
@ -256,11 +257,11 @@ export default {
|
||||||
|
|
||||||
return subTotal;
|
return subTotal;
|
||||||
},
|
},
|
||||||
getServicePackageDiscount() {
|
getQuotePageDiscount() {
|
||||||
const servicePackageDiscountLineItems = this.servicePackageDiscountCartItem;
|
const quotePageDiscountLineItems = this.quotePageDiscountCartItem;
|
||||||
let subTotal = 0;
|
let subTotal = 0;
|
||||||
|
|
||||||
subTotal += servicePackageDiscountLineItems?.subTotal ?? 0;
|
subTotal += quotePageDiscountLineItems?.subTotal ?? 0;
|
||||||
return subTotal;
|
return subTotal;
|
||||||
},
|
},
|
||||||
getVapsCartItemsForSelectedPackage(packageName) {
|
getVapsCartItemsForSelectedPackage(packageName) {
|
||||||
|
|
@ -303,7 +304,8 @@ export default {
|
||||||
|
|
||||||
getLineItemAmount(amount, useVerifyingText, category) {
|
getLineItemAmount(amount, useVerifyingText, category) {
|
||||||
if (useVerifyingText) return this.verifyingCoverageText;
|
if (useVerifyingText) return this.verifyingCoverageText;
|
||||||
return category == "promos" || category == "servicePackageDiscount"
|
return category == cartItemCategories.PROMOS ||
|
||||||
|
category == cartItemCategories.QUOTE_PAGE_DISCOUNT
|
||||||
? "(" + this.currencyFormatter.format(amount * -1) + ")"
|
? "(" + this.currencyFormatter.format(amount * -1) + ")"
|
||||||
: this.currencyFormatter.format(amount);
|
: this.currencyFormatter.format(amount);
|
||||||
},
|
},
|
||||||
|
|
@ -316,16 +318,21 @@ export default {
|
||||||
if (category == cartItemCategories.VAPS || category == cartItemCategories.PROMOS) {
|
if (category == cartItemCategories.VAPS || category == cartItemCategories.PROMOS) {
|
||||||
this.saveVaps(this.lineItems);
|
this.saveVaps(this.lineItems);
|
||||||
// Check if service package discount should be removed after vaps change
|
// Check if service package discount should be removed after vaps change
|
||||||
if (
|
if (this.quotePageDiscountCartItem) {
|
||||||
this.servicePackageDiscountCartItem &&
|
const existingLineItem = this.quotePageDiscountCartItem.lineItems.at(0);
|
||||||
this.discountPackageNames != this.packageLevel
|
const discountInfo = quotePageDiscountTable.find(
|
||||||
) {
|
(info) => info.partNumber === existingLineItem?.partNumber
|
||||||
this.lineItems.supportingItems = this.lineItems.supportingItems.filter(
|
|
||||||
(lineItemsToKeep) =>
|
|
||||||
lineItemsToKeep.cartItemType !=
|
|
||||||
this.servicePackageDiscountCartItem.cartItemType
|
|
||||||
);
|
);
|
||||||
shouldSaveSupportingItems = true;
|
const packageLevelForDiscount = discountInfo?.packageLevel;
|
||||||
|
|
||||||
|
if (this.packageLevel !== packageLevelForDiscount) {
|
||||||
|
this.lineItems.supportingItems = this.lineItems.supportingItems.filter(
|
||||||
|
(lineItemsToKeep) =>
|
||||||
|
lineItemsToKeep.cartItemType !=
|
||||||
|
this.quotePageDiscountCartItem.cartItemType
|
||||||
|
);
|
||||||
|
shouldSaveSupportingItems = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (shouldSaveSupportingItems) {
|
if (shouldSaveSupportingItems) {
|
||||||
|
|
@ -483,8 +490,8 @@ export default {
|
||||||
cartItems.push(this.mobileFeeCartItem);
|
cartItems.push(this.mobileFeeCartItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.servicePackageDiscountCartItem) {
|
if (this.quotePageDiscountCartItem) {
|
||||||
cartItems.push(this.servicePackageDiscountCartItem);
|
cartItems.push(this.quotePageDiscountCartItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.premiumAppointmentDiscountCartItem) {
|
if (this.premiumAppointmentDiscountCartItem) {
|
||||||
|
|
@ -500,12 +507,6 @@ export default {
|
||||||
return cartItems;
|
return cartItems;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
discountPackageNames() {
|
|
||||||
const discountServicePackage = experimentMixin.methods.getSettingValue(
|
|
||||||
experimentSettings.PROMO_ON_PACKAGE
|
|
||||||
);
|
|
||||||
return getDiscountedPackageName(discountServicePackage);
|
|
||||||
},
|
|
||||||
servicePackageTitleWidget() {
|
servicePackageTitleWidget() {
|
||||||
const servicePackageNames = this.getCmsContent(
|
const servicePackageNames = this.getCmsContent(
|
||||||
this.servicePackageOptionsCmsName,
|
this.servicePackageOptionsCmsName,
|
||||||
|
|
@ -550,8 +551,8 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
packagePrice += this.getVapsPrice(this.packageLevel);
|
packagePrice += this.getVapsPrice(this.packageLevel);
|
||||||
if (this.servicePackageDiscountCartItem) {
|
if (this.quotePageDiscountCartItem) {
|
||||||
packagePrice -= this.getServicePackageDiscount();
|
packagePrice -= this.getQuotePageDiscount();
|
||||||
}
|
}
|
||||||
|
|
||||||
return packagePrice;
|
return packagePrice;
|
||||||
|
|
@ -928,25 +929,25 @@ export default {
|
||||||
}
|
}
|
||||||
return cartItem;
|
return cartItem;
|
||||||
},
|
},
|
||||||
servicePackageDiscountCartItemName() {
|
quotePageDiscountCartItemName() {
|
||||||
return this.getCmsContent("ServicePackageDiscountTextWidget", "Text");
|
return this.getCmsContent("ServicePackageDiscountTextWidget", "Text");
|
||||||
},
|
},
|
||||||
servicePackageDiscountCartItem() {
|
quotePageDiscountCartItem() {
|
||||||
let cartItem = null;
|
let cartItem = null;
|
||||||
|
|
||||||
const servicePackageDiscountLineItem = this.supportingItems.find(
|
const quotePageDiscountLineItem = this.supportingItems.find(
|
||||||
(lineItem) => lineItem.partType == partTypeStrings.SERVICE_PACKAGE_DISCOUNT
|
(lineItem) => lineItem.partType == partTypeStrings.QUOTE_PAGE_DISCOUNT
|
||||||
);
|
);
|
||||||
|
|
||||||
if (servicePackageDiscountLineItem) {
|
if (quotePageDiscountLineItem) {
|
||||||
cartItem = {
|
cartItem = {
|
||||||
name:
|
name:
|
||||||
this.servicePackageDiscountCartItemName +
|
this.quotePageDiscountCartItemName +
|
||||||
Math.abs(
|
Math.abs(
|
||||||
baseMixin.methods.getTotalLineItemPrice(servicePackageDiscountLineItem)
|
baseMixin.methods.getTotalLineItemPrice(quotePageDiscountLineItem)
|
||||||
),
|
),
|
||||||
category: cartItemCategories.SERVICE_PACKAGE_DISCOUNT,
|
category: cartItemCategories.QUOTE_PAGE_DISCOUNT,
|
||||||
cartItemType: cartItemTypes.SERVICE_PACKAGE_DISCOUNT,
|
cartItemType: cartItemTypes.QUOTE_PAGE_DISCOUNT,
|
||||||
isDisplayed: true,
|
isDisplayed: true,
|
||||||
isRemovable: false,
|
isRemovable: false,
|
||||||
subTotal: 0,
|
subTotal: 0,
|
||||||
|
|
@ -955,15 +956,15 @@ export default {
|
||||||
isCoveredByInsurance: false,
|
isCoveredByInsurance: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
servicePackageDiscountLineItem.cartItemType = cartItem.cartItemType;
|
quotePageDiscountLineItem.cartItemType = cartItem.cartItemType;
|
||||||
cartItem.lineItems.push(servicePackageDiscountLineItem);
|
cartItem.lineItems.push(quotePageDiscountLineItem);
|
||||||
|
|
||||||
cartItem.subTotal +=
|
cartItem.subTotal +=
|
||||||
(servicePackageDiscountLineItem.kitPrice ?? 0) +
|
(quotePageDiscountLineItem.kitPrice ?? 0) +
|
||||||
(servicePackageDiscountLineItem.laborAmount ?? 0) +
|
(quotePageDiscountLineItem.laborAmount ?? 0) +
|
||||||
(servicePackageDiscountLineItem.sellingPrice ?? 0);
|
(quotePageDiscountLineItem.sellingPrice ?? 0);
|
||||||
|
|
||||||
cartItem.salesTax += servicePackageDiscountLineItem.salesTax ?? 0;
|
cartItem.salesTax += quotePageDiscountLineItem.salesTax ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cartItem;
|
return cartItem;
|
||||||
|
|
@ -972,7 +973,7 @@ export default {
|
||||||
let cartItem = null;
|
let cartItem = null;
|
||||||
|
|
||||||
const otherSupportingItems = this.supportingItems.filter((item) => {
|
const otherSupportingItems = this.supportingItems.filter((item) => {
|
||||||
return item.partType != partTypeStrings.SERVICE_PACKAGE_DISCOUNT;
|
return item.partType != partTypeStrings.QUOTE_PAGE_DISCOUNT;
|
||||||
});
|
});
|
||||||
// Don't include fees they are part of the package total
|
// Don't include fees they are part of the package total
|
||||||
let otherSupportingItemsLineItems =
|
let otherSupportingItemsLineItems =
|
||||||
|
|
|
||||||
|
|
@ -75,17 +75,12 @@ export default {
|
||||||
|
|
||||||
:deep(a) {
|
:deep(a) {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
&.new-window-link {
|
&.new-window-link,
|
||||||
font-family: Urbanist, Arial, Helvetica, sans-serif;
|
|
||||||
margin: 0 0.75rem;
|
|
||||||
color: $gray-600;
|
|
||||||
font-weight: 400;
|
|
||||||
}
|
|
||||||
&.navigation-link {
|
&.navigation-link {
|
||||||
font-family: Urbanist, Arial, Helvetica, sans-serif;
|
font-family: UrbanistRegular, Arial, Helvetica, sans-serif;
|
||||||
margin: 0 0.75rem;
|
margin: 0 0.75rem;
|
||||||
color: $gray-600;
|
color: $gray-600;
|
||||||
font-weight: 400;
|
font-weight: initial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,6 @@ export default {
|
||||||
return {
|
return {
|
||||||
globalAlertMessages: [],
|
globalAlertMessages: [],
|
||||||
sierraChatOpen: false,
|
sierraChatOpen: false,
|
||||||
salesforceChatOpen: false,
|
|
||||||
isSalesforceTransferInProgress: false,
|
isSalesforceTransferInProgress: false,
|
||||||
isScrolled: false,
|
isScrolled: false,
|
||||||
};
|
};
|
||||||
|
|
@ -80,20 +79,7 @@ export default {
|
||||||
return this.getCmsContent(this.cmsWidgetName, "LogoImage");
|
return this.getCmsContent(this.cmsWidgetName, "LogoImage");
|
||||||
},
|
},
|
||||||
shouldShowWebchatButton() {
|
shouldShowWebchatButton() {
|
||||||
// Hide the chat icon if Sierra chat is open
|
return this.webchatGlobalNonpersistedState.showWebchatButton;
|
||||||
if (this.sierraChatOpen) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Hide the chat icon if Salesforce chat is open or transfer is in progress
|
|
||||||
if (this.salesforceChatOpen || this.isSalesforceTransferInProgress) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Show if either Sierra is enabled or Salesforce button is available and not hidden by page
|
|
||||||
return (
|
|
||||||
(this.webchatGlobalNonpersistedState.shouldLaunchSierra ||
|
|
||||||
this.webchatGlobalNonpersistedState.showWebchatButton) &&
|
|
||||||
!this.shouldHideWebchatButtonOnPage
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
@ -121,10 +107,6 @@ export default {
|
||||||
webchatClicked(event) {
|
webchatClicked(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
this.launchWebchat();
|
this.launchWebchat();
|
||||||
// Only set sierraChatOpen if Sierra experiment is active
|
|
||||||
if (this.webchatGlobalNonpersistedState.shouldLaunchSierra) {
|
|
||||||
this.sierraChatOpen = true;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
syncSierraExperimentFlag() {
|
syncSierraExperimentFlag() {
|
||||||
const experiments = store.getters.applicationUser.experiments;
|
const experiments = store.getters.applicationUser.experiments;
|
||||||
|
|
@ -164,37 +146,6 @@ export default {
|
||||||
unknownAlertEvent.displayAlert = true;
|
unknownAlertEvent.displayAlert = true;
|
||||||
this.globalAlertMessages.push(unknownAlertEvent);
|
this.globalAlertMessages.push(unknownAlertEvent);
|
||||||
}
|
}
|
||||||
// Listen for Sierra chat open/close events from sierra-webchat
|
|
||||||
this._handleSierraChatVisibility = (event) => {
|
|
||||||
this.sierraChatOpen = !!(event.detail && event.detail.open);
|
|
||||||
if (this.sierraChatOpen) {
|
|
||||||
this.isSalesforceTransferInProgress = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
window.addEventListener("sierra-chat-visibility", this._handleSierraChatVisibility);
|
|
||||||
|
|
||||||
// Listen for Salesforce chat open/close events from salesforce-webchat
|
|
||||||
this._handleSalesforceChatVisibility = (event) => {
|
|
||||||
this.salesforceChatOpen = !!(event.detail && event.detail.open === true);
|
|
||||||
};
|
|
||||||
window.addEventListener("salesforce-chat-visibility", this._handleSalesforceChatVisibility);
|
|
||||||
|
|
||||||
// Listen for transfer event to set transfer-in-progress flag
|
|
||||||
this._handleSierraToSalesforceTransfer = () => {
|
|
||||||
this.isSalesforceTransferInProgress = true;
|
|
||||||
};
|
|
||||||
window.addEventListener("sierra-chat-transfer", this._handleSierraToSalesforceTransfer);
|
|
||||||
|
|
||||||
// Reset transfer flag when Salesforce chat opens
|
|
||||||
this._handleSalesforceChatOpened = (event) => {
|
|
||||||
if (event.detail && event.detail.open === true) {
|
|
||||||
this.isSalesforceTransferInProgress = false;
|
|
||||||
this.salesforceChatOpen = true;
|
|
||||||
} else {
|
|
||||||
this.salesforceChatOpen = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
window.addEventListener("salesforce-chat-visibility", this._handleSalesforceChatOpened);
|
|
||||||
|
|
||||||
// Add scroll listener for header shadow effect
|
// Add scroll listener for header shadow effect
|
||||||
this._handleScroll = () => {
|
this._handleScroll = () => {
|
||||||
|
|
@ -203,14 +154,7 @@ export default {
|
||||||
window.addEventListener("scroll", this._handleScroll);
|
window.addEventListener("scroll", this._handleScroll);
|
||||||
},
|
},
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
window.removeEventListener("sierra-chat-closed", this._handleSierraChatClosed);
|
|
||||||
window.removeEventListener("sierra-chat-visibility", this._handleSierraChatVisibility);
|
|
||||||
window.removeEventListener(
|
|
||||||
"salesforce-chat-visibility",
|
|
||||||
this._handleSalesforceChatVisibility
|
|
||||||
);
|
|
||||||
window.removeEventListener("sierra-chat-transfer", this._handleSierraToSalesforceTransfer);
|
window.removeEventListener("sierra-chat-transfer", this._handleSierraToSalesforceTransfer);
|
||||||
window.removeEventListener("salesforce-chat-visibility", this._handleSalesforceChatOpened);
|
|
||||||
window.removeEventListener("scroll", this._handleScroll);
|
window.removeEventListener("scroll", this._handleScroll);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -57,10 +57,6 @@ export default {
|
||||||
modalWidgetName: String,
|
modalWidgetName: String,
|
||||||
pageName: String,
|
pageName: String,
|
||||||
},
|
},
|
||||||
unmounted() {
|
|
||||||
// remove any modal effects before leaving page (e.g. user hits browser back button)
|
|
||||||
this.modal?.closeModal();
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
buttonText() {
|
buttonText() {
|
||||||
return this.getCmsContent(this.modalWidgetName, "SubheaderText");
|
return this.getCmsContent(this.modalWidgetName, "SubheaderText");
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIR
|
||||||
defineRule(
|
defineRule(
|
||||||
"email-address-format",
|
"email-address-format",
|
||||||
regex(
|
regex(
|
||||||
/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$/,
|
/^([a-zA-Z0-9_.+]+)@([a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*\.)+([a-zA-Z]{2,})$/,
|
||||||
errorMessages.EMAIL_ADDRESS_FORMAT
|
errorMessages.EMAIL_ADDRESS_FORMAT
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,6 @@ export default {
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.showSaveProgressPopup) this.modal.openModal();
|
if (this.showSaveProgressPopup) this.modal.openModal();
|
||||||
},
|
},
|
||||||
unmounted() {
|
|
||||||
// remove any modal effects before leaving page (e.g. user hits browser back button)
|
|
||||||
this.modal.closeModal();
|
|
||||||
},
|
|
||||||
emits: ["close-save-progress-popup", "save-progress"], // <--- should remove oodles of warnings in dev tools
|
emits: ["close-save-progress-popup", "save-progress"], // <--- should remove oodles of warnings in dev tools
|
||||||
props: {
|
props: {
|
||||||
modelValue: Object,
|
modelValue: Object,
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,13 @@ export default {
|
||||||
return resolve(response);
|
return resolve(response);
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
if (endpoint.toLowerCase().includes(endpoints.LogDigitalConsumer.url)) {
|
if (
|
||||||
|
endpoint.toLowerCase().includes(endpoints.LogDigitalConsumer.url) ||
|
||||||
|
endpoint.toLowerCase().includes(endpoints.LogFmgSessionData.url) ||
|
||||||
|
endpoint.toLowerCase().includes(endpoints.LogPageView.url) ||
|
||||||
|
endpoint.toLowerCase().includes(endpoints.LogCustomEvent.url) ||
|
||||||
|
endpoint.toLowerCase().includes(endpoints.LogPartQuestions.url)
|
||||||
|
) {
|
||||||
return resolve({ data: null, error: "Ignore errors when logging" });
|
return resolve({ data: null, error: "Ignore errors when logging" });
|
||||||
} else {
|
} else {
|
||||||
if (logApiCall) {
|
if (logApiCall) {
|
||||||
|
|
|
||||||
168
src/helpers/adyen-helper.js
Normal file
168
src/helpers/adyen-helper.js
Normal file
|
|
@ -0,0 +1,168 @@
|
||||||
|
import { AdyenCheckout } from "@adyen/adyen-web/auto";
|
||||||
|
import store from "@/store";
|
||||||
|
import globalMethods from "@/global-methods";
|
||||||
|
import { endpoints } from "@/constants/endpoints";
|
||||||
|
import { AppointmentTypeStrings } from "@/constants/schedule-constants";
|
||||||
|
import { paymentMethods } from "@/constants/payment-method-constants";
|
||||||
|
import { applicationConfig } from "../constants/application-config";
|
||||||
|
|
||||||
|
export async function getNewSession(sessionConfig) {}
|
||||||
|
|
||||||
|
export async function getSessionInfo(sessionId, encryptedSessionResult, pageNameToLog = "") {
|
||||||
|
const order = store.getters.order;
|
||||||
|
const location = getLocationInfo(order);
|
||||||
|
const workOrder = getWorkOrderLastSixDigits(order);
|
||||||
|
const system = getSourceSystem();
|
||||||
|
|
||||||
|
const request = {
|
||||||
|
sessionId: sessionId,
|
||||||
|
sessionResult: encryptedSessionResult,
|
||||||
|
zipCodeCtu: location.zipCodeCtu,
|
||||||
|
workOrderNumber: workOrder,
|
||||||
|
sourceSystem: system,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await globalMethods.callHttpClient({
|
||||||
|
method: endpoints.GetAdyenSessionResult.method,
|
||||||
|
endpoint: endpoints.GetAdyenSessionResult.url,
|
||||||
|
payload: request,
|
||||||
|
logApiCall: true,
|
||||||
|
pageNameToLog: pageNameToLog,
|
||||||
|
});
|
||||||
|
|
||||||
|
return response?.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createAdyenCheckout({
|
||||||
|
session: { id, sessionData },
|
||||||
|
handlers: { onPaymentCompleted, onPaymentFailed, onError },
|
||||||
|
options: { showPayButton = true, amount },
|
||||||
|
}) {
|
||||||
|
const config = {
|
||||||
|
session: {
|
||||||
|
id: id,
|
||||||
|
sessionData: sessionData,
|
||||||
|
},
|
||||||
|
clientKey: applicationConfig.ADYEN_CLIENT_KEY,
|
||||||
|
environment: applicationConfig.ADYEN_ENVIRONMENT,
|
||||||
|
locale: "en_US",
|
||||||
|
countryCode: "US",
|
||||||
|
showPayButton: showPayButton,
|
||||||
|
translations: {
|
||||||
|
en_US: {
|
||||||
|
"creditCard.securityCode.label": "CVV/CVC",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
onPaymentCompleted: onPaymentCompleted,
|
||||||
|
onPaymentFailed: onPaymentFailed,
|
||||||
|
onError: onError,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (amount !== undefined && amount !== null) {
|
||||||
|
config.amount = {
|
||||||
|
value: amount,
|
||||||
|
currency: "USD",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`Creating checkout with configuration:`);
|
||||||
|
console.log(config);
|
||||||
|
|
||||||
|
return await AdyenCheckout(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapAdyenToFmgPaymentMethod(adyenMethod) {
|
||||||
|
const paymentMethodMap = {
|
||||||
|
["scheme"]: paymentMethods.CREDIT_CARD,
|
||||||
|
["afterpaytouch"]: paymentMethods.AFTERPAY,
|
||||||
|
["paypal"]: paymentMethods.PAYPAL,
|
||||||
|
["applepay"]: paymentMethods.APPLE_PAY,
|
||||||
|
};
|
||||||
|
|
||||||
|
const match = paymentMethodMap[adyenMethod];
|
||||||
|
|
||||||
|
return match ?? paymentMethods.CREDIT_CARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapFmgToAdyenPaymentMethod(fmgMethod) {
|
||||||
|
const paymentMethodMap = {
|
||||||
|
[paymentMethods.CREDIT_CARD]: "scheme",
|
||||||
|
[paymentMethods.AFTERPAY]: "afterpaytouch",
|
||||||
|
[paymentMethods.PAYPAL]: "paypal",
|
||||||
|
[paymentMethods.APPLE_PAY]: "applepay",
|
||||||
|
[paymentMethods.PAY_NOW]: null,
|
||||||
|
[paymentMethods.LATER]: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const match = paymentMethodMap[fmgMethod];
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateCcToken(adyenSessionInfo) {
|
||||||
|
const order = store.getters.order;
|
||||||
|
const locationInfo = getLocationInfo(order);
|
||||||
|
|
||||||
|
const ccToken = {
|
||||||
|
subscriptionId: adyenSessionInfo?.storedToken,
|
||||||
|
expMonth: adyenSessionInfo?.cardExpiryMonth,
|
||||||
|
expYear: adyenSessionInfo?.cardExpiryYear,
|
||||||
|
cardType: adyenSessionInfo?.cardType,
|
||||||
|
billToPostalCode: locationInfo.zipCode, // TODO - real data?
|
||||||
|
billToFirstName: order.customer.firstName, // TODO - real data?
|
||||||
|
billToLastName: order.customer.lastName, // TODO - real data?
|
||||||
|
referenceNumber: adyenSessionInfo?.workOrderNumber,
|
||||||
|
authCode: adyenSessionInfo?.authCode,
|
||||||
|
transactionId: adyenSessionInfo?.transactionReference,
|
||||||
|
transReferenceNumber: adyenSessionInfo?.transactionReference,
|
||||||
|
lastFour: adyenSessionInfo?.last4DigitsOfCard,
|
||||||
|
};
|
||||||
|
|
||||||
|
return ccToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLocationInfo(order) {
|
||||||
|
const serviceLocation = order.serviceLocation;
|
||||||
|
const isMobile = serviceLocation.appointmentType === AppointmentTypeStrings.MOBILE;
|
||||||
|
if (isMobile) {
|
||||||
|
return {
|
||||||
|
address: serviceLocation.address,
|
||||||
|
address2: serviceLocation.address2,
|
||||||
|
city: serviceLocation.city,
|
||||||
|
state: serviceLocation.state,
|
||||||
|
zipCode: serviceLocation.zipCode,
|
||||||
|
zipCodeCtu: serviceLocation.zipCodeCtu,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const providerInfo = serviceLocation.provider.address;
|
||||||
|
return {
|
||||||
|
address: providerInfo.streetAddress,
|
||||||
|
address2: "",
|
||||||
|
city: providerInfo.city,
|
||||||
|
state: providerInfo.state,
|
||||||
|
zipCode: providerInfo.zipCode,
|
||||||
|
zipCodeCtu: providerInfo.zipCodeCtu,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getWorkOrderLastSixDigits(order) {
|
||||||
|
const workOrderNumber = order.workOrderNumber ?? "";
|
||||||
|
const tokens = workOrderNumber.split("-");
|
||||||
|
const lastSegment = tokens[tokens.length - 1] ?? "";
|
||||||
|
const numDigits = lastSegment.length;
|
||||||
|
const numZeroes = 6 - numDigits;
|
||||||
|
|
||||||
|
let result = "";
|
||||||
|
for (let i = 0; i < numZeroes; i++) {
|
||||||
|
result += "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
result += lastSegment;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSourceSystem() {
|
||||||
|
return "FMG-2.0";
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,14 @@ import { partTypeStrings } from "@/constants/part-type-strings";
|
||||||
|
|
||||||
const recalPartTypes = [partTypeStrings.RECALIBRATION, partTypeStrings.ADAS_RECALIBRATION];
|
const recalPartTypes = [partTypeStrings.RECALIBRATION, partTypeStrings.ADAS_RECALIBRATION];
|
||||||
|
|
||||||
|
export function anyPartWithRequiresRecalFlag(lineItems) {
|
||||||
|
if (!lineItems) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lineItems.glassParts?.some((li) => li.requiresRecalibration === true);
|
||||||
|
}
|
||||||
|
|
||||||
export function isRecalPartOrHasChildRecalPart(lineItem) {
|
export function isRecalPartOrHasChildRecalPart(lineItem) {
|
||||||
if (lineItem.childParts && lineItem.childParts.length > 0) {
|
if (lineItem.childParts && lineItem.childParts.length > 0) {
|
||||||
return isRecalPart(lineItem) || containsRecalParts(lineItem.childParts);
|
return isRecalPart(lineItem) || containsRecalParts(lineItem.childParts);
|
||||||
|
|
|
||||||
|
|
@ -254,6 +254,19 @@ export function getDiscountedPackageName(discountPackage) {
|
||||||
return package_names[discountPackage] || null;
|
return package_names[discountPackage] || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getPackageLabel(packageName) {
|
||||||
|
switch (packageName) {
|
||||||
|
case packageNames.TIER_ONE:
|
||||||
|
return externalParamPackageLabels.GLASS_ONLY;
|
||||||
|
case packageNames.TIER_TWO:
|
||||||
|
return externalParamPackageLabels.STANDARD;
|
||||||
|
case packageNames.TIER_THREE:
|
||||||
|
return externalParamPackageLabels.PREMIUM;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function maxTier(tierA, tierB) {
|
function maxTier(tierA, tierB) {
|
||||||
if (tierA === packageNames.TIER_THREE || tierB === packageNames.TIER_THREE) {
|
if (tierA === packageNames.TIER_THREE || tierB === packageNames.TIER_THREE) {
|
||||||
return packageNames.TIER_THREE;
|
return packageNames.TIER_THREE;
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,11 @@ const webchatGlobalNonpersistedState = reactive({
|
||||||
|
|
||||||
export const webchatHelper = () => {
|
export const webchatHelper = () => {
|
||||||
function launchWebchat() {
|
function launchWebchat() {
|
||||||
|
webchatGlobalNonpersistedState.showWebchatButton = false;
|
||||||
if (webchatGlobalNonpersistedState.shouldLaunchSierra) {
|
if (webchatGlobalNonpersistedState.shouldLaunchSierra) {
|
||||||
window.dispatchEvent(new CustomEvent("launch-sierra-webchat")); // launches the sierra chat
|
window.dispatchEvent(new CustomEvent("launch-sierra-webchat")); // launches the sierra chat
|
||||||
} else {
|
} else {
|
||||||
window.embedded_svc.bootstrapEmbeddedService(); // launches the salesForce prechat form
|
window.embeddedservice_bootstrap.utilAPI.launchChat(); // launches the salesForce prechat form
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIR
|
||||||
defineRule(
|
defineRule(
|
||||||
"email-address-format",
|
"email-address-format",
|
||||||
regex(
|
regex(
|
||||||
/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$/,
|
/^([a-zA-Z0-9_.+]+)@([a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*\.)+([a-zA-Z]{2,})$/,
|
||||||
errorMessages.EMAIL_ADDRESS_FORMAT
|
errorMessages.EMAIL_ADDRESS_FORMAT
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ defineRule("email-address-required", required(errorMessages.EMAIL_ADDRESS_REQUIR
|
||||||
defineRule(
|
defineRule(
|
||||||
"email-address-format",
|
"email-address-format",
|
||||||
regex(
|
regex(
|
||||||
/^([a-zA-Z0-9_\-.+]+)@([a-zA-Z0-9-]+)\.([a-zA-Z]{2,})$/,
|
/^([a-zA-Z0-9_.+]+)@([a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*\.)+([a-zA-Z]{2,})$/,
|
||||||
errorMessages.EMAIL_ADDRESS_FORMAT
|
errorMessages.EMAIL_ADDRESS_FORMAT
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -164,6 +164,8 @@ export default {
|
||||||
// await any pending save-sessions. if you don't, we will save the new parent account into vuex and then a pending async save-session response overwrites it
|
// await any pending save-sessions. if you don't, we will save the new parent account into vuex and then a pending async save-session response overwrites it
|
||||||
await flushSaveSessionQueue();
|
await flushSaveSessionQueue();
|
||||||
|
|
||||||
|
await this.removeQPDLineItemIfExists();
|
||||||
|
|
||||||
await this.dispatchStoreAction(
|
await this.dispatchStoreAction(
|
||||||
this.storeActions.SAVE_PARENT_ACCOUNT_NUMBER,
|
this.storeActions.SAVE_PARENT_ACCOUNT_NUMBER,
|
||||||
this.parentAccountNumber.toString(),
|
this.parentAccountNumber.toString(),
|
||||||
|
|
@ -193,6 +195,17 @@ export default {
|
||||||
handlePageShow() {
|
handlePageShow() {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
},
|
},
|
||||||
|
async removeQPDLineItemIfExists() {
|
||||||
|
const lineItems = deepClone(store.getters.order.lineItems);
|
||||||
|
lineItems.supportingItems = baseMixin.methods.filterOutQuotePageDiscountPart(
|
||||||
|
lineItems.supportingItems
|
||||||
|
);
|
||||||
|
await baseMixin.methods.dispatchStoreAction(
|
||||||
|
storeActions.SAVE_SUPPORTING_ITEMS_SUPPRESSING_STATE_RESETTING,
|
||||||
|
lineItems.supportingItems,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
unmounted() {
|
unmounted() {
|
||||||
window.removeEventListener("pageshow", this.handlePageShow);
|
window.removeEventListener("pageshow", this.handlePageShow);
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,11 @@
|
||||||
cmsWidgetName="PleaseProvideAddressWidget"
|
cmsWidgetName="PleaseProvideAddressWidget"
|
||||||
class="provide-address-header" />
|
class="provide-address-header" />
|
||||||
<textBlock
|
<textBlock
|
||||||
|
v-if="isMSRFeeApplicable()"
|
||||||
|
cmsWidgetName="VehicleKeysMSRMessageWidget"
|
||||||
|
class="keys-message" />
|
||||||
|
<textBlock
|
||||||
|
v-else
|
||||||
cmsWidgetName="VehicleKeysMessageWidget"
|
cmsWidgetName="VehicleKeysMessageWidget"
|
||||||
class="keys-message" />
|
class="keys-message" />
|
||||||
<mobileAddressQuestions
|
<mobileAddressQuestions
|
||||||
|
|
@ -143,6 +148,9 @@ export default {
|
||||||
getIsVehicleProtectedFromStore() {
|
getIsVehicleProtectedFromStore() {
|
||||||
return store.getters.order.serviceLocation.isVehicleProtected;
|
return store.getters.order.serviceLocation.isVehicleProtected;
|
||||||
},
|
},
|
||||||
|
isMSRFeeApplicable() {
|
||||||
|
return store.getters.order.isMSRFeeApplicable;
|
||||||
|
},
|
||||||
async forwardButtonAction() {
|
async forwardButtonAction() {
|
||||||
await this.dispatchStoreAction(
|
await this.dispatchStoreAction(
|
||||||
this.storeActions.SAVE_MOBILE_DETAILS,
|
this.storeActions.SAVE_MOBILE_DETAILS,
|
||||||
|
|
|
||||||
|
|
@ -306,6 +306,12 @@ describe("partQuestions.vue...", () => {
|
||||||
//Assert
|
//Assert
|
||||||
expect(spy).toHaveBeenNthCalledWith(
|
expect(spy).toHaveBeenNthCalledWith(
|
||||||
1,
|
1,
|
||||||
|
storeActions.SAVE_IS_OEM_GLASS_SELECTED,
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
expect(spy).toHaveBeenNthCalledWith(
|
||||||
|
2,
|
||||||
"savePartQuestionAnswers",
|
"savePartQuestionAnswers",
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -188,6 +188,8 @@ export default {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.dispatchStoreAction(this.storeActions.SAVE_IS_OEM_GLASS_SELECTED, false, false);
|
||||||
|
|
||||||
// save to vuex store as order.damage.partQuestionAnswers (array)
|
// save to vuex store as order.damage.partQuestionAnswers (array)
|
||||||
// used in GET_PARTS call following this one
|
// used in GET_PARTS call following this one
|
||||||
await this.dispatchStoreAction(
|
await this.dispatchStoreAction(
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue