DigitalConsumer.ISS/playwright-tests/pages/SchedulePage.ts

113 lines
No EOL
5.1 KiB
TypeScript

import { expect, type Locator, type Page } from '@playwright/test';
import { BasePage } from './BasePage';
import { IAppointmentDetails } from '@business-logic/types/CustomerDetails';
import { formatDate, formatTime } from '@impl/utils/DateUtils';
import { ServiceLocation } from '@business-logic/types/Enums';
import { getCustomerDetails, ITestData } from 'safelite-playwright-core';
export class SchedulePage extends BasePage {
readonly page: Page;
issPageValue = 'schedule-page';
readonly inShopButton: Locator;
readonly mobileButton: Locator;
readonly moreLocationsButton: Locator;
readonly zipCodeTextBox: Locator;
readonly findButton: Locator;
readonly selectAShopOptions: Locator;
readonly firstAppointmentButton : Locator;
readonly firstAvailableAMDate: Locator;
readonly firstAvailablePMDate: Locator;
readonly firstAvailableTime: Locator;
readonly firstAvailabeAMTime: Locator;
readonly modalContinueButton: Locator;
readonly dropOffButton: Locator;
readonly dateText: Locator;
readonly viewMoreDatesLink: Locator;
readonly continueButton: Locator;
constructor(page: Page) {
super(page);
this.page = page;
this.inShopButton = this.page.locator('[buttonlabel="At a Safelite shop"]');
this.mobileButton = this.page.locator('[buttonlabel="Have Safelite come to me"]');
// For in shop
this.moreLocationsButton = this.page.getByRole('button', { name: 'More Locations' });
// For mobile
this.zipCodeTextBox = this.page.locator('#serviceZipCode');
this.findButton = this.page.getByRole('button', { name: 'Find' });
// For in-shop and drop off
this.selectAShopOptions = this.page.locator('[class="shop-question"]');
this.firstAppointmentButton = this.page.locator('#availabilityIndicator').first();
this.firstAvailableAMDate = this.page.locator('morning-row-cell has-appointments selected-date').first();
this.firstAvailablePMDate = this.page.locator('afternoon-row-cell has-appointments selected-date').first();
this.firstAvailableTime = this.page.locator('.time-slot-button').first();
this.firstAvailabeAMTime = this.page.locator('.time-slot-button').nth(0);
this.modalContinueButton = this.page.locator('#modalbtn');
this.dropOffButton = this.page.locator('[class="dropoff-label"]');
this.dateText = this.page.locator('[class="modal-header mb-2 mt-2"]');
this.viewMoreDatesLink = this.page.getByRole('button', { name: 'More Right arrow icon' });
this.continueButton = this.page.locator('#stacked').locator('button:has-text("Continue")');
}
// Select in shop and schedule
async scheduleInShop(appointmentDetails?: IAppointmentDetails){
if (appointmentDetails?.serviceLocation === ServiceLocation.InShop) {
try {await this.inShopButton.waitFor({ state: 'visible', timeout: 5000 });
await this.inShopButton.isVisible()
await this.inShopButton.click();
await (await this.getFirstNonDropOffTimeSlot()).click();
} catch {
await this.inShopButton.isHidden()
await (await this.getFirstNonDropOffTimeSlot()).click();
}
} else if (appointmentDetails?.serviceLocation === ServiceLocation.DropOff) {
if (await this.inShopButton.isVisible()){
await this.inShopButton.waitFor({ state: 'visible', timeout: 5000 });
await this.inShopButton.click();
if (await this.dropOffButton.isVisible()) {
await this.dropOffButton.waitFor({ state: 'visible', timeout: 5000 });
await this.dropOffButton.click()
} else {
await (await this.getFirstNonDropOffTimeSlot()).click();
}
} else {
await (await this.getFirstNonDropOffTimeSlot()).click();
}
} else {
await this.selectFirstAvailableTime();
}
await this.continueButton.click();
}
// Select mobile button, enter zip code, click find button, select first available time and continue
async scheduleMobile(appointmentDetails: IAppointmentDetails){
await this.mobileButton.click();
await this.zipCodeTextBox.fill(appointmentDetails.serviceAddress!.postalCode!);
await this.findButton.click();
await this.selectFirstAvailableTime();
await this.continueButton.click();
}
// Selects the first available time slot but if its not visible, click "More" first to load more dates and times
async selectFirstAvailableTime(): Promise<void> {
if (await this.firstAvailableTime.isVisible()) {
await this.firstAvailableTime.click();
} else {
await this.viewMoreDatesLink.click();
await this.firstAvailableTime.waitFor({ state: 'visible' });
await this.firstAvailableTime.click();
}
}
async getFirstNonDropOffTimeSlot(): Promise<Locator> {
const timeSlots = this.page.locator('.time-slot-button');
const nonDropOff = timeSlots.filter({ hasNotText: /Drop & Go/i });
return nonDropOff.first();
}
}