diff --git a/playwright-tests/business-logic/types/ITestPages.ts b/playwright-tests/business-logic/types/ITestPages.ts index 77b9689e7..d8ba7e5bd 100644 --- a/playwright-tests/business-logic/types/ITestPages.ts +++ b/playwright-tests/business-logic/types/ITestPages.ts @@ -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, diff --git a/playwright-tests/business-logic/types/Step.ts b/playwright-tests/business-logic/types/Step.ts new file mode 100644 index 000000000..693e34da2 --- /dev/null +++ b/playwright-tests/business-logic/types/Step.ts @@ -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 (value: T, context: Context): Method => { + return function (this: any, ...args: any[]): Promise { + // console.log(`Method ${value.name} has been decorated`, context, args, label); + return test.step(label, async () => { + return value.call(this, ...args); + }); + }; + }; +} \ No newline at end of file diff --git a/playwright-tests/business-logic/types/TestCase.ts b/playwright-tests/business-logic/types/TestCase.ts index 5fe3ae857..ab45a6078 100644 --- a/playwright-tests/business-logic/types/TestCase.ts +++ b/playwright-tests/business-logic/types/TestCase.ts @@ -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), diff --git a/playwright-tests/pages/CCPolicyInfoPage.ts b/playwright-tests/pages/CCPolicyInfoPage.ts index 42ee3632b..7151e3c06 100644 --- a/playwright-tests/pages/CCPolicyInfoPage.ts +++ b/playwright-tests/pages/CCPolicyInfoPage.ts @@ -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) { + const { customerDetails, claimDetails } = testData; + + await this.populatePage(customerDetails!, claimDetails!, await this.hasCityInfo()); + await this.nextPage(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/CapabilityQuestionsPage.ts b/playwright-tests/pages/CapabilityQuestionsPage.ts index e2b6260a3..092a424f3 100644 --- a/playwright-tests/pages/CapabilityQuestionsPage.ts +++ b/playwright-tests/pages/CapabilityQuestionsPage.ts @@ -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) { + 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(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/ContactDetailsPage.ts b/playwright-tests/pages/ContactDetailsPage.ts index 0b10be42a..2641f6436 100644 --- a/playwright-tests/pages/ContactDetailsPage.ts +++ b/playwright-tests/pages/ContactDetailsPage.ts @@ -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) { + const { customerDetails } = testData; + await this.enterContactDetails(customerDetails!); + await this.nextPage(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/CoverageStatementPage.ts b/playwright-tests/pages/CoverageStatementPage.ts index a140604f7..7085c6794 100644 --- a/playwright-tests/pages/CoverageStatementPage.ts +++ b/playwright-tests/pages/CoverageStatementPage.ts @@ -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) { + const { claimDetails } = testData; + + await this.validateDeductibleAmount(claimDetails!); + await this.nextPage(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/DuplicateCheckPage.ts b/playwright-tests/pages/DuplicateCheckPage.ts index 58d5463dd..e5f44492c 100644 --- a/playwright-tests/pages/DuplicateCheckPage.ts +++ b/playwright-tests/pages/DuplicateCheckPage.ts @@ -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) { + await this.startNewClaim(); + await this.nextPage(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/EndorsementsPage.ts b/playwright-tests/pages/EndorsementsPage.ts index 08d69e4e3..3b63dcac0 100644 --- a/playwright-tests/pages/EndorsementsPage.ts +++ b/playwright-tests/pages/EndorsementsPage.ts @@ -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) { + const { endorsements } = testData; + await this.verifyEndorsements(endorsements!); + await this.selectEndorsements(endorsements!); + await this.nextPage(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/EstimatePage.ts b/playwright-tests/pages/EstimatePage.ts index 141fa73a6..2beb507b3 100644 --- a/playwright-tests/pages/EstimatePage.ts +++ b/playwright-tests/pages/EstimatePage.ts @@ -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) { + const { vehicleDetails } = testData; + await this.vehicleLookup(vehicleDetails!); + } } diff --git a/playwright-tests/pages/InsuranceCompanyPage.ts b/playwright-tests/pages/InsuranceCompanyPage.ts index 6bc125225..e2d63ec2d 100644 --- a/playwright-tests/pages/InsuranceCompanyPage.ts +++ b/playwright-tests/pages/InsuranceCompanyPage.ts @@ -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) { + const { claimDetails } = testData; + + await this.enterInsuranceCompany(claimDetails!.client!); + await this.nextPage(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/MoldingQuestionsPage.ts b/playwright-tests/pages/MoldingQuestionsPage.ts index 3221a35e2..5671900ff 100644 --- a/playwright-tests/pages/MoldingQuestionsPage.ts +++ b/playwright-tests/pages/MoldingQuestionsPage.ts @@ -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) { + const { moldingQuestions } = testCase; + await this.validatePartQuestions(moldingQuestions!); + await this.selectPartQuestionResponses(moldingQuestions!); + await this.nextPage(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/OrderConfirmationPage.ts b/playwright-tests/pages/OrderConfirmationPage.ts index c8b5f63f6..9ac31826f 100644 --- a/playwright-tests/pages/OrderConfirmationPage.ts +++ b/playwright-tests/pages/OrderConfirmationPage.ts @@ -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) { + 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}`); + }); + } } \ No newline at end of file diff --git a/playwright-tests/pages/PartQuestionPage.ts b/playwright-tests/pages/PartQuestionPage.ts index 02c26490f..831a27dc1 100644 --- a/playwright-tests/pages/PartQuestionPage.ts +++ b/playwright-tests/pages/PartQuestionPage.ts @@ -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) { + const { partQuestions } = testData; + await this.validatePartQuestions(partQuestions!); + await this.selectPartQuestionResponses(partQuestions!); + await this.nextPage(); + } } diff --git a/playwright-tests/pages/PaymentMethodPage.ts b/playwright-tests/pages/PaymentMethodPage.ts index 519cface5..210e9291f 100644 --- a/playwright-tests/pages/PaymentMethodPage.ts +++ b/playwright-tests/pages/PaymentMethodPage.ts @@ -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) { + 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(); + } + } } \ No newline at end of file diff --git a/playwright-tests/pages/PolicyDriverPage.ts b/playwright-tests/pages/PolicyDriverPage.ts index f6e56ca5f..1bb140088 100644 --- a/playwright-tests/pages/PolicyDriverPage.ts +++ b/playwright-tests/pages/PolicyDriverPage.ts @@ -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) { + const { customerDetails } = testData; + await this.selectPolicyDriver(customerDetails!); + await this.nextPage(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/PolicyInfoSubmittedPage.ts b/playwright-tests/pages/PolicyInfoSubmittedPage.ts index 6d5c96c5c..0a4bf79be 100644 --- a/playwright-tests/pages/PolicyInfoSubmittedPage.ts +++ b/playwright-tests/pages/PolicyInfoSubmittedPage.ts @@ -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(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/PolicyVehiclesPage.ts b/playwright-tests/pages/PolicyVehiclesPage.ts index 90882062d..67776adf6 100644 --- a/playwright-tests/pages/PolicyVehiclesPage.ts +++ b/playwright-tests/pages/PolicyVehiclesPage.ts @@ -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) { + + 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(); + } + } } \ No newline at end of file diff --git a/playwright-tests/pages/RecalibrationInfoPage.ts b/playwright-tests/pages/RecalibrationInfoPage.ts index 0af4b0a57..7310d6c16 100644 --- a/playwright-tests/pages/RecalibrationInfoPage.ts +++ b/playwright-tests/pages/RecalibrationInfoPage.ts @@ -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(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/SchedulePage.ts b/playwright-tests/pages/SchedulePage.ts index 0bf2b1105..80ae29920 100644 --- a/playwright-tests/pages/SchedulePage.ts +++ b/playwright-tests/pages/SchedulePage.ts @@ -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) { + const { customerDetails } = testData; + await this.scheduleFirstAppointment(customerDetails!); + } } \ No newline at end of file diff --git a/playwright-tests/pages/ServiceLocationPage.ts b/playwright-tests/pages/ServiceLocationPage.ts index f405175e6..a31f38eb5 100644 --- a/playwright-tests/pages/ServiceLocationPage.ts +++ b/playwright-tests/pages/ServiceLocationPage.ts @@ -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) { + const { appointmentDetails } = testData; + await this.selectLocation(appointmentDetails!); + await this.nextPage(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/ServicePackagesPage.ts b/playwright-tests/pages/ServicePackagesPage.ts index 360b285c3..89f085d3b 100644 --- a/playwright-tests/pages/ServicePackagesPage.ts +++ b/playwright-tests/pages/ServicePackagesPage.ts @@ -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) { + 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(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/ServiceZipPage.ts b/playwright-tests/pages/ServiceZipPage.ts new file mode 100644 index 000000000..d11ffa139 --- /dev/null +++ b/playwright-tests/pages/ServiceZipPage.ts @@ -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) { + const { customerDetails, vehicleDetails, alertFlags } = testData; + await this.enterZip(customerDetails!.address.postalCode!); + await this.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!); + } +} \ No newline at end of file diff --git a/playwright-tests/pages/VehicleDamagePage.ts b/playwright-tests/pages/VehicleDamagePage.ts index 33d778a79..1b48a1d4d 100644 --- a/playwright-tests/pages/VehicleDamagePage.ts +++ b/playwright-tests/pages/VehicleDamagePage.ts @@ -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): Promise { + 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(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/VehicleLookupAddressPage.ts b/playwright-tests/pages/VehicleLookupAddressPage.ts index 23ba8521a..ab0ad86f8 100644 --- a/playwright-tests/pages/VehicleLookupAddressPage.ts +++ b/playwright-tests/pages/VehicleLookupAddressPage.ts @@ -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) { + const { customerDetails, vehicleDetails, alertFlags } = testData; + await this.lookupVehicleByAddress(customerDetails!, vehicleDetails!); + await this.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!); + } } \ No newline at end of file diff --git a/playwright-tests/pages/VehicleLookupLicensePage.ts b/playwright-tests/pages/VehicleLookupLicensePage.ts index 492dfeffe..ef7f51f85 100644 --- a/playwright-tests/pages/VehicleLookupLicensePage.ts +++ b/playwright-tests/pages/VehicleLookupLicensePage.ts @@ -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) { + const { customerDetails, vehicleDetails, alertFlags } = testData; + await this.enterPlateDetails(vehicleDetails!); + await this.enterZip(customerDetails!.address.postalCode!); + await this.handleZipValidation(customerDetails!.address.postalCode!, vehicleDetails!.vehicleLookupType!, alertFlags!); + } } \ No newline at end of file diff --git a/playwright-tests/pages/VehiclePartsPage.ts b/playwright-tests/pages/VehiclePartsPage.ts index 1dc6b84f5..aabaa1f4e 100644 --- a/playwright-tests/pages/VehiclePartsPage.ts +++ b/playwright-tests/pages/VehiclePartsPage.ts @@ -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) { + const { vehiclePartQuestions } = testCase; + await this.validatePartQuestions(vehiclePartQuestions!); + await this.selectPartQuestionResponses(vehiclePartQuestions!); + await this.nextPage(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/VehicleSelectionPage.ts b/playwright-tests/pages/VehicleSelectionPage.ts index b2d370ef8..049f9fb8d 100644 --- a/playwright-tests/pages/VehicleSelectionPage.ts +++ b/playwright-tests/pages/VehicleSelectionPage.ts @@ -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) { + 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(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/VerifyDetailsPage.ts b/playwright-tests/pages/VerifyDetailsPage.ts index b74eb251e..212ed7968 100644 --- a/playwright-tests/pages/VerifyDetailsPage.ts +++ b/playwright-tests/pages/VerifyDetailsPage.ts @@ -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) { + const { customerDetails, claimDetails } = testData; + await this.verifyPolicyDetails(customerDetails!, claimDetails!); + await this.nextPage(); + } } \ No newline at end of file diff --git a/playwright-tests/pages/VinLookupPage.ts b/playwright-tests/pages/VinLookupPage.ts index 4ba2de260..1e96c14c5 100644 --- a/playwright-tests/pages/VinLookupPage.ts +++ b/playwright-tests/pages/VinLookupPage.ts @@ -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) { + 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!); + } } \ No newline at end of file diff --git a/playwright-tests/tests/0000__M.test.ts b/playwright-tests/tests/0000__M.test.ts index 6f84c9431..3c4349c87 100644 --- a/playwright-tests/tests/0000__M.test.ts +++ b/playwright-tests/tests/0000__M.test.ts @@ -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); } \ No newline at end of file