diff --git a/azure-pipelines-automated-testing.yml b/azure-pipelines-automated-testing.yml index 2d9c19d74..c38f6e7ed 100644 --- a/azure-pipelines-automated-testing.yml +++ b/azure-pipelines-automated-testing.yml @@ -80,6 +80,7 @@ stages: container_id=$(docker create \ --ipc=host \ -e "CCIS_API_AUTH=$(CCIS_API_AUTH)" \ + -e "SKIP_CONTENT_SITE=$(SKIP_CONTENT_SITE)" \ -e "BASE_URL=$(BASE_URL)" \ -e "CCIS_API_URL=$(CCIS_API_URL)" \ -e "ADMIN_SERVICE_API_URL=$(ADMIN_SERVICE_API_URL)" \ diff --git a/playwright-tests/pages/BasePage.ts b/playwright-tests/pages/BasePage.ts index 354e67ef4..5ea7f4c4c 100644 --- a/playwright-tests/pages/BasePage.ts +++ b/playwright-tests/pages/BasePage.ts @@ -29,15 +29,18 @@ export class BasePage { } async nextPage() { - const startingUrl = this.page.url(); - await expect(async () => { - const currentUrl = this.page.url(); - if (currentUrl === startingUrl) { - await this.continueButton.click({ timeout: 1000 }); - } - expect(currentUrl).not.toEqual(startingUrl); - }).toPass({ timeout: 240_000 }); + await waitUntil(async () => {; + return (await this.continueButton.getAttribute('aria-disabled')) !== 'true' + }); + + await this.continueButton.click(); + + await waitUntil(async () => { + let loaderElements = await this.page.locator('button .loader, .buy-loader, timeout, .modal-loader').all(); + return !(await Promise.any(loaderElements.map(el => el.isVisible())).catch(() => false)); + }); } + async previousPage() { const startingUrl = this.page.url(); diff --git a/playwright-tests/pages/CCPolicyInfoPage.ts b/playwright-tests/pages/CCPolicyInfoPage.ts index 22e2372d1..cac55a01c 100644 --- a/playwright-tests/pages/CCPolicyInfoPage.ts +++ b/playwright-tests/pages/CCPolicyInfoPage.ts @@ -16,6 +16,7 @@ export class CCPolicyInfoPage extends InsuranceBasePage { readonly hasAdditionalDamage: Locator; readonly isRentalVehicle: Locator; readonly isOtherPartyResponsibleForCoverage: Locator; + readonly lossLocation: Locator; url = `${process.env['BASE_URL']!}/FixMyGlass/CCPolicyInfo.aspx*`; @@ -32,6 +33,7 @@ export class CCPolicyInfoPage extends InsuranceBasePage { this.hasAdditionalDamage = page.locator('#HasAdditionalDamage'); this.isRentalVehicle = page.locator('#IsRentalVehicle'); this.isOtherPartyResponsibleForCoverage = page.locator('#IsOtherPartyResponsibleForCoverage'); + this.lossLocation = page.locator('#LossLocationType'); } async hasCityInfo(): Promise { @@ -67,6 +69,9 @@ export class CCPolicyInfoPage extends InsuranceBasePage { const stateAbbreviation = this.getStateAbbreviation(customerDetails.address.state); await this.state.selectOption({ value: stateAbbreviation }); } + if (claimDetails.lossLocation) { + await this.lossLocation.selectOption(claimDetails.lossLocation); + } } catch (error) { console.error('Error populating policy info page:', error); throw error; @@ -75,7 +80,7 @@ export class CCPolicyInfoPage extends InsuranceBasePage { @step("CCPolicyInfoPage >> Fill out claim information") async handleCCPolicyInfoPage(testData: Partial) { - const { customerDetails, claimDetails } = testData; + const { customerDetails, claimDetails} = testData; await this.populatePage(customerDetails!, claimDetails!, await this.hasCityInfo()); await this.nextPage(); diff --git a/playwright-tests/pages/OrderConfirmationPage.ts b/playwright-tests/pages/OrderConfirmationPage.ts index ca83b0f76..1b7f11daa 100644 --- a/playwright-tests/pages/OrderConfirmationPage.ts +++ b/playwright-tests/pages/OrderConfirmationPage.ts @@ -49,7 +49,7 @@ export class OrderConfirmationPage extends BasePage { isPolicyFound, claimDetails, paymentDetails, isUseVehicleOnPolicy, paymentMethod, isPolicyUnverified } = testData; await this.serviceText.waitFor({ state: "visible" }); - expect.soft((await this.getActualAppointmentSummary()).map(item => item.toLowerCase())).toEqual((await this.getExpectedAppointmentSummary(testData)).map(item => item.toLowerCase())); + Soft.expect((await this.getActualAppointmentSummary()).map(item => item.toLowerCase())).toEqual((await this.getExpectedAppointmentSummary(testData)).map(item => item.toLowerCase())); // Grab text const emailTextValue = await this.emailText.textContent(); @@ -63,15 +63,15 @@ export class OrderConfirmationPage extends BasePage { const servicePackageAmt = Number.parseFloat(servicePackageValue!.split('$')[1].replaceAll(',', '')); // General Validations - expect.soft(emailTextValue?.toLowerCase()).toContain(customerDetails!.email); + Soft.expect(emailTextValue?.toLowerCase()).toContain(customerDetails!.email); // Service package validations - await expect.soft(this.cartServicePackageText).toContainText(`${servicePackage}`) + await Soft.expect(servicePackageValue).toContain(`${servicePackage}`) if (servicePackage === ServicePackage.Premium || servicePackage === ServicePackage.Standard) { - expect.soft(servicePackageValue).toContain('New wiper blades'); + Soft.expect(servicePackageValue).toContain('New wiper blades'); } if (servicePackage === ServicePackage.Premium) { - expect.soft(servicePackageValue).toContain('Rain Repel Treatment'); + Soft.expect(servicePackageValue).toContain('Rain Repel Treatment'); } // Promo Code Validation @@ -90,21 +90,21 @@ export class OrderConfirmationPage extends BasePage { - expect.soft(subtotalAmt).toBeGreaterThan(0); - // expect.soft(deductibleAmt).toEqual(0); + Soft.expect(subtotalAmt).toBeGreaterThan(0); + // Soft.expect(deductibleAmt).toEqual(0); if ((paymentDetails!.paymentType === PaymentType.PayAtService || isCashInsuranceFlow) && (servicePackageAmt > 0)) { // Verify amount due > 0 - expect.soft(amountDueAmt).toBeGreaterThan(0); - expect.soft(finalAmountDueAmt).toBeGreaterThan(0); + Soft.expect(amountDueAmt).toBeGreaterThan(0); + Soft.expect(finalAmountDueAmt).toBeGreaterThan(0); if (isPolicyUnverified && PaymentType.PayWithInsurance){ - expect.soft(finalAmountDueAmt).toContain('Verifying coverage') + Soft.expect(finalAmountDueAmt).toContain('Verifying coverage') } } else { // Verify amount due 0 - expect.soft(amountDueAmt).toEqual(0); - expect.soft(finalAmountDueAmt).toEqual(0); + Soft.expect(amountDueAmt).toEqual(0); + Soft.expect(finalAmountDueAmt).toEqual(0); } } } diff --git a/playwright-tests/pages/PaymentMethodPage.ts b/playwright-tests/pages/PaymentMethodPage.ts index 0ac24500b..106c760fc 100644 --- a/playwright-tests/pages/PaymentMethodPage.ts +++ b/playwright-tests/pages/PaymentMethodPage.ts @@ -92,8 +92,14 @@ export class PaymentMethodPage extends BasePage { // Wait for review table to be visible to ensure page is loaded await this.appointmentDetailsDropdown.waitFor({state: "visible"}); - await this.appointmentDetailsDropdown.click(); - + await this.appointmentDetailsDropdown.click().then( + async () => { + await waitUntil(async () => { + return (await this.page.locator('.review-toggle.expanded').evaluate(el => window.getComputedStyle(el, ':after').transform)) === 'matrix(-1, 0, 0, -1, 0, 0)'; + }); + } + ); + let expectedAppointmentDetails = new Map(); expectedAppointmentDetails = await this.getExpectedVehicleDetails(testData, expectedAppointmentDetails); expectedAppointmentDetails = await this.getExpectedVehicleDamage(testData, expectedAppointmentDetails); @@ -105,7 +111,7 @@ export class PaymentMethodPage extends BasePage { let actualAppointmentDetails = await this.getActualAppointmentDetails(); for (const key in expectedAppointmentDetails) { - expect.soft(actualAppointmentDetails[key]?.map(item => item.toLowerCase())) + Soft.expect(actualAppointmentDetails[key]?.map(item => item.toLowerCase())) .toEqual(expectedAppointmentDetails[key].map(item => item.toLowerCase())); } @@ -126,11 +132,11 @@ export class PaymentMethodPage extends BasePage { const finalAmountDueAmount = this.extractAmount(finalAmountDueValue); // Subtotal should be greater than 0 - expect.soft(subtotalAmount).toBeGreaterThan(0); + Soft.expect(subtotalAmount).toBeGreaterThan(0); // Final amount differs based on payment type if (paymentDetails?.paymentType === PaymentType.PayAtService) { - expect.soft(finalAmountDueAmount).toBeGreaterThan(0); + Soft.expect(finalAmountDueAmount).toBeGreaterThan(0); } else if (paymentDetails?.paymentType === PaymentType.Credit || paymentDetails?.paymentType === PaymentType.Paypal || paymentDetails?.paymentType === PaymentType.AfterPay) { @@ -144,12 +150,12 @@ export class PaymentMethodPage extends BasePage { // Service package validations const servicePackageValue = await this.cartPanelDetails.textContent(); - await expect.soft(this.cartPanelDetails).toContainText(`${servicePackage}`) + await Soft.expect(servicePackageValue).toContain(`${servicePackage}`) if (servicePackage === ServicePackage.Premium || servicePackage === ServicePackage.Standard) { - expect.soft(servicePackageValue).toContain('New wiper blades'); + Soft.expect(servicePackageValue).toContain('New wiper blades'); } if (servicePackage === ServicePackage.Premium) { - expect.soft(servicePackageValue).toContain('Rain Repel Treatment'); + Soft.expect(servicePackageValue).toContain('Rain Repel Treatment'); } // Promo Code Validation @@ -160,7 +166,7 @@ export class PaymentMethodPage extends BasePage { // Early Bird line item validation if (appointmentDetails?.appointmentTimeSlot == AppointmentTimeslot.EarlyBird) { - expect.soft(servicePackageValue).toContain('Early bird'); + Soft.expect(servicePackageValue).toContain('Early bird'); } } } diff --git a/playwright-tests/tests/0000__M.test.ts b/playwright-tests/tests/0000__M.test.ts index 9179bb1df..495a202e6 100644 --- a/playwright-tests/tests/0000__M.test.ts +++ b/playwright-tests/tests/0000__M.test.ts @@ -38,6 +38,7 @@ import cashReplaceSwitchToInsuranceProgressiveNoCompTests from "./CashReplaceSwi import insuranceBigTruckVerifiedTests from "./InsuranceBigTruckVerified"; import insuranceUnverifiedTests from "./InsuranceUnverified"; import CashReplaceSplitWindshieldTests from "./CashReplaceSplitWindshield"; +import insuranceMeemicNearSchoolVerifiedTests from "./InsuranceMeemicNearSchoolVerified"; const test = getTestObject(); @@ -84,6 +85,7 @@ const allStandardTests = [ {name: "InsuranceUnverified", tests: insuranceUnverifiedTests}, // {name: "InsuranceGeico", tests: insuranceGeicoTests}, // {name: "InsuranceITACOptimizedPriceValidationAllState", tests: insuranceITACOptimizedPriceValidationAllStateTests} + {name: "InsuranceMeemicNearSchoolVerified", tests: insuranceMeemicNearSchoolVerifiedTests}, ]; diff --git a/playwright-tests/tests/InsuranceMeemicNearSchoolVerified.ts b/playwright-tests/tests/InsuranceMeemicNearSchoolVerified.ts new file mode 100644 index 000000000..7cde375cd --- /dev/null +++ b/playwright-tests/tests/InsuranceMeemicNearSchoolVerified.ts @@ -0,0 +1,73 @@ +//Imports here +import { ITestData } from 'framework/TestData' +import { ServiceLocation, DamageType, Flow, PartQuestionType } from 'safelite-playwright-core'; +import { PaymentMethod } from "framework/localTypes/Enums"; +import { ITestCase } from '../framework/Typedefs' +import { VehicleLookupType } from 'safelite-playwright-core'; +import { getDefaultTestData, setFakerSeedFromTestName } from 'safelite-playwright-core'; + +// Seed for consistent test data generation +setFakerSeedFromTestName("InsuranceMeemicNearSchoolVerified"); + +// Now get the test data with the seeded faker +const insuranceMeemicNearSchoolVerifiedData: Partial = { + ...getDefaultTestData(), + + paymentMethod: PaymentMethod.Insurance, + + isDuplicateClaim: false, + isPolicyFound: true, + isUseVehicleOnPolicy: true, + isRecalVehicle: false, + + customerDetails: { + ...getDefaultTestData().customerDetails!, + address: { + ...getDefaultTestData().customerDetails!.address, + postalCode: '48382' + } + }, + + claimDetails: { + client: 'Meemic', + policyNumber: 'Mock427352LD', + policyDeductible: 0, + damageDate: new Date().toLocaleDateString('en-US', {month: '2-digit', day: '2-digit', year: 'numeric'}), + damageCause: DamageType.Rock, + lossLocation: LossLocation.School + }, + + vehicleDetails: { + ...getDefaultTestData().vehicleDetails!, + year: '2015', + make: 'Jeep', + model: 'Wrangler', + style: '4 door utility', + vehicleLookupType: VehicleLookupType.Zip, + }, + + appointmentDetails: { + serviceLocation: ServiceLocation.InShop, + appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate, + shopAddress: "3451 Washtenaw Ave, Ann Arbor, MI 48104" + }, + + partQuestions: [ + { + partQuestionType: PartQuestionType.GeneralQuestion1, + isOnPage: true, + optionToSelect: 'No' + }, + ] +}; + +const insuranceMeemicNearSchoolVerifiedTests: ITestCase[] = []; + +const tc = { + name: `InsuranceMeemicNearSchoolVerified`, + tags: ['@E2E', '@InsuranceMeemicNearSchool', '@test_report', '@Insurance'], + testData: insuranceMeemicNearSchoolVerifiedData +}; +insuranceMeemicNearSchoolVerifiedTests.push(tc); + +export default insuranceMeemicNearSchoolVerifiedTests; \ No newline at end of file