diff --git a/playwright-tests/framework/TestPages.ts b/playwright-tests/framework/TestPages.ts index 54078e266..650e96fda 100644 --- a/playwright-tests/framework/TestPages.ts +++ b/playwright-tests/framework/TestPages.ts @@ -34,8 +34,12 @@ import { PolicyDriverPage } from "../pages/PolicyDriverPage" import { ServiceZipPage } from "../pages/ServiceZipPage" import { MobileDetailsPage } from "pages/MobileDetailsPage"; import { PolicyInfoPage } from "../pages/PolicyInfoPage"; +import { BailoutPage } from '../pages/BailoutPage'; +import { BailoutSuccessPage } from '../pages/BailoutSuccessPage'; export interface ITestPages { + bailoutPage: BailoutPage, + bailoutSuccessPage: BailoutSuccessPage, capabilityQuestionsPage: CapabilityQuestionsPage, ccPolicyInfoPage: CCPolicyInfoPage, contactDetailsPage: ContactDetailsPage, @@ -74,6 +78,8 @@ export interface ITestPages { export const createTestPages: TestPagesFactory = (page: Page) => { const pages: ITestPages = { + bailoutPage: new BailoutPage(page), + bailoutSuccessPage: new BailoutSuccessPage(page), capabilityQuestionsPage: new CapabilityQuestionsPage(page), ccPolicyInfoPage: new CCPolicyInfoPage(page), contactDetailsPage: new ContactDetailsPage(page), diff --git a/playwright-tests/pages/BailoutPage.ts b/playwright-tests/pages/BailoutPage.ts new file mode 100644 index 000000000..5d8c54428 --- /dev/null +++ b/playwright-tests/pages/BailoutPage.ts @@ -0,0 +1,51 @@ +import { type Locator, type Page, expect } from '@playwright/test'; +import { BasePage } from './BasePage'; +import { step } from 'framework/localTypes/Step'; +import { ICustomerDetails } from 'safelite-playwright-core'; +import { ITestData } from 'framework/TestData'; + +export class BailoutPage extends BasePage { + readonly page: Page; + readonly firstNameTextBox: Locator; + readonly lastNameTextBox: Locator; + readonly emailAddressTextBox: Locator; + readonly phoneNumberTextBox: Locator; + readonly optInToSMSBox: Locator; + + constructor(page: Page) { + super(page); + this.page = page; + + this.firstNameTextBox = this.page.getByRole('textbox', { name: 'First name' }); + this.lastNameTextBox = this.page.getByRole('textbox', { name: 'Last name' }); + this.emailAddressTextBox = this.page.getByRole('textbox', { name: 'Email address' }); + this.phoneNumberTextBox = this.page.getByRole('textbox', { name: 'Phone number' }); + this.optInToSMSBox = this.page.getByRole('checkbox', { name: 'Opt in to SMS' }); + } + + async fillOutBailoutForm(customerDetails: ICustomerDetails) { + await this.firstNameTextBox.fill(customerDetails!.firstName!); + await this.lastNameTextBox.fill(customerDetails!.lastName!); + await this.emailAddressTextBox.fill(customerDetails!.email!); + await this.phoneNumberTextBox.fill(customerDetails!.phoneNumber!); + } + + async checkOptInToSMSBox() { + await this.optInToSMSBox.check(); + } + + @step("BailoutPage >> Fill out bailout form: ") + async handleBailoutPage(testData: Partial) { + + const { customerDetails } = testData; + + await expect(this.page).toHaveURL(/bailout/); + await this.fillOutBailoutForm(customerDetails!); + + if (testData.isOptedInForTextMessages) { + await this.checkOptInToSMSBox(); + } + + await this.nextPage(); + } +} diff --git a/playwright-tests/pages/BailoutSuccessPage.ts b/playwright-tests/pages/BailoutSuccessPage.ts new file mode 100644 index 000000000..603172bd3 --- /dev/null +++ b/playwright-tests/pages/BailoutSuccessPage.ts @@ -0,0 +1,35 @@ +import { type Locator, type Page, expect } from '@playwright/test'; +import { BasePage } from './BasePage'; +import { TestSuccessAlert } from 'safelite-playwright-core'; +import { step } from 'framework/localTypes/Step'; + +export class BailoutSuccessPage extends BasePage { + readonly thankYouHeading: Locator; + readonly bodyText: Locator; + readonly returnToHomepageButton: Locator; + + constructor(page: Page) { + super(page); + this.thankYouHeading = page.getByText("Thanks! We'll get back to you soon"); + this.bodyText = page.getByText(/We've got it from here!/); + this.returnToHomepageButton = page.locator('#btn-vehicle-not-listed'); + } + + async validateBailoutSuccessPage() { + await expect(this.page).toHaveURL(/bailout-success/); + await expect(this.thankYouHeading).toBeVisible(); + await expect(this.bodyText).toBeVisible(); + await expect(this.bodyText).toHaveText( + /We've got it from here! One of our experts will be in touch to schedule your appointment\. If you have any questions, please contact 1-888-238-4527/ + ); + await expect(this.returnToHomepageButton).toBeVisible(); + } + + @step("BailoutSuccessPage >> Validate bailout success page and return to vehicle page") + async handleBailoutSuccessPage() { + await this.validateBailoutSuccessPage(); + await this.returnToHomepageButton.click(); + await expect(this.page).toHaveURL(/vehicle/); + throw new TestSuccessAlert('Parts not found bailout validated successfully.'); + } +} diff --git a/playwright-tests/pages/SchedulePage.ts b/playwright-tests/pages/SchedulePage.ts index 088049693..8d863e94f 100644 --- a/playwright-tests/pages/SchedulePage.ts +++ b/playwright-tests/pages/SchedulePage.ts @@ -261,6 +261,12 @@ export class SchedulePage extends BasePage { await this.waitForPageOrComponentload(); await this.validateProgressBar(ProgressBarPercentages.SchedulePage); + //Looks like an issue with the insurance flow - remove comments once fixed + /*if (testData.isHeavyTruck) { + const vuexState = JSON.parse(await this.page.evaluate('localStorage.getItem(\'vuex\')')); + expect(vuexState.order.lineItems.supportingItems.find((item: any) => item && item.partNumber == "labor2")).toBeTruthy(); + }*/ + if (handleMobileFirstModal) { return await this.handleMobileFirstPopUp(testData); } diff --git a/playwright-tests/tests/0000__M.test.ts b/playwright-tests/tests/0000__M.test.ts index 9eed669b4..6ef799455 100644 --- a/playwright-tests/tests/0000__M.test.ts +++ b/playwright-tests/tests/0000__M.test.ts @@ -40,7 +40,8 @@ import cashReplaceMultiGlassMobileTests from "./CashReplaceMultiGlassMobile"; import { getTestObject, TestCase, prepareTest, RuleEngine, TestInfo } from 'framework/Typedefs'; import { createTestPages } from "framework/TestPages"; import cashReplaceSwitchToInsuranceProgressiveNoCompTests from "./CashReplaceSwitchToInsuranceProgressiveNoComp"; -import insuranceBigTruckVerifiedTests from "./InsuranceBigTruckVerified"; +import insuranceUSAABigTruckVerifiedTests from "./InsuranceUSAABigTruckVerified"; +import partsNotFoundBailoutTests from "./PartsNotFoundBailout"; import insuranceUnverifiedTests from "./InsuranceUnverified"; import CashReplaceSplitWindshieldTests from "./CashReplaceSplitWindshield"; import insuranceMeemicNearSchoolVerifiedTests from "./InsuranceMeemicNearSchoolVerified"; @@ -96,7 +97,7 @@ const allStandardTests = [ // { name: "InsuranceUSAAMsr", tests: insuranceUSAAMsrTests }, { name: "InsuranceITAC21stCentury", tests: insuranceITAC21stCenturyTests }, { name: "InsuranceNoCompProgressive", tests: insuranceNoCompProgressiveTests }, - // {name: "InsuranceBigTruckVerified", tests: insuranceBigTruckVerifiedTests}, + {name: "InsuranceUSAABigTruckVerified", tests: insuranceUSAABigTruckVerifiedTests}, { name: "InsuranceOEMAllstate", tests: insuranceOEMAllstateTests }, { name: "InsuranceUnverified", tests: insuranceUnverifiedTests }, // {name: "InsuranceGeico", tests: insuranceGeicoTests}, @@ -104,6 +105,7 @@ const allStandardTests = [ { name: "InsuranceMeemicNearSchoolVerified", tests: insuranceMeemicNearSchoolVerifiedTests }, { name: "InsuranceLibertyMutual", tests: insuranceLibertyMutualTests }, + // { name: "PartsNotFoundBailout", tests: partsNotFoundBailoutTests }, // code is not available in QA ]; // Alert validation scenarios @@ -277,6 +279,14 @@ async function runWorkflow(page: Page, testCase: TestCase) { await serviceZipPage.handleServiceZipPage(testCase.testData); } + // Handle bailout page if parts bailout scenario + if (testCase.testData.bailoutFlags?.isVehicleLookupBailout) { + let bailoutPage = testCase.pages.bailoutPage; + await bailoutPage.handleBailoutPage(testCase.testData); + let bailoutSuccessPage = testCase.pages.bailoutSuccessPage; + await bailoutSuccessPage.handleBailoutSuccessPage(); + } + // Handle part questions if applicable if (partQuestions && partQuestions.length > 0) { let partQuestionsPage = testCase.pages.partQuestionsPage; diff --git a/playwright-tests/tests/InsuranceBigTruckVerified.ts b/playwright-tests/tests/InsuranceUSAABigTruckVerified.ts similarity index 81% rename from playwright-tests/tests/InsuranceBigTruckVerified.ts rename to playwright-tests/tests/InsuranceUSAABigTruckVerified.ts index 3e616230e..74566a535 100644 --- a/playwright-tests/tests/InsuranceBigTruckVerified.ts +++ b/playwright-tests/tests/InsuranceUSAABigTruckVerified.ts @@ -1,16 +1,16 @@ //Imports here import { ITestData, getDefaultExperimentsData } from 'framework/TestData' -import { ServiceLocation, DamageType, PaymentType, PartQuestionType } from 'safelite-playwright-core'; +import { ServiceLocation, DamageType, Flow} from 'safelite-playwright-core'; import { ITestCase } from '../framework/Typedefs' import { PaymentMethod } from "framework/localTypes/Enums"; import { VehicleLookupType } from 'safelite-playwright-core'; import { getDefaultTestData, setFakerSeedFromTestName } from 'safelite-playwright-core'; // Set the seed based on test name for consistent but unique data -setFakerSeedFromTestName("InsuranceBigTruckVerified"); +setFakerSeedFromTestName("InsuranceUSAABigTruckVerified"); // Now get the test data with the seeded faker -const insuranceBigTruckVerifiedData: Partial = { +const insuranceUSAABigTruckVerifiedData: Partial = { ...getDefaultTestData(), // Get default data with current seed // Key feature: Insurance flow with GEICO @@ -19,6 +19,8 @@ const insuranceBigTruckVerifiedData: Partial = { // Insurance claim flags isDuplicateClaim: true, isPolicyFound: true, + flow: Flow.Managed, + isCanNotRecal: true, isUseVehicleOnPolicy: true, isHeavyTruck: true, @@ -62,7 +64,7 @@ const insuranceBigTruckVerifiedData: Partial = { // Override for in-shop appointment appointmentDetails: { serviceLocation: ServiceLocation.InShop, - shopAddress: '5719 Brandt Pike, Dayton, OH 45424', + shopAddress: '3455 Centerpoint Dr, Urbancrest, OH 43123', appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate }, @@ -75,13 +77,13 @@ const insuranceBigTruckVerifiedData: Partial = { } } -const insuranceBigTruckVerifiedTests: ITestCase[] = []; +const insuranceUSAABigTruckVerifiedTests: ITestCase[] = []; const tc = { - name: `InsuranceBigTruckVerified`, + name: `InsuranceUSAABigTruckVerified`, tags: ['@E2E','@InsuranceBigTruckVerified', '@test_report', '@Insurance'], - testData: insuranceBigTruckVerifiedData + testData: insuranceUSAABigTruckVerifiedData }; -insuranceBigTruckVerifiedTests.push(tc); +insuranceUSAABigTruckVerifiedTests.push(tc); -export default insuranceBigTruckVerifiedTests; \ No newline at end of file +export default insuranceUSAABigTruckVerifiedTests; \ No newline at end of file diff --git a/playwright-tests/tests/PartsNotFoundBailout.ts b/playwright-tests/tests/PartsNotFoundBailout.ts new file mode 100644 index 000000000..1ec10c36c --- /dev/null +++ b/playwright-tests/tests/PartsNotFoundBailout.ts @@ -0,0 +1,52 @@ +import { ITestData, getDefaultExperimentsData } from 'framework/TestData'; +import { VehicleDamage, VehicleLookupType } from 'safelite-playwright-core'; +import { ITestCase } from '../framework/Typedefs'; +import { getDefaultTestData, setFakerSeedFromTestName } from 'safelite-playwright-core'; + +setFakerSeedFromTestName("CashDiamondReoBailout"); + +const partsNotFoundBailoutTestData: Partial = { + ...getDefaultTestData(), + + isHeavyTruck: true, + + customerDetails: { + ...getDefaultTestData().customerDetails!, + address: { + ...getDefaultTestData().customerDetails!.address, + postalCode: '43085' + } + }, + + vehicleDetails: { + ...getDefaultTestData().vehicleDetails!, + year: '1974', + make: 'Diamond Reo', + model: 'CF65', + style: 'cabover', + vehicleLookupType: VehicleLookupType.Zip, + }, + + vehicleDamage: [ + VehicleDamage.WindshieldCrack + ], + + bailoutFlags: { + isVehicleLookupBailout: true + }, + + experiments: { + ...getDefaultExperimentsData() + } +}; + +const partsNotFoundBailoutTests: ITestCase[] = []; + +const tc = { + name: `PartsNotFoundBailout`, + tags: ['@E2E', '@PartsNotFoundBailout', '@test_report', '@Bailout'], + testData: partsNotFoundBailoutTestData +}; +partsNotFoundBailoutTests.push(tc); + +export default partsNotFoundBailoutTests;