fix for playwright tests
This commit is contained in:
parent
e8f6c34385
commit
3b065579e1
8 changed files with 41 additions and 45 deletions
|
|
@ -10,6 +10,8 @@ export class AfterpayPage extends BasePage {
|
||||||
readonly passwordTextBox: Locator;
|
readonly passwordTextBox: Locator;
|
||||||
|
|
||||||
// Card details
|
// Card details
|
||||||
|
readonly paymentOptionsButton: Locator;
|
||||||
|
readonly continueButtonAfterpay: Locator;
|
||||||
readonly cardholderNameTextBox: Locator;
|
readonly cardholderNameTextBox: Locator;
|
||||||
readonly cardNumberTextBox: Locator;
|
readonly cardNumberTextBox: Locator;
|
||||||
readonly expirationDateTextBox: Locator;
|
readonly expirationDateTextBox: Locator;
|
||||||
|
|
@ -23,6 +25,8 @@ export class AfterpayPage extends BasePage {
|
||||||
this.passwordTextBox = page.getByTestId('login-password-input');
|
this.passwordTextBox = page.getByTestId('login-password-input');
|
||||||
this.submitButton = page.getByRole('button', { name: 'Continue' });
|
this.submitButton = page.getByRole('button', { name: 'Continue' });
|
||||||
|
|
||||||
|
this.paymentOptionsButton = page.locator('div:has(>input[id*=\'payment-types\']) label').nth(1);
|
||||||
|
this.continueButtonAfterpay = page.getByRole('button').filter({hasText: 'Continue'});
|
||||||
this.cardholderNameTextBox = page.getByTestId('payment-method-cardHolderName-input');
|
this.cardholderNameTextBox = page.getByTestId('payment-method-cardHolderName-input');
|
||||||
this.cardNumberTextBox = page.getByTestId('payment-method-cardNumber-input');
|
this.cardNumberTextBox = page.getByTestId('payment-method-cardNumber-input');
|
||||||
this.expirationDateTextBox = page.getByTestId('payment-method-cardExpiry-input');
|
this.expirationDateTextBox = page.getByTestId('payment-method-cardExpiry-input');
|
||||||
|
|
@ -46,7 +50,12 @@ export class AfterpayPage extends BasePage {
|
||||||
|
|
||||||
async executeAfterpayPayment(paymentDetails: IPaymentDetails) {
|
async executeAfterpayPayment(paymentDetails: IPaymentDetails) {
|
||||||
await this.login(paymentDetails.password!);
|
await this.login(paymentDetails.password!);
|
||||||
|
await this.page.locator('div[data-testid=\'loading-icon-svg\']').filter({ visible: true}).first().waitFor({ state: 'hidden' });
|
||||||
|
if (await this.paymentOptionsButton.isVisible())
|
||||||
|
{
|
||||||
|
await this.paymentOptionsButton.click();
|
||||||
|
await this.continueButtonAfterpay.click();
|
||||||
|
}
|
||||||
await this.confirmButton.click();
|
await this.confirmButton.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ export class PaymentMethodPage extends BasePage {
|
||||||
this.payNowButton = this.page.locator('[buttonlabel="Pay now"]');
|
this.payNowButton = this.page.locator('[buttonlabel="Pay now"]');
|
||||||
this.payInFourButton = this.page.locator('[buttonlabel="Pay in 4 installments"]');
|
this.payInFourButton = this.page.locator('[buttonlabel="Pay in 4 installments"]');
|
||||||
this.submitButton = this.page.locator('[data-test-id="nav-bar-main-button"]');
|
this.submitButton = this.page.locator('[data-test-id="nav-bar-main-button"]');
|
||||||
this.recalibrationCheckbox = this.page.getByLabel('I understand after windshield');
|
this.recalibrationCheckbox = this.page.locator('label:has(>input[name=\'recalAckOptIn\'])');
|
||||||
// this.creditCardButton = page.locator('div').filter({ hasText: /^Credit or Debit$/ }).nth(1);
|
// this.creditCardButton = page.locator('div').filter({ hasText: /^Credit or Debit$/ }).nth(1);
|
||||||
this.paymentPage = new PaymentPage(page);
|
this.paymentPage = new PaymentPage(page);
|
||||||
this.paypalPage = new PaypalPage(page);
|
this.paypalPage = new PaypalPage(page);
|
||||||
|
|
@ -101,7 +101,7 @@ export class PaymentMethodPage extends BasePage {
|
||||||
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);
|
||||||
expectedAppointmentDetails = await this.expectedServicePackageDetails(testData, expectedAppointmentDetails);
|
// expectedAppointmentDetails = await this.expectedServicePackageDetails(testData, expectedAppointmentDetails);
|
||||||
expectedAppointmentDetails = await this.getExpectedServiceLocation(testData, expectedAppointmentDetails);
|
expectedAppointmentDetails = await this.getExpectedServiceLocation(testData, expectedAppointmentDetails);
|
||||||
expectedAppointmentDetails = await this.getExpectedAppointmentDate(testData, expectedAppointmentDetails);
|
expectedAppointmentDetails = await this.getExpectedAppointmentDate(testData, expectedAppointmentDetails);
|
||||||
expectedAppointmentDetails = await this.getExpectedCustomerDetails(testData, expectedAppointmentDetails);
|
expectedAppointmentDetails = await this.getExpectedCustomerDetails(testData, expectedAppointmentDetails);
|
||||||
|
|
@ -403,7 +403,7 @@ l
|
||||||
const { appointmentDetails } = testData;
|
const { appointmentDetails } = testData;
|
||||||
let serviceLocationTitle = appointmentDetails?.serviceLocation == ServiceLocation.Mobile
|
let serviceLocationTitle = appointmentDetails?.serviceLocation == ServiceLocation.Mobile
|
||||||
? "We're coming to you"
|
? "We're coming to you"
|
||||||
: "You're going to a Safelite shop";
|
: "You're coming to us";
|
||||||
let serviceLocation: string[] = [];
|
let serviceLocation: string[] = [];
|
||||||
|
|
||||||
serviceLocation.push(
|
serviceLocation.push(
|
||||||
|
|
@ -443,7 +443,7 @@ l
|
||||||
customerDetails?.apptDuration ? "Estimated appointment length: " + customerDetails.apptDuration : ""
|
customerDetails?.apptDuration ? "Estimated appointment length: " + customerDetails.apptDuration : ""
|
||||||
);
|
);
|
||||||
|
|
||||||
expectedServicePackageDetails["Appointment date + time"] = appointmentDateText;
|
expectedServicePackageDetails["Appointment Date + Time"] = appointmentDateText;
|
||||||
return expectedServicePackageDetails;
|
return expectedServicePackageDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -452,7 +452,7 @@ l
|
||||||
let customerDetailsText: string[] = [];
|
let customerDetailsText: string[] = [];
|
||||||
|
|
||||||
customerDetailsText.push(
|
customerDetailsText.push(
|
||||||
customerDetails?.firstName.toUpperCase() + " " + customerDetails?.lastName.toUpperCase(),
|
// customerDetails?.firstName.toUpperCase() + " " + customerDetails?.lastName.toUpperCase(),
|
||||||
customerDetails?.email ? customerDetails?.email.toUpperCase() : "",
|
customerDetails?.email ? customerDetails?.email.toUpperCase() : "",
|
||||||
customerDetails?.phoneNumber ? customerDetails?.phoneNumber : "",
|
customerDetails?.phoneNumber ? customerDetails?.phoneNumber : "",
|
||||||
"Opted out of text message updates"
|
"Opted out of text message updates"
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ export class PaypalPage extends BasePage {
|
||||||
this.passwordTextBox = page.getByPlaceholder('Password');
|
this.passwordTextBox = page.getByPlaceholder('Password');
|
||||||
this.paypalLoginButton = page.getByRole('button', { name: 'Log In', exact: true });
|
this.paypalLoginButton = page.getByRole('button', { name: 'Log In', exact: true });
|
||||||
this.completePurchaseButton = page.getByTestId('submit-button-initial')
|
this.completePurchaseButton = page.getByTestId('submit-button-initial')
|
||||||
this.payWithRadioButton = page.locator('.py-4').first();
|
this.payWithRadioButton = page.getByRole('button').filter({ hasText: 'Pay with' });
|
||||||
this.payButton = page.getByRole('button', { name: 'Pay $' });
|
this.payButton = page.locator('#one-time-cta');
|
||||||
}
|
}
|
||||||
|
|
||||||
async completePaypalPurchase(paymentDetails: IPaymentDetails){
|
async completePaypalPurchase(paymentDetails: IPaymentDetails){
|
||||||
|
|
@ -45,7 +45,8 @@ export class PaypalPage extends BasePage {
|
||||||
await this.passwordTextBox.fill(paymentDetails.password!);
|
await this.passwordTextBox.fill(paymentDetails.password!);
|
||||||
await this.paypalLoginButton.click();
|
await this.paypalLoginButton.click();
|
||||||
await this.payWithRadioButton.click();
|
await this.payWithRadioButton.click();
|
||||||
await this.payButton.click();
|
await this.page.waitForTimeout(2000); // wait for 2 seconds to ensure the Pay button is clickable
|
||||||
|
await this.payButton.dblclick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ export class SchedulePage extends BasePage {
|
||||||
this.selectAShopOptions = this.page.locator('[class="shop-question"]');
|
this.selectAShopOptions = this.page.locator('[class="shop-question"]');
|
||||||
this.yourSafeliteShop = this.page.locator("fieldset:has(#chooseShop) label");
|
this.yourSafeliteShop = this.page.locator("fieldset:has(#chooseShop) label");
|
||||||
|
|
||||||
this.allDayDropOffButton = this.page.locator("label[buttonlabel='Drop off all day']");
|
this.allDayDropOffButton = this.page.locator("label[buttonlabel*='Drop']");
|
||||||
this.pickATimeButton = this.page.locator("label[buttonlabel='Pick a time']");
|
this.pickATimeButton = this.page.locator("label[buttonlabel='Pick a time']");
|
||||||
this.firstAvailableDate = this.page.locator('.selectable-day').filter({ visible: true}).locator('nth=0');
|
this.firstAvailableDate = this.page.locator('.selectable-day').filter({ visible: true}).locator('nth=0');
|
||||||
this.firstAvailableTime = this.page.locator('label').filter({ hasText: /AM|PM/ }).locator('div').locator('nth=0');
|
this.firstAvailableTime = this.page.locator('label').filter({ hasText: /AM|PM/ }).locator('div').locator('nth=0');
|
||||||
|
|
@ -64,7 +64,7 @@ export class SchedulePage extends BasePage {
|
||||||
this.dateText = this.page.locator('label.modal-title');
|
this.dateText = this.page.locator('label.modal-title');
|
||||||
this.viewMoreDatesLink = this.page.getByText(/View more dates/).first();
|
this.viewMoreDatesLink = this.page.getByText(/View more dates/).first();
|
||||||
this.appointmentDuration = this.page.locator('.duration-text-block');
|
this.appointmentDuration = this.page.locator('.duration-text-block');
|
||||||
this.timeSlots = this.page.locator('fieldset:has(>legend#chooseTimeSlot) label');
|
this.timeSlots = this.page.locator('fieldset:has(>legend#chooseTimeSlot) label').filter({ visible: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
async selectLocation(testData: Partial<ITestData>) {
|
async selectLocation(testData: Partial<ITestData>) {
|
||||||
|
|
@ -82,7 +82,8 @@ export class SchedulePage extends BasePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
async scheduleInShop(appointmentDetails?: IAppointmentDetails) {
|
async scheduleInShop(appointmentDetails?: IAppointmentDetails) {
|
||||||
await this.inShopButton.click();
|
|
||||||
|
await this.inShopButton.isVisible() ? await this.inShopButton.click() : null;
|
||||||
if (appointmentDetails && appointmentDetails.shopAddress) {
|
if (appointmentDetails && appointmentDetails.shopAddress) {
|
||||||
const zipCodeMatch = appointmentDetails.shopAddress.match(/\b\d{5}$/);
|
const zipCodeMatch = appointmentDetails.shopAddress.match(/\b\d{5}$/);
|
||||||
if (zipCodeMatch) {
|
if (zipCodeMatch) {
|
||||||
|
|
@ -97,28 +98,20 @@ export class SchedulePage extends BasePage {
|
||||||
await this.saveLocationButton.click();
|
await this.saveLocationButton.click();
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.inShopButton.click().then(async () => {
|
// await this.inShopButton.click();
|
||||||
if (appointmentDetails && (appointmentDetails.shopAddress === "" || appointmentDetails.shopAddress === undefined )) {
|
|
||||||
appointmentDetails.shopAddress = '';
|
|
||||||
const elements = await this.storeAddressText.all();
|
|
||||||
elements.forEach(async(element) => {
|
|
||||||
appointmentDetails.shopAddress += await element.textContent() || "" + " ";
|
|
||||||
});
|
|
||||||
appointmentDetails.shopAddress?.trim();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// await this.selectAShopOptions.locator(`[buttonbodycopy="${appointmentDetails.shopAddress}"]`).scrollIntoViewIfNeeded().then(() => this.selectAShopOptions.locator(`[buttonbodycopy="${appointmentDetails.shopAddress}"]`).click());
|
// await this.selectAShopOptions.locator(`[buttonbodycopy="${appointmentDetails.shopAddress}"]`).scrollIntoViewIfNeeded().then(() => this.selectAShopOptions.locator(`[buttonbodycopy="${appointmentDetails.shopAddress}"]`).click());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appointmentDetails && (appointmentDetails.shopAddress === "" || appointmentDetails.shopAddress === undefined )) {
|
if (appointmentDetails && (appointmentDetails.shopAddress === "" || appointmentDetails.shopAddress === undefined )) {
|
||||||
appointmentDetails.shopAddress = '';
|
appointmentDetails.shopAddress = '';
|
||||||
|
await this.storeAddressText.first().waitFor({ state: 'visible' });
|
||||||
const elements = await this.storeAddressText.all();
|
const elements = await this.storeAddressText.all();
|
||||||
elements.forEach(async(element) =>
|
|
||||||
{
|
for (let element of elements) {
|
||||||
appointmentDetails.shopAddress += await element.textContent() || "" + " ";
|
let addressLine = await element.textContent() || "";
|
||||||
}
|
appointmentDetails.shopAddress += addressLine + ", "
|
||||||
)
|
};
|
||||||
appointmentDetails.shopAddress?.trim();
|
appointmentDetails.shopAddress = appointmentDetails.shopAddress?.slice(0, -2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,6 +163,7 @@ export class SchedulePage extends BasePage {
|
||||||
const inshopAvailableDates = this.page.locator('.selectable-day').filter({ visible: true}).all();
|
const inshopAvailableDates = this.page.locator('.selectable-day').filter({ visible: true}).all();
|
||||||
for (const inshopAvailableDate of await inshopAvailableDates) {
|
for (const inshopAvailableDate of await inshopAvailableDates) {
|
||||||
await inshopAvailableDate.click();
|
await inshopAvailableDate.click();
|
||||||
|
await this.page.waitForTimeout(500);
|
||||||
if (await this.allDayDropOffButton.isVisible()) {
|
if (await this.allDayDropOffButton.isVisible()) {
|
||||||
customerDetails!.apptDate = `${await inshopAvailableDate.getAttribute("id")}`;
|
customerDetails!.apptDate = `${await inshopAvailableDate.getAttribute("id")}`;
|
||||||
break;
|
break;
|
||||||
|
|
@ -210,13 +204,13 @@ export class SchedulePage extends BasePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
// appointmentmentDetails.serviceLocation === ServiceLocation.DropOff ? await this.dropOffButton.click() : await this.firstAvailableTime.click();
|
// appointmentmentDetails.serviceLocation === ServiceLocation.DropOff ? await this.dropOffButton.click() : await this.firstAvailableTime.click();
|
||||||
customerDetails!.apptDuration = (await this.appointmentDuration.innerText()).replace("Your service will take approximately ", "");
|
customerDetails!.apptDuration = (await this.appointmentDuration.innerText()).replace("Your service will take approximately ", "").replace("Duration: ", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
async getFormattedTimeSlot(timeSlot: Locator) {
|
async getFormattedTimeSlot(timeSlot: Locator) {
|
||||||
const selectedTimeSlot = await timeSlot.innerText();
|
const selectedTimeSlot = await timeSlot.innerText();
|
||||||
let formattedTimeSlot: string = "";
|
let formattedTimeSlot: string = "";
|
||||||
if (selectedTimeSlot.toLowerCase().includes("drop off"))
|
if (selectedTimeSlot.toLowerCase().includes("drop"))
|
||||||
{
|
{
|
||||||
formattedTimeSlot = selectedTimeSlot.includes("overnight") ? "drop off by 5:30 pm on the night of your scheduled appointment. Pick-up time dependent on shop schedule" : "drop off before 9:30 AM";
|
formattedTimeSlot = selectedTimeSlot.includes("overnight") ? "drop off by 5:30 pm on the night of your scheduled appointment. Pick-up time dependent on shop schedule" : "drop off before 9:30 AM";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,9 @@ export class VehicleDamagePage extends BasePage {
|
||||||
super(page);
|
super(page);
|
||||||
this.page = page;
|
this.page = page;
|
||||||
this.windshieldChkBox = this.page.locator('[buttonlabel="Windshield"]');
|
this.windshieldChkBox = this.page.locator('[buttonlabel="Windshield"]');
|
||||||
this.crackButton = this.page.locator('[buttonlabel="Crack"]');
|
this.crackButton = this.page.locator('[buttonlabelsubcopy="Replace my windshield"]');
|
||||||
this.chipButton = this.page.locator('[buttonlabel="Chip(s)"]');
|
this.chipButton = this.page.locator('[buttonlabelsubcopy="Repair my windshield"]');
|
||||||
this.sideDoorButton = this.page.locator('[buttonlabel="Side door"]');
|
this.sideDoorButton = this.page.locator('[buttonlabel="Side window"]');
|
||||||
this.driverSideButton = this.page.locator('[buttonlabel="Driver side"]');
|
this.driverSideButton = this.page.locator('[buttonlabel="Driver side"]');
|
||||||
this.passengerSideButton = this.page.locator('[buttonlabel="Passenger side"]');
|
this.passengerSideButton = this.page.locator('[buttonlabel="Passenger side"]');
|
||||||
this.driverQuarterPanelChkBox = this.page.locator('[aria-labelledby="driverSideOptions"]').locator('[buttonlabel="Quarter panel"]');
|
this.driverQuarterPanelChkBox = this.page.locator('[aria-labelledby="driverSideOptions"]').locator('[buttonlabel="Quarter panel"]');
|
||||||
|
|
|
||||||
|
|
@ -42,14 +42,6 @@ const cashReplaceGlassAddressLookupInshopAfterPayData: Partial<ITestData> = {
|
||||||
vehicleLookupType: VehicleLookupType.Address
|
vehicleLookupType: VehicleLookupType.Address
|
||||||
},
|
},
|
||||||
|
|
||||||
// No need to override vehicleDamage as it already defaults to WindshieldCrack
|
|
||||||
|
|
||||||
// Override appointment details
|
|
||||||
appointmentDetails: {
|
|
||||||
...getDefaultTestData().appointmentDetails!,
|
|
||||||
shopAddress: "6826 Sawmill Rd, Columbus, OH 43235"
|
|
||||||
},
|
|
||||||
|
|
||||||
// Override payment details
|
// Override payment details
|
||||||
paymentDetails: ClientData.getDefaultAfterpayDetails()
|
paymentDetails: ClientData.getDefaultAfterpayDetails()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ const cashReplaceMultiSlidingGlassDropoffData: Partial<ITestData> = {
|
||||||
appointmentDetails: {
|
appointmentDetails: {
|
||||||
serviceLocation: ServiceLocation.DropOff,
|
serviceLocation: ServiceLocation.DropOff,
|
||||||
appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate,
|
appointmentDate: getDefaultTestData().appointmentDetails?.appointmentDate,
|
||||||
shopAddress: "6826 Sawmill Rd, Columbus, OH 43235"
|
shopAddress: "6826 sawmill rd, Columbus, OH 43235"
|
||||||
},
|
},
|
||||||
|
|
||||||
// Override vehicle details
|
// Override vehicle details
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ const cashReplaceWiperDropoffData: Partial<ITestData> = {
|
||||||
servicePackage: ServicePackage.Standard,
|
servicePackage: ServicePackage.Standard,
|
||||||
|
|
||||||
// Special flags
|
// Special flags
|
||||||
isSkipEstimatePage: true,
|
isSkipEstimatePage: false,
|
||||||
isRecalVehicle: true,
|
isRecalVehicle: true,
|
||||||
|
|
||||||
// Override customer postal code
|
// Override customer postal code
|
||||||
|
|
@ -28,7 +28,7 @@ const cashReplaceWiperDropoffData: Partial<ITestData> = {
|
||||||
...getDefaultTestData().customerDetails!,
|
...getDefaultTestData().customerDetails!,
|
||||||
address: {
|
address: {
|
||||||
...getDefaultTestData().customerDetails!.address,
|
...getDefaultTestData().customerDetails!.address,
|
||||||
postalCode: '43085'
|
postalCode: '43235'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue