Updating 836 with 631

Adds a new environment variable to skip content site checks, improving test environment flexibility.
Improves the "nextPage" function in BasePage to handle loader elements and button states more reliably.
Adds support for selecting loss location in CCPolicyInfoPage to reflect claim details accurately.
Updates assertion methods to use Soft assertions for smoother test execution.
Adds a new test case "InsuranceMeemicNearSchoolVerified" to expand test coverage.
This commit is contained in:
maguire-arman 2025-07-08 14:59:48 -04:00
parent 565d9f473e
commit 92c223487a
7 changed files with 120 additions and 30 deletions

View file

@ -80,6 +80,7 @@ stages:
container_id=$(docker create \ container_id=$(docker create \
--ipc=host \ --ipc=host \
-e "CCIS_API_AUTH=$(CCIS_API_AUTH)" \ -e "CCIS_API_AUTH=$(CCIS_API_AUTH)" \
-e "SKIP_CONTENT_SITE=$(SKIP_CONTENT_SITE)" \
-e "BASE_URL=$(BASE_URL)" \ -e "BASE_URL=$(BASE_URL)" \
-e "CCIS_API_URL=$(CCIS_API_URL)" \ -e "CCIS_API_URL=$(CCIS_API_URL)" \
-e "ADMIN_SERVICE_API_URL=$(ADMIN_SERVICE_API_URL)" \ -e "ADMIN_SERVICE_API_URL=$(ADMIN_SERVICE_API_URL)" \

View file

@ -29,15 +29,18 @@ export class BasePage {
} }
async nextPage() { async nextPage() {
const startingUrl = this.page.url(); await waitUntil(async () => {;
await expect(async () => { return (await this.continueButton.getAttribute('aria-disabled')) !== 'true'
const currentUrl = this.page.url(); });
if (currentUrl === startingUrl) {
await this.continueButton.click({ timeout: 1000 }); await this.continueButton.click();
}
expect(currentUrl).not.toEqual(startingUrl); await waitUntil(async () => {
}).toPass({ timeout: 240_000 }); 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() { async previousPage() {
const startingUrl = this.page.url(); const startingUrl = this.page.url();

View file

@ -16,6 +16,7 @@ export class CCPolicyInfoPage extends InsuranceBasePage {
readonly hasAdditionalDamage: Locator; readonly hasAdditionalDamage: Locator;
readonly isRentalVehicle: Locator; readonly isRentalVehicle: Locator;
readonly isOtherPartyResponsibleForCoverage: Locator; readonly isOtherPartyResponsibleForCoverage: Locator;
readonly lossLocation: Locator;
url = `${process.env['BASE_URL']!}/FixMyGlass/CCPolicyInfo.aspx*`; url = `${process.env['BASE_URL']!}/FixMyGlass/CCPolicyInfo.aspx*`;
@ -32,6 +33,7 @@ export class CCPolicyInfoPage extends InsuranceBasePage {
this.hasAdditionalDamage = page.locator('#HasAdditionalDamage'); this.hasAdditionalDamage = page.locator('#HasAdditionalDamage');
this.isRentalVehicle = page.locator('#IsRentalVehicle'); this.isRentalVehicle = page.locator('#IsRentalVehicle');
this.isOtherPartyResponsibleForCoverage = page.locator('#IsOtherPartyResponsibleForCoverage'); this.isOtherPartyResponsibleForCoverage = page.locator('#IsOtherPartyResponsibleForCoverage');
this.lossLocation = page.locator('#LossLocationType');
} }
async hasCityInfo(): Promise<boolean> { async hasCityInfo(): Promise<boolean> {
@ -67,6 +69,9 @@ export class CCPolicyInfoPage extends InsuranceBasePage {
const stateAbbreviation = this.getStateAbbreviation(customerDetails.address.state); const stateAbbreviation = this.getStateAbbreviation(customerDetails.address.state);
await this.state.selectOption({ value: stateAbbreviation }); await this.state.selectOption({ value: stateAbbreviation });
} }
if (claimDetails.lossLocation) {
await this.lossLocation.selectOption(claimDetails.lossLocation);
}
} catch (error) { } catch (error) {
console.error('Error populating policy info page:', error); console.error('Error populating policy info page:', error);
throw error; throw error;
@ -75,7 +80,7 @@ export class CCPolicyInfoPage extends InsuranceBasePage {
@step("CCPolicyInfoPage >> Fill out claim information") @step("CCPolicyInfoPage >> Fill out claim information")
async handleCCPolicyInfoPage(testData: Partial<ITestData>) { async handleCCPolicyInfoPage(testData: Partial<ITestData>) {
const { customerDetails, claimDetails } = testData; const { customerDetails, claimDetails} = testData;
await this.populatePage(customerDetails!, claimDetails!, await this.hasCityInfo()); await this.populatePage(customerDetails!, claimDetails!, await this.hasCityInfo());
await this.nextPage(); await this.nextPage();

View file

@ -49,7 +49,7 @@ export class OrderConfirmationPage extends BasePage {
isPolicyFound, claimDetails, paymentDetails, isUseVehicleOnPolicy, paymentMethod, isPolicyUnverified } = testData; isPolicyFound, claimDetails, paymentDetails, isUseVehicleOnPolicy, paymentMethod, isPolicyUnverified } = testData;
await this.serviceText.waitFor({ state: "visible" }); 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 // Grab text
const emailTextValue = await this.emailText.textContent(); const emailTextValue = await this.emailText.textContent();
@ -63,15 +63,15 @@ export class OrderConfirmationPage extends BasePage {
const servicePackageAmt = Number.parseFloat(servicePackageValue!.split('$')[1].replaceAll(',', '')); const servicePackageAmt = Number.parseFloat(servicePackageValue!.split('$')[1].replaceAll(',', ''));
// General Validations // General Validations
expect.soft(emailTextValue?.toLowerCase()).toContain(customerDetails!.email); Soft.expect(emailTextValue?.toLowerCase()).toContain(customerDetails!.email);
// Service package validations // Service package validations
await expect.soft(this.cartServicePackageText).toContainText(`${servicePackage}`) await Soft.expect(servicePackageValue).toContain(`${servicePackage}`)
if (servicePackage === ServicePackage.Premium || servicePackage === ServicePackage.Standard) { 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) { if (servicePackage === ServicePackage.Premium) {
expect.soft(servicePackageValue).toContain('Rain Repel Treatment'); Soft.expect(servicePackageValue).toContain('Rain Repel Treatment');
} }
// Promo Code Validation // Promo Code Validation
@ -90,21 +90,21 @@ export class OrderConfirmationPage extends BasePage {
expect.soft(subtotalAmt).toBeGreaterThan(0); Soft.expect(subtotalAmt).toBeGreaterThan(0);
// expect.soft(deductibleAmt).toEqual(0); // Soft.expect(deductibleAmt).toEqual(0);
if ((paymentDetails!.paymentType === PaymentType.PayAtService || isCashInsuranceFlow) && (servicePackageAmt > 0)) { if ((paymentDetails!.paymentType === PaymentType.PayAtService || isCashInsuranceFlow) && (servicePackageAmt > 0)) {
// Verify amount due > 0 // Verify amount due > 0
expect.soft(amountDueAmt).toBeGreaterThan(0); Soft.expect(amountDueAmt).toBeGreaterThan(0);
expect.soft(finalAmountDueAmt).toBeGreaterThan(0); Soft.expect(finalAmountDueAmt).toBeGreaterThan(0);
if (isPolicyUnverified && PaymentType.PayWithInsurance){ if (isPolicyUnverified && PaymentType.PayWithInsurance){
expect.soft(finalAmountDueAmt).toContain('Verifying coverage') Soft.expect(finalAmountDueAmt).toContain('Verifying coverage')
} }
} else { } else {
// Verify amount due 0 // Verify amount due 0
expect.soft(amountDueAmt).toEqual(0); Soft.expect(amountDueAmt).toEqual(0);
expect.soft(finalAmountDueAmt).toEqual(0); Soft.expect(finalAmountDueAmt).toEqual(0);
} }
} }
} }

View file

@ -92,8 +92,14 @@ export class PaymentMethodPage extends BasePage {
// Wait for review table to be visible to ensure page is loaded // Wait for review table to be visible to ensure page is loaded
await this.appointmentDetailsDropdown.waitFor({state: "visible"}); 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<string, string[]>(); let expectedAppointmentDetails = new Map<string, string[]>();
expectedAppointmentDetails = await this.getExpectedVehicleDetails(testData, expectedAppointmentDetails); expectedAppointmentDetails = await this.getExpectedVehicleDetails(testData, expectedAppointmentDetails);
expectedAppointmentDetails = await this.getExpectedVehicleDamage(testData, expectedAppointmentDetails); expectedAppointmentDetails = await this.getExpectedVehicleDamage(testData, expectedAppointmentDetails);
@ -105,7 +111,7 @@ export class PaymentMethodPage extends BasePage {
let actualAppointmentDetails = await this.getActualAppointmentDetails(); let actualAppointmentDetails = await this.getActualAppointmentDetails();
for (const key in expectedAppointmentDetails) { 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())); .toEqual(expectedAppointmentDetails[key].map(item => item.toLowerCase()));
} }
@ -126,11 +132,11 @@ export class PaymentMethodPage extends BasePage {
const finalAmountDueAmount = this.extractAmount(finalAmountDueValue); const finalAmountDueAmount = this.extractAmount(finalAmountDueValue);
// Subtotal should be greater than 0 // Subtotal should be greater than 0
expect.soft(subtotalAmount).toBeGreaterThan(0); Soft.expect(subtotalAmount).toBeGreaterThan(0);
// Final amount differs based on payment type // Final amount differs based on payment type
if (paymentDetails?.paymentType === PaymentType.PayAtService) { if (paymentDetails?.paymentType === PaymentType.PayAtService) {
expect.soft(finalAmountDueAmount).toBeGreaterThan(0); Soft.expect(finalAmountDueAmount).toBeGreaterThan(0);
} else if (paymentDetails?.paymentType === PaymentType.Credit || } else if (paymentDetails?.paymentType === PaymentType.Credit ||
paymentDetails?.paymentType === PaymentType.Paypal || paymentDetails?.paymentType === PaymentType.Paypal ||
paymentDetails?.paymentType === PaymentType.AfterPay) { paymentDetails?.paymentType === PaymentType.AfterPay) {
@ -144,12 +150,12 @@ export class PaymentMethodPage extends BasePage {
// Service package validations // Service package validations
const servicePackageValue = await this.cartPanelDetails.textContent(); 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) { 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) { if (servicePackage === ServicePackage.Premium) {
expect.soft(servicePackageValue).toContain('Rain Repel Treatment'); Soft.expect(servicePackageValue).toContain('Rain Repel Treatment');
} }
// Promo Code Validation // Promo Code Validation
@ -160,7 +166,7 @@ export class PaymentMethodPage extends BasePage {
// Early Bird line item validation // Early Bird line item validation
if (appointmentDetails?.appointmentTimeSlot == AppointmentTimeslot.EarlyBird) { if (appointmentDetails?.appointmentTimeSlot == AppointmentTimeslot.EarlyBird) {
expect.soft(servicePackageValue).toContain('Early bird'); Soft.expect(servicePackageValue).toContain('Early bird');
} }
} }
} }

View file

@ -38,6 +38,7 @@ import cashReplaceSwitchToInsuranceProgressiveNoCompTests from "./CashReplaceSwi
import insuranceBigTruckVerifiedTests from "./InsuranceBigTruckVerified"; import insuranceBigTruckVerifiedTests from "./InsuranceBigTruckVerified";
import insuranceUnverifiedTests from "./InsuranceUnverified"; import insuranceUnverifiedTests from "./InsuranceUnverified";
import CashReplaceSplitWindshieldTests from "./CashReplaceSplitWindshield"; import CashReplaceSplitWindshieldTests from "./CashReplaceSplitWindshield";
import insuranceMeemicNearSchoolVerifiedTests from "./InsuranceMeemicNearSchoolVerified";
const test = getTestObject(); const test = getTestObject();
@ -84,6 +85,7 @@ const allStandardTests = [
{name: "InsuranceUnverified", tests: insuranceUnverifiedTests}, {name: "InsuranceUnverified", tests: insuranceUnverifiedTests},
// {name: "InsuranceGeico", tests: insuranceGeicoTests}, // {name: "InsuranceGeico", tests: insuranceGeicoTests},
// {name: "InsuranceITACOptimizedPriceValidationAllState", tests: insuranceITACOptimizedPriceValidationAllStateTests} // {name: "InsuranceITACOptimizedPriceValidationAllState", tests: insuranceITACOptimizedPriceValidationAllStateTests}
{name: "InsuranceMeemicNearSchoolVerified", tests: insuranceMeemicNearSchoolVerifiedTests},
]; ];

View file

@ -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<ITestData> = {
...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;