Merge pull request #1150 from Safelite/feature/jnou/fix-iss-regression
Fix ISS Playwright tests
This commit is contained in:
commit
5c22d0ba31
70 changed files with 1025 additions and 659 deletions
|
|
@ -14,7 +14,7 @@ resources:
|
|||
type: github
|
||||
name: Safelite/AzureDevOps
|
||||
endpoint: Safelite
|
||||
ref: refs/tags/t5.7.40
|
||||
ref: refs/tags/t5.7.53
|
||||
|
||||
variables:
|
||||
# - group: Digital-Infrastructure
|
||||
|
|
|
|||
|
|
@ -235,6 +235,7 @@ const defaultAfterpayDetails: IPaymentDetails = {
|
|||
|
||||
const defaultPaypalDetails: IPaymentDetails = {
|
||||
paymentType: PaymentType.Paypal,
|
||||
username:'Itqatest@safelite.com',
|
||||
password: 'Safelite1'
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ export interface IAppointmentDetails {
|
|||
serviceAddress?: IAddress, // Used for mobile
|
||||
isVehicleProtected?: boolean // Used for mobile
|
||||
alternateServiceZip?: string // Used for in-shop and drop-off if doing service in a different ZIP
|
||||
alternateMobileCity?: string // Used for mobile if doing service in a different city then customers address
|
||||
alternateMobileStreetAddress?: string // Used for mobile if doing service in a different street address then customers address
|
||||
}
|
||||
|
||||
export interface IPartQuestion {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export enum DamageType {
|
|||
Theft = 'Attempted theft or theft',
|
||||
Hail = 'Hailstorm',
|
||||
HurricaneStorm = 'Hurricane/storm',
|
||||
Collision = 'Collision',
|
||||
OtherWeather = 'Other weather',
|
||||
Object = 'Object hit glass',
|
||||
Other = 'Other/unknown'
|
||||
}
|
||||
|
|
@ -90,7 +90,11 @@ export enum PartQuestionType {
|
|||
RearWindowColor = 'Rear-Stationary',
|
||||
LeatherSeats = 'question-0-1',
|
||||
DriverSideColor = 'Driver-SideDoor',
|
||||
LaneKeepAssist = 'question-0-1'
|
||||
LaneKeepAssist = 'question-0-1',
|
||||
GeneralQuestion1 = "question-0-1",
|
||||
GeneralQuestion2 = "question-0-2",
|
||||
GeneralQuestion3 = "question-0-3",
|
||||
GeneralQuestion4 = "question-0-4"
|
||||
}
|
||||
|
||||
export enum PaymentType{
|
||||
|
|
@ -133,19 +137,23 @@ export enum SideDoorDamage{
|
|||
|
||||
export enum BailoutCode {
|
||||
Unknown = 0,
|
||||
SaveSessionError,
|
||||
VehicleNotFound,
|
||||
VehicleLookupError,
|
||||
CoverageStatementInvalidState,
|
||||
DoNotSeeMyShop,
|
||||
PricingResponseError,
|
||||
TPANotEnabled,
|
||||
RequestCallback,
|
||||
HeavyTruckVehicle,
|
||||
NoPartsAvailable,
|
||||
PartsServiceError,
|
||||
SafeliteNotTheProvider,
|
||||
VehicleYMMSLookupError
|
||||
SaveSessionError = 1,
|
||||
VehicleNotFound = 2,
|
||||
VehicleVinLookupError = 3,
|
||||
CoverageStatementInvalidState = 4,
|
||||
DoNotSeeMyShop = 5,
|
||||
PricingResponseError = 6,
|
||||
TPANotEnabled = 7,
|
||||
RequestCallback = 8,
|
||||
HeavyTruckVehicle = 9,
|
||||
NoPartsAvailable = 10,
|
||||
PartsServiceError = 11,
|
||||
SafeliteNotTheProvider = 12,
|
||||
VehicleYMMSLookupError = 13,
|
||||
ApplicationError = 14,
|
||||
ApiError = 15,
|
||||
RouterError = 16,
|
||||
CoverageCancelledByUser = 17
|
||||
}
|
||||
|
||||
export enum SignatureAlgorithm {
|
||||
|
|
@ -170,4 +178,33 @@ export enum Authentication {
|
|||
RSATokenEncParams = 'RSATokenEncParams',
|
||||
RSATokenEncParamsOneTimeUse = 'RSATokenEncParamsOneTimeUse',
|
||||
Unknown = 'Unknown',
|
||||
}
|
||||
|
||||
// TODO: Add validations for the percentages on each page like url validations
|
||||
export enum ProgressBarPercentage {
|
||||
DuplicateCheckPage = '15%',
|
||||
PolicyVehiclesPage = '20%',
|
||||
PolicyEndorsementsPage = '20%',
|
||||
VehicleSelectionPage = '25%',
|
||||
PolicyHolderDetailsPage = '30%',
|
||||
VehicleDamagePage = '35%',
|
||||
PartQuestionsPage = '40%',
|
||||
MoldingQuestionsPage = '45%',
|
||||
VehiclePartsPage = '45%',
|
||||
CapabilityQuestionsPage = '45%',
|
||||
VehicleLookupPage = '45%',
|
||||
VinLookupPage = '50%',
|
||||
LicensePlateLookupPage = '50%',
|
||||
AddressLookupPage = '50%',
|
||||
AddressVehiclesPage = '50%',
|
||||
CoverageStatementPage = '55%',
|
||||
ProviderPreferencePage = '60%',
|
||||
SchedulePage = '70%',
|
||||
ServicePackagesPage = '75%',
|
||||
ContactDetailsPage = '85%',
|
||||
PaymentMethodPage = '95%',
|
||||
PaymentPage = '0%',
|
||||
OrderConfirmationPage = '100%',
|
||||
TpaSearchPage = '80%',
|
||||
TpaSubmitPage = '95%',
|
||||
}
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
export default interface IBailoutFlags {
|
||||
isVehicleSelectBailout: boolean,
|
||||
isDoNotSeeMyShopBailout: boolean,
|
||||
isTpaNotEnabledBailout: boolean,
|
||||
isRequestCallbackBailout: boolean,
|
||||
isHeavyTruckVehicleBailout: boolean,
|
||||
isPartsServiceErrorBailout: boolean,
|
||||
isSafeliteNotTheProviderBailout: boolean,
|
||||
isVehicleLookupBailout: boolean,
|
||||
isPriceServiceErrorBailout: boolean
|
||||
isPriceServiceErrorBailout: boolean,
|
||||
isCoverageCancelledByUser: boolean,
|
||||
isAPIErrorBailout: boolean
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ export interface ITestData {
|
|||
clientTag: string,
|
||||
isDuplicateClaim: boolean,
|
||||
isPolicyFound: boolean, // Effective difference between advanced and essential
|
||||
isUnverifiedPolicyAfterVehicleLookup: boolean, // Changing license plate can cause flow to change to unverified from verified
|
||||
isUseVehicleOnPolicy: boolean, // Should we use the vehicle on the policy?
|
||||
isVehicleLookupValidations: boolean, // Should we validate vehicle lookup?
|
||||
isAddressLookupValidations: boolean, // Should we validate address lookup errors?
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ export default class CcisApiUtil {
|
|||
createFakeResponse(requestBody: IPostSaveFakeResponseRequestBody) {
|
||||
return axios.post(this.postCreateMockPolicyUrl, requestBody, {
|
||||
headers: {
|
||||
'X-Mule-Origin-Verify': authToken
|
||||
'X-Mule-Origin-Verify': authToken,
|
||||
'x-Application-Name': 'ISS Playwright'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -21,7 +22,8 @@ export default class CcisApiUtil {
|
|||
const deleteUrl = `${this.deleteFakeResponseUrl}/${params.accountNumber}/${params.key}/${params.responseType}`;
|
||||
return axios.delete(deleteUrl, {
|
||||
headers: {
|
||||
'X-Mule-Origin-Verify': authToken
|
||||
'X-Mule-Origin-Verify': authToken,
|
||||
'x-Application-Name': 'ISS Playwright'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export class AddressLookupPage extends BasePage {
|
|||
super(page);
|
||||
this.page = page;
|
||||
this.addressForm = new AddressForm(page);
|
||||
this.addressNoMatchTextBox = page.getByText('Your address didn’t return a VIN matchPlease re-enter the information below or');
|
||||
this.addressNoMatchTextBox = page.getByText('Your address didn’t return a VIN match');
|
||||
this.stateRestrictionsTextBox = page.getByText('State restrictionsLooks like');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,34 +1,31 @@
|
|||
import { Locator, Page } from "@playwright/test";
|
||||
import { BasePage } from "./BasePage";
|
||||
import { IPaymentDetails } from "@business-logic/types/CustomerDetails";
|
||||
import { IClaimDetails, IPaymentDetails } from "@business-logic/types/CustomerDetails";
|
||||
import { ServicePackage } from "@business-logic/types/Enums";
|
||||
|
||||
export class AfterpayPage extends BasePage {
|
||||
readonly page: Page;
|
||||
readonly submitButton: Locator;
|
||||
|
||||
// Login
|
||||
|
||||
readonly passwordTextBox: Locator;
|
||||
|
||||
// Card details
|
||||
readonly cardholderNameTextBox: Locator;
|
||||
readonly cardNumberTextBox: Locator;
|
||||
readonly expirationDateTextBox: Locator;
|
||||
readonly cvvTextBox: Locator;
|
||||
|
||||
readonly submitButton: Locator;
|
||||
readonly confirmButton: Locator;
|
||||
|
||||
readonly selectAfterpayWithInterestButton: Locator;
|
||||
readonly selectAfterpayWithoutInterestButton: Locator;
|
||||
readonly continueAfterpayButton: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.passwordTextBox = page.getByRole('textbox', { name: 'Please enter your password' });
|
||||
this.passwordTextBox = page.getByTestId('login-password-input');
|
||||
this.submitButton = page.getByRole('button', { name: 'Continue' });
|
||||
|
||||
this.cardholderNameTextBox = page.getByTestId('payment-method-cardHolderName-input');
|
||||
this.cardNumberTextBox = page.getByTestId('payment-method-cardNumber-input');
|
||||
this.expirationDateTextBox = page.getByTestId('payment-method-cardExpiry-input');
|
||||
this.cvvTextBox = page.getByTestId('payment-method-cardCvv-input');
|
||||
|
||||
this.confirmButton = page.getByRole('button', { name: 'Confirm' });
|
||||
|
||||
// Monthly with interest option
|
||||
this.selectAfterpayWithInterestButton = page.getByRole('radio', { name: /month/ });
|
||||
// Biweekly without interest option
|
||||
this.selectAfterpayWithoutInterestButton = page.getByTestId('payment-types-label').filter({ hasText: /every 2 weeks/ });
|
||||
this.continueAfterpayButton = page.getByRole('button', { name: 'Continue' });
|
||||
}
|
||||
|
||||
async login(password: string) {
|
||||
|
|
@ -36,21 +33,28 @@ export class AfterpayPage extends BasePage {
|
|||
await this.submitButton.click();
|
||||
}
|
||||
|
||||
async populateCardDetails(paymentDetails: IPaymentDetails) {
|
||||
await this.cardholderNameTextBox.fill('Roberts'); // TODO: Add cardholder name field
|
||||
await this.cardNumberTextBox.fill(paymentDetails.cardNumber!);
|
||||
await this.expirationDateTextBox.fill(`${paymentDetails.expirationMonth}/${paymentDetails.expirationYear}`);
|
||||
await this.cvvTextBox.fill(paymentDetails.cvv!);
|
||||
await this.submitButton.click();
|
||||
}
|
||||
async executeAfterpayPayment(paymentDetails: IPaymentDetails, claimDetails: IClaimDetails, servicePackage: ServicePackage) {
|
||||
|
||||
async executeAfterpayPayment(paymentDetails: IPaymentDetails) {
|
||||
const confirmButtonOrPaymentOptions = this.confirmButton.or(this.selectAfterpayWithoutInterestButton);
|
||||
|
||||
await this.login(paymentDetails.password!);
|
||||
|
||||
await this.populateCardDetails(paymentDetails);
|
||||
|
||||
|
||||
await this.page.locator('div[data-testid=\'loading-icon-svg\']').filter({ visible: true}).first().waitFor({ state: 'hidden' });
|
||||
await confirmButtonOrPaymentOptions.waitFor({ state: 'visible' });
|
||||
|
||||
if (await this.confirmButton.isVisible()) {
|
||||
await this.confirmButton.waitFor({ state: 'attached' });
|
||||
await this.confirmButton.click();
|
||||
} else {
|
||||
// For some orders, user will have 2 options to choose from: monthly with interest or biweekly without interest
|
||||
if (await this.selectAfterpayWithoutInterestButton.isVisible()) {
|
||||
await this.selectAfterpayWithoutInterestButton.click();
|
||||
await this.continueAfterpayButton.click();
|
||||
} else if (await this.selectAfterpayWithInterestButton.isVisible()) {
|
||||
await this.selectAfterpayWithInterestButton.click();
|
||||
await this.continueAfterpayButton.click();
|
||||
}
|
||||
await this.confirmButton.click();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -28,8 +28,7 @@ export class BailoutPage extends BasePage {
|
|||
await expect.soft(this.firstNameTextBox).toHaveValue(customerDetails.firstName);
|
||||
await expect.soft(this.lastNameTextBox).toHaveValue(customerDetails.lastName);
|
||||
await expect.soft(this.phoneNumberTextBox).toHaveValue(customerDetails.phoneNumber);
|
||||
await expect.soft(this.emailAddressTextBox).toHaveValue(customerDetails.email);
|
||||
await expect.soft(await this.getBailoutCode()).toEqual(bailoutCode);
|
||||
expect.soft(await this.getBailoutCode()).toEqual(bailoutCode);
|
||||
}
|
||||
|
||||
async validateBailoutDetailsNotNull(){
|
||||
|
|
@ -41,7 +40,7 @@ export class BailoutPage extends BasePage {
|
|||
}
|
||||
|
||||
async getBailoutCode() {
|
||||
const mainLocalStorage = JSON.parse(await this.page.evaluate('localStorage.getItem(\'main\')'));
|
||||
const mainLocalStorage = JSON.parse(await this.page.evaluate('sessionStorage.getItem(\'main\')'));
|
||||
const bailoutCode = mainLocalStorage.applicationUser.pageData['bailout-page'].bailoutCode as number;
|
||||
return bailoutCode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ export class BasePage {
|
|||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.continueButton = page.locator('[id="infoBox"]').getByRole('button');
|
||||
this.continueButton = page.locator('button[data-test-id="site-footer-main-button"]')
|
||||
.and(page.locator('button', { hasText: /get\s*started|continue|submit/i }));
|
||||
this.pageSpinner = page.getByRole('status');
|
||||
this.buttonLoadSpin = page.getByRole('alert');
|
||||
}
|
||||
|
|
@ -95,16 +96,16 @@ export class BasePage {
|
|||
}
|
||||
|
||||
async logReferralNumber() {
|
||||
let mainLocalStorage = JSON.parse(await this.page.evaluate('localStorage.getItem(\'main\')'));
|
||||
let referralNumber = mainLocalStorage.order.referralNumber as number;
|
||||
let referralSequenceNumber = mainLocalStorage.order.referralSequenceNumber as number;
|
||||
let mainSessionStorage = JSON.parse(await this.page.evaluate('sessionStorage.getItem(\'main\')'));
|
||||
let referralNumber = mainSessionStorage.order.referralNumber as number;
|
||||
let referralSequenceNumber = mainSessionStorage.order.referralSequenceNumber as number;
|
||||
if (referralNumber == null) {
|
||||
for (let i = 1; i <= 20; i++) {
|
||||
if (!referralNumber == null) break;
|
||||
await this.page.waitForTimeout(500);
|
||||
mainLocalStorage = JSON.parse(await this.page.evaluate('localStorage.getItem(\'main\')'));
|
||||
referralNumber = mainLocalStorage.order.referralNumber as number;
|
||||
referralSequenceNumber = mainLocalStorage.order.referralSequenceNumber as number;
|
||||
mainSessionStorage = JSON.parse(await this.page.evaluate('localStorage.getItem(\'main\')'));
|
||||
referralNumber = mainSessionStorage.order.referralNumber as number;
|
||||
referralSequenceNumber = mainSessionStorage.order.referralSequenceNumber as number;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,35 +6,57 @@ export class ContactDetailsPage extends BasePage {
|
|||
readonly page: Page;
|
||||
issPageValue = 'contact-details';
|
||||
|
||||
// Contact details form
|
||||
// TODO: Check if we can consolidate
|
||||
readonly firstNameTextBox: Locator;
|
||||
readonly lastNameTextBox: Locator;
|
||||
readonly emailAddressTextBox: Locator;
|
||||
readonly phoneNumberTextBox: Locator;
|
||||
readonly appointmentInformationAlert: Locator;
|
||||
readonly changeZipCodeAlert: Locator;
|
||||
|
||||
readonly streetAddressTextBox: Locator;
|
||||
readonly apartmentNumberTextBox: Locator;
|
||||
readonly cityTextBox: Locator;
|
||||
readonly stateTextBox: Locator;
|
||||
readonly zipCodeTextBox: Locator;
|
||||
readonly coveredLocationYesButton: Locator;
|
||||
readonly coveredLocationNoButton: Locator
|
||||
readonly notesTextBox: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
|
||||
// Alerts
|
||||
this.appointmentInformationAlert = this.page.locator('[class*="widget-name-AppointmentInformationAlertWidget"]');
|
||||
this.changeZipCodeAlert = this.page.locator('[class*="widget-name-ChangeZipCodeAlertWidget"]');
|
||||
|
||||
// Contact details form
|
||||
this.firstNameTextBox = this.page.getByRole('textbox', { name: 'First name' });
|
||||
this.lastNameTextBox = this.page.getByRole('textbox', { name: 'Last name' });
|
||||
this.emailAddressTextBox = this.page.getByRole('textbox', { name: 'Email address' });
|
||||
this.phoneNumberTextBox = this.page.getByRole('textbox', { name: 'Phone number' });
|
||||
this.notesTextBox = this.page.getByRole('textbox', { name: 'Notes' });
|
||||
this.streetAddressTextBox = this.page.getByRole('textbox', { name: 'Street address' });
|
||||
this.apartmentNumberTextBox = this.page.getByRole('textbox', { name: 'Apartment number or letter (Optional)' });
|
||||
this.cityTextBox = this.page.getByRole('textbox', { name: 'City' });
|
||||
this.stateTextBox = this.page.getByRole('textbox', { name: 'state' });
|
||||
this.zipCodeTextBox = this.page.getByRole('textbox', { name: 'ZIP' });
|
||||
this.coveredLocationYesButton = this.page.locator('#vehicleProtectedQuestion-true');
|
||||
this.coveredLocationNoButton = this.page.locator('#vehicleProtectedQuestion-false');
|
||||
this.notesTextBox = this.page.getByRole('textbox', { name: 'technicianNotes' });
|
||||
}
|
||||
|
||||
|
||||
async getContactDetails() {
|
||||
const customerDetails: Partial<ICustomerDetails> = {};
|
||||
customerDetails.firstName = await this.firstNameTextBox.inputValue();
|
||||
customerDetails.lastName = await this.lastNameTextBox.inputValue();
|
||||
customerDetails.email = await this.emailAddressTextBox.inputValue();
|
||||
customerDetails.phoneNumber = await this.phoneNumberTextBox.inputValue();
|
||||
async validateAlertsAreVisible() {
|
||||
await expect(this.appointmentInformationAlert).toBeVisible();
|
||||
await this.appointmentInformationAlert.click(); //
|
||||
await expect(this.appointmentInformationAlert).toContainText('Please have your vehicle keys or key card available, as your technician needs access inside the vehicle and may need to move your vehicle to complete service.');
|
||||
|
||||
return customerDetails;
|
||||
await expect(this.changeZipCodeAlert).toBeVisible();
|
||||
await this.changeZipCodeAlert.click();
|
||||
await expect(this.changeZipCodeAlert).toContainText('If your service ZIP code has changed, please go back and update it to ensure we have the correct information for your appointment.');
|
||||
}
|
||||
|
||||
// TO-DO add method for when checkbox for same as policy address displays
|
||||
|
||||
async fillContactDetails(customerDetails: ICustomerDetails) {
|
||||
await this.streetAddressTextBox.fill(customerDetails.address.street!);
|
||||
await this.cityTextBox.fill(customerDetails.address.city!);
|
||||
}
|
||||
|
||||
async fillAlternateMobileStreetAndCity(alternateMobileStreetAddress: string, alternateMobileCity: string) {
|
||||
await this.streetAddressTextBox.fill(alternateMobileStreetAddress);
|
||||
await this.cityTextBox.fill(alternateMobileCity);
|
||||
}
|
||||
|
||||
async fillNotes(notes?: string) {
|
||||
|
|
|
|||
|
|
@ -1,30 +1,46 @@
|
|||
import { expect, type Locator, type Page } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
import { IClaimDetails, ICustomerDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { defaultTestData, ITestData, VehicleDamage } from 'safelite-playwright-core';
|
||||
|
||||
export class CoverageStatementPage extends BasePage {
|
||||
readonly page: Page;
|
||||
readonly scheduleOnlineButton: Locator;
|
||||
readonly cancelMyClaimButton: Locator;
|
||||
readonly cancelMyClaimConfirm: Locator;
|
||||
readonly deductibleAmount: Locator;
|
||||
readonly verfiyingCoverageText: Locator;
|
||||
readonly continueToScheduleButton: Locator; // For ITAC/NoComp
|
||||
readonly noDeductibleRepairText: Locator; // For essential flow when there is no deductible and repair is covered
|
||||
readonly youPayYourDeductibleText: Locator;
|
||||
readonly verifiedCoverageHeader: Locator; // For essential flow when coverage is verified
|
||||
readonly headerForITAC: Locator; // For ITAC when coverage is found
|
||||
readonly headerForNoComp: Locator; // For NoComp when coverage is found
|
||||
readonly unverifiedCoverageHeader: Locator; // For essential flows when verifying deductible
|
||||
readonly oemBullet: Locator; // For OEM bullet when OEM endorsement is present
|
||||
readonly continueSchedulingButton: Locator; // For ITAC/NoComp
|
||||
readonly continueButton: Locator; // For essential flows
|
||||
issPageValue = 'coverage-statement';
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.scheduleOnlineButton = this.page.getByText('Continue to schedule online');
|
||||
this.cancelMyClaimButton = this.page.getByText('Cancel my claim');
|
||||
this.cancelMyClaimConfirm = this.page.getByText('No, I want to cancel');
|
||||
|
||||
this.cancelMyClaimButton = this.page.getByRole('link', { name: "No, I want to cancel" }); // seen for ITAC/NoComp flows
|
||||
this.cancelMyClaimConfirm = this.page.locator('div.text-center', { hasText: "No, I want to cancel" }); // on modal for cancel claim
|
||||
|
||||
this.deductibleAmount = this.page.getByText('$');
|
||||
this.verfiyingCoverageText = this.page.getByRole('heading', { name: 'We’re verifying your coverage' });
|
||||
this.continueToScheduleButton = page.locator('div[class*="button-content"]', {hasText:'Continue to schedule online'});
|
||||
this.deductibleAmount = this.page.locator('.cost-underline');
|
||||
this.noDeductibleRepairText = this.page.getByText('According to your policy, there is no deductible for a repair.'); // no deductible for repair text
|
||||
this.youPayYourDeductibleText = this.page.getByText('You pay your deductible:'); // no deductible for replacement text
|
||||
this.verifiedCoverageHeader = this.page.getByRole('heading', { name: 'We have verified your coverage' });
|
||||
this.unverifiedCoverageHeader = this.page.getByRole('heading', { level: 5, name: "We’re verifying your coverage" });
|
||||
this.headerForITAC = this.page.getByRole('heading', { name: 'Good news! Safelite\'s price is lower than your deductible' });
|
||||
this.headerForNoComp = this.page.getByRole('heading', { name: 'Looks like your policy doesn\'t include comprehensive coverage.\nSafelite can still get you fixed up and safely back on the road.' });
|
||||
this.oemBullet = this.page.getByText('OEM (Original Equipment Manufacturer) glass replacement is included under your policy and will be installed in your vehicle.');
|
||||
|
||||
this.continueSchedulingButton = page.getByRole('button', { name: 'Continue scheduling' }); // continue button for ITAC/NoComp flow
|
||||
this.continueButton = page.getByRole('button', { name: 'Continue' }); // continue button for essential flow
|
||||
}
|
||||
|
||||
async scheduleOnline(){
|
||||
await this.scheduleOnlineButton.click();
|
||||
async scheduleOnline(){
|
||||
await this.continueSchedulingButton.click();
|
||||
}
|
||||
|
||||
async cancelMyClaim(){
|
||||
|
|
@ -32,11 +48,70 @@ export class CoverageStatementPage extends BasePage {
|
|||
await this.cancelMyClaimConfirm.click();
|
||||
}
|
||||
|
||||
async validateDeductibleAmount(customer){
|
||||
await expect(this.deductibleAmount). toContainText(`$${customer.deductibleAmount}`, {timeout: 60000});
|
||||
async handleRepairWithNoDeductibleFlow() {
|
||||
|
||||
if (VehicleDamage.WindshieldOneChip || VehicleDamage.WindshieldTwoChips || VehicleDamage.WindshieldThreeChips) {
|
||||
await expect(this.verifiedCoverageHeader).toBeVisible();
|
||||
await expect(this.noDeductibleRepairText).toBeVisible();
|
||||
}
|
||||
}
|
||||
|
||||
async validateUnverifiedText(){
|
||||
await expect(this.verfiyingCoverageText).toBeEnabled();
|
||||
async handleReplacementOrRepairWithNoDeductibleFlow(claimDetails: IClaimDetails, VehicleDamage){
|
||||
const noDeductibleFlow = claimDetails.policyDeductible === 0;
|
||||
|
||||
if (noDeductibleFlow && VehicleDamage === VehicleDamage.WindshieldOneChip || VehicleDamage.WindshieldTwoChips || VehicleDamage.WindshieldThreeChips) {
|
||||
|
||||
// await expect(this.noDeductibleRepairText).toBeVisible();
|
||||
await this.continueButton.click();
|
||||
|
||||
} else {
|
||||
await expect(this.youPayYourDeductibleText).toBeVisible();
|
||||
await expect(this.deductibleAmount).toContainText(`$0`, {timeout: 60000});
|
||||
await this.continueButton.click();
|
||||
}
|
||||
}
|
||||
|
||||
async handleReplacementWithDeductibleFlow(claimDetails: IClaimDetails){
|
||||
const replaceWithDeductibleFlow = claimDetails.policyDeductible! > 0 && claimDetails.policyDeductible !== 9999;
|
||||
|
||||
if (replaceWithDeductibleFlow) {
|
||||
await expect(this.youPayYourDeductibleText).toBeVisible();
|
||||
await expect(this.deductibleAmount).toContainText(`$${claimDetails.policyDeductible?.toLocaleString()}`, {timeout: 60000});
|
||||
|
||||
await this.continueButton.click();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async handleUnverifiedFlow(claimDetails: IClaimDetails){
|
||||
const unVerifiedCustomer = claimDetails.policyDeductible === -1; // if deductible is -1, we treat it as unverified flow
|
||||
|
||||
if (unVerifiedCustomer) {
|
||||
await expect(this.unverifiedCoverageHeader).toBeVisible();
|
||||
|
||||
await this.continueButton.click();
|
||||
}
|
||||
}
|
||||
|
||||
async handleUnverifiedPolicyAfterVehicleLookupFlow(){
|
||||
await expect(this.unverifiedCoverageHeader).toBeVisible();
|
||||
await this.continueButton.click();
|
||||
}
|
||||
|
||||
async handleITACFlow(){
|
||||
await expect(this.headerForITAC).toBeVisible(); // verify ITAC header is visible
|
||||
|
||||
await this.continueSchedulingButton.click(); // happy path to scheduling for ITAC
|
||||
}
|
||||
|
||||
async handleNoCompFlow(){
|
||||
await expect(this.headerForNoComp).toBeVisible(); // verify NoComp header is visible
|
||||
|
||||
await this.continueSchedulingButton.click(); // happy path to scheduling for NoComp
|
||||
}
|
||||
|
||||
async validateOEMBullet(){
|
||||
await expect(this.oemBullet).toBeVisible();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -12,11 +12,11 @@ export class EndorsementsPage extends BasePage {
|
|||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.educatorYesButton = this.page.locator('label[for="schoolProperty-Yes"]');
|
||||
this.educatorNoButton = this.page.locator('label[for="schoolProperty-No"]');
|
||||
this.educatorYesButton = this.page.locator('label:has(div.button-content:has(span:has-text("Yes")))');
|
||||
this.educatorNoButton = this.page.locator('label:has(div.button-content:has(span:has-text("No")))');
|
||||
}
|
||||
|
||||
async verifyEndorsements(endorsements: IEndorsementDetails[]) {
|
||||
async verifyEndorsements(endorsements: IEndorsementDetails[]) {
|
||||
for (const endorsement of endorsements) {
|
||||
switch(endorsement.endorsementType) {
|
||||
case EndorsementType.Educator:
|
||||
|
|
|
|||
|
|
@ -6,110 +6,175 @@ import { ITestData } from '@business-logic/types/ITestData';
|
|||
|
||||
export class OrderConfirmationPage extends BasePage {
|
||||
readonly page: Page;
|
||||
|
||||
readonly successCheckmark: Locator;
|
||||
readonly successHeader: Locator;
|
||||
|
||||
readonly serviceText: Locator;
|
||||
readonly emailText: Locator;
|
||||
readonly apptDateText: Locator;
|
||||
readonly amountDueText: Locator;
|
||||
readonly viewCartButton: Locator;
|
||||
readonly workOrderNumberText: Locator;
|
||||
readonly confirmationText: Locator;
|
||||
readonly appointmentTypeText: Locator;
|
||||
readonly apptDetailsText: Locator;
|
||||
readonly deductibleText: Locator;
|
||||
readonly subtotalText: Locator;
|
||||
readonly totalAmountDueText: Locator;
|
||||
readonly amountPaidText: Locator;
|
||||
readonly finalAmountDue: Locator;
|
||||
readonly cartServicePackageText: Locator;
|
||||
readonly cartLineItemsText: Locator;
|
||||
readonly unverifiedCoverageDeductibleText: Locator;
|
||||
|
||||
issPageValue = 'order-confirmation';
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.serviceText = this.page.locator('[class="appointment-text text-center lh-base"]');
|
||||
this.emailText = this.page.locator('[class="email-confirmation-text"]');
|
||||
this.apptDateText = this.page.locator('[class="appointment-date-time text-center mt-4"]');
|
||||
this.amountDueText = this.page.getByLabel('expand cart details');
|
||||
this.viewCartButton = this.page.locator('#cart-dropdown-head');
|
||||
this.deductibleText = this.page.locator('#deductible-value');
|
||||
this.subtotalText = this.page.locator("#subtotal-value");
|
||||
|
||||
this.successCheckmark = this.page.locator('img[src*="-checkmark.svg"]');
|
||||
this.successHeader = this.page.locator('[class="header-text"]');
|
||||
|
||||
this.confirmationText = this.page.locator('[class="subheader-text"]', { hasText: 'Your appointment is on Safelite\'s schedule and your confirmation email is on the way.' });
|
||||
this.serviceText = this.page.locator('[class="service-description confirmation-section"]');
|
||||
this.workOrderNumberText = this.page.locator('[class="work-order-description"]');
|
||||
this.appointmentTypeText = this.page.locator('[class="appointment-title"]');
|
||||
this.apptDetailsText = this.page.locator('[class="appointment-details confirmation-section"]');
|
||||
|
||||
// Order details section
|
||||
this.deductibleText = this.page.locator('span#deductible-value, span.deductible-value');
|
||||
this.subtotalText = this.page.locator('#subtotal-value');
|
||||
this.totalAmountDueText = this.page.locator('#total-value');
|
||||
this.amountPaidText = this.page.locator('#amount-paid-value');
|
||||
this.finalAmountDue = this.page.locator('#bottom-amount-due-value');
|
||||
this.cartServicePackageText = this.page.locator('#cart-service-package');
|
||||
this.cartLineItemsText = this.page.locator('.cart-item-list');
|
||||
this.unverifiedCoverageDeductibleText = this.page.locator('span#deductible-value', { hasText: 'Verifying coverage' });
|
||||
}
|
||||
|
||||
async validateOrderConfirmationPage(testData: Partial<ITestData>) {
|
||||
// Destructure data we use
|
||||
const { vehicleDetails, customerDetails, servicePackage, isItac,
|
||||
isNoComp, isPolicyFound, claimDetails, paymentDetails, isUseVehicleOnPolicy } = testData;
|
||||
await this.serviceText.waitFor({ state: "visible" });
|
||||
await this.logOrderNumber();
|
||||
|
||||
|
||||
// Grab text
|
||||
const serviceTextValue = await this.serviceText.textContent();
|
||||
const apptDateValue = await this.apptDateText.textContent();
|
||||
const emailTextValue = await this.emailText.textContent();
|
||||
const servicePackageValue = await this.cartServicePackageText.textContent();
|
||||
const amountDueValue = await this.amountDueText.textContent();
|
||||
const deductibleTextValue = (isItac || isNoComp) ? null : await this.deductibleText.textContent();
|
||||
const subtotalTextValue = await this.subtotalText.textContent();
|
||||
const finalAmountDueValue = await this.finalAmountDue.textContent();
|
||||
const apptDetailsValue = await this.apptDetailsText.textContent();
|
||||
const appointmentTypeValue = await this.appointmentTypeText.textContent();
|
||||
|
||||
|
||||
// Derived conditions
|
||||
const isItacOrNoComp = !!(isItac || isNoComp);
|
||||
const isUnverified = !isPolicyFound;
|
||||
const isUnverifiedPolicyAfterVehicleLookup = testData.isUnverifiedPolicyAfterVehicleLookup === true;
|
||||
const hasPremiumOrStandard =
|
||||
(claimDetails!.policyDeductible >= 0 || !isPolicyFound) &&
|
||||
(servicePackage === ServicePackage.Premium || servicePackage === ServicePackage.Standard);
|
||||
|
||||
const payAtService =
|
||||
(claimDetails!.policyDeductible >= 0 &&
|
||||
paymentDetails?.paymentType === PaymentType.PayAtService) || !paymentDetails?.paymentType;
|
||||
|
||||
const paidWithPIA =
|
||||
claimDetails!.policyDeductible >= 0 &&
|
||||
paymentDetails?.paymentType !== PaymentType.PayAtService;
|
||||
|
||||
// Helper: grab textContent only when the element is expected on-screen
|
||||
const textIf = async (condition: boolean, locator: Locator) =>
|
||||
condition ? await locator.textContent() : null;
|
||||
|
||||
// Grab text content for elements that are expected on-screen
|
||||
const lineItemsValue = await textIf(hasPremiumOrStandard, this.cartLineItemsText);
|
||||
const deductibleTextValue = await textIf(!isItacOrNoComp, this.deductibleText);
|
||||
const subtotalTextValue = await textIf((hasPremiumOrStandard || isItacOrNoComp) && !isUnverified && !isUnverifiedPolicyAfterVehicleLookup, this.subtotalText);
|
||||
const totalAmountDueValue = await textIf((hasPremiumOrStandard && !payAtService) || (isItacOrNoComp && !payAtService) && !isUnverified && !isUnverifiedPolicyAfterVehicleLookup, this.totalAmountDueText);
|
||||
const amountPaidTextValue = await textIf((hasPremiumOrStandard && !payAtService) || (isItacOrNoComp && !payAtService) && !isUnverified && !isUnverifiedPolicyAfterVehicleLookup, this.totalAmountDueText);
|
||||
const finalAmountDueValue = await textIf(hasPremiumOrStandard || isItacOrNoComp || isUnverified || isUnverifiedPolicyAfterVehicleLookup, this.finalAmountDue);
|
||||
const confirmationTextValue = await this.confirmationText.textContent();
|
||||
|
||||
|
||||
// Extract service package price
|
||||
const servicePackageAmt = Number.parseFloat(servicePackageValue!.split('$')[1].replaceAll(',', ''));
|
||||
|
||||
// General Validations
|
||||
expect.soft(this.serviceText).toBeVisible();;
|
||||
expect.soft(this.successHeader).toBeVisible();
|
||||
expect.soft(confirmationTextValue).toContain('Your appointment is on Safelite\'s schedule and your confirmation email is on the way.');
|
||||
expect.soft(serviceTextValue).toContain(`${vehicleDetails!.year} ${vehicleDetails!.make} ${vehicleDetails!.model}`);
|
||||
expect.soft(apptDateValue).toContain(customerDetails!.apptDate);
|
||||
expect.soft(emailTextValue).toContain(customerDetails!.email);
|
||||
|
||||
// Service package validations
|
||||
await expect.soft(this.cartServicePackageText).toContainText(`${servicePackage}`)
|
||||
if ((servicePackage === ServicePackage.Premium && testData.isReplace === true) || servicePackage === ServicePackage.Standard) {
|
||||
expect.soft(servicePackageValue).toContain('New wiper blades');
|
||||
}
|
||||
if (servicePackage === ServicePackage.Premium) {
|
||||
expect.soft(servicePackageValue).toContain('Rain Defense™ treatment');
|
||||
}
|
||||
// Validate order number and appointment type header
|
||||
await this.validateOrderNumber();
|
||||
await this.validateAppointmentTypeHeader();
|
||||
|
||||
// Price validations
|
||||
if (servicePackage === ServicePackage.GlassOnly) {
|
||||
expect.soft(servicePackageAmt).toEqual(0);
|
||||
} else {
|
||||
expect.soft(servicePackageAmt).toBeGreaterThan(0);
|
||||
}
|
||||
// Validate line items
|
||||
if (servicePackage === ServicePackage.Premium) {
|
||||
expect.soft(lineItemsValue).toContain('Front advanced beam blades');
|
||||
expect.soft(lineItemsValue).toContain('Safelite Rain Repellent Treatment');
|
||||
} else {
|
||||
if (servicePackage === ServicePackage.Standard) {
|
||||
expect.soft(lineItemsValue).toContain('Front advanced beam blades');
|
||||
}
|
||||
}
|
||||
|
||||
if (isPolicyFound && (isUseVehicleOnPolicy ?? true)) {
|
||||
// Extract numbers
|
||||
const amountDueAmt = Number.parseFloat(amountDueValue!.split('$')[1].replaceAll(',', ''));
|
||||
|
||||
if (isPolicyFound && (claimDetails!.policyDeductible === 0 && (servicePackage === ServicePackage.GlassOnly))) {
|
||||
const zeroDeductibleText = await this.deductibleText.textContent();
|
||||
expect.soft(zeroDeductibleText).toEqual('$0.00');
|
||||
} else if (isPolicyFound && claimDetails!.policyDeductible > 0 && !(isItac || isNoComp) && servicePackage === ServicePackage.GlassOnly){
|
||||
expect.soft(deductibleTextValue).not.toBeNull();
|
||||
const deductibleAmt = deductibleTextValue ? Number.parseFloat(deductibleTextValue.split('$')[1].replaceAll(',', '')) : 0;
|
||||
const subtotalAmt = Number.parseFloat(subtotalTextValue!.split('$')[1].replaceAll(',', ''));
|
||||
subtotalTextValue?.replaceAll(',', '')
|
||||
const finalAmountDueAmt = Number.parseFloat(finalAmountDueValue!.split('$')[1].replaceAll(',', ''));
|
||||
expect.soft(deductibleAmt).toEqual(claimDetails!.policyDeductible);
|
||||
|
||||
} else if ((isPolicyFound || isItac || (isNoComp && paymentDetails!.paymentType === PaymentType.PayAtService)) && !isUnverifiedPolicyAfterVehicleLookup && finalAmountDueValue !== null && subtotalTextValue !== null) {
|
||||
// Extract numbers
|
||||
const deductibleAmt = deductibleTextValue ? Number.parseFloat(deductibleTextValue.split('$')[1].replaceAll(',', '')) : null;
|
||||
|
||||
const subtotalAmt = subtotalTextValue ? Number.parseFloat(subtotalTextValue!.split('$')[1].replaceAll(',', '')) : null;
|
||||
|
||||
|
||||
//const totalAmountDueAmt = Number.parseFloat(totalAmountDueValue!.split('$')[1].replaceAll(',', ''));
|
||||
const finalAmountDueAmt = finalAmountDueValue ? Number.parseFloat(finalAmountDueValue!.split('$')[1].replaceAll(',', '')) : null;
|
||||
|
||||
if (!(isItac || isNoComp)) {
|
||||
expect.soft(subtotalAmt).toEqual(claimDetails!.policyDeductible + servicePackageAmt);
|
||||
expect.soft(deductibleAmt).toEqual(claimDetails!.policyDeductible);
|
||||
} else {
|
||||
expect.soft(subtotalAmt).toBeGreaterThan(0);
|
||||
expect.soft(deductibleAmt).toEqual(0);
|
||||
//expect.soft(deductibleAmt).toEqual(0);
|
||||
}
|
||||
|
||||
if (paymentDetails!.paymentType === PaymentType.PayAtService && (claimDetails!.policyDeductible > 0 || servicePackageAmt > 0)) {
|
||||
// Verify amount due > 0
|
||||
expect.soft(amountDueAmt).toBeGreaterThan(0);
|
||||
if ((paymentDetails!.paymentType === PaymentType.PayAtService) && (claimDetails!.policyDeductible >= 0 && (servicePackage === ServicePackage.Standard || servicePackage === ServicePackage.Premium))) {
|
||||
expect.soft(finalAmountDueAmt).toBeGreaterThan(0);
|
||||
} else {
|
||||
// Verify amount due 0
|
||||
expect.soft(amountDueAmt).toEqual(0);
|
||||
const totalAmountDueAmt = Number.parseFloat(totalAmountDueValue!.split('$')[1].replaceAll(',', ''));
|
||||
const amountPaidValue = Number.parseFloat(amountPaidTextValue!.split('$')[1].replaceAll(',', ''));
|
||||
// Verify amount due 0 usually when PIA is selected
|
||||
expect.soft(amountPaidValue).toEqual(totalAmountDueAmt);
|
||||
expect.soft(finalAmountDueAmt).toEqual(0);
|
||||
}
|
||||
} else {
|
||||
expect.soft(amountDueValue).toContain('Verifying coverage');
|
||||
expect.soft(subtotalTextValue).toEqual('Verifying coverage');
|
||||
// essential flows will have deductible and amount due as "Verifying coverage"
|
||||
const verifyingCoverageText = this.unverifiedCoverageDeductibleText;
|
||||
|
||||
expect.soft(verifyingCoverageText).toContainText('Verifying coverage');
|
||||
expect.soft(finalAmountDueValue).toEqual('Verifying coverage');
|
||||
}
|
||||
}
|
||||
|
||||
async logOrderNumber() {
|
||||
async validateOrderNumber() {
|
||||
const sessionStorage = JSON.parse(await this.page.evaluate('sessionStorage.getItem(\'submittedOrder\')'));
|
||||
const workOrderNumber = sessionStorage.workOrderNumber;
|
||||
await test.step(`SessionStorage Work Order Number:${workOrderNumber}`, async () => {
|
||||
console.log(`SessionStorage Work Order Number:${workOrderNumber}`);
|
||||
});
|
||||
const workOrderNumberValue = await this.workOrderNumberText.textContent();
|
||||
expect.soft(workOrderNumberValue).toEqual(workOrderNumber);
|
||||
}
|
||||
|
||||
async validateAppointmentTypeHeader() {
|
||||
const sessionStorage = JSON.parse(await this.page.evaluate('sessionStorage.getItem(\'submittedOrder\')'));
|
||||
const appointmentType = sessionStorage.serviceLocation.appointmentType;
|
||||
const appointmentTypeValue = await this.appointmentTypeText.textContent();
|
||||
const apptDetailsValue = await this.apptDetailsText.textContent();
|
||||
|
||||
if (appointmentTypeValue?.includes('going to a Safelite shop') && apptDetailsValue?.includes('Drop off before 9:30 AM')) {
|
||||
expect.soft(appointmentType).toEqual('Dropoff');
|
||||
} else if (appointmentTypeValue?.includes('going to a Safelite shop')) {
|
||||
expect.soft(appointmentType).toEqual('Inshop');
|
||||
} else {
|
||||
expect.soft(appointmentType).toEqual('Mobile');
|
||||
}
|
||||
}
|
||||
|
||||
async validateURL() {
|
||||
|
|
|
|||
|
|
@ -1,60 +1,79 @@
|
|||
import { expect, type Locator, type Page } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
import { IPaymentDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { PaymentType } from '@business-logic/types/Enums';
|
||||
import { IClaimDetails, IPaymentDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { PaymentType, ServicePackage } from '@business-logic/types/Enums';
|
||||
import { PaymentPage } from './PaymentPage';
|
||||
import { AfterpayPage } from './AfterpayPage';
|
||||
import { PaypalPage } from './PaypalPage';
|
||||
|
||||
export class PaymentMethodPage extends BasePage {
|
||||
readonly page: Page;
|
||||
readonly payAtServiceButton: Locator;
|
||||
readonly havePaymentReadyMsg: Locator;
|
||||
readonly payNowButton: Locator;
|
||||
readonly payInFourButton: Locator;
|
||||
readonly paypalButton: Locator;
|
||||
readonly paymentPage: PaymentPage;
|
||||
readonly paypalPage: PaypalPage;
|
||||
readonly paymentPage: PaymentPage;
|
||||
|
||||
readonly payNowButton: Locator;
|
||||
readonly paypalButton: Locator;
|
||||
readonly payInFourButton: Locator;
|
||||
readonly payAtAppointmentButton: Locator;
|
||||
|
||||
readonly textReminderYesButton: Locator;
|
||||
readonly textReminderNoButton: Locator;
|
||||
readonly continueToCheckoutButton: Locator;
|
||||
readonly submitButton: Locator;
|
||||
|
||||
issPageValue = 'payment-method';
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.payAtServiceButton = this.page.locator('[buttonlabel="Pay at my appointment"]'); //this.page.getByText('Pay at time of service');
|
||||
this.havePaymentReadyMsg = this.page.getByText('Please have payment ready during your appointment.'); // it will be displayed when there is no payment option
|
||||
this.payNowButton = this.page.locator('[buttonlabel="Pay now"]');
|
||||
this.payInFourButton = this.page.locator('[buttonlabel="Pay in 4 installments"]');
|
||||
this.paypalButton = this.page.frameLocator('iframe[name="card-frame"]').locator('div[id="paypalParentDiv"]');
|
||||
this.paymentPage = new PaymentPage(page);
|
||||
this.paypalPage = new PaypalPage(page);
|
||||
this.paymentPage = new PaymentPage(page);
|
||||
|
||||
this.payNowButton = this.page.locator('[buttonlabel="Pay now"]'); // credit and paypal options behind this button
|
||||
this.paypalButton = this.page.frameLocator('iframe[name="card-frame"]').locator('div[id="paypalParentDiv"]');
|
||||
this.payInFourButton = this.page.locator('[buttonlabel="Pay in 4 installments"]'); // Afterpay
|
||||
this.payAtAppointmentButton = this.page.locator('[buttonlabel="Pay at my appointment"]');
|
||||
|
||||
this.textReminderYesButton = this.page.locator('div.button-content', { hasText: /^yes$/i });
|
||||
this.textReminderNoButton = this.page.locator('div.button-content', { hasText: 'No' });
|
||||
this.continueToCheckoutButton = this.page.getByRole('button', { name: 'Continue to checkout' });
|
||||
this.submitButton = this.page.getByRole('button', { name: 'Submit' });
|
||||
}
|
||||
|
||||
async executePayment(paymentDetails: IPaymentDetails) {
|
||||
async executePayment(paymentDetails: IPaymentDetails, claimDetails: IClaimDetails, servicePackage: ServicePackage) {
|
||||
const browserContext = this.page.context();
|
||||
|
||||
switch (paymentDetails.paymentType) {
|
||||
case PaymentType.Credit:
|
||||
await this.selectCreditCard();
|
||||
await this.paymentPage.populateCreditCardDetails(paymentDetails);
|
||||
await this.payNowButton.click();
|
||||
await this.textReminderYesButton.click();
|
||||
await this.continueToCheckoutButton.click();
|
||||
await this.selectCreditCard(paymentDetails);
|
||||
break;
|
||||
case PaymentType.Paypal:
|
||||
await this.payNowButton.click();
|
||||
await this.textReminderYesButton.click();
|
||||
await this.continueToCheckoutButton.click();
|
||||
await this.selectPaypal();
|
||||
await this.paypalPage.completePaypalPurchase(paymentDetails);
|
||||
break;
|
||||
case PaymentType.AfterPay:
|
||||
await this.payInFourButton.click();
|
||||
await this.nextPage();
|
||||
await this.textReminderYesButton.click();
|
||||
await this.continueToCheckoutButton.click();
|
||||
|
||||
// Capture popup
|
||||
const afterpayPopup = await browserContext.waitForEvent('page');
|
||||
const afterpayPage = new AfterpayPage(afterpayPopup);
|
||||
|
||||
// Execute payment
|
||||
await afterpayPage.executeAfterpayPayment(paymentDetails);
|
||||
await afterpayPage.executeAfterpayPayment(paymentDetails, claimDetails, servicePackage);
|
||||
break;
|
||||
|
||||
case PaymentType.PayAtService:
|
||||
await this.selectPayAtService();
|
||||
await this.payAtAppointmentButton.click();
|
||||
await this.textReminderYesButton.click();
|
||||
await this.submitButton.click();
|
||||
break;
|
||||
default:
|
||||
console.error('PaymentMethodPage >> Logic for this payment method unimplemented');
|
||||
|
|
@ -63,22 +82,19 @@ export class PaymentMethodPage extends BasePage {
|
|||
}
|
||||
|
||||
async selectPaypal() {
|
||||
await this.payNowButton.click();
|
||||
await this.nextPage();
|
||||
await this.paypalButton.click();
|
||||
}
|
||||
|
||||
async selectCreditCard() {
|
||||
await this.payNowButton.click();
|
||||
await this.nextPage();
|
||||
async selectCreditCard(paymentDetails: IPaymentDetails) {
|
||||
await this.paymentPage.populateCreditCardDetails(paymentDetails);
|
||||
}
|
||||
|
||||
async selectPayAtAppointment() {
|
||||
await this.payAtAppointmentButton.click();
|
||||
}
|
||||
|
||||
async selectPayAtService() {
|
||||
await this.payAtServiceButton.click();
|
||||
async submitOrderWithoutPIA() {
|
||||
await this.textReminderYesButton.click();
|
||||
await this.submitButton.click();
|
||||
}
|
||||
|
||||
// async validateAmountDue(customer){
|
||||
// await this.amountDueDropDown.click();
|
||||
// await expect(this.deductibleAmountTextField).toContainText(`${customer.deductibleAmount}`);
|
||||
// }
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import { type Locator, type Page } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
import { AfterpayPage } from './AfterpayPage';
|
||||
import { IPaymentDetails } from '@business-logic/types/CustomerDetails';
|
||||
|
||||
export class PaymentPage extends BasePage {
|
||||
|
|
@ -26,8 +27,7 @@ export class PaymentPage extends BasePage {
|
|||
this.cityTextField = page.frameLocator('iframe[name="card-frame"]').getByRole('textbox', { name: 'City' });
|
||||
this.stateDropDown = page.frameLocator('iframe[name="card-frame"]').getByRole('combobox', { name: 'State' });
|
||||
this.billingZipTextField = page.frameLocator('iframe[name="card-frame"]').getByRole('textbox', { name: 'Billing ZIP code' });;
|
||||
this.submitPaymentButton = page.frameLocator('iframe[name="card-frame"]').locator('#buttonContainer');
|
||||
// this.validateURL(this.url);
|
||||
this.submitPaymentButton = page.getByRole('button', { name: 'Submit payment' });
|
||||
}
|
||||
|
||||
async populateCreditCardDetails(paymentDetails: IPaymentDetails){
|
||||
|
|
|
|||
|
|
@ -1,27 +1,33 @@
|
|||
import { expect, type Locator, type Page } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
import { IPaymentDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { expect, type Locator, type Page } from "@playwright/test";
|
||||
import { BasePage } from "./BasePage";
|
||||
import { IPaymentDetails } from "@business-logic/types/CustomerDetails";
|
||||
|
||||
export class PaypalPage extends BasePage {
|
||||
readonly page: Page;
|
||||
readonly loginWithPasswordButton: Locator;
|
||||
readonly passwordTextBox: Locator;
|
||||
readonly paypalLoginButton: Locator;
|
||||
readonly completePurchaseButton: Locator;
|
||||
readonly page: Page;
|
||||
readonly usernameTextBox: Locator;
|
||||
readonly nextButton: Locator;
|
||||
readonly passwordTextBox: Locator;
|
||||
readonly paypalLoginButton: Locator;
|
||||
readonly payButton: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.loginWithPasswordButton = page.getByRole('link', { name: 'Log in with a password instead' });
|
||||
this.passwordTextBox = page.getByPlaceholder('Password');
|
||||
this.paypalLoginButton = page.getByRole('button', { name: 'Log In', exact: true });
|
||||
this.completePurchaseButton = page.getByTestId('submit-button-initial');
|
||||
}
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.usernameTextBox = page.locator("#email");
|
||||
this.nextButton = page.getByRole("button", { name: "Next" });
|
||||
this.passwordTextBox = page.getByRole("textbox", { name: "Password" });
|
||||
this.paypalLoginButton = page.getByRole("button", {
|
||||
name: "Log In",
|
||||
exact: true,
|
||||
});
|
||||
this.payButton = page.getByRole("button", { name: "Pay $" });
|
||||
}
|
||||
|
||||
async completePaypalPurchase(paymentDetails: IPaymentDetails){
|
||||
await this.loginWithPasswordButton.click();
|
||||
await this.passwordTextBox.fill(paymentDetails.password!);
|
||||
await this.paypalLoginButton.click();
|
||||
await this.completePurchaseButton.click();
|
||||
}
|
||||
async completePaypalPurchase(paymentDetails: IPaymentDetails) {
|
||||
await this.usernameTextBox.fill(paymentDetails.username!);
|
||||
await this.nextButton.click();
|
||||
await this.passwordTextBox.fill(paymentDetails.password!);
|
||||
await this.paypalLoginButton.click();
|
||||
await this.payButton.click();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,60 @@
|
|||
import { type Locator, type Page } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
import { ICustomerDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { AddressForm } from './forms/AddressForm';
|
||||
|
||||
export class PolicyHolderDetailsPage extends BasePage {
|
||||
readonly page: Page;
|
||||
readonly addressForm: AddressForm;
|
||||
readonly firstNameTextBox: Locator;
|
||||
readonly lastNameTextBox: Locator;
|
||||
readonly addressInputBox: Locator;
|
||||
readonly emailAddressTextBox: Locator;
|
||||
|
||||
readonly issPageValue = 'policy-holder-details';
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.addressForm = new AddressForm(page);
|
||||
this.firstNameTextBox = page.locator('#firstNameField');
|
||||
this.lastNameTextBox = page.locator('#lastNameField');
|
||||
this.emailAddressTextBox = page.locator('#emailField');
|
||||
this.addressInputBox = page.locator('input[name="autocomplete"]'); // for essential flows
|
||||
}
|
||||
|
||||
async fillCustomerDetails(customerDetails: ICustomerDetails){
|
||||
await this.addressForm.populateAddress(customerDetails);
|
||||
// Check if firstName field is empty, then fill it
|
||||
const firstNameValue = await this.firstNameTextBox.inputValue();
|
||||
if (!firstNameValue || firstNameValue.trim() === '') {
|
||||
if (customerDetails.firstName) {
|
||||
await this.firstNameTextBox.fill(customerDetails.firstName);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if lastName field is empty, then fill it
|
||||
const lastNameValue = await this.lastNameTextBox.inputValue();
|
||||
if (!lastNameValue || lastNameValue.trim() === '') {
|
||||
if (customerDetails.lastName) {
|
||||
await this.lastNameTextBox.fill(customerDetails.lastName);
|
||||
}
|
||||
}
|
||||
|
||||
// Fill email address for both essential and advanced flows
|
||||
await this.emailAddressTextBox.fill(customerDetails.email);
|
||||
|
||||
const addressValue = await this.addressInputBox.inputValue();
|
||||
|
||||
// For essential flows, when address fields are not pre-filled
|
||||
if (!addressValue || addressValue.trim() === '') {
|
||||
await this.addressInputBox.click();
|
||||
await this.addressInputBox.fill(customerDetails.address.street);
|
||||
|
||||
// Wait for suggestions to load (Google Places has a slight delay)
|
||||
await this.page.locator('.pac-item').first().waitFor({ state: 'visible', timeout: 5000 });
|
||||
|
||||
// Click the first result
|
||||
await this.page.locator('.pac-item').first().click();
|
||||
|
||||
// Optional: wait for the input to be populated by Google Places
|
||||
await this.addressInputBox.waitFor({ state: 'attached' });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,11 +5,14 @@ import { IVehicleDetails } from '@business-logic/types/CustomerDetails';
|
|||
export class PolicyVehiclesPage extends BasePage {
|
||||
readonly page: Page;
|
||||
issPageValue = 'policy-vehicles';
|
||||
readonly addAnotherVehicleButton: Locator;
|
||||
readonly selectVehicleOnPolicyButton: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
// this.validateURL(this.url);
|
||||
this.addAnotherVehicleButton = this.page.getByText('Add another vehicle');
|
||||
this.selectVehicleOnPolicyButton = this.page.locator(`input[type="radio"][name="policyVehiclesQuestionOption"]`).first();
|
||||
}
|
||||
|
||||
async validateVehicleIsOnPolicy(vehicleDetails: IVehicleDetails) {
|
||||
|
|
@ -21,8 +24,9 @@ export class PolicyVehiclesPage extends BasePage {
|
|||
const vehicleRegExp = new RegExp(`${vehicleDetails.year} .+ ${vehicleDetails.model}`, 'i');
|
||||
await this.page.locator('label').filter({hasText: vehicleRegExp}).locator('div').click();
|
||||
}
|
||||
async selectVehicleNotListed(){
|
||||
await this.page.getByText('Vehicle not listed').click();
|
||||
|
||||
async addAnotherVehicle(){
|
||||
await this.page.getByRole('button', {name: 'Add another vehicle'}).click();
|
||||
}
|
||||
|
||||
async assertNonServiceableAlertBehavior(){
|
||||
|
|
|
|||
|
|
@ -3,48 +3,78 @@ import { BasePage } from './BasePage';
|
|||
|
||||
export class ProviderPreferencePage extends BasePage {
|
||||
readonly page: Page;
|
||||
readonly scheduleWithSafelite: Locator;
|
||||
readonly scheduleWithOther: Locator;
|
||||
readonly acknowledgeAdasButton: Locator;
|
||||
readonly scheduleNowButton: Locator;
|
||||
readonly findAnotherShopButton: Locator;
|
||||
|
||||
readonly acknowledgeAdasCheckbox: Locator;
|
||||
readonly gotItButton: Locator;
|
||||
readonly tpaRecalModal: Locator;
|
||||
readonly learnMoreLink: Locator;
|
||||
readonly yesButton: Locator;
|
||||
readonly noButton: Locator;
|
||||
readonly acknowledgeCheckbox: Locator;
|
||||
readonly stateLawModalHeading: Locator;
|
||||
readonly tpaRecalModalContinueButton: Locator;
|
||||
readonly stateLawModalText: Locator;
|
||||
readonly stateLawRepairModalText: Locator;
|
||||
readonly stateLawModalOkayButton: Locator;
|
||||
issPageValue = 'provider-preference';
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
// this.scheduleWithSafelite = this.page.locator('div').filter({ hasText: /Schedule online with |Safelite AutoGlass/ }).first();
|
||||
this.scheduleWithSafelite = this.page.getByText(/Schedule online with|Safelite AutoGlass/).first();
|
||||
this.scheduleWithOther = this.page.getByText(/Find another shop|Choose my own shop/).first();
|
||||
this.acknowledgeAdasButton = this.page.getByLabel('I acknowledge that my vehicle');
|
||||
this.gotItButton = this.page.getByRole('button', { name: 'Got it' });
|
||||
this.acknowledgeCheckbox = this.page.locator('#tpaAcknowledgement');
|
||||
this.stateLawModalHeading = this.page.getByRole('heading').filter({ hasText: /.* State Law/});
|
||||
|
||||
this.scheduleNowButton = this.page.getByRole('button', { name: 'Schedule now' });
|
||||
this.findAnotherShopButton = this.page.getByRole('link', { name: 'Find another shop' });
|
||||
|
||||
//Recal modal
|
||||
this.tpaRecalModal = this.page.locator('#TPARecalModal');
|
||||
this.learnMoreLink = this.page.locator('#moreDetails');
|
||||
this.yesButton = this.page.getByText('Yes', { exact: true }); // schedule with Safelite
|
||||
this.noButton = this.page.getByText('No', { exact: true }); // schedule with TPA
|
||||
this.acknowledgeAdasCheckbox = this.page.getByRole('checkbox', { name: /I acknowledge/i })
|
||||
this.tpaRecalModalContinueButton = this.page.locator('#modalbtn', { hasText: 'Continue' });
|
||||
|
||||
// State law modal - is there a difference between repair and replacement modals? need to check
|
||||
this.stateLawModalText = this.page.getByText(/law prohibits us from requiring you.*You have the right to select the motor vehicle repair shop of your choice\./is);
|
||||
this.stateLawRepairModalText = this.page.getByText(/We are prohibited by law from requiring that repairs be done at a specific automotive repair dealer. You are entitled to select the auto body repair shop to repair damage covered by us\./is);
|
||||
this.stateLawModalOkayButton = this.page.getByRole('button', { name: 'Okay' })
|
||||
}
|
||||
|
||||
async selectProvider(isSafelite = true) {
|
||||
if (isSafelite) {
|
||||
await this.scheduleWithSafelite.click();
|
||||
await this.scheduleNowButton.click();
|
||||
await this.nextPage();
|
||||
}
|
||||
else {
|
||||
await this.scheduleWithOther.waitFor({ state: 'visible' });
|
||||
await this.scheduleWithOther.click();
|
||||
await this.continueButton.click();
|
||||
//if(await this.acknowledgeAdasButton.isEnabled({timeout: 2500})){
|
||||
// await this.acknowledgeAdasButton.click();
|
||||
// await this.gotItButton.click();
|
||||
// await this.page.waitForTimeout(1000);
|
||||
//}
|
||||
await this.findAnotherShopButton.waitFor({ state: 'visible' });
|
||||
await this.findAnotherShopButton.click();
|
||||
await this.tpaRecalModal.waitFor({ state: 'visible' });
|
||||
await this.scheduleTPAWithAdas();
|
||||
}
|
||||
}
|
||||
async acknowledgeRecalNotificaiton() {
|
||||
await this.acknowledgeAdasButton.click();
|
||||
await this.gotItButton.click();
|
||||
|
||||
async scheduleWithSafeliteADAS() {
|
||||
await this.learnMoreLink.click();
|
||||
await this.yesButton.click();
|
||||
await this.tpaRecalModalContinueButton.click();
|
||||
}
|
||||
|
||||
async scheduleTPAWithAdas() {
|
||||
await this.learnMoreLink.click();
|
||||
await this.noButton.click();
|
||||
await this.acknowledgeAdasCheckbox.click();
|
||||
await this.tpaRecalModalContinueButton.click();
|
||||
}
|
||||
|
||||
async scheduleTPAWithoutAdas() {
|
||||
await this.findAnotherShopButton.click();
|
||||
}
|
||||
|
||||
async validateStateLawModalIsVisible() {
|
||||
await expect.soft(this.stateLawModalHeading).toBeVisible();
|
||||
await expect.soft(this.stateLawModalText).toBeVisible();
|
||||
}
|
||||
|
||||
async validateStateLawRepairModalIsVisible() {
|
||||
await expect.soft(this.stateLawRepairModalText).toBeVisible();
|
||||
}
|
||||
}
|
||||
|
|
@ -3,56 +3,111 @@ import { BasePage } from './BasePage';
|
|||
import { IAppointmentDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { formatDate, formatTime } from '@impl/utils/DateUtils';
|
||||
import { ServiceLocation } from '@business-logic/types/Enums';
|
||||
import { getCustomerDetails, ITestData } from 'safelite-playwright-core';
|
||||
|
||||
export class SchedulePage extends BasePage {
|
||||
readonly page: Page;
|
||||
issPageValue = 'schedule-page';
|
||||
readonly firstAvailableDate: Locator;
|
||||
|
||||
readonly inShopButton: Locator;
|
||||
readonly mobileButton: Locator;
|
||||
readonly moreLocationsButton: Locator;
|
||||
readonly zipCodeTextBox: Locator;
|
||||
readonly findButton: Locator;
|
||||
readonly selectAShopOptions: Locator;
|
||||
readonly firstAppointmentButton : Locator;
|
||||
readonly firstAvailableAMDate: Locator;
|
||||
readonly firstAvailablePMDate: Locator;
|
||||
readonly firstAvailableTime: Locator;
|
||||
readonly firstAvailabeAMTime: Locator;
|
||||
readonly modalContinueButton: Locator;
|
||||
readonly dropOffButton: Locator;
|
||||
readonly dateText: Locator;
|
||||
readonly viewMoreDatesLink: Locator;
|
||||
|
||||
readonly continueButton: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.firstAvailableDate = this.page.locator('.selectable-day').locator('nth=0');
|
||||
this.firstAvailableTime = this.page.locator('label').filter({ hasText: /AM|PM/ }).locator('div').locator('nth=0');
|
||||
|
||||
this.inShopButton = this.page.locator('[buttonlabel="At a Safelite shop"]');
|
||||
this.mobileButton = this.page.locator('[buttonlabel="Have Safelite come to me"]');
|
||||
// For in shop
|
||||
this.moreLocationsButton = this.page.getByRole('button', { name: 'More Locations' });
|
||||
// For mobile
|
||||
this.zipCodeTextBox = this.page.locator('#serviceZipCode');
|
||||
this.findButton = this.page.getByRole('button', { name: 'Find' });
|
||||
// For in-shop and drop off
|
||||
this.selectAShopOptions = this.page.locator('[class="shop-question"]');
|
||||
this.firstAppointmentButton = this.page.locator('#availabilityIndicator').first();
|
||||
this.firstAvailableAMDate = this.page.locator('morning-row-cell has-appointments selected-date').first();
|
||||
this.firstAvailablePMDate = this.page.locator('afternoon-row-cell has-appointments selected-date').first();
|
||||
this.firstAvailableTime = this.page.locator('.time-slot-button').first();
|
||||
this.firstAvailabeAMTime = this.page.locator('.time-slot-button').nth(0);
|
||||
this.modalContinueButton = this.page.locator('#modalbtn');
|
||||
this.dropOffButton = this.page.getByText('Drop off your vehicle', { exact: true });
|
||||
this.dropOffButton = this.page.locator('[class="dropoff-label"]');
|
||||
this.dateText = this.page.locator('[class="modal-header mb-2 mt-2"]');
|
||||
this.viewMoreDatesLink = this.page.getByText(/View more dates/).first();
|
||||
this.viewMoreDatesLink = this.page.getByRole('button', { name: 'More Right arrow icon' });
|
||||
|
||||
this.continueButton = this.page.locator('#stacked').locator('button:has-text("Continue")');
|
||||
}
|
||||
|
||||
async scheduleAppointment(appointmentDetails: IAppointmentDetails) {
|
||||
const formattedDate = formatDate(appointmentDetails.appointmentDate!);
|
||||
const formattedTime = formatTime(appointmentDetails.appointmentDate!);
|
||||
const dateInput = this.page.locator(`div[id="${formattedDate}"]`);
|
||||
const timeButton = this.page.locator(`div[aria-label="${formattedTime}"]`);
|
||||
if (await dateInput.isVisible()) {
|
||||
await dateInput.click();
|
||||
} else {
|
||||
await this.viewMoreDatesLink.click();
|
||||
await dateInput.click();
|
||||
}
|
||||
await timeButton.click();
|
||||
await this.modalContinueButton.click();
|
||||
}
|
||||
// Select in shop and schedule
|
||||
async scheduleInShop(appointmentDetails?: IAppointmentDetails){
|
||||
|
||||
if (appointmentDetails?.serviceLocation === ServiceLocation.InShop) {
|
||||
try {await this.inShopButton.waitFor({ state: 'visible', timeout: 5000 });
|
||||
await this.inShopButton.isVisible()
|
||||
await this.inShopButton.click();
|
||||
await (await this.getFirstNonDropOffTimeSlot()).click();
|
||||
} catch {
|
||||
await this.inShopButton.isHidden()
|
||||
await (await this.getFirstNonDropOffTimeSlot()).click();
|
||||
}
|
||||
} else if (appointmentDetails?.serviceLocation === ServiceLocation.DropOff) {
|
||||
if (await this.inShopButton.isVisible()){
|
||||
await this.inShopButton.waitFor({ state: 'visible', timeout: 5000 });
|
||||
await this.inShopButton.click();
|
||||
|
||||
async scheduleFirstAppointment(serviceLocation: ServiceLocation) {
|
||||
if (await this.firstAvailableDate.isVisible()) {
|
||||
await this.firstAvailableDate.click();
|
||||
} else {
|
||||
await this.viewMoreDatesLink.click();
|
||||
while(await this.firstAvailableDate.isHidden()){
|
||||
await this.viewMoreDatesLink.click();
|
||||
if (await this.dropOffButton.isVisible()) {
|
||||
await this.dropOffButton.waitFor({ state: 'visible', timeout: 5000 });
|
||||
await this.dropOffButton.click()
|
||||
} else {
|
||||
await (await this.getFirstNonDropOffTimeSlot()).click();
|
||||
}
|
||||
await this.firstAvailableDate.click();
|
||||
} else {
|
||||
await (await this.getFirstNonDropOffTimeSlot()).click();
|
||||
}
|
||||
} else {
|
||||
await this.selectFirstAvailableTime();
|
||||
}
|
||||
await this.continueButton.click();
|
||||
}
|
||||
|
||||
serviceLocation === ServiceLocation.DropOff ? await this.dropOffButton.click() : await this.firstAvailableTime.click();
|
||||
await this.modalContinueButton.click();
|
||||
return (`${await this.dateText.allInnerTexts()}`);
|
||||
// Select mobile button, enter zip code, click find button, select first available time and continue
|
||||
async scheduleMobile(appointmentDetails: IAppointmentDetails){
|
||||
await this.mobileButton.click();
|
||||
await this.zipCodeTextBox.fill(appointmentDetails.serviceAddress!.postalCode!);
|
||||
await this.findButton.click();
|
||||
await this.selectFirstAvailableTime();
|
||||
await this.continueButton.click();
|
||||
}
|
||||
|
||||
// Selects the first available time slot but if its not visible, click "More" first to load more dates and times
|
||||
async selectFirstAvailableTime(): Promise<void> {
|
||||
if (await this.firstAvailableTime.isVisible()) {
|
||||
await this.firstAvailableTime.click();
|
||||
} else {
|
||||
await this.viewMoreDatesLink.click();
|
||||
await this.firstAvailableTime.waitFor({ state: 'visible' });
|
||||
await this.firstAvailableTime.click();
|
||||
}
|
||||
}
|
||||
|
||||
async getFirstNonDropOffTimeSlot(): Promise<Locator> {
|
||||
const timeSlots = this.page.locator('.time-slot-button');
|
||||
const nonDropOff = timeSlots.filter({ hasNotText: /Drop & Go/i });
|
||||
return nonDropOff.first();
|
||||
}
|
||||
}
|
||||
|
|
@ -18,26 +18,6 @@ export class ServiceLocationPage extends BasePage {
|
|||
readonly RecalWarningMessage2: Locator;
|
||||
readonly militaryWarningMessage: Locator;
|
||||
|
||||
// For in-shop and drop off
|
||||
readonly selectAShopOptions: Locator;
|
||||
readonly firstAppointmentButton: Locator;
|
||||
readonly changeZipButton: Locator;
|
||||
readonly updateZipTextBox: Locator;
|
||||
readonly saveZipButton: Locator;
|
||||
|
||||
// For mobile
|
||||
readonly enterServiceAddressButton: Locator;
|
||||
readonly serviceAddressTextBox: Locator;
|
||||
readonly aptNumberTextBox: Locator;
|
||||
readonly cityTextBox: Locator;
|
||||
readonly stateDropDown: Locator;
|
||||
readonly zipCodeTextBox: Locator;
|
||||
readonly vehicleProtectedYesButton: Locator;
|
||||
readonly vehicleProtectedNoButton: Locator;
|
||||
readonly saveAddressButton: Locator;
|
||||
|
||||
issPageValue = 'service-location';
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
|
|
@ -52,80 +32,6 @@ export class ServiceLocationPage extends BasePage {
|
|||
this.RecalWarningMessage2 = this.page.getByText(/advanced safety system recalibration needs to be done in our shop./);
|
||||
this.militaryWarningMessage = this.page.locator('[class*="widget-name-AlertMilitaryBaseZipWidget"]');
|
||||
|
||||
// For in-shop and drop off
|
||||
this.selectAShopOptions = this.page.locator('[class="shop-question"]');
|
||||
// this.firstAppointmentButton = this.page.locator('div').filter({ hasText: /Appts/}).first();
|
||||
this.firstAppointmentButton = this.page.locator('#availabilityIndicator').first();
|
||||
this.changeZipButton = this.page.locator('[id="serviceZipLinkPromptId"]');
|
||||
this.updateZipTextBox = this.page.getByRole('textbox', { name: 'Update your service ZIP code'});
|
||||
this.saveZipButton = this.page.getByRole('button', { name: 'Save ZIP code' });
|
||||
|
||||
|
||||
// For mobile
|
||||
this.enterServiceAddressButton = this.page.getByRole('link', { name: 'Enter your service address' });
|
||||
this.serviceAddressTextBox = this.page.getByRole('textbox', { name: 'Street Address' });
|
||||
this.aptNumberTextBox = this.page.getByRole('textbox', { name: 'Apt. number'});
|
||||
this.cityTextBox = this.page.getByRole('textbox', { name: 'City' });
|
||||
this.stateDropDown = this.page.getByRole('combobox', { name: 'State' });
|
||||
this.zipCodeTextBox = this.page.getByRole('textbox', { name: 'Zip code' });
|
||||
this.vehicleProtectedYesButton = this.page.locator('label').filter({ hasText: 'Yes' }).locator('div');
|
||||
this.vehicleProtectedNoButton = this.page.locator('label').filter({ hasText: 'No' }).locator('div');
|
||||
this.saveAddressButton = this.page.getByRole('button', { name: 'Save Address' });
|
||||
}
|
||||
|
||||
async selectLocation(appointmentDetails: IAppointmentDetails){
|
||||
if (appointmentDetails.alternateServiceZip) {
|
||||
await this.changeZipButton.click();
|
||||
await this.fillAndValidate(this.updateZipTextBox, appointmentDetails.alternateServiceZip);
|
||||
await this.saveZipButton.click();
|
||||
}
|
||||
|
||||
switch(appointmentDetails.serviceLocation) {
|
||||
case ServiceLocation.Mobile:
|
||||
await this.scheduleMobile(appointmentDetails);
|
||||
break;
|
||||
case ServiceLocation.InShop:
|
||||
await this.scheduleInShop(appointmentDetails);
|
||||
break;
|
||||
case ServiceLocation.DropOff:
|
||||
await this.scheduleDropOff(appointmentDetails);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async scheduleInShop(appointmentDetails?: IAppointmentDetails) {
|
||||
await this.inShopButton.click();
|
||||
if (appointmentDetails && appointmentDetails.shopAddress) {
|
||||
await this.selectAShopOptions.locator(`[buttonbodycopy="${appointmentDetails.shopAddress}"]`).check();
|
||||
} else {
|
||||
await this.firstAppointmentButton.click();
|
||||
}
|
||||
}
|
||||
|
||||
async scheduleMobile(appointmentDetails: IAppointmentDetails){
|
||||
if (appointmentDetails.serviceAddress) {
|
||||
await this.mobileButton.click();
|
||||
await this.enterServiceAddressButton.click();
|
||||
await this.addressForm.populateAddress({ address: appointmentDetails.serviceAddress! });
|
||||
if (faker.datatype.boolean()) {
|
||||
await this.vehicleProtectedYesButton.check();
|
||||
} else {
|
||||
await this.vehicleProtectedNoButton.check();
|
||||
}
|
||||
await this.saveAddressButton.click();
|
||||
} else {
|
||||
console.error('ServiceLocationPage >> Please supply an address')
|
||||
}
|
||||
}
|
||||
|
||||
async scheduleDropOff(appointmentDetails?: IAppointmentDetails){
|
||||
await this.dropOffButton.click();
|
||||
if (appointmentDetails && appointmentDetails.shopAddress) {
|
||||
await this.selectAShopOptions.locator(`[buttonbodycopy="${appointmentDetails.shopAddress}"]`).check();
|
||||
} else {
|
||||
await this.firstAppointmentButton.click();
|
||||
}
|
||||
}
|
||||
|
||||
async validateRecalWarning(){
|
||||
|
|
|
|||
|
|
@ -6,21 +6,37 @@ export class ServicePackagesPage extends BasePage {
|
|||
readonly page: Page;
|
||||
readonly standardPackageButton: Locator;
|
||||
readonly premiumPackageButton: Locator;
|
||||
readonly glassOnlyButton: Locator;
|
||||
readonly glassOnlyPackageButton: Locator;
|
||||
readonly wiperModal: Locator;
|
||||
readonly wiperModalCloseButton: Locator;
|
||||
readonly continueButton: Locator;
|
||||
issPageValue = 'service-packages';
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.standardPackageButton = this.page.locator('li').filter({ hasText: 'Standard' });
|
||||
this.premiumPackageButton = this.page.locator('li').filter({ hasText: 'Premium' });
|
||||
this.glassOnlyButton = this.page.locator('li').filter({ hasText: 'Glass service' });
|
||||
this.standardPackageButton = this.page.locator('label[for="ServicePackageQuestion-TierTwo"]'); // standard package
|
||||
this.premiumPackageButton = this.page.locator('label[for="ServicePackageQuestion-TierThree"]'); // premium package
|
||||
this.glassOnlyPackageButton = this.page.locator('label[for="ServicePackageQuestion-TierOne"]'); // glass only package
|
||||
this.wiperModal = this.page.locator('#FrontWiperModal #modalbtn');
|
||||
this.wiperModalCloseButton = this.page.locator('#FrontWiperModal').getByLabel('Close')
|
||||
this.continueButton = this.page.getByRole('button', { name: 'Continue' });
|
||||
// this.validateURL(this.url);
|
||||
}
|
||||
|
||||
async selectServicePackage(servicePackage: ServicePackage){
|
||||
await this.page.getByText(servicePackage).click();
|
||||
return (`${await this.page.locator('li').filter({ hasText: 'Premium' }).locator('[class="pricing-info"]').allInnerTexts()}`);
|
||||
//return (`${await this.page.getByText(servicePackage).locator('[class="pricing-info"]').allInnerTexts()}`);
|
||||
if (servicePackage === ServicePackage.Standard) {
|
||||
await this.standardPackageButton.check();
|
||||
} else if (servicePackage === ServicePackage.Premium) {
|
||||
await this.premiumPackageButton.check();
|
||||
try {await this.wiperModal.waitFor({ state: 'visible', timeout: 5000 });
|
||||
await this.wiperModalCloseButton.click();
|
||||
} catch {
|
||||
await this.continueButton.click();
|
||||
}
|
||||
} else if (servicePackage === ServicePackage.GlassOnly) {
|
||||
await this.glassOnlyPackageButton.check();
|
||||
}
|
||||
await this.continueButton.click();
|
||||
}
|
||||
}
|
||||
|
|
@ -4,16 +4,30 @@ import { BasePage } from './BasePage';
|
|||
export class TpaConfirmationPage extends BasePage {
|
||||
readonly page: Page;
|
||||
readonly successMessage: Locator;
|
||||
readonly shopConfirmationMessage: Locator;
|
||||
readonly issPageValue = 'tpa-confirmation';
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.successMessage = page.getByText('Success');
|
||||
this.successMessage = page.getByText('Thank you for submitting your claim; there is one final step.');
|
||||
this.shopConfirmationMessage = page.locator('div.subheader').first()
|
||||
}
|
||||
|
||||
async getTpaShopSelectedName() {
|
||||
const sessionStorage = JSON.parse(await this.page.evaluate('sessionStorage.getItem(\'submittedOrder\')'));
|
||||
const tpaShopSelectedName = sessionStorage.serviceLocation.provider.companyName;
|
||||
return tpaShopSelectedName;
|
||||
}
|
||||
|
||||
async validateSuccessMessage() {
|
||||
await expect(this.successMessage).toBeVisible();
|
||||
}
|
||||
const shopConfirmationMessageText = await this.shopConfirmationMessage.textContent();
|
||||
const tpaShopSelectedNameText = await this.getTpaShopSelectedName();
|
||||
|
||||
await this.successMessage.waitFor({ state: 'visible' });
|
||||
await expect(this.successMessage).toBeVisible();
|
||||
expect.soft(shopConfirmationMessageText?.toLowerCase()).toContain(
|
||||
('Your information has been sent to' + ' ' + tpaShopSelectedNameText).toLowerCase()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,22 +4,14 @@ import { BasePage } from './BasePage';
|
|||
export class TpaSearchPage extends BasePage {
|
||||
readonly page: Page;
|
||||
readonly firstLocationButton: Locator;
|
||||
readonly doNotSeeMyShopButton: Locator;
|
||||
issPageValue = 'tpa-search';
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
// this.firstLocationButton = page.locator("fieldset[aria-labelledby='chooseShop']/span").first();
|
||||
this.firstLocationButton = page.locator("#buttonLabelSpan").first();
|
||||
|
||||
this.doNotSeeMyShopButton = page.getByRole('link', { name: 'I don\'t see my shop' });
|
||||
this.firstLocationButton = page.locator('div.button-content').first();
|
||||
}
|
||||
|
||||
async selectDoNotSeeMyShop() {
|
||||
await this.doNotSeeMyShopButton.click()
|
||||
}
|
||||
|
||||
|
||||
async selectFirstLocation() {
|
||||
await this.firstLocationButton.click();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,29 @@
|
|||
import { expect, type Locator, type Page } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
import { IClaimDetails } from '@business-logic/types/CustomerDetails';
|
||||
|
||||
export class TpaSubmitPage extends BasePage {
|
||||
readonly page: Page;
|
||||
readonly deductible: Locator;
|
||||
readonly recalAlert: Locator;
|
||||
readonly learnMoreLink: Locator;
|
||||
readonly recalModal: Locator;
|
||||
readonly closeRecalModalButton: Locator;
|
||||
issPageValue = 'tpa-submit';
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.deductible = page.getByText('Deductible $');
|
||||
this.recalAlert = page.getByRole('alert').filter({ hasText: 'Some vehicle safety features may not work properly.'});
|
||||
this.learnMoreLink = page.getByRole('link', { name: 'Learn more' });
|
||||
this.recalModal = page.getByRole('dialog').filter({ hasText: 'IMPORTANT SERVICE REQUIRED' }).first();
|
||||
this.closeRecalModalButton = page.locator('.modalbtn', { hasText: 'Close' });
|
||||
this.deductible = page.locator('span#deductible-value, span.deductible-value');
|
||||
}
|
||||
|
||||
async validateDeductible(expDeductible) {
|
||||
await expect(this.deductible).toContainText(expDeductible);
|
||||
async validateDeductible(claimDetails: IClaimDetails) {
|
||||
await expect(this.deductible).toContainText(claimDetails.policyDeductible.toLocaleString());
|
||||
}
|
||||
|
||||
// TODO: Validate change preferred shop and contact details flows
|
||||
}
|
||||
|
|
@ -4,13 +4,13 @@ import { VehicleDamage } from '@business-logic/types/Enums';
|
|||
|
||||
export class VehicleDamagePage extends BasePage {
|
||||
readonly page: Page;
|
||||
readonly windshieldChkBox: Locator;
|
||||
readonly crackButton: Locator;
|
||||
readonly chipButton: Locator;
|
||||
readonly windshieldButton: Locator;
|
||||
readonly sideDoorButton: Locator;
|
||||
readonly replaceButton: Locator;
|
||||
readonly repairButton: Locator;
|
||||
readonly singleWindshieldButton: Locator;
|
||||
readonly splitWindshieldDriverSideButton: Locator;
|
||||
readonly splitWindshieldPassengerSideButton: Locator;
|
||||
readonly sideDoorButton: Locator;
|
||||
readonly driverSideButton: Locator;
|
||||
readonly passengerSideButton: Locator;
|
||||
readonly driverQuarterPanelChkBox: Locator;
|
||||
|
|
@ -30,9 +30,11 @@ export class VehicleDamagePage extends BasePage {
|
|||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.windshieldChkBox = this.page.locator('[buttonlabel="Windshield"]');
|
||||
this.crackButton = this.page.locator('[buttonlabel="Crack"]');
|
||||
this.chipButton = this.page.locator('[buttonlabel="Chip(s)"]');
|
||||
this.windshieldButton = this.page.locator('[buttonlabel="Windshield"]');
|
||||
this.sideDoorButton = this.page.locator('[buttonlabel="Side door"]');
|
||||
this.rearWindowChkBox = this.page.locator('[buttonlabel="Rear window"]');
|
||||
this.replaceButton = this.page.locator('div.list-card-content:has-text("Replace")');
|
||||
this.repairButton = this.page.locator('div.list-card-content:has-text("Repair")');
|
||||
this.singleWindshieldButton = this.page.locator('[buttonlabel="Single windshield"]');
|
||||
this.splitWindshieldDriverSideButton = this.page.locator('[buttonlabel="Split windshield, driver side"]');
|
||||
this.splitWindshieldPassengerSideButton = this.page.locator('[buttonlabel="Split windshield, passenger side"]');
|
||||
|
|
@ -55,17 +57,17 @@ export class VehicleDamagePage extends BasePage {
|
|||
|
||||
async checkSeparateApptsWarning() {
|
||||
// Select conflict
|
||||
await this.windshieldChkBox.check();
|
||||
await this.chipButton.check();
|
||||
await this.windshieldButton.check();
|
||||
await this.repairButton.check();
|
||||
await this.rearWindowChkBox.check();
|
||||
|
||||
// Expect warning
|
||||
await expect.soft(this.separateApptsWarning).toBeAttached();
|
||||
|
||||
// Undo changes
|
||||
await this.crackButton.check();
|
||||
await this.windshieldChkBox.uncheck();
|
||||
await expect.soft(this.crackButton).not.toBeVisible();
|
||||
await this.replaceButton.check();
|
||||
await this.windshieldButton.uncheck();
|
||||
await expect.soft(this.replaceButton).not.toBeVisible();
|
||||
await this.rearWindowChkBox.uncheck();
|
||||
}
|
||||
|
||||
|
|
@ -73,33 +75,33 @@ export class VehicleDamagePage extends BasePage {
|
|||
for (const damage of vehicleDamage) {
|
||||
switch(damage) {
|
||||
case VehicleDamage.WindshieldOneChip:
|
||||
await this.windshieldChkBox.check();
|
||||
await this.windshieldButton.check();
|
||||
await this.selectChips('1');
|
||||
break;
|
||||
case VehicleDamage.WindshieldTwoChips:
|
||||
await this.windshieldChkBox.check();
|
||||
await this.windshieldButton.check();
|
||||
await this.selectChips('2');
|
||||
break;
|
||||
case VehicleDamage.WindshieldThreeChips:
|
||||
await this.windshieldChkBox.check();
|
||||
await this.windshieldButton.check();
|
||||
await this.selectChips('3');
|
||||
break;
|
||||
case VehicleDamage.WindshieldCrack:
|
||||
await this.windshieldChkBox.check();
|
||||
await this.windshieldButton.check();
|
||||
await this.selectCrack();
|
||||
break;
|
||||
case VehicleDamage.WindshieldCrackSingleWindshield:
|
||||
await this.windshieldChkBox.check();
|
||||
await this.windshieldButton.check();
|
||||
await this.selectCrack();
|
||||
await this.singleWindshieldButton.check();
|
||||
break;
|
||||
case VehicleDamage.WindshieldCrackDriverSide:
|
||||
await this.windshieldChkBox.check();
|
||||
await this.windshieldButton.check();
|
||||
await this.selectCrack();
|
||||
await this.splitWindshieldDriverSideButton.check();
|
||||
break;
|
||||
case VehicleDamage.WindshieldCrackPassengerSide:
|
||||
await this.windshieldChkBox.check();
|
||||
await this.windshieldButton.check();
|
||||
await this.selectCrack();
|
||||
await this.splitWindshieldPassengerSideButton.check();
|
||||
break;
|
||||
|
|
@ -156,12 +158,12 @@ export class VehicleDamagePage extends BasePage {
|
|||
}
|
||||
|
||||
async selectCrack(){
|
||||
await this.crackButton.check();
|
||||
await this.replaceButton.click();
|
||||
}
|
||||
|
||||
async selectChips(numChips: string){
|
||||
const numChipsButton = this.page.getByText(numChips, {exact: true});
|
||||
await this.chipButton.check();
|
||||
await this.repairButton.check();
|
||||
await numChipsButton.check();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export class VehicleLookupLicensePage extends BasePage {
|
|||
this.licensePlateNumTextBox = page.getByRole('textbox', { name: 'License plate number' });
|
||||
this.licensePlateStateDrpDwn = page.getByRole('combobox', { name: 'License plate state' });
|
||||
this.plateNoMatchError = page.getByText('Your license plate didn’t return a VIN match.Please re-enter the information');
|
||||
this.plateMismatchAlert = page.getByRole('alert').locator('div');
|
||||
this.plateMismatchAlert = page.getByText('We found a windshield, but the VIN associated with the license plate you provided is for a');
|
||||
}
|
||||
|
||||
async enterPlateDetails(vehicleDetails: IVehicleDetails, isVehicleLookupValidations = false) {
|
||||
|
|
@ -26,6 +26,7 @@ export class VehicleLookupLicensePage extends BasePage {
|
|||
await this.continueButton.click({ timeout: 1000 });
|
||||
await expect(this.plateNoMatchError).toBeVisible();
|
||||
await this.licensePlateNumTextBox.fill(vehicleDetails.licensePlateNumber[1]);
|
||||
await this.licensePlateStateDrpDwn.selectOption(vehicleDetails.licensePlateState![1]);
|
||||
await this.continueButton.click({ timeout: 1000 });
|
||||
await expect(this.plateMismatchAlert).toBeVisible();
|
||||
await this.licensePlateNumTextBox.fill(vehicleDetails.licensePlateNumber[2]);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ export class VehicleLookupPage extends BasePage {
|
|||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.vinLookupButton = page.getByLabel('Provide my VIN manually', { exact: true });
|
||||
this.vinLookupButton = page.getByLabel('Provide my VIN', { exact: true });
|
||||
this.addressLookupButton = page.getByLabel('Provide my home address', { exact: true });
|
||||
this.licenseLookupButton = page.getByLabel('Provide my license plate #', { exact: true });
|
||||
this.vinLookupPage = new VinLookupPage(page);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { Page } from "@playwright/test";
|
||||
import { expect, type Locator, type Page } from "@playwright/test";
|
||||
import { PartQuestionsPage } from "./PartQuestionsPage";
|
||||
import { IPartQuestion } from '@business-logic/types/CustomerDetails';
|
||||
|
||||
export default class VehiclePartQuestionsPage extends PartQuestionsPage{
|
||||
issPageValue = 'vehicle-parts';
|
||||
|
|
@ -7,4 +8,16 @@ export default class VehiclePartQuestionsPage extends PartQuestionsPage{
|
|||
constructor(page: Page) {
|
||||
super(page);
|
||||
}
|
||||
|
||||
async selectPartQuestionResponses(partQuestions: IPartQuestion[]) {
|
||||
for (const pq of partQuestions) {
|
||||
const parentobject=this.page.locator(`fieldset[aria-labelledby="${pq.partQuestionType}"]`);
|
||||
const partQuestionOptionButton = parentobject.locator(`[buttonlabel="${pq.optionToSelect}"]`);
|
||||
await partQuestionOptionButton.nth(0).click();
|
||||
if (pq.secondaryQuestionOptionToSelect != null) {
|
||||
const secondaryQuestionButton = parentobject.getByText(`${pq.secondaryQuestionOptionToSelect}`);
|
||||
await secondaryQuestionButton.nth(1).click();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ export class WelcomePage extends BasePage {
|
|||
readonly city: Locator;
|
||||
readonly state: Locator;
|
||||
readonly cookieCloseButton: Locator;
|
||||
readonly GetStartedButton: Locator;
|
||||
url = process.env['BASE_URL']! + '/?issPage=welcome-page';
|
||||
issPageValue = 'welcome-page';
|
||||
|
||||
|
|
@ -24,13 +25,14 @@ export class WelcomePage extends BasePage {
|
|||
this.page = page;
|
||||
this.policyNumber = page.getByRole('textbox', { name: 'Policy number' });
|
||||
this.policyZip = page.getByRole('textbox', { name: 'Policy ZIP' });
|
||||
this.damageDate = page.getByRole('textbox', { name: 'When did the damage occur?<' });
|
||||
this.damageDate = page.locator('#dateOfLossField');
|
||||
this.damageCause = page.locator('#damageCauseQuestionField');
|
||||
this.phoneNumber = page.getByRole('textbox', { name: 'Best number to reach you' });
|
||||
this.emailAddress = page.getByRole('textbox', { name: 'Email address' });
|
||||
this.city = page.getByRole('textbox', { name: 'In which city did the damage' });
|
||||
this.state = page.locator('select[name="\\38 fdf9dc2e13e430eb57529499dceb3eb"]');
|
||||
this.cookieCloseButton = page.getByRole('button', { name: 'Close' });
|
||||
this.GetStartedButton = page.getByRole('button', { name: 'Get Started' });
|
||||
}
|
||||
|
||||
async goto(clientTag: string) {
|
||||
|
|
@ -66,18 +68,17 @@ export class WelcomePage extends BasePage {
|
|||
|
||||
async populatePage(customerDetails: ICustomerDetails, claimDetails: IClaimDetails, isFillCityInfo: boolean) {
|
||||
await this.policyNumber.fill(claimDetails.policyNumber);
|
||||
await this.policyZip.fill(customerDetails.address.postalCode);
|
||||
await this.phoneNumber.fill(customerDetails.phoneNumber);
|
||||
await this.damageDate.click();
|
||||
await this.damageDate.fill(claimDetails.damageDate);
|
||||
await this.damageCause.selectOption(claimDetails.damageCause);
|
||||
await this.damageCause.press('Tab');
|
||||
await this.phoneNumber.fill(customerDetails.phoneNumber);
|
||||
// Phone number fixed 12/5. Can't start with 1 or 0
|
||||
await this.emailAddress.fill(customerDetails.email);
|
||||
await this.policyZip.fill(customerDetails.address.postalCode);
|
||||
|
||||
if (isFillCityInfo) {
|
||||
await this.city.fill(customerDetails.address.city);
|
||||
await this.state.selectOption(customerDetails.address.state);
|
||||
await this.city.fill(customerDetails.address.city);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -88,6 +88,7 @@ export default defineConfig({
|
|||
// baseURL: 'http://127.0.0.1:3000',
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
baseURL: process.env.BASE_URL || 'https://selfservice.test.glassclaim.com',
|
||||
trace: 'on-first-retry',
|
||||
headless: process.env.CI ? true : false,
|
||||
screenshot: "only-on-failure",
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import TestCase from "@business-logic/types/TestCase";
|
||||
import { expect, Page } from "@playwright/test";
|
||||
import { getDefaultTestData } from "safelite-playwright-core";
|
||||
import { addSmokeTagToRandomTest, prepareTest, test, TestInfo } from "@business-logic/types/Test";
|
||||
import { RuleEngine, ValidationOptions } from "@business-logic/types/RuleEngine";
|
||||
import { ICustomerDetails } from "@business-logic/types/CustomerDetails";
|
||||
import essentialHpTestCases from "./0016_EssentialRepairInShop";
|
||||
import essentialReplaceTestCases from "./0013_EssentialReplace";
|
||||
import { BailoutCode, VehicleDamage, VehicleLookupType } from "@business-logic/types/Enums";
|
||||
import { BailoutCode, ServiceLocation, VehicleDamage, VehicleLookupType } from "@business-logic/types/Enums";
|
||||
import essentialTpaNotEnabledTestCases from "./0003_EssentialTpaNotEnabledBailout";
|
||||
import essentialDoNotSeeShopTestCases from "./0011_EssentialDoNotSeeShopBailout";
|
||||
import essentialVehicleNotFoundTestCases from "./0010_EssentialVehicleNotFoundBailout";
|
||||
|
|
@ -58,7 +59,7 @@ import advancedScenario0025TestCases from "./advanced/0025a_VehicleByVINUnverifi
|
|||
import advancedScenario0026aTestCases from "./advanced/0026a_NoDeductibleAdasBailout5";
|
||||
import advancedScenario0028aTestCases from "./advanced/0028a_ItacCancelMyClaim";
|
||||
import advancedScenario0029aTestCases from "./advanced/0029a_HeavyVehicleBailout";
|
||||
import advancedScenario0030aTestCases from "./advanced/0030a_PartsServiceBailout";
|
||||
import advancedScenario0030aTestCases from "./advanced/0030a_APIErrorBailout";
|
||||
import advancedScenario0031aTestCases from "./advanced/0031a_ReplaceServiceableBigTruck";
|
||||
import advancedScenario0032aTestCases from "./advanced/0032a_DeclineNonServiceableBigTruck";
|
||||
|
||||
|
|
@ -382,8 +383,8 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
// Destructure data for easy access
|
||||
const { customerDetails, claimDetails, vehicleDetails, vehicleDamage,
|
||||
appointmentDetails, isSafelite, endorsements,
|
||||
partQuestions, paymentDetails, isNoComp, isItac, isRecalNotification,
|
||||
isRecalWarning, servicePackage, hasStateLawPopup, otherVehiclesOnPolicy,
|
||||
partQuestions, paymentDetails, isNoComp, isItac, isRecalNotification, isUnverifiedPolicyAfterVehicleLookup,
|
||||
isRecalWarning, servicePackage, hasOemEndorsement, hasStateLawPopup, otherVehiclesOnPolicy,
|
||||
isSeparateApptsWarning, vehiclePartQuestions, editVehicleDetails, isAddressLookupValidations,
|
||||
hasMilitaryWarning, capabilityQuestions, isUseVehicleOnPolicy,
|
||||
isVehicleLookupValidations, isMoldingQuestion, isNonServiceable, isNonServiceableVin } = testCase.testData;
|
||||
|
|
@ -401,9 +402,9 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
vehiclePartQuestionsPage, capabilityQuestionsPage, moldingQuestionsPage, addressLookupPage } = testCase.pages;
|
||||
|
||||
// Destructure bailout flags
|
||||
const { isVehicleSelectBailout, isDoNotSeeMyShopBailout, isTpaNotEnabledBailout,
|
||||
isPartsServiceErrorBailout, isVehicleLookupBailout, isPriceServiceErrorBailout,
|
||||
isRequestCallbackBailout } = testCase.testData.bailoutFlags || {};
|
||||
const { isVehicleSelectBailout, isTpaNotEnabledBailout,
|
||||
isAPIErrorBailout, isVehicleLookupBailout, isPriceServiceErrorBailout,
|
||||
isRequestCallbackBailout, isHeavyTruckVehicleBailout, isCoverageCancelledByUser } = testCase.testData.bailoutFlags || {};
|
||||
|
||||
const repairTypes: VehicleDamage[] = [
|
||||
VehicleDamage.WindshieldOneChip,
|
||||
|
|
@ -420,7 +421,7 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
|
||||
await test.step('WelcomePage >> Populate Customer Details', async () => {
|
||||
await welcomePage.populatePage(customerDetails!, claimDetails!, await welcomePage.hasCityInfo());
|
||||
await welcomePage.nextPage();
|
||||
await welcomePage.GetStartedButton.click();
|
||||
});
|
||||
|
||||
if (testCase.testData.isDuplicateClaim) {
|
||||
|
|
@ -445,26 +446,35 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
}
|
||||
}
|
||||
if (!(isUseVehicleOnPolicy ?? true)) {
|
||||
await policyVehiclesPage.selectVehicleNotListed();
|
||||
await policyVehiclesPage.addAnotherVehicle();
|
||||
await policyVehiclesPage.nextPage();
|
||||
await vehicleSelectionPage.selectVehicle(vehicleDetails!);
|
||||
await policyVehiclesPage.nextPage();
|
||||
|
||||
await test.step('PolicyHolderDetailsPage >> Enter customer data', async () => {
|
||||
await policyHolderDetailsPage.validateURL(policyHolderDetailsPage.issPageValue);
|
||||
await policyHolderDetailsPage.fillCustomerDetails(customerDetails!);
|
||||
await policyHolderDetailsPage.nextPage();
|
||||
});
|
||||
} else {
|
||||
// Select vehicle
|
||||
await policyVehiclesPage.selectVehicle(vehicleDetails!);
|
||||
|
||||
await policyVehiclesPage.nextPage();
|
||||
await policyVehiclesPage.logReferralNumber();
|
||||
|
||||
if (isNonServiceable && isHeavyTruckVehicleBailout) {
|
||||
await bailoutPage.validateURL(bailoutPage.issPageValue);
|
||||
await bailoutPage.validateBailoutDetails(customerDetails!, BailoutCode.HeavyTruckVehicle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNonServiceable) {
|
||||
await policyVehiclesPage.assertNonServiceableAlertBehavior();
|
||||
return;
|
||||
}
|
||||
await policyVehiclesPage.nextPage();
|
||||
}
|
||||
});
|
||||
|
||||
if (isNonServiceable) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hasEndorsements) {
|
||||
if (hasEndorsements) {
|
||||
await test.step('EndorsementsPage >> Select Endorsements', async () => {
|
||||
await endorsementsPage.validateURL(endorsementsPage.issPageValue);
|
||||
await endorsementsPage.verifyEndorsements(endorsements);
|
||||
|
|
@ -472,29 +482,22 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
await endorsementsPage.nextPage();
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
await policyVehiclesPage.logReferralNumber();
|
||||
await test.step('PolicyHolderDetailsPage >> Enter customer data', async () => {
|
||||
await policyHolderDetailsPage.validateURL(policyHolderDetailsPage.issPageValue);
|
||||
await policyHolderDetailsPage.fillCustomerDetails(customerDetails!);
|
||||
await policyHolderDetailsPage.nextPage();
|
||||
await test.step('PolicyHolderDetailsPage >> Enter customer data', async () => {
|
||||
await policyHolderDetailsPage.validateURL(policyHolderDetailsPage.issPageValue);
|
||||
await policyHolderDetailsPage.fillCustomerDetails(customerDetails!);
|
||||
await policyHolderDetailsPage.nextPage();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (isNonServiceable) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isVehicleLookupBailout) {
|
||||
forceAPIError(page, '/vehicle/api/v1/vehicle/lookup')
|
||||
}
|
||||
|
||||
await test.step('VehicleDetailsPage >> Select Vehicle', async () => {
|
||||
await vehicleSelectionPage.validateURL(vehicleSelectionPage.issPageValue);
|
||||
await vehicleSelectionPage.selectVehicle(vehicleDetails!);
|
||||
if (isNonServiceable) {
|
||||
await vehicleSelectionPage.assertNonServiceableAlertBehavior();
|
||||
return;
|
||||
}
|
||||
await vehicleSelectionPage.nextPage();
|
||||
});
|
||||
|
||||
if (isNonServiceable) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -508,20 +511,21 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
}
|
||||
}
|
||||
|
||||
if (editVehicleDetails) {
|
||||
isPolicyFound = false; // Flow proceeds as unverified
|
||||
// Essential flow when policy is not found
|
||||
if (isPolicyFound === false) {
|
||||
testCase.testData.isPolicyFound = false;
|
||||
await test.step('VehicleDamagePage >> Click Edit Vehicle', async () => {
|
||||
await vehicleDamagePage.validateURL(vehicleDamagePage.issPageValue);
|
||||
await vehicleDamagePage.editVehicleButton.click();
|
||||
});
|
||||
|
||||
await test.step('VehicleDetailsPage >> Select edited vehicle', async () => {
|
||||
await test.step('VehicleDetailsPage >> Select Vehicle', async () => {
|
||||
await test.step('VehicleSelectionPage >> Select vehicle for essential flow', async () => {
|
||||
await vehicleSelectionPage.validateURL(vehicleSelectionPage.issPageValue);
|
||||
await vehicleSelectionPage.selectVehicle(editVehicleDetails);
|
||||
await vehicleSelectionPage.selectVehicle(vehicleDetails!);
|
||||
await vehicleSelectionPage.nextPage();
|
||||
});
|
||||
});
|
||||
|
||||
await test.step('PolicyHolderDetailsPage >> Enter customer data', async () => {
|
||||
await policyHolderDetailsPage.validateURL(policyHolderDetailsPage.issPageValue);
|
||||
await policyHolderDetailsPage.fillCustomerDetails(customerDetails!);
|
||||
|
||||
await policyHolderDetailsPage.nextPage();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -534,7 +538,7 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
await vehicleDamagePage.nextPage();
|
||||
});
|
||||
|
||||
if (isPartsServiceErrorBailout) {
|
||||
if (isAPIErrorBailout) {
|
||||
await test.step('VehicleLookupPage >> Select Lookup Type', async () => {
|
||||
await vehicleLookupPage.validateURL(vehicleLookupPage.issPageValue);
|
||||
await vehicleLookupPage.vehicleLookup(vehicleDetails!);
|
||||
|
|
@ -545,9 +549,9 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
forceAPIError(page, '/parts/api/v1/parts')
|
||||
await vinLookupPage.nextPage();
|
||||
});
|
||||
await test.step('BailoutPage >> Parts Service Error Bailout', async () => {
|
||||
await test.step('BailoutPage >> API error occurred bailout', async () => {
|
||||
await bailoutPage.validateURL(bailoutPage.issPageValue);
|
||||
await bailoutPage.validateBailoutDetails(customerDetails!, BailoutCode.PartsServiceError);
|
||||
await bailoutPage.validateBailoutDetails(customerDetails!, BailoutCode.ApiError);
|
||||
return;
|
||||
});
|
||||
return;
|
||||
|
|
@ -584,10 +588,14 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
await test.step('Address Lookup validations >> Vehicle Lookup by address: ' + customerDetails!.address.street, async () => {
|
||||
if (Array.isArray(vehicleDetails?.address)) {
|
||||
await addressLookupPage.validateURL(addressLookupPage.issPageValue);
|
||||
await addressLookupPage.validateAddressLookupAlerts(vehicleDetails?.address);
|
||||
await addressLookupPage.validateAddressLookupAlerts(vehicleDetails?.address!);
|
||||
await addressLookupPage.nextPage();
|
||||
}
|
||||
});
|
||||
|
||||
await test.step('Address Vehicles >> Next page', async () => {
|
||||
await addressLookupPage.nextPage();
|
||||
});
|
||||
} else {
|
||||
await test.step('VehicleLookupAddressPage >> Lookup by address: ' + customerDetails!.address.street, async () => {
|
||||
await vehicleLookupAddressPage.validateURL(vehicleLookupAddressPage.issPageValue);
|
||||
|
|
@ -627,6 +635,7 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isMoldingQuestion) {
|
||||
await test.step('Molding Questions Page >> Select Yes', async () => {
|
||||
await moldingQuestionsPage.validateURL(moldingQuestionsPage.issPageValue);
|
||||
|
|
@ -637,6 +646,7 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
await moldingQuestionsPage.nextPage();
|
||||
});
|
||||
}
|
||||
|
||||
if (capabilityQuestions && capabilityQuestions.length > 0) {
|
||||
await capabilityQuestionsPage.validateURL(capabilityQuestionsPage.issPageValue);
|
||||
await capabilityQuestionsPage.validatePartQuestions(capabilityQuestions);
|
||||
|
|
@ -645,6 +655,7 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
}
|
||||
|
||||
if (partQuestions && partQuestions.length > 0) {
|
||||
let partQuestionsPage = testCase.pages.partQuestionsPage;
|
||||
await partQuestionsPage.validateURL(partQuestionsPage.issPageValue);
|
||||
await partQuestionsPage.validatePartQuestions(partQuestions);
|
||||
await partQuestionsPage.selectPartQuestionResponses(partQuestions);
|
||||
|
|
@ -653,60 +664,96 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
|
||||
if (vehiclePartQuestions && vehiclePartQuestions.length > 0) {
|
||||
await vehiclePartQuestionsPage.validateURL(vehiclePartQuestionsPage.issPageValue);
|
||||
await vehiclePartQuestionsPage.validatePartQuestions(vehiclePartQuestions);
|
||||
await vehiclePartQuestionsPage.selectPartQuestionResponses(vehiclePartQuestions);
|
||||
await vehiclePartQuestionsPage.nextPage();
|
||||
}
|
||||
if (isRequestCallbackBailout) {
|
||||
await test.step('CoverageStatementPage >> Cancel My claim', async () => {
|
||||
|
||||
if (isCoverageCancelledByUser) {
|
||||
await test.step('CoverageStatementPage >> Cancel my claim', async () => {
|
||||
await coverageStatementPage.validateURL(coverageStatementPage.issPageValue);
|
||||
await coverageStatementPage.cancelMyClaim();
|
||||
});
|
||||
|
||||
await test.step('BailoutPage >> Request Callback Bailout', async () => {
|
||||
await test.step('BailoutPage >> User canceled claim on ITAC/No Comp coverage statement', async () => {
|
||||
await bailoutPage.validateURL(bailoutPage.issPageValue);
|
||||
await bailoutPage.validateBailoutDetails(customerDetails!, BailoutCode.RequestCallback);
|
||||
await bailoutPage.validateBailoutDetails(customerDetails!, BailoutCode.CoverageCancelledByUser);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await test.step('CoverageStatementPage >> Next page', async () => {
|
||||
await coverageStatementPage.validateURL(coverageStatementPage.issPageValue);
|
||||
// Confirm no coverage
|
||||
if (isPolicyFound && (isItac || isNoComp)) {
|
||||
await coverageStatementPage.continueToScheduleButton.click();
|
||||
}
|
||||
|
||||
await coverageStatementPage.nextPage();
|
||||
if (hasOemEndorsement) {
|
||||
await coverageStatementPage.validateOEMBullet();
|
||||
}
|
||||
// For essential/unverified flows
|
||||
if (!isPolicyFound) {
|
||||
await coverageStatementPage.handleUnverifiedFlow(claimDetails!);
|
||||
}
|
||||
|
||||
// For No Comp flows
|
||||
if (isPolicyFound && isNoComp === true) {
|
||||
await coverageStatementPage.handleNoCompFlow();
|
||||
}
|
||||
|
||||
// For ITAC flows
|
||||
if (isPolicyFound && isItac === true) {
|
||||
await coverageStatementPage.handleITACFlow();
|
||||
}
|
||||
|
||||
// For replacements with deductible
|
||||
if (isPolicyFound && claimDetails?.policyDeductible! > 0 && claimDetails?.policyDeductible !== 9999 && testCase.testData.isUnverifiedPolicyAfterVehicleLookup !== true) {
|
||||
await coverageStatementPage.handleReplacementWithDeductibleFlow(claimDetails!);
|
||||
}
|
||||
|
||||
// For replacements or repairs with 0 deductible
|
||||
if (isPolicyFound && claimDetails?.policyDeductible === 0) {
|
||||
await coverageStatementPage.handleReplacementOrRepairWithNoDeductibleFlow(claimDetails!, VehicleDamage!);
|
||||
}
|
||||
|
||||
// For unverified policy after vehicle lookup
|
||||
if (isPolicyFound && testCase.testData.isUnverifiedPolicyAfterVehicleLookup === true) {
|
||||
await coverageStatementPage.handleUnverifiedPolicyAfterVehicleLookupFlow();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (hasStateLawPopup) {
|
||||
await test.step('ProviderPreferencePage >> Dismiss state law popup', async () => {
|
||||
await providerPreferencePage.validateURL(providerPreferencePage.issPageValue);
|
||||
await providerPreferencePage.validateStateLawModalIsVisible();
|
||||
await providerPreferencePage.gotItButton.click();
|
||||
});
|
||||
if (vehicleDamage!.includes(VehicleDamage.WindshieldCrack)) {
|
||||
await providerPreferencePage.stateLawModalOkayButton.click();
|
||||
} else {
|
||||
await providerPreferencePage.stateLawModalOkayButton.click();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!isPolicyFound || !(isItac || isNoComp)) {
|
||||
if (!isPolicyFound || !(isItac || isNoComp) && !isUnverifiedPolicyAfterVehicleLookup) {
|
||||
await test.step('ProviderPreferencePage >> Select Provider ' + isSafelite ? "Safelite" : "Other shops(Non-Safelite)", async () => {
|
||||
await providerPreferencePage.validateURL(providerPreferencePage.issPageValue);
|
||||
await providerPreferencePage.selectProvider(isSafelite);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// validations for Recal warning mesage
|
||||
if (isRecalWarning) {
|
||||
await serviceLocationPage.validateURL(serviceLocationPage.issPageValue);
|
||||
await serviceLocationPage.validateRecalWarning();
|
||||
if (isSafelite && isUnverifiedPolicyAfterVehicleLookup) {
|
||||
await test.step('ProviderPreferencePage >> Select Provider ' + isSafelite ? "Safelite" : "Other shops(Non-Safelite)", async () => {
|
||||
await providerPreferencePage.validateURL(providerPreferencePage.issPageValue);
|
||||
await providerPreferencePage.selectProvider(isSafelite);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// if isRecalNotifidation flag true additional step to acknowledge Recal notification.
|
||||
if (isRecalNotification) {
|
||||
await providerPreferencePage.validateURL(providerPreferencePage.issPageValue);
|
||||
await providerPreferencePage.acknowledgeRecalNotificaiton();
|
||||
|
||||
if (!isSafelite && isUnverifiedPolicyAfterVehicleLookup) {
|
||||
await test.step('ProviderPreferencePage >> Schedule TPA without Adas', async () => {
|
||||
await providerPreferencePage.validateURL(providerPreferencePage.issPageValue);
|
||||
await providerPreferencePage.scheduleTPAWithoutAdas();
|
||||
});
|
||||
}
|
||||
// If No-Comp or ITAC, ProviderPreferencePage does not appear
|
||||
if (!isPolicyFound || !(isItac || isNoComp)) {
|
||||
if (!isPolicyFound || !(isItac || isNoComp) || isUnverifiedPolicyAfterVehicleLookup) {
|
||||
|
||||
|
||||
if (!isSafelite) {
|
||||
|
|
@ -728,16 +775,6 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (isDoNotSeeMyShopBailout) {
|
||||
await test.step('TpaSearchPage >> Select "Do Not See My Shop"', async () => {
|
||||
await tpaSearchPage.validateURL(tpaSearchPage.issPageValue);
|
||||
await tpaSearchPage.selectDoNotSeeMyShop();
|
||||
});
|
||||
await bailoutPage.validateURL(bailoutPage.issPageValue);
|
||||
await bailoutPage.validateBailoutDetails(customerDetails!, BailoutCode.DoNotSeeMyShop);
|
||||
return;
|
||||
}
|
||||
|
||||
await test.step('TpaSearchPage >> TPA Search', async () => {
|
||||
await tpaSearchPage.validateURL(tpaSearchPage.issPageValue);
|
||||
await tpaSearchPage.selectFirstLocation();
|
||||
|
|
@ -745,9 +782,12 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
});
|
||||
|
||||
await test.step('TpaSubmitPage >> TPA Submit', async () => {
|
||||
// TODO: Validations
|
||||
await tpaSubmitPage.validateURL(tpaSubmitPage.issPageValue);
|
||||
if (!isUnverifiedPolicyAfterVehicleLookup) {
|
||||
await tpaSubmitPage.validateDeductible(claimDetails!);
|
||||
} else {
|
||||
await tpaSubmitPage.nextPage();
|
||||
}
|
||||
});
|
||||
|
||||
await test.step('TpaConfirmationPage >> TPA Confirmation', async () => {
|
||||
|
|
@ -756,43 +796,41 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
return;
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await test.step('ServiceLocationPage >> Select service location', async () => {
|
||||
await serviceLocationPage.validateURL(serviceLocationPage.issPageValue);
|
||||
await serviceLocationPage.selectLocation(appointmentDetails!);
|
||||
if (hasMilitaryWarning) {
|
||||
await expect.soft(serviceLocationPage.militaryWarningMessage).toBeVisible();
|
||||
}
|
||||
await serviceLocationPage.nextPage();
|
||||
});
|
||||
}}
|
||||
|
||||
await test.step('SchedulePage >> Select day and time', async () => {
|
||||
await schedulePage.validateURL(schedulePage.issPageValue);
|
||||
customerDetails!.apptDate = await schedulePage.scheduleFirstAppointment(appointmentDetails!.serviceLocation);
|
||||
});
|
||||
|
||||
await test.step('ContactDetailsPage >> Validate contact details', async () => {
|
||||
const expectedContactDetails: Partial<ICustomerDetails> = {
|
||||
firstName: customerDetails!.firstName,
|
||||
lastName: customerDetails!.lastName,
|
||||
email: customerDetails!.email,
|
||||
phoneNumber: customerDetails!.phoneNumber
|
||||
};
|
||||
await contactDetailsPage.validateURL(contactDetailsPage.issPageValue);
|
||||
const actualContactDetails = await contactDetailsPage.getContactDetails();
|
||||
expect.soft(actualContactDetails).toEqual(expectedContactDetails);
|
||||
|
||||
await contactDetailsPage.fillNotes(customerDetails!.notes);
|
||||
|
||||
if (isPriceServiceErrorBailout) {
|
||||
forceAPIError(page, '/price/api/v1/price/combined-quote');
|
||||
if (appointmentDetails?.serviceLocation === ServiceLocation.Mobile) {
|
||||
await schedulePage.scheduleMobile(appointmentDetails);
|
||||
}
|
||||
|
||||
await contactDetailsPage.nextPage();
|
||||
if (appointmentDetails?.serviceLocation === ServiceLocation.InShop || appointmentDetails?.serviceLocation === ServiceLocation.DropOff) {
|
||||
await schedulePage.scheduleInShop(appointmentDetails);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
await test.step('ServicePackagesPage >> Choose service package', async () => {
|
||||
await servicePackagesPage.validateURL(servicePackagesPage.issPageValue);
|
||||
await servicePackagesPage.selectServicePackage(servicePackage!);
|
||||
});
|
||||
|
||||
if (appointmentDetails?.serviceLocation === ServiceLocation.Mobile) {
|
||||
await test.step('ContactDetailsPage >> Validate contact details', async () => {
|
||||
await contactDetailsPage.validateURL(contactDetailsPage.issPageValue);
|
||||
|
||||
|
||||
await contactDetailsPage.fillContactDetails(customerDetails!);
|
||||
if (appointmentDetails?.alternateMobileCity) {
|
||||
await contactDetailsPage.fillAlternateMobileStreetAndCity(appointmentDetails?.alternateMobileStreetAddress!, appointmentDetails?.alternateMobileCity!);
|
||||
}
|
||||
|
||||
await contactDetailsPage.nextPage();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
if (isPriceServiceErrorBailout) {
|
||||
await test.step('BailoutPage >> Price Service Error Bailout', async () => {
|
||||
await bailoutPage.validateURL(bailoutPage.issPageValue);
|
||||
|
|
@ -801,22 +839,29 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
return;
|
||||
}
|
||||
|
||||
await test.step('ServicePackagesPage >> Choose service package', async () => {
|
||||
await servicePackagesPage.validateURL(servicePackagesPage.issPageValue);
|
||||
customerDetails!.packagePrice = await servicePackagesPage.selectServicePackage(servicePackage!);
|
||||
await servicePackagesPage.nextPage();
|
||||
});
|
||||
|
||||
if (isPolicyFound && (isUseVehicleOnPolicy ?? true) && claimDetails!.policyDeductible > 0) {
|
||||
await test.step('PaymentMethodPage >> Execute Payment', async () => {
|
||||
await paymentMethodPage.validateURL(paymentMethodPage.issPageValue);
|
||||
await paymentMethodPage.executePayment(paymentDetails!);
|
||||
await paymentMethodPage.executePayment(paymentDetails!, claimDetails!, servicePackage!);
|
||||
await paymentMethodPage.nextPage();
|
||||
|
||||
});
|
||||
} else {
|
||||
await test.step('PaymentMethodPage >> Skip to Order Confirmation', async () => {
|
||||
await paymentMethodPage.validateURL(paymentMethodPage.issPageValue);
|
||||
await paymentMethodPage.nextPage();
|
||||
|
||||
if (isPolicyFound && (isUseVehicleOnPolicy ?? true) && claimDetails!.policyDeductible === 0) {
|
||||
await paymentMethodPage.submitOrderWithoutPIA();
|
||||
}
|
||||
|
||||
if (!isPolicyFound) {
|
||||
await paymentMethodPage.submitOrderWithoutPIA();
|
||||
}
|
||||
|
||||
if (isPolicyFound && testCase.testData.isUnverifiedPolicyAfterVehicleLookup === true) {
|
||||
await paymentMethodPage.submitOrderWithoutPIA();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ const essentialReplaceStaticAdasData: Partial<ITestData> = {
|
|||
phoneNumber: faker.helpers.fromRegExp(/[2-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]/),
|
||||
notes: 'Automated Test',
|
||||
address: {
|
||||
street: faker.location.streetAddress(),
|
||||
city: 'Knoxville',
|
||||
state: 'Tennessee',
|
||||
postalCode: '37996',
|
||||
street: "123 Test Road",
|
||||
city: 'Columbus',
|
||||
state: 'OHIO',
|
||||
postalCode: '43085',
|
||||
country: 'United States'
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ const essentialRepairInShopAcuraData: Partial<ITestData> = {
|
|||
phoneNumber: faker.helpers.fromRegExp(/[2-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]/),
|
||||
notes: 'Automated Test',
|
||||
address: {
|
||||
street: faker.location.streetAddress(),
|
||||
street: '200 W. Oak Street',
|
||||
city: 'Fort Collins',
|
||||
state: 'Colorado',
|
||||
state: 'COLORADO',
|
||||
postalCode: '80526',
|
||||
country: 'United States'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ const essentialTpaEnabledData: Partial<ITestData> = {
|
|||
notes: 'Automated Test',
|
||||
address: {
|
||||
// street: faker.location.streetAddress(),
|
||||
street: '134 Woodlands Place',
|
||||
city: 'Dublin',
|
||||
state: 'Florida',
|
||||
postalCode: '32040',
|
||||
street: '1343 Cameron Ave',
|
||||
city: 'Lewis Center',
|
||||
state: 'OH',
|
||||
postalCode: '43035',
|
||||
country: 'United States'
|
||||
}
|
||||
},
|
||||
|
|
@ -42,10 +42,10 @@ const essentialTpaEnabledData: Partial<ITestData> = {
|
|||
damageCause: DamageType.Other
|
||||
},
|
||||
vehicleDetails: {
|
||||
year: '2022',
|
||||
year: '2015',
|
||||
make: 'Honda',
|
||||
model: 'Civic',
|
||||
style: '4 door hatchback'
|
||||
model: 'Accord',
|
||||
style: '4 door sedan'
|
||||
},
|
||||
vehicleDamage: [
|
||||
VehicleDamage.WindshieldThreeChips,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ const essentialDoNotSeeShopData: Partial<ITestData> = {
|
|||
partQuestions: undefined,
|
||||
isSafelite: false,
|
||||
bailoutFlags: {
|
||||
isDoNotSeeMyShopBailout: true
|
||||
},
|
||||
servicePackage: faker.helpers.enumValue(ServicePackage),
|
||||
customerDetails: {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const customerDetails: ICustomerDetails = {
|
|||
}
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0001a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policyNumber = `~AutomatedScenario0001a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0001a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0001Data: Partial<ITestData> = {
|
||||
|
|
@ -31,7 +31,6 @@ const advancedScenario0001Data: Partial<ITestData> = {
|
|||
isDuplicateClaim: false,
|
||||
isPolicyFound: true,
|
||||
isNoComp: false,
|
||||
hasStateLawPopup: true,
|
||||
endorsements: undefined,
|
||||
vehiclePartQuestions: [
|
||||
|
||||
|
|
@ -60,7 +59,7 @@ const advancedScenario0001Data: Partial<ITestData> = {
|
|||
shopAddress: undefined,
|
||||
appointmentDate: nextWeekday
|
||||
},
|
||||
paymentDetails: ClientData.getDefaultPaypalDetails()//ClientData.getDefaultCreditCardDetails()
|
||||
paymentDetails: ClientData.getDefaultCreditCardDetails()
|
||||
}
|
||||
|
||||
// TODO: Add validation for deductible/covered amount
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ if ((process.env.ENABLE_MOCK_TESTING ?? 'false') === 'true') {
|
|||
customerDetails.lastName = 'Cormier';
|
||||
customerDetails.address.street = '69825 W Pine Street';
|
||||
} else {
|
||||
policyNumber = `~AutomatedScenario0002a${faker.string.uuid().substring(0, 6)}`;
|
||||
policyNumber = `~AutomatedScenario0002a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`;
|
||||
};
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0002a', customerDetails, policyNumber);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0003a${faker.string.uuid().substring(0,6)}`;
|
||||
const policyNumber = `~AutomatedScenario0003a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`;
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0003a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0003Data: Partial<ITestData> = {
|
||||
|
|
@ -33,6 +33,7 @@ const advancedScenario0003Data: Partial<ITestData> = {
|
|||
isDuplicateClaim: false,
|
||||
isPolicyFound: true,
|
||||
isNoComp: false,
|
||||
hasOemEndorsement: true,
|
||||
hasStateLawPopup: false,
|
||||
endorsements: undefined,
|
||||
vehiclePartQuestions: [
|
||||
|
|
@ -44,7 +45,7 @@ const advancedScenario0003Data: Partial<ITestData> = {
|
|||
{
|
||||
partQuestionType: PartQuestionType.PassengerRearColor,
|
||||
isOnPage: true,
|
||||
optionToSelect: 'Green Tint'
|
||||
optionToSelect: 'Solar, Passenger side, Rear'
|
||||
},
|
||||
],
|
||||
isSafelite: true,
|
||||
|
|
@ -53,7 +54,7 @@ const advancedScenario0003Data: Partial<ITestData> = {
|
|||
claimDetails: {
|
||||
policyNumber: policyNumber,
|
||||
policyDeductible: 50,
|
||||
damageDate: '2016-01-02',
|
||||
damageDate: '2026-01-02',
|
||||
damageCause: faker.helpers.enumValue(DamageType)
|
||||
},
|
||||
policySoap: policySoap,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const customerDetails: ICustomerDetails = {
|
|||
}
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0004a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policyNumber = `~AutomatedScenario0004a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0004a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0004aData: Partial<ITestData> = {
|
||||
|
|
@ -33,8 +33,7 @@ const advancedScenario0004aData: Partial<ITestData> = {
|
|||
isNoComp: false,
|
||||
hasStateLawPopup: false,
|
||||
endorsements: undefined,
|
||||
vehiclePartQuestions: [
|
||||
],
|
||||
partQuestions: [],
|
||||
isSafelite: true,
|
||||
servicePackage: faker.helpers.enumValue(ServicePackage),
|
||||
customerDetails: customerDetails,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0005a${faker.string.uuid().substring(0,6)}`;
|
||||
const policyNumber = `~AutomatedScenario0005a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0005a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0005Data: Partial<ITestData> = {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0006a${faker.string.uuid().substring(0,6)}`;
|
||||
const policyNumber = `~AutomatedScenario0006a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0006a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0006Data: Partial<ITestData> = {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0007a${faker.string.uuid().substring(0,6)}`;
|
||||
const policyNumber = `~AutomatedScenario0007a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0007a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0007Data: Partial<ITestData> = {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ const nextWeekday = getNextWeekday();
|
|||
const customerAddress: IAddress = {
|
||||
street: faker.location.streetAddress(),
|
||||
city: 'Hamden',
|
||||
state: 'CT',
|
||||
state: 'CONNECTICUT',
|
||||
postalCode: '06517',
|
||||
country: 'United States'
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0008a${faker.string.uuid().substring(0,6)}`;
|
||||
const policyNumber = `~AutomatedScenario0008a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0008a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0008Data: Partial<ITestData> = {
|
||||
|
|
@ -33,7 +33,7 @@ const advancedScenario0008Data: Partial<ITestData> = {
|
|||
isDuplicateClaim: false,
|
||||
isPolicyFound: true,
|
||||
isNoComp: false,
|
||||
hasStateLawPopup: true,
|
||||
hasStateLawPopup: false,
|
||||
endorsements: undefined,
|
||||
vehiclePartQuestions: [
|
||||
// {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0009a${faker.string.uuid().substring(0,6)}`;
|
||||
const policyNumber = `~AutomatedScenario0009a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0009a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0009Data: Partial<ITestData> = {
|
||||
|
|
@ -38,7 +38,7 @@ const advancedScenario0009Data: Partial<ITestData> = {
|
|||
{
|
||||
endorsementType: EndorsementType.Educator,
|
||||
isOnPolicy: true,
|
||||
isClickYes: false
|
||||
isClickYes: true
|
||||
}
|
||||
],
|
||||
vehiclePartQuestions: [
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0010a${faker.string.uuid().substring(0,6)}`;
|
||||
const policyNumber = `~AutomatedScenario0010a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0010a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0010Data: Partial<ITestData> = {
|
||||
|
|
@ -92,7 +92,7 @@ for (const client of advancedClients) {
|
|||
const data = {...advancedScenario0010Data};
|
||||
data.clientTag = client.clientTag;
|
||||
const tc = new TestCase({
|
||||
name: `0010a Advanced Repair No Deductible FL Rear Client: "${client.accountName}"`,
|
||||
name: `0010a Advanced Replace No Deductible FL Rear Client: "${client.accountName}"`,
|
||||
tags: [`@${client.clientTag}`, `@${client.accountName}`, '@Advanced'],
|
||||
testData: data
|
||||
}, undefined, '0010a');
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0011a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policyNumber = `~AutomatedScenario0011a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0011a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0011Data: Partial<ITestData> = {
|
||||
|
|
@ -33,13 +33,13 @@ const advancedScenario0011Data: Partial<ITestData> = {
|
|||
isDuplicateClaim: false,
|
||||
isPolicyFound: true,
|
||||
isNoComp: false,
|
||||
isItac: true,
|
||||
isItac: false,
|
||||
hasStateLawPopup: false,
|
||||
endorsements: [
|
||||
{
|
||||
endorsementType: EndorsementType.Educator,
|
||||
isOnPolicy: true,
|
||||
isClickYes: false
|
||||
isClickYes: true
|
||||
}
|
||||
],
|
||||
partQuestions: undefined,
|
||||
|
|
@ -48,7 +48,7 @@ const advancedScenario0011Data: Partial<ITestData> = {
|
|||
customerDetails: customerDetails,
|
||||
claimDetails: {
|
||||
policyNumber: policyNumber,
|
||||
policyDeductible: 500,
|
||||
policyDeductible: 0,
|
||||
damageDate: '2023-03-01',
|
||||
damageCause: faker.helpers.enumValue(DamageType)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0012a${faker.string.uuid().substring(0,6)}`;
|
||||
const policyNumber = `~AutomatedScenario0012a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0012a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0012Data: Partial<ITestData> = {
|
||||
|
|
@ -48,7 +48,7 @@ const advancedScenario0012Data: Partial<ITestData> = {
|
|||
customerDetails: customerDetails,
|
||||
claimDetails: {
|
||||
policyNumber: policyNumber,
|
||||
policyDeductible: 500,
|
||||
policyDeductible: 9999,
|
||||
damageDate: '2023-09-01',
|
||||
damageCause: faker.helpers.enumValue(DamageType)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import ClientData from "@business-logic/data/ClientData";
|
||||
import TestCase from "@business-logic/types/TestCase";
|
||||
import { DamageType, EndorsementType, ServiceLocation, ServicePackage, VehicleDamage } from "@business-logic/types/Enums";
|
||||
import { DamageType, EndorsementType, PaymentType, ServiceLocation, ServicePackage, VehicleDamage } from "@business-logic/types/Enums";
|
||||
import { ITestData } from "@business-logic/types/ITestData"
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { getNextWeekday } from "@impl/utils/DateUtils";
|
||||
|
|
@ -11,9 +11,9 @@ import { IAddress } from "@business-logic/types/IAddress";
|
|||
const nextWeekday = getNextWeekday();
|
||||
const customerAddress: IAddress = {
|
||||
street: faker.location.streetAddress(),
|
||||
city: 'Birmingham',
|
||||
state: 'AL',
|
||||
postalCode: '35118',
|
||||
city: 'Worthington',
|
||||
state: 'OH',
|
||||
postalCode: '43085',
|
||||
country: 'United States'
|
||||
}
|
||||
const customerDetails: ICustomerDetails = {
|
||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0013a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policyNumber = `~AutomatedScenario0013a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0013a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0013Data: Partial<ITestData> = {
|
||||
|
|
@ -33,13 +33,13 @@ const advancedScenario0013Data: Partial<ITestData> = {
|
|||
isDuplicateClaim: false,
|
||||
isPolicyFound: true,
|
||||
isNoComp: false,
|
||||
isItac: true,
|
||||
isItac: false,
|
||||
hasStateLawPopup: false,
|
||||
endorsements: [
|
||||
{
|
||||
endorsementType: EndorsementType.Educator,
|
||||
isOnPolicy: true,
|
||||
isClickYes: false
|
||||
isClickYes: true
|
||||
}
|
||||
],
|
||||
vehiclePartQuestions: [
|
||||
|
|
@ -49,7 +49,7 @@ const advancedScenario0013Data: Partial<ITestData> = {
|
|||
customerDetails: customerDetails,
|
||||
claimDetails: {
|
||||
policyNumber: policyNumber,
|
||||
policyDeductible: 9999,
|
||||
policyDeductible: 0,
|
||||
damageDate: '2023-08-01',
|
||||
damageCause: faker.helpers.enumValue(DamageType)
|
||||
},
|
||||
|
|
@ -68,7 +68,9 @@ const advancedScenario0013Data: Partial<ITestData> = {
|
|||
serviceAddress: customerAddress,
|
||||
appointmentDate: nextWeekday
|
||||
},
|
||||
paymentDetails: ClientData.getDefaultCreditCardDetails()
|
||||
paymentDetails: {
|
||||
paymentType: PaymentType.PayAtService
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -80,7 +82,7 @@ for (const client of advancedClients) {
|
|||
const data = { ...advancedScenario0013Data };
|
||||
data.clientTag = client.clientTag;
|
||||
const tc = new TestCase({
|
||||
name: `0013a Advanced ITAC Mobile Client: "${client.accountName}"`,
|
||||
name: `0013a Advanced $0 Deductible with Vaps Mobile Client: "${client.accountName}"`,
|
||||
tags: [`@${client.clientTag}`, `@${client.accountName}`, '@Advanced'],
|
||||
testData: data
|
||||
}, undefined, '0013a');
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0014a${faker.string.uuid().substring(0,6)}`;
|
||||
const policyNumber = `~AutomatedScenario0014a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0014a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0014Data: Partial<ITestData> = {
|
||||
|
|
@ -33,13 +33,13 @@ const advancedScenario0014Data: Partial<ITestData> = {
|
|||
isDuplicateClaim: false,
|
||||
isPolicyFound: true,
|
||||
isNoComp: true,
|
||||
isRecalWarning: true,
|
||||
isRecalWarning: false,
|
||||
hasStateLawPopup: false,
|
||||
endorsements: [
|
||||
{
|
||||
endorsementType: EndorsementType.Educator,
|
||||
isOnPolicy: true,
|
||||
isClickYes: true
|
||||
isClickYes: false
|
||||
}
|
||||
],
|
||||
partQuestions: undefined,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0015a${faker.string.uuid().substring(0,6)}`;
|
||||
const policyNumber = `~AutomatedScenario0015a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0015a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0015Data: Partial<ITestData> = {
|
||||
|
|
@ -46,16 +46,16 @@ const advancedScenario0015Data: Partial<ITestData> = {
|
|||
{
|
||||
partQuestionType: PartQuestionType.WindshieldColor,
|
||||
isOnPage: true,
|
||||
optionToSelect: 'Green Tint, Blue Shade'
|
||||
optionToSelect: 'Heated glass, Heated glass Wiper Park'
|
||||
},
|
||||
{
|
||||
partQuestionType: PartQuestionType.DriverFrontColor,
|
||||
isOnPage: true,
|
||||
optionToSelect: 'Green Tint'
|
||||
optionToSelect: 'Driver side, Front'
|
||||
}
|
||||
],
|
||||
isSafelite: true,
|
||||
servicePackage: faker.helpers.enumValue(ServicePackage),
|
||||
servicePackage: ServicePackage.Premium,
|
||||
customerDetails: customerDetails,
|
||||
claimDetails: {
|
||||
policyNumber: policyNumber,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0016a${faker.string.uuid().substring(0,6)}`;
|
||||
const policyNumber = `~AutomatedScenario0016a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0016a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0016Data: Partial<ITestData> = {
|
||||
|
|
@ -39,38 +39,37 @@ const advancedScenario0016Data: Partial<ITestData> = {
|
|||
{
|
||||
partQuestionType: PartQuestionType.WindshieldColor,
|
||||
isOnPage: true,
|
||||
optionToSelect: 'Green Tint'
|
||||
optionToSelect: 'Solar, Third Visor Frit, soundproofing, Infrared Interlayer'
|
||||
},
|
||||
{
|
||||
partQuestionType: PartQuestionType.DriverFrontColor,
|
||||
isOnPage: true,
|
||||
optionToSelect: 'Green Tint'
|
||||
optionToSelect: 'Solar, Driver side, Front'
|
||||
},
|
||||
{
|
||||
partQuestionType: PartQuestionType.DriverRearColor,
|
||||
isOnPage: true,
|
||||
optionToSelect: 'Green Tint'
|
||||
optionToSelect: 'Solar, Driver side, Rear'
|
||||
},
|
||||
{
|
||||
partQuestionType: PartQuestionType.DriverVentColor,
|
||||
isOnPage: true,
|
||||
optionToSelect: 'Green Tint',
|
||||
secondaryQuestionOptionToSelect: 'solar, driver side, rear'
|
||||
optionToSelect: 'Solar, Driver side, Rear'
|
||||
},
|
||||
{
|
||||
partQuestionType: PartQuestionType.PassengerFrontColor,
|
||||
isOnPage: true,
|
||||
optionToSelect: 'Green Tint'
|
||||
optionToSelect: 'Solar, Passenger side, Front'
|
||||
},
|
||||
{
|
||||
partQuestionType: PartQuestionType.PassengerRearColor,
|
||||
isOnPage: true,
|
||||
optionToSelect: 'Green Tint'
|
||||
optionToSelect: 'Solar, Passenger side, Rear'
|
||||
},
|
||||
{
|
||||
partQuestionType: PartQuestionType.RearWindowColor,
|
||||
isOnPage: true,
|
||||
optionToSelect: 'Green Tint'
|
||||
optionToSelect: 'Heated glass, Solar'
|
||||
},
|
||||
],
|
||||
isSafelite: true,
|
||||
|
|
@ -100,8 +99,8 @@ const advancedScenario0016Data: Partial<ITestData> = {
|
|||
// VehicleDamage.PassengerVentGlass // TODO: Verify if this is intentionally not in UI
|
||||
],
|
||||
appointmentDetails: {
|
||||
serviceLocation: ServiceLocation.Mobile,
|
||||
serviceAddress: customerAddress,
|
||||
serviceLocation: ServiceLocation.InShop,
|
||||
serviceAddress: undefined,
|
||||
appointmentDate: nextWeekday
|
||||
},
|
||||
paymentDetails: ClientData.getDefaultPaypalDetails()
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0017a${faker.string.uuid().substring(0,6)}`;
|
||||
const policyNumber = `~AutomatedScenario0017a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0017a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0017Data: Partial<ITestData> = {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0018a${faker.string.uuid().substring(0,6)}`;
|
||||
const policyNumber = `~AutomatedScenario0018a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0018a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0018Data: Partial<ITestData> = {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ const vehicleDetails: IVehicleDetails = {
|
|||
style: '4 door sedan'
|
||||
};
|
||||
|
||||
const policyNumber = `~AutomatedScenario0019a${faker.string.uuid().substring(0,6)}`;
|
||||
const policyNumber = `~AutomatedScenario0019a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0019a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0019Data: Partial<ITestData> = {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0020a${faker.string.uuid().substring(0,6)}`;
|
||||
const policyNumber = `~AutomatedScenario0020a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0020a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0020Data: Partial<ITestData> = {
|
||||
|
|
@ -60,12 +60,14 @@ const advancedScenario0020Data: Partial<ITestData> = {
|
|||
serviceLocation: ServiceLocation.Mobile,
|
||||
serviceAddress: {
|
||||
street: faker.location.streetAddress(),
|
||||
city: 'Goose Creek',
|
||||
state: 'SC',
|
||||
postalCode: '29445',
|
||||
city: 'Worthington',
|
||||
state: 'OH',
|
||||
postalCode: '43085',
|
||||
country: 'US'
|
||||
},
|
||||
alternateServiceZip: '29445',
|
||||
alternateServiceZip: '43085',
|
||||
alternateMobileCity: 'Worthington',
|
||||
alternateMobileStreetAddress: '177 Franklin Ave',
|
||||
appointmentDate: nextWeekday
|
||||
},
|
||||
paymentDetails: {
|
||||
|
|
|
|||
|
|
@ -23,13 +23,14 @@ const customerDetails: ICustomerDetails = {
|
|||
}
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0021a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policyNumber = `~AutomatedScenario0021a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0021a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0021Data: Partial<ITestData> = {
|
||||
clientTag: '',
|
||||
isDuplicateClaim: false,
|
||||
isPolicyFound: true,
|
||||
isUnverifiedPolicyAfterVehicleLookup: true,
|
||||
isNoComp: false,
|
||||
hasStateLawPopup: true,
|
||||
endorsements: undefined,
|
||||
|
|
@ -54,8 +55,8 @@ const advancedScenario0021Data: Partial<ITestData> = {
|
|||
model: 'RX 300',
|
||||
style: undefined,
|
||||
vehicleLookupType: VehicleLookupType.LicensePlateNumber,
|
||||
licensePlateNumber: ['NoPlate753', 'BQ40903','1111'],
|
||||
licensePlateState: ['Illinois','Illinois','California'],
|
||||
licensePlateNumber: ['NoPlate753', 'GAH2307','1111'],
|
||||
licensePlateState: ['Illinois','Ohio','California'],
|
||||
},
|
||||
vehicleDamage: [
|
||||
VehicleDamage.WindshieldCrack,
|
||||
|
|
|
|||
|
|
@ -23,13 +23,14 @@ const customerDetails: ICustomerDetails = {
|
|||
}
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0022a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policyNumber = `~AutomatedScenario0022a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0022a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0022Data: Partial<ITestData> = {
|
||||
clientTag: '',
|
||||
isDuplicateClaim: false,
|
||||
isPolicyFound: true,
|
||||
isUnverifiedPolicyAfterVehicleLookup: true,
|
||||
isNoComp: false,
|
||||
hasStateLawPopup: true,
|
||||
endorsements: undefined,
|
||||
|
|
|
|||
|
|
@ -23,13 +23,14 @@ const customerDetails: ICustomerDetails = {
|
|||
}
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0023a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policyNumber = `~AutomatedScenario0023a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0023a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0023Data: Partial<ITestData> = {
|
||||
clientTag: '',
|
||||
isDuplicateClaim: false,
|
||||
isPolicyFound: true,
|
||||
isUnverifiedPolicyAfterVehicleLookup: true,
|
||||
isNoComp: false,
|
||||
hasStateLawPopup: true,
|
||||
endorsements: undefined,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const customerDetails: ICustomerDetails = {
|
|||
}
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0024a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policyNumber = `~AutomatedScenario0024a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0024a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0024Data: Partial<ITestData> = {
|
||||
|
|
@ -50,14 +50,14 @@ const advancedScenario0024Data: Partial<ITestData> = {
|
|||
policySoap: policySoap,
|
||||
vehicleDetails: {
|
||||
year: '2015',
|
||||
make: 'Ford',
|
||||
model: 'F Series F150',
|
||||
style: '2 door super cab',
|
||||
make: 'Audi',
|
||||
model: 'A7',
|
||||
style: '4 door hatchback',
|
||||
vehicleLookupType: VehicleLookupType.Address,
|
||||
address: [
|
||||
{ street: '9 Test Street', city: 'Columbus', state: 'OH', postalCode: '43220', lastName: 'Test' },
|
||||
{ street: '8621 GREENLEAF AVE', city: 'Whittier', state: 'California', postalCode: '90602', lastName: 'Johnson' },
|
||||
{ street: '10212 JEWEL CT', city: 'Conroe', state: 'Texas', postalCode: '77385', lastName: 'Reed' }
|
||||
{ street: '6531 CANYON RANCH', city: 'Frisco', state: 'Texas', postalCode: '75036', lastName: 'TRAINOR' }
|
||||
],
|
||||
},
|
||||
vehicleDamage: [
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ const customerDetails: ICustomerDetails = {
|
|||
phoneNumber: '614-531-0031',
|
||||
notes: 'Automated Test',
|
||||
address: {
|
||||
street: faker.location.streetAddress(),
|
||||
street: '5273 Berrywood Dr',
|
||||
city: 'Columbus',
|
||||
state: 'OH',
|
||||
postalCode: '43220',
|
||||
|
|
@ -23,7 +23,7 @@ const customerDetails: ICustomerDetails = {
|
|||
}
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0025a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policyNumber = `~AutomatedScenario0025a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0025a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0025Data: Partial<ITestData> = {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const customerDetails: ICustomerDetails = {
|
|||
}
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0026a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policyNumber = `~AutomatedScenario0026a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0026a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0026aData: Partial<ITestData> = {
|
||||
|
|
@ -35,7 +35,6 @@ const advancedScenario0026aData: Partial<ITestData> = {
|
|||
isRecalNotification: true,
|
||||
endorsements: undefined,
|
||||
bailoutFlags: {
|
||||
isDoNotSeeMyShopBailout: true
|
||||
},
|
||||
vehiclePartQuestions: [
|
||||
],
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0028a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policyNumber = `~AutomatedScenario0028a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0028a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0028aData: Partial<ITestData> = {
|
||||
|
|
@ -36,7 +36,7 @@ const advancedScenario0028aData: Partial<ITestData> = {
|
|||
isItac: true,
|
||||
hasStateLawPopup: false,
|
||||
bailoutFlags: {
|
||||
isRequestCallbackBailout: true,
|
||||
isCoverageCancelledByUser: true,
|
||||
},
|
||||
isVehicleSelectBailout: false,
|
||||
endorsements: [
|
||||
|
|
|
|||
|
|
@ -23,21 +23,27 @@ const customerDetails: ICustomerDetails = {
|
|||
}
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0029a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policyNumber = `~AutomatedScenario0029a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0029a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0029Data: Partial<ITestData> = {
|
||||
clientTag: '',
|
||||
isDuplicateClaim: false,
|
||||
isPolicyFound: true,
|
||||
isUnverifiedPolicyAfterVehicleLookup: true,
|
||||
hasStateLawPopup: true,
|
||||
isNoComp: false,
|
||||
endorsements: undefined,
|
||||
vehiclePartQuestions: [
|
||||
{
|
||||
partQuestionType: PartQuestionType.WindshieldColor,
|
||||
isOnPage: true,
|
||||
optionToSelect: 'Heated glass, Encap, Asymmetrically Strengthen'
|
||||
},
|
||||
],
|
||||
isUseVehicleOnPolicy: false,
|
||||
servicePackage: faker.helpers.enumValue(ServicePackage),
|
||||
customerDetails: customerDetails,
|
||||
bailoutFlags: {
|
||||
isHeavyTruckVehicleBailout: true,
|
||||
},
|
||||
claimDetails: {
|
||||
policyNumber: policyNumber,
|
||||
policyDeductible: 500,
|
||||
|
|
@ -50,7 +56,7 @@ const advancedScenario0029Data: Partial<ITestData> = {
|
|||
make: 'Freightliner',
|
||||
model: '114sd',
|
||||
vehicleLookupType: VehicleLookupType.Vin,
|
||||
vin: '1FUJG3DV5HHJH2985',
|
||||
vin: '1FVMG3DV5HHJA1388',
|
||||
},
|
||||
vehicleDamage: [
|
||||
VehicleDamage.WindshieldCrack,
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ import { IAddress } from "@business-logic/types/IAddress";
|
|||
|
||||
const nextWeekday = getNextWeekday();
|
||||
const customerAddress: IAddress = {
|
||||
street: faker.location.streetAddress(),
|
||||
city: 'Birmingham',
|
||||
state: 'AL',
|
||||
postalCode: '35118',
|
||||
street: '474 1st St',
|
||||
city: 'Lindsay',
|
||||
state: 'CA',
|
||||
postalCode: '93247',
|
||||
country: 'United States'
|
||||
}
|
||||
const customerDetails: ICustomerDetails = {
|
||||
|
|
@ -25,7 +25,7 @@ const customerDetails: ICustomerDetails = {
|
|||
address: customerAddress
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0030a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policyNumber = `~AutomatedScenario0030a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0030a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0030aData: Partial<ITestData> = {
|
||||
|
|
@ -36,7 +36,7 @@ const advancedScenario0030aData: Partial<ITestData> = {
|
|||
isItac: false,
|
||||
hasStateLawPopup: false,
|
||||
bailoutFlags: {
|
||||
isPartsServiceErrorBailout: true,
|
||||
isAPIErrorBailout: true,
|
||||
},
|
||||
|
||||
vehiclePartQuestions: [
|
||||
|
|
@ -79,7 +79,7 @@ for (const client of advancedClients) {
|
|||
const data = { ...advancedScenario0030aData };
|
||||
data.clientTag = client.clientTag;
|
||||
const tc = new TestCase({
|
||||
name: `0030a Advanced ITAC Cancel My Claim: "${client.accountName}"`,
|
||||
name: `0030a Advanced API Error Bailout: "${client.accountName}"`,
|
||||
tags: [`@${client.clientTag}`, `@${client.accountName}`, '@Advanced', '@INSR-2057'],
|
||||
testData: data
|
||||
}, undefined, '0030a');
|
||||
|
|
@ -23,7 +23,7 @@ const customerDetails: ICustomerDetails = {
|
|||
}
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0031a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policyNumber = `~AutomatedScenario0031a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0031a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0031Data: Partial<ITestData> = {
|
||||
|
|
@ -33,19 +33,11 @@ const advancedScenario0031Data: Partial<ITestData> = {
|
|||
isNoComp: false,
|
||||
hasStateLawPopup: false,
|
||||
endorsements: undefined,
|
||||
partQuestions: [
|
||||
{
|
||||
partQuestionType: PartQuestionType.LaneKeepAssist,
|
||||
isOnPage: true,
|
||||
optionToSelect: 'Yes',
|
||||
}
|
||||
],
|
||||
vehiclePartQuestions: [
|
||||
{
|
||||
partQuestionType: PartQuestionType.WindshieldColor,
|
||||
isOnPage: true,
|
||||
optionToSelect: 'Green Tint',
|
||||
secondaryQuestionOptionToSelect: 'one-piece, w/lane departure warning system',
|
||||
optionToSelect: 'One-Piece, With Lane Departure Warning System',
|
||||
},
|
||||
],
|
||||
isSafelite: true,
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const customerDetails: ICustomerDetails = {
|
|||
}
|
||||
}
|
||||
|
||||
const policyNumber = `~AutomatedScenario0032a${faker.string.uuid().substring(0, 6)}`;
|
||||
const policyNumber = `~AutomatedScenario0032a${crypto.randomUUID().replace(/-/g, '').slice(0, 16).toUpperCase()}`; // Ensure unique policy number for each test run since same key in request can cause 500 error
|
||||
const policySoap = MockPolicyData.getPolicySoapByScenario('0032a', customerDetails, policyNumber);
|
||||
|
||||
const advancedScenario0032Data: Partial<ITestData> = {
|
||||
|
|
@ -33,6 +33,9 @@ const advancedScenario0032Data: Partial<ITestData> = {
|
|||
isNoComp: false,
|
||||
hasStateLawPopup: false,
|
||||
endorsements: undefined,
|
||||
bailoutFlags: {
|
||||
isHeavyTruckVehicleBailout: true,
|
||||
},
|
||||
vehiclePartQuestions: [
|
||||
|
||||
],
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
"coverage/api/v1/coverage/register-claim": "0002a_Advanced_Replace_Deductible_Client/coverage/api/v1/coverage/register-claim.json",
|
||||
"price/api/v1/price/order-items-with-itac-pricing": "0002a_Advanced_Replace_Deductible_Client/price/api/v1/price/order-items-with-itac-pricing.json",
|
||||
"location/api/v1/location/providers/75023/Replace/100/550036/true/CR00056707/DW01571GTNNOEM": "0002a_Advanced_Replace_Deductible_Client/location/api/v1/location/providers/75023/Replace/100/550036/true/CR00056707/DW01571GTNNOEM.json",
|
||||
"schedule/api/v1/schedule/shop-time-slots": "0002a_Advanced_Replace_Deductible_Client/schedule/api/v1/schedule/shop-time-slots.json",
|
||||
"location/api/v1/location/alert-reasons/01813": "0002a_Advanced_Replace_Deductible_Client/location/api/v1/location/alert-reasons/01813.json",
|
||||
"parts/api/v1/parts/rain-repel": "0002a_Advanced_Replace_Deductible_Client/parts/api/v1/parts/rain-repel.json",
|
||||
"price/api/v1/price/combined-quote": "0002a_Advanced_Replace_Deductible_Client/price/api/v1/price/combined-quote.json"
|
||||
|
|
|
|||
Loading…
Reference in a new issue