Fixed playwright tests

This commit is contained in:
kpatel8hs4io 2025-07-23 22:17:59 -04:00
parent be3d7fd7c4
commit b6b8d739f7
8 changed files with 48 additions and 40 deletions

View file

@ -28,7 +28,7 @@ export class AfterpayPage extends BasePage {
this.expirationDateTextBox = page.getByTestId('payment-method-cardExpiry-input');
this.cvvTextBox = page.getByTestId('payment-method-cardCvv-input');
this.confirmButton = page.getByRole('button', { name: 'Confirm' });
this.confirmButton = page.getByRole('button').filter({hasText: 'Confirm'});
}
async login(password: string) {
@ -47,7 +47,7 @@ export class AfterpayPage extends BasePage {
async executeAfterpayPayment(paymentDetails: IPaymentDetails) {
await this.login(paymentDetails.password!);
await this.populateCardDetails(paymentDetails);
//await this.populateCardDetails(paymentDetails);
await this.confirmButton.click();
}

View file

@ -103,32 +103,31 @@ export class BasePage {
}
async mockScheduleResponseForEarlyBird(customerDetails: ICustomerDetails) {
{
const apiUrl = `https://digitalapi.${process.env['NODE_ENV']!.replace('sys', 'test').toLowerCase()}.safelite.io/schedule/api/v1/schedule/mobile-time-slots`;
await this.page.route(apiUrl, async (route) => {
const response = await route.fetch();
const responseBody = await response.json();
const currentDate = new Date().toISOString().split('T')[0]; // e.g., "2025-07-23"
if(route.request().postDataJSON().startDate === currentDate) {
const response = await route.fetch();
const responseBody = await response.json();
responseBody.days.forEach((day: any) => {
day.timeSlots.forEach((slot: any) => {
if (slot.id.includes("AM")) {
slot.offerPremium = true;
}
responseBody.days.forEach((day: any) => {
day.timeSlots.forEach((slot: any) => {
if (slot.id.includes("AM")) {
slot.offerPremium = true;
}
});
});
});
customerDetails.apptDate = responseBody.days.find((day: any) =>
day.timeSlots.some((slot: any) => slot.offerPremium === true)
).date || undefined;
customerDetails.apptDate = responseBody.days.find((day: any) => day.timeSlots.some((slot: any) => slot.offerPremium === true)).date || undefined;
// Mock the response
await route.fulfill({
response,
body: JSON.stringify(responseBody),
});
});
}
// Mock the response
await route.fulfill({
response,
body: JSON.stringify(responseBody),
});
}
});
}
async validateProgressBar(progressPercentage: string, timeout: number = 60000) {

View file

@ -56,7 +56,7 @@ export class CoverageStatementPage extends InsuranceBasePage {
if (await unverifiedDeductibleElement.isVisible() || await this.noCompText.isVisible()) {
// Click on continue button if unverified header is visible
await this.continueButton.click();
// await this.continueButton.click();
}
}

View file

@ -206,7 +206,7 @@ export class PaymentMethodPage extends BasePage {
break;
case PaymentType.AfterPay:
await this.payInFourButton.click();
await this.nextPage();
await this.continueButton.click();
// Capture popup
const afterpayPopup = await browserContext.waitForEvent('page');

View file

@ -121,6 +121,8 @@ export class SchedulePage extends BasePage {
async scheduleFirstAppointment(testData: Partial<ITestData>) {
const { appointmentDetails, customerDetails } = testData;
// await this.page.waitForTimeout(1000);
await this.page.waitForSelector('.date-picker', { state: 'visible' });
while (!(await this.firstAvailableDate.isVisible())) {
if (appointmentDetails?.appointmentTimeSlot === AppointmentTimeslot.EarlyBird) {
@ -139,25 +141,27 @@ export class SchedulePage extends BasePage {
}
break;
case ServiceLocation.DropOff:
const inshopAvailableSlots = this.page.locator('.selectable-day').filter({ visible: true}).all();
for (const inshopAvailableSlot of await inshopAvailableSlots) {
const inshopAvailableDates = this.page.locator('.selectable-day').filter({ visible: true}).all();
for (const inshopAvailableDate of await inshopAvailableDates) {
await inshopAvailableDate.click();
if (await this.allDayDropOffButton.isVisible()) {
await inshopAvailableSlot.click().then(async () => {
customerDetails!.apptDate = `${await inshopAvailableSlot.getAttribute("id")}`
});
customerDetails!.apptDate = `${await inshopAvailableDate.getAttribute("id")}`;
break;
}
}
break;
case ServiceLocation.Mobile:
await this.firstAvailableDate.click().then(async () => {
if (appointmentDetails?.appointmentTimeSlot === AppointmentTimeslot.EarlyBird) {
await this.page.locator(`.selectable-days, [id='${customerDetails?.apptDate}-mobile']`).click();
} else {
await this.firstAvailableDate.click().then(async () => {
customerDetails!.apptDate = `${await this.firstAvailableDate.getAttribute("id")}`.replace("-mobile", "");
});
});
}
break;
}
if (appointmentDetails?.appointmentTimeSlot == AppointmentTimeslot.EarlyBird) {
await this.page.locator(`.selectable-days, [id='${customerDetails?.apptDate}']`).click();
const earlyBirdTimeSlot = this.timeSlots.filter({ hasText: "Earlybird" }).first();
await earlyBirdTimeSlot.click().then(async () => {
customerDetails!.apptTime = await this.getFormattedTimeSlot(earlyBirdTimeSlot);

View file

@ -1,6 +1,6 @@
import { expect, type Locator, type Page } from '@playwright/test';
import { BasePage } from './BasePage';
import { ServicePackage, VehicleDamage } from 'safelite-playwright-core';
import { AppointmentTimeslot, ServicePackage, VehicleDamage } from 'safelite-playwright-core';
import { ProgressBarPercentages } from 'framework/localTypes/Enums';
import { PaymentMethod } from "framework/localTypes/Enums";
import { step } from 'framework/localTypes/Step';
@ -189,7 +189,7 @@ export class ServicePackagesPage extends BasePage {
@step("ServicePackagePage >> Select Payment Method and Service Type: ")
async handleServicePackagePage(testData: Partial<ITestData>) {
const { customerDetails, paymentMethod, paymentDetails, servicePackage, isCanNotRecal, isDynamicRecal, hasOemEndorsement, vehicleDamage } = testData;
const { customerDetails, paymentMethod, paymentDetails, servicePackage, isCanNotRecal, isDynamicRecal, hasOemEndorsement, vehicleDamage, appointmentDetails } = testData;
await this.validateProgressBar(ProgressBarPercentages.ServicePackagePage);
// Define repair damage types (vs. replacement types)
@ -235,6 +235,10 @@ export class ServicePackagesPage extends BasePage {
if (hasOemEndorsement) {
await this.verifyOEMPart();
}
if (appointmentDetails?.appointmentTimeSlot === AppointmentTimeslot.EarlyBird) {
await this.mockScheduleResponseForEarlyBird(customerDetails!);
}
await this.nextPage();
}

View file

@ -381,12 +381,14 @@ export async function handleInsuranceFlow(testCase: TestCase) {
// Handle scenario where user selected Cash to Insurance and needs to go back through the flow
// right now we are choosing pay at appointment as payment method for this scenario
if (isCashInsuranceFlow) {
let serviceLocationPage = testCase.pages.serviceLocationPage;
await serviceLocationPage.nextPage();
//schedule
// Schedule appointment
let schedulePage = testCase.pages.schedulePage;
await schedulePage.nextPage();
await schedulePage.handleSchedulePage(testCase.testData);
if (testCase.testData.appointmentDetails?.serviceLocation === ServiceLocation.Mobile) {
let mobileDetailsPage = testCase.pages.mobileDetailsPage;
await mobileDetailsPage.handleMobileDetailsPage(testCase.testData);
}
//customer dertails
let contactDetailsPage = testCase.pages.contactDetailsPage;
await contactDetailsPage.nextPage();

View file

@ -31,7 +31,6 @@ const cashRepairInShopAfterPayData : Partial<ITestData> = {
// Override appointment details
appointmentDetails: {
...getDefaultTestData().appointmentDetails!,
shopAddress: "6826 Sawmill Rd, Columbus, OH 43235"
},
// Use predefined payment data