110 lines
No EOL
5.2 KiB
TypeScript
110 lines
No EOL
5.2 KiB
TypeScript
import { expect, type Locator, type Page } from '@playwright/test';
|
|
import { BasePage } from './BasePage';
|
|
import { IAppointmentDetails, ICustomerDetails } from '@business-logic/types/CustomerDetails';
|
|
import { formatDate, formatTime } from '@impl/utils/DateUtils';
|
|
import { AppointmentTimeslot, AppointmentType, ServiceLocation } from '@business-logic/types/Enums';
|
|
import { time } from 'console';
|
|
import { step } from '@business-logic/types/Step';
|
|
import { ITestData } from '@business-logic/types/ITestData';
|
|
|
|
export class SchedulePage extends BasePage {
|
|
readonly page: Page;
|
|
url = process.env['BASE_URL']! + '/fmg/?fmgPage=schedule';
|
|
readonly firstAvailableDate: Locator;
|
|
readonly firstAvailableTime: Locator;
|
|
readonly modalContinueButton: Locator;
|
|
readonly dropOffButton: Locator;
|
|
readonly dateText: Locator;
|
|
readonly viewMoreDatesLink: Locator;
|
|
readonly appointmentDuration: Locator;
|
|
readonly timeSlots: Locator;
|
|
|
|
constructor(page: Page) {
|
|
super(page);
|
|
this.page = page;
|
|
this.firstAvailableDate = this.page.locator('.selectable-day').locator('nth=0');
|
|
this.firstAvailableTime = this.page.locator('label').filter({ hasText: /AM|PM/ }).locator('div').locator('nth=0');
|
|
this.modalContinueButton = this.page.getByRole('dialog').getByRole('button', { name: 'Continue' });
|
|
this.dropOffButton = this.page.getByText('Drop off your vehicle', { exact: true });
|
|
this.dateText = this.page.locator('label.modal-title');
|
|
this.viewMoreDatesLink = this.page.getByText(/View more dates/).first();
|
|
this.appointmentDuration = this.page.locator('.duration-text-block');
|
|
this.timeSlots = this.page.locator('fieldset[aria-labelledby=\'chooseTimeSlot\'] label');
|
|
}
|
|
|
|
async scheduleAppointment(appointmentDetails: IAppointmentDetails) {
|
|
const formattedDate = formatDate(appointmentDetails.appointmentDate!);
|
|
const formattedTime = formatTime(appointmentDetails.appointmentDate!);
|
|
const dateInput = this.page.locator(`div[id="${formattedDate}"]`);
|
|
const timeButton = this.page.locator(`div[aria-label="${formattedTime}"]`);
|
|
if (await dateInput.isVisible()) {
|
|
await dateInput.click();
|
|
} else {
|
|
await this.viewMoreDatesLink.click();
|
|
await dateInput.click();
|
|
}
|
|
await timeButton.click();
|
|
await this.modalContinueButton.click();
|
|
}
|
|
|
|
async scheduleFirstAppointment(testData: Partial<ITestData>) {
|
|
const { appointmentDetails, customerDetails } = testData;
|
|
while (!(await this.firstAvailableDate.isVisible())) {
|
|
|
|
if (appointmentDetails?.appointmentTimeSlot == AppointmentTimeslot.EarlyBird) {
|
|
await this.mockScheduleResponseForEarlyBird(customerDetails!);
|
|
}
|
|
await this.viewMoreDatesLink.click();
|
|
}
|
|
|
|
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);
|
|
});
|
|
}
|
|
else {
|
|
await this.firstAvailableDate.click().then(async () => {
|
|
customerDetails!.apptDate = `${await this.firstAvailableDate.getAttribute("id")}`
|
|
});
|
|
|
|
// const timeSlots = this.timeSlots;
|
|
const timeSlotCount = await this.timeSlots.count();
|
|
const randomIndex = Math.floor(Math.random() * timeSlotCount);
|
|
const timeSlot = this.timeSlots.nth(randomIndex);
|
|
await timeSlot.click().then(async () => {
|
|
customerDetails!.apptTime = await this.getFormattedTimeSlot(timeSlot);
|
|
});
|
|
}
|
|
|
|
// appointmentmentDetails.serviceLocation === AppointmentType.DropOff ? await this.dropOffButton.click() : await this.firstAvailableTime.click();
|
|
customerDetails!.apptDuration = (await this.appointmentDuration.innerText()).replace("Duration: ", "");
|
|
await this.nextPage();
|
|
}
|
|
|
|
async getFormattedTimeSlot(timeSlot: Locator) {
|
|
const selectedTimeSlot = await timeSlot.innerText();
|
|
let formattedTimeSlot: string = "";
|
|
if (selectedTimeSlot.toLowerCase().includes("drop off"))
|
|
{
|
|
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";
|
|
}
|
|
else if (selectedTimeSlot.includes("-") || selectedTimeSlot.includes("Earlybird"))
|
|
{
|
|
formattedTimeSlot = selectedTimeSlot.includes("Earlybird") ? "arriving between 8:00 AM - 12:00 PM" : `arriving between ${selectedTimeSlot}`;
|
|
}
|
|
else
|
|
{
|
|
formattedTimeSlot = `at ${selectedTimeSlot}`;
|
|
}
|
|
return formattedTimeSlot;
|
|
}
|
|
|
|
@step("SchedulePage >> Schedule appointment: ")
|
|
async handleSchedulePage(testData: Partial<ITestData>) {
|
|
|
|
await this.validateProgressBar("72");
|
|
await this.scheduleFirstAppointment(testData);
|
|
}
|
|
}
|