Refactored master script with step decorator feature
This commit is contained in:
parent
c74a6a7d10
commit
932949004e
31 changed files with 487 additions and 374 deletions
|
|
@ -27,6 +27,7 @@ import { CoverageStatementPage } from "../../pages/CoverageStatementPage"
|
|||
import { VerifyDetailsPage } from "../../pages/VerifyDetailsPage"
|
||||
import { EndorsementsPage } from "../../pages/EndorsementsPage"
|
||||
import { PolicyDriverPage } from "../../pages/PolicyDriverPage"
|
||||
import { ServiceZipPage } from "../../pages/ServiceZipPage"
|
||||
// File containing interface for all Page Object Models
|
||||
|
||||
export default interface ITestPages {
|
||||
|
|
@ -48,7 +49,8 @@ export default interface ITestPages {
|
|||
recalibrationInfoPage: RecalibrationInfoPage,
|
||||
schedulePage: SchedulePage,
|
||||
serviceLocationPage: ServiceLocationPage,
|
||||
servicePackagePage: ServicePackagesPage,
|
||||
servicePackagesPage: ServicePackagesPage,
|
||||
serviceZipPage: ServiceZipPage,
|
||||
vehicleDamagePage: VehicleDamagePage,
|
||||
vehicleLookupAddressPage: VehicleLookupAddressPage,
|
||||
vehicleLookupLicensePage: VehicleLookupLicensePage,
|
||||
|
|
|
|||
27
playwright-tests/business-logic/types/Step.ts
Normal file
27
playwright-tests/business-logic/types/Step.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import { test } from '@business-logic/types/Test';
|
||||
|
||||
export type Context = {
|
||||
kind: string;
|
||||
name: string | symbol;
|
||||
access: {
|
||||
get?(): unknown;
|
||||
set?(value: unknown): void;
|
||||
has?(value: unknown): boolean;
|
||||
};
|
||||
private?: boolean;
|
||||
static?: boolean;
|
||||
addInitializer?(initializer: () => void): void;
|
||||
};
|
||||
|
||||
export type Method = (...args: any[]) => any;
|
||||
|
||||
export function step(label: string): Method {
|
||||
return <T extends Method>(value: T, context: Context): Method => {
|
||||
return function (this: any, ...args: any[]): Promise<any> {
|
||||
// console.log(`Method ${value.name} has been decorated`, context, args, label);
|
||||
return test.step(label, async () => {
|
||||
return value.call(this, ...args);
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -41,6 +41,7 @@ import { CoverageStatementPage } from "../../pages/CoverageStatementPage";
|
|||
import { VerifyDetailsPage } from "../../pages/VerifyDetailsPage";
|
||||
import { EndorsementsPage } from "../../pages/EndorsementsPage";
|
||||
import { PolicyDriverPage } from "../../pages/PolicyDriverPage";
|
||||
import { ServiceZipPage } from "../../pages/ServiceZipPage";
|
||||
|
||||
// File for Test Case Class
|
||||
|
||||
|
|
@ -164,7 +165,8 @@ export default class TestCase extends DisposableBase implements ITestCase {
|
|||
recalibrationInfoPage: new RecalibrationInfoPage(page),
|
||||
schedulePage: new SchedulePage(page),
|
||||
serviceLocationPage: new ServiceLocationPage(page),
|
||||
servicePackagePage: new ServicePackagesPage(page),
|
||||
servicePackagesPage: new ServicePackagesPage(page),
|
||||
serviceZipPage: new ServiceZipPage(page),
|
||||
vehicleDamagePage: new VehicleDamagePage(page),
|
||||
vehicleLookupAddressPage: new VehicleLookupAddressPage(page),
|
||||
vehicleLookupLicensePage: new VehicleLookupLicensePage(page),
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ import { expect, type Locator, type Page } from '@playwright/test';
|
|||
import { IClaimDetails, ICustomerDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { InsuranceBasePage } from './InsuranceBasePage';
|
||||
import { STATE_ABBREVIATIONS } from '@business-logic/constants/StateAbbreviation';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
|
||||
export class CCPolicyInfoPage extends InsuranceBasePage {
|
||||
readonly policyNumber: Locator;
|
||||
|
|
@ -70,4 +72,12 @@ export class CCPolicyInfoPage extends InsuranceBasePage {
|
|||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@step("CCPolicyInfoPage >> Fill out claim information")
|
||||
async handleCCPolicyInfoPage(testData: Partial<ITestData>) {
|
||||
const { customerDetails, claimDetails } = testData;
|
||||
|
||||
await this.populatePage(customerDetails!, claimDetails!, await this.hasCityInfo());
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
import { Page } from "@playwright/test";
|
||||
import { PartQuestionsPage } from "./PartQuestionPage";
|
||||
import { step } from "@business-logic/types/Step";
|
||||
import { ITestData } from "@business-logic/types/ITestData";
|
||||
|
||||
export default class CapabilityQuestionsPage extends PartQuestionsPage {
|
||||
url = process.env['BASE_URL']! + '/fmg/?fmgPage=capability-questions';
|
||||
|
|
@ -7,4 +9,18 @@ export default class CapabilityQuestionsPage extends PartQuestionsPage {
|
|||
constructor(page: Page) {
|
||||
super(page);
|
||||
}
|
||||
|
||||
@step("CapabilityQuestionsPage >> Select Capability Questions: ")
|
||||
async handleCapabilityQuestionsPage(testCase: Partial<ITestData>) {
|
||||
const { capabilityQuestions } = testCase;
|
||||
|
||||
// Validate the capability questions are on the page
|
||||
await this.validatePartQuestions(capabilityQuestions!);
|
||||
|
||||
// Select the capability question responses
|
||||
await this.selectPartQuestionResponses(capabilityQuestions!);
|
||||
|
||||
// Proceed to the next page
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import { expect, type Locator, type Page } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
import { ICustomerDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
|
||||
export class ContactDetailsPage extends BasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -39,4 +41,11 @@ export class ContactDetailsPage extends BasePage {
|
|||
await this.notesTextBox.fill(notes);
|
||||
}
|
||||
}
|
||||
|
||||
@step("ContactDetailsPage >> Enter contact details: ")
|
||||
async handleContactDetailsPage(testData: Partial<ITestData>) {
|
||||
const { customerDetails } = testData;
|
||||
await this.enterContactDetails(customerDetails!);
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import { expect, type Locator, type Page } from '@playwright/test';
|
||||
import { InsuranceBasePage } from './InsuranceBasePage';
|
||||
import { IClaimDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
|
||||
export class CoverageStatementPage extends InsuranceBasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -54,5 +56,12 @@ export class CoverageStatementPage extends InsuranceBasePage {
|
|||
async validateUnverifiedText(){
|
||||
await expect(this.verfiyingCoverageText).toBeEnabled();
|
||||
}
|
||||
|
||||
|
||||
@step("CoverageStatementPage >> Next page: ")
|
||||
async handleCoverageStatementPage(testData: Partial<ITestData>) {
|
||||
const { claimDetails } = testData;
|
||||
|
||||
await this.validateDeductibleAmount(claimDetails!);
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
import { expect, type Locator, type Page } from '@playwright/test';
|
||||
import { InsuranceBasePage } from './InsuranceBasePage';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
|
||||
export class DuplicateCheckPage extends InsuranceBasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -18,4 +20,9 @@ export class DuplicateCheckPage extends InsuranceBasePage {
|
|||
await this.page.waitForLoadState();
|
||||
}
|
||||
|
||||
@step("DuplicateCheckPage >> Start a new claim: ")
|
||||
async handleDuplicateCheckPage(testCase: Partial<ITestData>) {
|
||||
await this.startNewClaim();
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,8 @@ import { BasePage } from './BasePage';
|
|||
import { IEndorsementDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { EndorsementType } from '@business-logic/types/Enums';
|
||||
import { InsuranceBasePage } from './InsuranceBasePage';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
|
||||
export class EndorsementsPage extends InsuranceBasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -52,4 +54,12 @@ export class EndorsementsPage extends InsuranceBasePage {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@step("EndorsementsPage >> Select endorsements: ")
|
||||
async handleEndorsementsPage(testData: Partial<ITestData>) {
|
||||
const { endorsements } = testData;
|
||||
await this.verifyEndorsements(endorsements!);
|
||||
await this.selectEndorsements(endorsements!);
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,8 @@ import { IVehicleDetails } from '@business-logic/types/CustomerDetails';
|
|||
import { VinLookupPage } from './VinLookupPage';
|
||||
import { VehicleLookupAddressPage } from './VehicleLookupAddressPage';
|
||||
import { VehicleLookupLicensePage } from './VehicleLookupLicensePage';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
|
||||
export class EstimatePage extends BasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -20,7 +22,7 @@ export class EstimatePage extends BasePage {
|
|||
constructor(page: Page) {
|
||||
super(page);
|
||||
this.page = page;
|
||||
this.vinLookupButton = page.getByLabel('Provide my VIN', { exact: true });
|
||||
this.vinLookupButton = page.locator('label').filter({ hasText: 'Provide my VIN' }).locator('div');
|
||||
this.zipLookupButton = page.locator('label').filter({ hasText: 'I\'d rather not share my VIN' }).locator('div');
|
||||
this.addressLookupButton = page.getByLabel('Provide my home address', { exact: true });
|
||||
this.licenseLookupButton = page.getByLabel('Provide my license plate #', { exact: true });
|
||||
|
|
@ -68,4 +70,10 @@ export class EstimatePage extends BasePage {
|
|||
async selectZipLookup(){
|
||||
await this.zipLookupButton.click();
|
||||
}
|
||||
|
||||
@step("EstimatePage >> Select Lookup Type")
|
||||
async handleEstimatePage(testData: Partial<ITestData>) {
|
||||
const { vehicleDetails } = testData;
|
||||
await this.vehicleLookup(vehicleDetails!);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
import { type Locator, type Page } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
import { IClaimDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
import TestCase from '@business-logic/types/TestCase';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
|
||||
|
||||
export class InsuranceCompanyPage extends BasePage {
|
||||
|
|
@ -44,4 +47,12 @@ export class InsuranceCompanyPage extends BasePage {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@step("InsuranceCompanyPage >> Enter insurance company: ")
|
||||
async handleInsuranceCompanyPage(testData: Partial<ITestData>) {
|
||||
const { claimDetails } = testData;
|
||||
|
||||
await this.enterInsuranceCompany(claimDetails!.client!);
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
import { Page } from "@playwright/test";
|
||||
import { PartQuestionsPage } from "./PartQuestionPage";
|
||||
import { step } from "@business-logic/types/Step";
|
||||
import { ITestData } from "@business-logic/types/ITestData";
|
||||
|
||||
export default class MoldingQuestionsPage extends PartQuestionsPage {
|
||||
url = process.env['BASE_URL']! + '/fmg/?fmgPage=molding-questions';
|
||||
|
|
@ -7,4 +9,12 @@ export default class MoldingQuestionsPage extends PartQuestionsPage {
|
|||
constructor(page: Page) {
|
||||
super(page);
|
||||
}
|
||||
|
||||
@step("MoldingQuestionsPage >> Select Molding Questions: ")
|
||||
async handleMoldingQuestionsPage(testCase: Partial<ITestData>) {
|
||||
const { moldingQuestions } = testCase;
|
||||
await this.validatePartQuestions(moldingQuestions!);
|
||||
await this.selectPartQuestionResponses(moldingQuestions!);
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
import { expect, type Locator, type Page } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
import { test } from '@business-logic/types/Test';
|
||||
import { ICustomerDetails, IVehicleDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { ServicePackage, PaymentType, PaymentMethod } from '@business-logic/types/Enums';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
|
||||
export class OrderConfirmationPage extends BasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -125,7 +127,15 @@ export class OrderConfirmationPage extends BasePage {
|
|||
|
||||
async logOrderNumber() {
|
||||
const sessionStorage = JSON.parse(await this.page.evaluate('sessionStorage.getItem(\'submittedState\')'));
|
||||
return sessionStorage.workOrderNumber;
|
||||
return sessionStorage.order.workOrderNumber;
|
||||
}
|
||||
|
||||
|
||||
@step("OrderConfirmationPage >> Validate order")
|
||||
async verifyOrderConfirmationPage(testData: Partial<ITestData>) {
|
||||
await this.validateOrderConfirmationPage(testData);
|
||||
const workOrderNumber = await this.logOrderNumber();
|
||||
await test.step(`Session Storage Work Order Number: ${workOrderNumber}`, async () => {
|
||||
console.log(`Session Storage Work Order Number: ${workOrderNumber}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import { expect, type Locator, type Page } from '@playwright/test';
|
||||
import { BasePage } from './BasePage';
|
||||
import { IPartQuestion } from '@business-logic/types/CustomerDetails';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
|
||||
export class PartQuestionsPage extends BasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -56,4 +58,12 @@ export class PartQuestionsPage extends BasePage {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@step("PartQuestionsPage >> Select Vehicle Part Question Responses")
|
||||
async handlePartQuestionsPage(testData: Partial<ITestData>) {
|
||||
const { partQuestions } = testData;
|
||||
await this.validatePartQuestions(partQuestions!);
|
||||
await this.selectPartQuestionResponses(partQuestions!);
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import { PaymentPage } from './PaymentPage';
|
|||
import { AfterpayPage } from './AfterpayPage';
|
||||
import { PaypalPage } from './PaypalPage';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
|
||||
export class PaymentMethodPage extends BasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -464,4 +465,21 @@ l
|
|||
let updatedAppointmentDate = parsedAppointmentDate.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
|
||||
return updatedAppointmentDate;
|
||||
}
|
||||
|
||||
@step("PaymentMethodPage >> Select Payment Method: ")
|
||||
async handlePaymentMethodPage(testData: Partial<ITestData>) {
|
||||
const { servicePackage, isRecalVehicle, paymentDetails } = testData;
|
||||
|
||||
await this.validatePaymentDetailsPage(testData);
|
||||
|
||||
// Verify VAPS wipers on backend for standard and premium packages
|
||||
if (servicePackage === ServicePackage.Standard || servicePackage === ServicePackage.Premium) {
|
||||
await this.verifyVAPS();
|
||||
}
|
||||
if (paymentDetails?.paymentType) {
|
||||
await this.executePayment(paymentDetails!, isRecalVehicle!);
|
||||
} else {
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import { expect, type Locator, type Page } from '@playwright/test';
|
||||
import { InsuranceBasePage } from './InsuranceBasePage';
|
||||
import { ICustomerDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
|
||||
export class PolicyDriverPage extends InsuranceBasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -47,5 +49,11 @@ export class PolicyDriverPage extends InsuranceBasePage {
|
|||
await this.driverNotListedOption.click();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@step("PolicyDriverPage >> Select policy driver: ")
|
||||
async handlePolicyDriverPage(testData: Partial<ITestData>) {
|
||||
const { customerDetails } = testData;
|
||||
await this.selectPolicyDriver(customerDetails!);
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import { expect, type Locator, type Page } from '@playwright/test';
|
||||
import { InsuranceBasePage } from './InsuranceBasePage';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
|
||||
export class PolicyInfoSubmittedPage extends InsuranceBasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -20,5 +21,10 @@ export class PolicyInfoSubmittedPage extends InsuranceBasePage {
|
|||
const policyInfoMessage = await this.policyInfoMessage.textContent();
|
||||
expect(policyInfoMessage).toBe("Your policy and vehicle information has been submitted for coverage verification")
|
||||
}
|
||||
|
||||
|
||||
@step("PolicyInfoSubmittedPage >> Verify policy info submitted: ")
|
||||
async handlePolicyInfoSubmittedPage() {
|
||||
await this.verifyPolicyInfoSubmitted();
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import { expect, type Locator, type Page } from '@playwright/test';
|
||||
import { IVehicleDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { InsuranceBasePage } from './InsuranceBasePage';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
|
||||
export class PolicyVehiclesPage extends InsuranceBasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -26,4 +28,29 @@ export class PolicyVehiclesPage extends InsuranceBasePage {
|
|||
async selectVehicleNotListed(){
|
||||
await this.page.getByText('Vehicle not listed').click();
|
||||
}
|
||||
|
||||
@step("PolicyVehiclesPage >> Select Vehicle: ")
|
||||
async handlePolicyVehiclesPage(testCase: Partial<ITestData>) {
|
||||
|
||||
const { vehicleDetails, otherVehiclesOnPolicy, isUseVehicleOnPolicy } = testCase;
|
||||
|
||||
// Validate other vehicles on policy
|
||||
if (otherVehiclesOnPolicy && otherVehiclesOnPolicy.length > 0) {
|
||||
for (const vehicle of otherVehiclesOnPolicy) {
|
||||
await this.validateVehicleIsOnPolicy(vehicle);
|
||||
}
|
||||
}
|
||||
|
||||
// If vehicle is not on the policy, select new vehicle
|
||||
if (!(isUseVehicleOnPolicy ?? true)) {
|
||||
await this.selectVehicleNotListed();
|
||||
await this.nextPage();
|
||||
await this.selectVehicle(vehicleDetails!);
|
||||
await this.nextPage();
|
||||
} else {
|
||||
// Otherwise, select the vehicle entered in Safelite.com
|
||||
await this.selectVehicle(vehicleDetails!);
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import { Locator, Page } from "@playwright/test";
|
||||
import { InsuranceBasePage } from "./InsuranceBasePage";
|
||||
import { step } from "@business-logic/types/Step";
|
||||
|
||||
export default class RecalibrationInfoPage extends InsuranceBasePage {
|
||||
url = process.env['BASE_URL']! + '/FixMyGlass/RecalibrationInfo.aspx';
|
||||
|
|
@ -11,4 +12,9 @@ export default class RecalibrationInfoPage extends InsuranceBasePage {
|
|||
|
||||
this.continueButton = page.getByRole('button', { name: 'Continue' });
|
||||
}
|
||||
|
||||
@step("RecalibrationInfoPage >> Click continue button: ")
|
||||
async handleRecalibrationInfoPage() {
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@ import { IAppointmentDetails, ICustomerDetails } from '@business-logic/types/Cus
|
|||
import { formatDate, formatTime } from '@impl/utils/DateUtils';
|
||||
import { AppointmentType, ServiceLocation } from '@business-logic/types/Enums';
|
||||
import { time } from 'console';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
|
||||
export class SchedulePage extends BasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -81,4 +83,10 @@ export class SchedulePage extends BasePage {
|
|||
}
|
||||
return formattedTimeSlot;
|
||||
}
|
||||
|
||||
@step("SchedulePage >> Schedule appointment: ")
|
||||
async handleSchedulePage(testData: Partial<ITestData>) {
|
||||
const { customerDetails } = testData;
|
||||
await this.scheduleFirstAppointment(customerDetails!);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@ import { IAppointmentDetails } from '@business-logic/types/CustomerDetails';
|
|||
import { AppointmentType } from '@business-logic/types/Enums';
|
||||
import { AddressForm } from './forms/AddressForm';
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
|
||||
export class ServiceLocationPage extends BasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -154,4 +156,11 @@ export class ServiceLocationPage extends BasePage {
|
|||
await expect(this.RecalWarningMessage2).toBeVisible();
|
||||
|
||||
}
|
||||
|
||||
@step("ServiceLocationPage >> Select service location: ")
|
||||
async handleServiceLocationPage(testData: Partial<ITestData>) {
|
||||
const { appointmentDetails } = testData;
|
||||
await this.selectLocation(appointmentDetails!);
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ import { expect, type Locator, type Page } from '@playwright/test';
|
|||
import { BasePage } from './BasePage';
|
||||
import { ServicePackage, VehicleDamage } from '@business-logic/types/Enums';
|
||||
import { PaymentMethod } from '@business-logic/types/Enums';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
|
||||
export class ServicePackagesPage extends BasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -178,4 +180,55 @@ export class ServicePackagesPage extends BasePage {
|
|||
throw new Error("No glass parts found in the order");
|
||||
}
|
||||
}
|
||||
|
||||
@step("ServicePackagePage >> Select Payment Method and Service Type: ")
|
||||
async handleServicePackagePage(testData: Partial<ITestData>) {
|
||||
const { customerDetails, paymentMethod, servicePackage, promoCode, canNotRecal, dynamicRecal, hasOemEndorsement, vehicleDamage } = testData;
|
||||
|
||||
// Define repair damage types (vs. replacement types)
|
||||
const repairTypes: VehicleDamage[] = [
|
||||
VehicleDamage.WindshieldOneChip,
|
||||
VehicleDamage.WindshieldTwoChips,
|
||||
VehicleDamage.WindshieldThreeChips
|
||||
];
|
||||
|
||||
// Determine if we're replacing or repairing
|
||||
const isReplace = !repairTypes.some(damageType => {
|
||||
return vehicleDamage!.includes(damageType);
|
||||
});
|
||||
|
||||
await this.handleQuotePopup(customerDetails!.email!);
|
||||
await this.selectPaymentMethod(paymentMethod!);
|
||||
await this.selectServicePackage(servicePackage!);
|
||||
|
||||
// Enter promo code
|
||||
if (promoCode) {
|
||||
await this.enterPromo(promoCode);
|
||||
}
|
||||
|
||||
// Backend Validations
|
||||
// Validate backend for can not recal if applicable
|
||||
if (canNotRecal) {
|
||||
await this.verifyCanNotRecal();
|
||||
}
|
||||
|
||||
// Validate backend for dynamic recal if applicable
|
||||
if (dynamicRecal) {
|
||||
await this.verifyDynamicRecal();
|
||||
}
|
||||
|
||||
// Validate backend for repair info (including chip verification)
|
||||
await this.verifyIsRepair(!isReplace, vehicleDamage!);
|
||||
if (isReplace) {
|
||||
// Validate backend for parts info
|
||||
await this.verifyVehicleParts(vehicleDamage!);
|
||||
}
|
||||
|
||||
// Validate backend for OEM endorsement
|
||||
if (hasOemEndorsement) {
|
||||
await this.verifyOEMPart();
|
||||
}
|
||||
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
20
playwright-tests/pages/ServiceZipPage.ts
Normal file
20
playwright-tests/pages/ServiceZipPage.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import { Page } from "@playwright/test";
|
||||
import { LookupPage } from "./LookupPage";
|
||||
import { step } from "@business-logic/types/Step";
|
||||
import { ITestData } from "@business-logic/types/ITestData";
|
||||
|
||||
export class ServiceZipPage extends LookupPage {
|
||||
|
||||
url = process.env['BASE_URL']! + '/fmg/?fmgPage=service-zip';
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
}
|
||||
|
||||
@step("ZipLookupPage >> Lookup by service ZIP: ")
|
||||
async handleServiceZipPage(testData: Partial<ITestData>) {
|
||||
const { customerDetails, vehicleDetails, alertFlags } = testData;
|
||||
await this.enterZip(customerDetails!.address.postalCode!);
|
||||
await this.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ import { type Locator, type Page, expect, test } from '@playwright/test';
|
|||
import { BasePage } from './BasePage';
|
||||
import { SideDoorDamage, VehicleDamage, WindshieldDamage } from '@business-logic/types/Enums';
|
||||
import TestSuccessAlert from '@business-logic/types/TestSuccessAlert';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
|
||||
export class VehicleDamagePage extends BasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -161,4 +163,22 @@ export class VehicleDamagePage extends BasePage {
|
|||
console.log(`Alert encountered: ${alertMessage}`);
|
||||
expect(alertMessage).toContain("Service not availableWe're sorry, but we currently offer only repair service for your vehicle type. Need help with next steps? Call us at800-394-0288.")
|
||||
}
|
||||
|
||||
@step('VehicleDamagePage >> Select Damage')
|
||||
async handleVehicleDamagePage(testData: Partial<ITestData>): Promise<void> {
|
||||
const {vehicleDamage} = testData;
|
||||
const {isRepairReplace, isRepairOnly} = testData.alertFlags || {};
|
||||
|
||||
await this.selectDamage(vehicleDamage!);
|
||||
// Handle alert conditions for vehicle damage
|
||||
if (isRepairReplace) {
|
||||
await this.checkForBothRepairReplaceAlertMessage();
|
||||
throw new TestSuccessAlert('Both assertions are met successfully.');
|
||||
}
|
||||
if (isRepairOnly) {
|
||||
await this.checkForRepairOnlyAlertMessage();
|
||||
throw new TestSuccessAlert('Both assertions are met successfully.');
|
||||
}
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,8 @@ import { LookupPage } from './LookupPage';
|
|||
import { AddressForm } from './forms/AddressForm';
|
||||
import { VehicleSelectionForm } from './forms/VehicleSelectionForm';
|
||||
import { ICustomerDetails, IVehicleDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
|
||||
export class VehicleLookupAddressPage extends LookupPage {
|
||||
readonly addressForm: AddressForm;
|
||||
|
|
@ -25,4 +27,11 @@ export class VehicleLookupAddressPage extends LookupPage {
|
|||
//await this.nextPage();
|
||||
//await this.vehicleSelectionForm.selectVehicle(vehicleDetails);
|
||||
}
|
||||
|
||||
@step("VehicleLookupAddressPage >> Lookup by address: ")
|
||||
async handleVehicleLookupAddressPage(testData: Partial<ITestData>) {
|
||||
const { customerDetails, vehicleDetails, alertFlags } = testData;
|
||||
await this.lookupVehicleByAddress(customerDetails!, vehicleDetails!);
|
||||
await this.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import { type Locator, type Page } from '@playwright/test';
|
||||
import { LookupPage } from './LookupPage';
|
||||
import { IVehicleDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
|
||||
export class VehicleLookupLicensePage extends LookupPage {
|
||||
readonly licensePlateNumTextBox: Locator;
|
||||
|
|
@ -24,4 +26,12 @@ export class VehicleLookupLicensePage extends LookupPage {
|
|||
async enterPlateDetails(vehicleDetails: IVehicleDetails) {
|
||||
await this.licensePlateNumTextBox.fill(vehicleDetails.licensePlateNumber || '');
|
||||
}
|
||||
|
||||
@step("VehicleLookupLicensePage >> Lookup by license plate: ")
|
||||
async handleVehicleLookupLicensePage(testData: Partial<ITestData>) {
|
||||
const { customerDetails, vehicleDetails, alertFlags } = testData;
|
||||
await this.enterPlateDetails(vehicleDetails!);
|
||||
await this.enterZip(customerDetails!.address.postalCode!);
|
||||
await this.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
import { Page } from "@playwright/test";
|
||||
import { PartQuestionsPage } from "./PartQuestionPage";
|
||||
import { step } from "@business-logic/types/Step";
|
||||
import { ITestData } from "@business-logic/types/ITestData";
|
||||
|
||||
export default class VehiclePartQuestionsPage extends PartQuestionsPage{
|
||||
url = process.env['BASE_URL']! + '/fmg/?fmgPage=vehicle-parts';
|
||||
|
|
@ -7,4 +9,12 @@ export default class VehiclePartQuestionsPage extends PartQuestionsPage{
|
|||
constructor(page: Page) {
|
||||
super(page);
|
||||
}
|
||||
|
||||
@step("VehiclePartsPage >> Select Vehicle Part Questions: ")
|
||||
async handleVehiclePartsPage(testCase: Partial<ITestData>) {
|
||||
const { vehiclePartQuestions } = testCase;
|
||||
await this.validatePartQuestions(vehiclePartQuestions!);
|
||||
await this.selectPartQuestionResponses(vehiclePartQuestions!);
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@ import { type Locator, type Page, expect, test } from '@playwright/test';
|
|||
import { BasePage } from './BasePage';
|
||||
import { IVehicleDetails } from '@business-logic/types/CustomerDetails';
|
||||
import TestSuccessAlert from '@business-logic/types/TestSuccessAlert';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
|
||||
export class VehicleSelectionPage extends BasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -42,4 +44,20 @@ export class VehicleSelectionPage extends BasePage {
|
|||
await console.log(`Alert encountered: ${alertMessage}`);
|
||||
await expect(alertMessage).toContain('Service not available in your areaWe do not offer glass service for your vehicle in your ZIP code. We apologize for the inconvenience.');
|
||||
}
|
||||
|
||||
@step("VehicleSelectionPage >> Select Vehicle: ")
|
||||
async handleVehicleSelectionPage(testData: Partial<ITestData>) {
|
||||
const { vehicleDetails } = testData;
|
||||
const { isHeavyTruckVehicle, isSplitWindshield } = testData.alertFlags || {};
|
||||
|
||||
await this.selectVehicle(vehicleDetails!);
|
||||
|
||||
// Handle alert conditions for vehicle selection
|
||||
if (isHeavyTruckVehicle || isSplitWindshield) {
|
||||
await this.checkForAlertMessages();
|
||||
throw new TestSuccessAlert('Both assertions are met successfully.');
|
||||
}
|
||||
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import { expect, type Locator, type Page } from '@playwright/test';
|
||||
import { IClaimDetails, ICustomerDetails } from '@business-logic/types/CustomerDetails';
|
||||
import { InsuranceBasePage } from './InsuranceBasePage';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
|
||||
export class VerifyDetailsPage extends InsuranceBasePage {
|
||||
readonly page: Page;
|
||||
|
|
@ -74,4 +76,11 @@ export class VerifyDetailsPage extends InsuranceBasePage {
|
|||
// Return the original string if format is unknown
|
||||
return date;
|
||||
}
|
||||
|
||||
@step("VerifyDetailsPage >> Verify policy details: ")
|
||||
async handleVerifyDetailsPage(testData: Partial<ITestData>) {
|
||||
const { customerDetails, claimDetails } = testData;
|
||||
await this.verifyPolicyDetails(customerDetails!, claimDetails!);
|
||||
await this.nextPage();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
import { type Locator, type Page } from '@playwright/test';
|
||||
import { LookupPage } from './LookupPage';
|
||||
import { step } from '@business-logic/types/Step';
|
||||
import { ITestData } from '@business-logic/types/ITestData';
|
||||
|
||||
export class VinLookupPage extends LookupPage {
|
||||
readonly vinLookupTextBox: Locator;
|
||||
|
|
@ -20,4 +22,12 @@ export class VinLookupPage extends LookupPage {
|
|||
async enterVin(vin: string) {
|
||||
await this.vinLookupTextBox.fill(vin);
|
||||
}
|
||||
|
||||
@step("VinLookupPage >> Lookup by VIN: ")
|
||||
async handleVehicleLookupVinPage(testData: Partial<ITestData>) {
|
||||
const { customerDetails, vehicleDetails, alertFlags } = testData;
|
||||
await this.enterVin(vehicleDetails!.vin!);
|
||||
await this.enterZip(customerDetails!.address.postalCode!);
|
||||
await this.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
|
||||
}
|
||||
}
|
||||
|
|
@ -164,27 +164,6 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
dynamicRecal, hasOemEndorsement, promoCode
|
||||
} = testCase.testData;
|
||||
|
||||
// Destructure alert flag data
|
||||
const {
|
||||
isHeavyTruckVehicle, isRepairReplace, isSplitWindshield, isRepairOnly,
|
||||
isUnserviceableZip, isInvalidZip, isVinNotFound
|
||||
} = testCase.testData.alertFlags || {};
|
||||
|
||||
// Define repair damage types (vs. replacement types)
|
||||
const repairTypes: VehicleDamage[] = [
|
||||
VehicleDamage.WindshieldOneChip,
|
||||
VehicleDamage.WindshieldTwoChips,
|
||||
VehicleDamage.WindshieldThreeChips
|
||||
];
|
||||
|
||||
// Determine if we're replacing or repairing
|
||||
const isReplace = !repairTypes.some(damageType => {
|
||||
return vehicleDamage!.includes(damageType);
|
||||
});
|
||||
|
||||
// Check if the insurance policy has endorsements
|
||||
const hasEndorsements = endorsements && endorsements.length > 0;
|
||||
|
||||
// Check if the vehicle damage includes a windshield crack
|
||||
const hasWindshieldCrack = vehicleDamage!.some(damage =>
|
||||
damage === VehicleDamage.WindshieldCrack
|
||||
|
|
@ -211,414 +190,166 @@ async function runWorkflow(page: Page, testCase: TestCase) {
|
|||
console.log(`Customer for this test: ${customerDetails?.firstName} ${customerDetails?.lastName}`);
|
||||
}
|
||||
|
||||
// Handle vehicle selection page
|
||||
let vehicleSelectionPage = testCase.pages.vehicleSelectionPage;
|
||||
await vehicleSelectionPage.handleVehicleSelectionPage(testCase.testData);
|
||||
|
||||
await test.step('VehicleSelectionPage >> Select Vehicle', async () => {
|
||||
let vehicleSelectionPage = testCase.pages.vehicleSelectionPage;
|
||||
await vehicleSelectionPage.selectVehicle(vehicleDetails!);
|
||||
|
||||
// Handle alert conditions for vehicle selection
|
||||
if (isHeavyTruckVehicle || isSplitWindshield) {
|
||||
await vehicleSelectionPage.checkForAlertMessages();
|
||||
throw new TestSuccessAlert('Both assertions are met successfully.');
|
||||
}
|
||||
|
||||
await vehicleSelectionPage.nextPage();
|
||||
});
|
||||
|
||||
await test.step('VehicleDamagePage >> Select Damage', async () => {
|
||||
let vehicleDamagePage = testCase.pages.vehicleDamagePage;
|
||||
await vehicleDamagePage.selectDamage(vehicleDamage!);
|
||||
|
||||
// Handle alert conditions for vehicle damage
|
||||
if (isRepairReplace) {
|
||||
await vehicleDamagePage.checkForBothRepairReplaceAlertMessage();
|
||||
throw new TestSuccessAlert('Both assertions are met successfully.');
|
||||
}
|
||||
if (isRepairOnly) {
|
||||
await vehicleDamagePage.checkForRepairOnlyAlertMessage();
|
||||
throw new TestSuccessAlert('Both assertions are met successfully.');
|
||||
}
|
||||
|
||||
await vehicleDamagePage.nextPage();
|
||||
});
|
||||
// Handle vehicle damage page
|
||||
let vehicleDamagePage = testCase.pages.vehicleDamagePage;
|
||||
await vehicleDamagePage.handleVehicleDamagePage(testCase.testData);
|
||||
|
||||
// If the vehicle has a windshield crack as part of its damage, go to estimate page and select lookup type
|
||||
if (hasWindshieldCrack && !skipEstimatePage) {
|
||||
await test.step('EstimatePage >> Select Lookup Type', async () => {
|
||||
let estimatePage = testCase.pages.estimatePage;
|
||||
await estimatePage.vehicleLookup(vehicleDetails!);
|
||||
});
|
||||
let estimatePage = testCase.pages.estimatePage;
|
||||
await estimatePage.handleEstimatePage(testCase.testData);
|
||||
|
||||
// Handle different vehicle lookup methods
|
||||
switch (vehicleDetails!.vehicleLookupType!) {
|
||||
case VehicleLookupType.Address:
|
||||
await test.step('VehicleLookupAddressPage >> Lookup by address: ' + customerDetails!.address.street, async () => {
|
||||
let vehicleLookupAddressPage = testCase.pages.vehicleLookupAddressPage;
|
||||
await vehicleLookupAddressPage.lookupVehicleByAddress(customerDetails!, vehicleDetails!);
|
||||
await vehicleLookupAddressPage.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
|
||||
});
|
||||
let vehicleLookupAddressPage = testCase.pages.vehicleLookupAddressPage;
|
||||
await vehicleLookupAddressPage.handleVehicleLookupAddressPage(testCase.testData);
|
||||
break;
|
||||
|
||||
case VehicleLookupType.LicensePlateNumber:
|
||||
await test.step('VehicleLookupLicensePage >> Lookup by license plate: ' + vehicleDetails!.licensePlateNumber, async () => {
|
||||
let vehicleLookupLicensePage = testCase.pages.vehicleLookupLicensePage;
|
||||
await vehicleLookupLicensePage.enterPlateDetails(vehicleDetails!);
|
||||
await vehicleLookupLicensePage.enterZip(customerDetails!.address.postalCode!);
|
||||
await vehicleLookupLicensePage.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
|
||||
});
|
||||
let vehicleLookupLicensePage = testCase.pages.vehicleLookupLicensePage;
|
||||
await vehicleLookupLicensePage.handleVehicleLookupLicensePage(testCase.testData);
|
||||
break;
|
||||
|
||||
case VehicleLookupType.Vin:
|
||||
await test.step('VinLookupPage >> Lookup by VIN: ' + vehicleDetails!.vin!, async () => {
|
||||
let vinLookupPage = testCase.pages.vinLookupPage;
|
||||
await vinLookupPage.enterVin(vehicleDetails!.vin!);
|
||||
await vinLookupPage.enterZip(customerDetails!.address.postalCode!);
|
||||
await vinLookupPage.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
|
||||
});
|
||||
let vinLookupPage = testCase.pages.vinLookupPage;
|
||||
await vinLookupPage.handleVehicleLookupVinPage(testCase.testData);
|
||||
break;
|
||||
|
||||
case VehicleLookupType.Zip:
|
||||
await test.step('ZipLookupPage >> Lookup by service ZIP: ' + customerDetails!.address.postalCode!, async () => {
|
||||
let zipLookupPage = testCase.pages.zipLookupPage;
|
||||
let vinLookupPage = testCase.pages.vinLookupPage;
|
||||
await vinLookupPage.enterZip(customerDetails!.address.postalCode!);
|
||||
await zipLookupPage.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
|
||||
});
|
||||
let serviceZipPage = testCase.pages.serviceZipPage;
|
||||
await serviceZipPage.handleServiceZipPage(testCase.testData);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Otherwise just use zip lookup
|
||||
await test.step('ZipLookupPage >> Lookup by service ZIP: ' + customerDetails!.address.postalCode!, async () => {
|
||||
let zipLookupPage = testCase.pages.zipLookupPage;
|
||||
let vinLookupPage = testCase.pages.vinLookupPage;
|
||||
await vinLookupPage.enterZip(customerDetails!.address.postalCode!);
|
||||
await zipLookupPage.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!);
|
||||
});
|
||||
// Otherwise just use zip lookup for service zip page
|
||||
let serviceZipPage = testCase.pages.serviceZipPage;
|
||||
await serviceZipPage.handleServiceZipPage(testCase.testData);
|
||||
}
|
||||
|
||||
// Handle part questions if applicable
|
||||
if (partQuestions && partQuestions.length > 0) {
|
||||
await test.step('PartQuestionsPage >> Select Vehicle Part Question Responses', async () => {
|
||||
let partQuestionsPage = testCase.pages.partQuestionsPage;
|
||||
await partQuestionsPage.validatePartQuestions(partQuestions);
|
||||
await partQuestionsPage.selectPartQuestionResponses(partQuestions);
|
||||
await partQuestionsPage.nextPage();
|
||||
});
|
||||
let partQuestionsPage = testCase.pages.partQuestionsPage;
|
||||
await partQuestionsPage.handlePartQuestionsPage(testCase.testData);
|
||||
}
|
||||
|
||||
// Handle molding questions if applicable
|
||||
if (moldingQuestions && moldingQuestions.length > 0) {
|
||||
await test.step('MoldingQuestionsPage >> Select Molding Question Responses', async () => {
|
||||
let moldingQuestionsPage = testCase.pages.moldingQuestionsPage;
|
||||
await moldingQuestionsPage.validatePartQuestions(moldingQuestions);
|
||||
await moldingQuestionsPage.selectPartQuestionResponses(moldingQuestions);
|
||||
await moldingQuestionsPage.nextPage();
|
||||
});
|
||||
let moldingQuestionsPage = testCase.pages.moldingQuestionsPage;
|
||||
await moldingQuestionsPage.handleMoldingQuestionsPage(testCase.testData);
|
||||
}
|
||||
|
||||
// Handle vehicle part questions if applicable
|
||||
if (vehiclePartQuestions && vehiclePartQuestions.length > 0) {
|
||||
await test.step('VehiclePartsPage >> Select Vehicle Part Responses', async () => {
|
||||
let vehiclePartsPage = testCase.pages.vehiclePartsPage;
|
||||
await vehiclePartsPage.validatePartQuestions(vehiclePartQuestions);
|
||||
await vehiclePartsPage.selectPartQuestionResponses(vehiclePartQuestions);
|
||||
await vehiclePartsPage.nextPage();
|
||||
});
|
||||
let vehiclePartsPage = testCase.pages.vehiclePartsPage;
|
||||
await vehiclePartsPage.handleVehiclePartsPage(testCase.testData);
|
||||
}
|
||||
|
||||
// Handle capability questions if applicable
|
||||
if (capabilityQuestions && capabilityQuestions.length > 0) {
|
||||
await test.step('CapabilityQuestionsPage >> Select Capability Question Responses', async () => {
|
||||
let capabilityQuestionsPage = testCase.pages.capabilityQuestionsPage;
|
||||
await capabilityQuestionsPage.validatePartQuestions(capabilityQuestions);
|
||||
await capabilityQuestionsPage.selectPartQuestionResponses(capabilityQuestions);
|
||||
await capabilityQuestionsPage.nextPage();
|
||||
});
|
||||
let capabilityQuestionsPage = testCase.pages.capabilityQuestionsPage;
|
||||
await capabilityQuestionsPage.handleCapabilityQuestionsPage(testCase.testData);
|
||||
}
|
||||
|
||||
// Select service package and payment method
|
||||
await test.step('ServicePackagePage >> Select Payment Method and Service Type', async() => {
|
||||
let servicePackagePage = testCase.pages.servicePackagePage;
|
||||
await servicePackagePage.handleQuotePopup(customerDetails!.email!);
|
||||
await servicePackagePage.selectPaymentMethod(paymentMethod!);
|
||||
await servicePackagePage.selectServicePackage(servicePackage!);
|
||||
// Enter promo code
|
||||
if (promoCode) {
|
||||
await servicePackagePage.enterPromo(promoCode);
|
||||
}
|
||||
|
||||
// Backend Validations
|
||||
// Validate backend for can not recal if applicable
|
||||
if (canNotRecal) {
|
||||
await servicePackagePage.verifyCanNotRecal();
|
||||
}
|
||||
// Validate backend for dynamic recal if applicable
|
||||
if (dynamicRecal) {
|
||||
await servicePackagePage.verifyDynamicRecal();
|
||||
}
|
||||
// Validate backend for repair info (including chip verification)
|
||||
await servicePackagePage.verifyIsRepair(!isReplace, vehicleDamage!);
|
||||
if (isReplace) {
|
||||
// Validate backend for parts info
|
||||
await servicePackagePage.verifyVehicleParts(vehicleDamage!);
|
||||
}
|
||||
// Validate backend for OEM endorsement
|
||||
if (hasOemEndorsement) {
|
||||
await servicePackagePage.verifyOEMPart();
|
||||
}
|
||||
|
||||
await servicePackagePage.nextPage();
|
||||
});
|
||||
let servicePackagesPage = testCase.pages.servicePackagesPage;
|
||||
await servicePackagesPage.handleServicePackagePage(testCase.testData);
|
||||
|
||||
//============================= INSURANCE FLOW =============================`
|
||||
|
||||
// Insurance flow - if user selected Insurance as Payment Method
|
||||
if (paymentMethod == PaymentMethod.Insurance) {
|
||||
await test.step('InsuranceCoveragePage >> Select your insurance', async() => {
|
||||
let insuranceCompanyPage = testCase.pages.insuranceCompanyPage;
|
||||
await insuranceCompanyPage.enterInsuranceCompany(claimDetails!.client!);
|
||||
await insuranceCompanyPage.nextPage();
|
||||
});
|
||||
|
||||
await test.step('CCPolicyInfoPage >> Fill out claim information', async() => {
|
||||
let ccPolicyInfoPage = testCase.pages.ccPolicyInfoPage;
|
||||
await ccPolicyInfoPage.populatePage(customerDetails!, claimDetails!, await ccPolicyInfoPage.hasCityInfo());
|
||||
await ccPolicyInfoPage.nextPage();
|
||||
});
|
||||
|
||||
// Handle duplicate claim case if applicable
|
||||
if (isDuplicateClaim) {
|
||||
await test.step('DuplicateCheckPage >> Start New Claim', async () => {
|
||||
let duplicateCheckPage = testCase.pages.duplicateCheckPage;
|
||||
await duplicateCheckPage.startNewClaim();
|
||||
await duplicateCheckPage.nextPage();
|
||||
});
|
||||
}
|
||||
|
||||
// Handle policy found vs. not found flows
|
||||
if (isPolicyFound) {
|
||||
await test.step('PolicyVehiclesPage >> Select vehicle', async () => {
|
||||
let policyVehiclesPage = testCase.pages.policyVehiclesPage;
|
||||
let vehicleSelectionPage = testCase.pages.vehicleSelectionPage;
|
||||
|
||||
// Validate other vehicles on policy
|
||||
if (otherVehiclesOnPolicy && otherVehiclesOnPolicy.length > 0) {
|
||||
for (const vehicle of otherVehiclesOnPolicy) {
|
||||
await policyVehiclesPage.validateVehicleIsOnPolicy(vehicle);
|
||||
}
|
||||
}
|
||||
|
||||
// If vehicle is not on the policy, select new vehicle
|
||||
if (!(isUseVehicleOnPolicy ?? true)) {
|
||||
await policyVehiclesPage.selectVehicleNotListed();
|
||||
await policyVehiclesPage.nextPage();
|
||||
await vehicleSelectionPage.selectVehicle(vehicleDetails!);
|
||||
await policyVehiclesPage.nextPage();
|
||||
} else {
|
||||
// Otherwise, select the vehicle entered in Safelite.com
|
||||
await policyVehiclesPage.selectVehicle(vehicleDetails!);
|
||||
await policyVehiclesPage.nextPage();
|
||||
}
|
||||
});
|
||||
|
||||
// Handle policy driver selection if applicable
|
||||
if (isPolicyDriver) {
|
||||
await test.step('PolicyDriverPage >> Confirm Driver at time of damage', async () => {
|
||||
let policyDriverPage = testCase.pages.policyDriverPage;
|
||||
await policyDriverPage.selectPolicyDriver(customerDetails!);
|
||||
await policyDriverPage.nextPage();
|
||||
});
|
||||
}
|
||||
|
||||
// Handle endorsements if applicable
|
||||
if (hasEndorsements) {
|
||||
await test.step('EndorsementsPage >> Select Endorsements', async () => {
|
||||
let endorsementsPage = testCase.pages.endorsementsPage;
|
||||
await endorsementsPage.verifyEndorsements(endorsements);
|
||||
await endorsementsPage.selectEndorsements(endorsements);
|
||||
await endorsementsPage.nextPage();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Policy not found flow
|
||||
await test.step('VerifyDetailsPage >> Verify Details', async () => {
|
||||
let verifyDetailsPage = testCase.pages.verifyDetailsPage;
|
||||
await verifyDetailsPage.verifyPolicyDetails(customerDetails!, claimDetails!);
|
||||
await verifyDetailsPage.nextPage();
|
||||
});
|
||||
}
|
||||
|
||||
// Continue with the insurance flow after policy information
|
||||
await test.step('PolicyInfoSubmittedPage >> Continue With Safelite Autoglass', async () => {
|
||||
let policyInfoSubmittedPage = testCase.pages.policyInfoSubmittedPage;
|
||||
await policyInfoSubmittedPage.verifyPolicyInfoSubmitted();
|
||||
await policyInfoSubmittedPage.nextPage();
|
||||
});
|
||||
|
||||
// Handle recalibration notification if applicable
|
||||
if (isRecalNotification) {
|
||||
await test.step('RecallibrationInfoPage >> Continue With Recalibration Information', async () => {
|
||||
let recalibrationInfoPage = testCase.pages.recalibrationInfoPage;
|
||||
await recalibrationInfoPage.nextPage();
|
||||
});
|
||||
}
|
||||
|
||||
// Continue to coverage statement
|
||||
await test.step('CoverageStatementPage >> Next page', async () => {
|
||||
let coverageStatementPage = testCase.pages.coverageStatementPage;
|
||||
await coverageStatementPage.validateDeductibleAmount(claimDetails!);
|
||||
await coverageStatementPage.nextPage();
|
||||
});
|
||||
await handleInsuranceFlow(testCase);
|
||||
}
|
||||
|
||||
//============================= SERVICE SCHEDULING =============================
|
||||
|
||||
// Select service location
|
||||
await test.step('ServiceLocationPage >> Select service location', async () => {
|
||||
let serviceLocationPage = testCase.pages.serviceLocationPage;
|
||||
await serviceLocationPage.selectLocation(appointmentDetails!);
|
||||
await serviceLocationPage.nextPage();
|
||||
});
|
||||
let serviceLocationPage = testCase.pages.serviceLocationPage;
|
||||
await serviceLocationPage.handleServiceLocationPage(testCase.testData);
|
||||
|
||||
// Schedule appointment
|
||||
await test.step('SchedulePage >> Select day and time', async () => {
|
||||
let schedulePage = testCase.pages.schedulePage;
|
||||
await schedulePage.scheduleFirstAppointment(customerDetails!);
|
||||
});
|
||||
let schedulePage = testCase.pages.schedulePage;
|
||||
await schedulePage.handleSchedulePage(testCase.testData);
|
||||
|
||||
// Enter contact details
|
||||
await test.step('ContactDetailsPage >> Enter contact details', async () => {
|
||||
let contactDetailsPage = testCase.pages.contactDetailsPage;
|
||||
await contactDetailsPage.enterContactDetails(customerDetails!);
|
||||
await contactDetailsPage.nextPage();
|
||||
});
|
||||
let contactDetailsPage = testCase.pages.contactDetailsPage;
|
||||
await contactDetailsPage.handleContactDetailsPage(testCase.testData);
|
||||
|
||||
//============================= PAYMENT PROCESSING =============================
|
||||
|
||||
// Handle payment
|
||||
await test.step('PaymentMethodPage >> Execute Payment', async () => {
|
||||
let paymentMethodPage = testCase.pages.paymentMethodPage;
|
||||
await paymentMethodPage.validatePaymentDetailsPage(testCase.testData);
|
||||
// Verify VAPS wipers on backend for standard and premium packages
|
||||
if (servicePackage === ServicePackage.Standard || servicePackage === ServicePackage.Premium) {
|
||||
await paymentMethodPage.verifyVAPS();
|
||||
}
|
||||
if (paymentDetails?.paymentType) {
|
||||
await paymentMethodPage.executePayment(paymentDetails!, isRecalVehicle!);
|
||||
} else {
|
||||
await paymentMethodPage.nextPage();
|
||||
}
|
||||
});
|
||||
let paymentMethodPage = testCase.pages.paymentMethodPage;
|
||||
await paymentMethodPage.handlePaymentMethodPage(testCase.testData);
|
||||
|
||||
// If user selected Pay with Insurance as Payment Method, Enter Insurance Flow
|
||||
if (paymentDetails?.paymentType === PaymentType.PayWithInsurance) {
|
||||
await test.step('InsuranceCoveragePage >> Select your insurance', async() => {
|
||||
let insuranceCompanyPage = testCase.pages.insuranceCompanyPage;
|
||||
await insuranceCompanyPage.enterInsuranceCompany(claimDetails!.client!);
|
||||
await insuranceCompanyPage.nextPage();
|
||||
});
|
||||
|
||||
await test.step('CCPolicyInfoPage >> Fill out claim information', async() => {
|
||||
const ccPolicyInfoPage = testCase.pages.ccPolicyInfoPage;
|
||||
await ccPolicyInfoPage.populatePage(customerDetails!, claimDetails!, await ccPolicyInfoPage.hasCityInfo());
|
||||
await ccPolicyInfoPage.nextPage();
|
||||
});
|
||||
|
||||
// Handle duplicate claim case if applicable
|
||||
if (isDuplicateClaim) {
|
||||
await test.step('DuplicateCheckPage >> Start New Claim', async () => {
|
||||
const duplicateCheckPage = testCase.pages.duplicateCheckPage;
|
||||
await duplicateCheckPage.startNewClaim();
|
||||
await duplicateCheckPage.nextPage();
|
||||
});
|
||||
}
|
||||
|
||||
// Handle policy found vs. not found flows
|
||||
if (isPolicyFound) {
|
||||
await test.step('PolicyVehiclesPage >> Select vehicle', async () => {
|
||||
const policyVehiclesPage = testCase.pages.policyVehiclesPage;
|
||||
const vehicleSelectionPage = testCase.pages.vehicleSelectionPage;
|
||||
|
||||
// Validate other vehicles on policy
|
||||
if (otherVehiclesOnPolicy && otherVehiclesOnPolicy.length > 0) {
|
||||
for (const vehicle of otherVehiclesOnPolicy) {
|
||||
await policyVehiclesPage.validateVehicleIsOnPolicy(vehicle);
|
||||
}
|
||||
}
|
||||
|
||||
// If vehicle is not on the policy, select new vehicle
|
||||
if (!(isUseVehicleOnPolicy ?? true)) {
|
||||
await policyVehiclesPage.selectVehicleNotListed();
|
||||
await policyVehiclesPage.nextPage();
|
||||
await vehicleSelectionPage.selectVehicle(vehicleDetails!);
|
||||
await policyVehiclesPage.nextPage();
|
||||
} else {
|
||||
// Otherwise, select the vehicle entered in Safelite.com
|
||||
await policyVehiclesPage.selectVehicle(vehicleDetails!);
|
||||
await policyVehiclesPage.nextPage();
|
||||
}
|
||||
});
|
||||
|
||||
// Handle policy driver selection if applicable
|
||||
if (isPolicyDriver) {
|
||||
await test.step('PolicyDriverPage >> Confirm Driver at time of damage', async () => {
|
||||
const policyDriverPage = testCase.pages.policyDriverPage;
|
||||
await policyDriverPage.selectPolicyDriver(customerDetails!);
|
||||
await policyDriverPage.nextPage();
|
||||
});
|
||||
}
|
||||
|
||||
// Handle endorsements if applicable
|
||||
if (hasEndorsements) {
|
||||
await test.step('EndorsementsPage >> Select Endorsements', async () => {
|
||||
const endorsementsPage = testCase.pages.endorsementsPage;
|
||||
await endorsementsPage.verifyEndorsements(endorsements);
|
||||
await endorsementsPage.selectEndorsements(endorsements);
|
||||
await endorsementsPage.nextPage();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Policy not found flow
|
||||
await test.step('VerifyDetailsPage >> Verify Details', async () => {
|
||||
const verifyDetailsPage = testCase.pages.verifyDetailsPage;
|
||||
await verifyDetailsPage.verifyPolicyDetails(customerDetails!, claimDetails!);
|
||||
await verifyDetailsPage.nextPage();
|
||||
});
|
||||
}
|
||||
|
||||
// Continue with the insurance flow after policy information
|
||||
await test.step('PolicyInfoSubmittedPage >> Continue With Safelite Autoglass', async () => {
|
||||
const policyInfoSubmittedPage = testCase.pages.policyInfoSubmittedPage;
|
||||
await policyInfoSubmittedPage.verifyPolicyInfoSubmitted();
|
||||
await policyInfoSubmittedPage.nextPage();
|
||||
});
|
||||
|
||||
// Handle recalibration notification if applicable
|
||||
if (isRecalNotification) {
|
||||
await test.step('RecallibrationInfoPage >> Continue With Recalibration Information', async () => {
|
||||
const recalibrationInfoPage = testCase.pages.recalibrationInfoPage;
|
||||
await recalibrationInfoPage.nextPage();
|
||||
});
|
||||
}
|
||||
|
||||
// Continue to coverage statement
|
||||
await test.step('CoverageStatementPage >> Next page', async () => {
|
||||
const coverageStatementPage = testCase.pages.coverageStatementPage;
|
||||
await coverageStatementPage.validateDeductibleAmount(claimDetails!);
|
||||
await coverageStatementPage.nextPage();
|
||||
});
|
||||
await handleInsuranceFlow(testCase);
|
||||
}
|
||||
|
||||
//============================= ORDER CONFIRMATION =============================
|
||||
|
||||
// Validate order confirmation
|
||||
await test.step('OrderConfirmationPage >> Validate order', async () => {
|
||||
let orderConfirmationPage = testCase.pages.orderConfirmationPage;
|
||||
await orderConfirmationPage.validateOrderConfirmationPage(testCase.testData);
|
||||
});
|
||||
let orderConfirmationPage = testCase.pages.orderConfirmationPage;
|
||||
await orderConfirmationPage.verifyOrderConfirmationPage(testCase.testData);
|
||||
}
|
||||
|
||||
// Get the order number and wrap it in a test step
|
||||
const workOrderNumber = await testCase.pages.orderConfirmationPage.logOrderNumber();
|
||||
await test.step(`Session Storage Work Order Number: ${workOrderNumber}`, async () => {
|
||||
console.log(`Session Storage Work Order Number: ${workOrderNumber}`);
|
||||
});
|
||||
export async function handleInsuranceFlow(testCase: TestCase) {
|
||||
const { isPolicyFound, isPolicyDriver, endorsements, isRecalNotification } = testCase.testData;
|
||||
|
||||
// Check if the insurance policy has endorsements
|
||||
const hasEndorsements = endorsements && endorsements.length > 0;
|
||||
|
||||
// Handle insurance company page
|
||||
let insuranceCompanyPage = testCase.pages.insuranceCompanyPage;
|
||||
await insuranceCompanyPage.handleInsuranceCompanyPage(testCase.testData);
|
||||
|
||||
// Handle ccPolicyInfoPage
|
||||
let ccPolicyInfoPage = testCase.pages.ccPolicyInfoPage;
|
||||
await ccPolicyInfoPage.handleCCPolicyInfoPage(testCase.testData);
|
||||
|
||||
let duplicateCheckPage = testCase.pages.duplicateCheckPage;
|
||||
if (duplicateCheckPage.page.url().includes('dup')) {
|
||||
await duplicateCheckPage.handleDuplicateCheckPage(testCase.testData);
|
||||
}
|
||||
|
||||
if (isPolicyFound) {
|
||||
let policyVehiclesPage = testCase.pages.policyVehiclesPage;
|
||||
await policyVehiclesPage.handlePolicyVehiclesPage(testCase.testData);
|
||||
|
||||
// Handle policy driver selection if applicable
|
||||
if (isPolicyDriver) {
|
||||
let policyDriverPage = testCase.pages.policyDriverPage;
|
||||
await policyDriverPage.handlePolicyDriverPage(testCase.testData);
|
||||
}
|
||||
|
||||
// Handle endorsements if applicable
|
||||
if (hasEndorsements) {
|
||||
let endorsementsPage = testCase.pages.endorsementsPage;
|
||||
await endorsementsPage.handleEndorsementsPage(testCase.testData);
|
||||
}
|
||||
}else {
|
||||
|
||||
//Handle verify details page
|
||||
let verifyDetailsPage = testCase.pages.verifyDetailsPage;
|
||||
await verifyDetailsPage.handleVerifyDetailsPage(testCase.testData);
|
||||
}
|
||||
|
||||
// Handle Policy info submitted page
|
||||
let policyInfoSubmittedPage = testCase.pages.policyInfoSubmittedPage;
|
||||
await policyInfoSubmittedPage.handlePolicyInfoSubmittedPage();
|
||||
|
||||
if(isRecalNotification)
|
||||
{
|
||||
let recalibrationInfoPage = testCase.pages.recalibrationInfoPage;
|
||||
await recalibrationInfoPage.handleRecalibrationInfoPage();
|
||||
}
|
||||
|
||||
//handle coveraage statement page
|
||||
let coverageStatementPage = testCase.pages.coverageStatementPage;
|
||||
await coverageStatementPage.handleCoverageStatementPage(testCase.testData);
|
||||
}
|
||||
Loading…
Reference in a new issue