@@ -4,6 +4,7 @@ import { APPT_MY_SHARE_LINK, APPT_SHORT_SHARE_LINK_PREFIX, APPT_LONG_SHARE_LINK_
44
55export class BookingPage {
66 readonly page : Page ;
7+ readonly testPlatform : String ;
78 readonly titleText : Locator ;
89 readonly bookATimeToMeetText : Locator ;
910 readonly selectTimeSlotText : Locator ;
@@ -29,8 +30,10 @@ export class BookingPage {
2930 readonly bookApptPage630PMSlot : Locator ;
3031 readonly bookApptPage15MinSlot : Locator ;
3132
32- constructor ( page : Page ) {
33+ constructor ( page : Page , testPlatform : string = 'desktop' ) {
3334 this . page = page ;
35+ this . testPlatform = testPlatform ;
36+
3437 this . titleText = this . page . getByTestId ( 'booking-view-title-text' ) ;
3538 this . bookATimeToMeetText = this . page . getByTestId ( 'booking-view-book-a-time-to-meet-with-text' ) ;
3639 this . selectTimeSlotText = this . page . getByText ( 'Select an open time slot from the calendar' ) ;
@@ -42,11 +45,11 @@ export class BookingPage {
4245 this . bookingCalendarHdrFri = this . page . getByText ( 'FRI' , { exact : true } ) ;
4346 this . bookingCalendarHdrSat = this . page . getByText ( 'SAT' , { exact : true } ) ;
4447 this . bookingWeekPickerBtn = this . page . locator ( '.week-picker-button' ) ;
45- this . bookApptBtn = this . page . getByTestId ( 'booking-view-confirm-selection-button' ) ;
4648 this . nextWeekArrow = this . page . getByRole ( 'button' , { name : 'Next week' } ) ;
47- this . availableBookingSlot = this . page . locator ( '.selectable-slot' , { hasNotText : 'Busy' } ) ;
48- this . bookSelectionNameInput = this . page . getByPlaceholder ( 'First and last name' ) ;
49- this . bookSelectionEmailInput = this . page . getByPlaceholder ( 'john.doe@example.com' ) ;
49+ this . availableBookingSlot = this . page . locator ( '.selectable-slot' , { hasNotText : 'Busy' } ) ;
50+ this . bookSelectionNameInput = this . page . locator ( '[name="booker-view-user-name"]' ) ;
51+ this . bookSelectionEmailInput = this . page . locator ( '[name="booker-view-user-email"]' ) ;
52+ this . bookApptBtn = this . page . getByTestId ( 'booking-view-confirm-selection-button' ) ;
5053 this . bookingConfirmedTitleText = this . page . getByText ( 'Booking confirmed' ) ;
5154 this . requestSentAvailabilityText = this . page . getByText ( "'s Availability" ) ;
5255 this . requestSentCloseBtn = this . page . getByRole ( 'button' , { name : 'Close' } ) ;
@@ -86,6 +89,15 @@ export class BookingPage {
8689 await expect ( this . selectTimeSlotText ) . toBeVisible ( { timeout : TIMEOUT_30_SECONDS } ) ;
8790 }
8891
92+ /**
93+ * Scroll the given element into view. The reason why we do this here is because playright doesn't yet supported this on ios.
94+ */
95+ async scrollIntoView ( targetElement : Locator , timeout : number = 10000 ) {
96+ if ( ! this . testPlatform . includes ( 'ios' ) ) {
97+ await targetElement . scrollIntoViewIfNeeded ( { timeout : timeout } ) ;
98+ }
99+ }
100+
89101 /**
90102 * With the booking page week view already displayed, go forward to the next week.
91103 */
@@ -105,28 +117,26 @@ export class BookingPage {
105117 */
106118 async selectAvailableBookingSlot ( userDisplayName : string ) : Promise < string > {
107119 // let's check if a non-busy appointment slot exists in the current week view
108- const slotCount : number = await this . availableBookingSlot . count ( ) ;
109- console . log ( `available slot count: ${ slotCount } ` ) ;
120+ // playwrignt doesn't yet support ' count' or 'all' or 'elementHandles' on ios
121+ var availableSlot : Locator = this . availableBookingSlot . first ( ) ;
110122
111123 // if no slots are available in current week view then fast forward to next week
112- if ( slotCount === 0 ) {
124+ if ( ! availableSlot ) {
113125 console . log ( 'no slots available in current week, skipping ahead to the next week' ) ;
114126 await this . goForwardOneWeek ( ) ;
115127 // now check again for available slots; if none then fail out the test (safety catch but shouldn't happen)
116- const newSlotCount : number = await this . availableBookingSlot . count ( ) ;
117- console . log ( `available slot count: ${ newSlotCount } ` ) ;
118- expect ( newSlotCount , `no booking slots available, please check availability settings for ${ userDisplayName } ` ) . toBeGreaterThan ( 0 ) ;
128+ availableSlot = this . availableBookingSlot . first ( ) ;
129+ expect ( availableSlot , `no booking slots available, please check availability settings for ${ userDisplayName } ` ) . toBeTruthy ( ) ;
119130 }
120131
121- // slots are available in current week view so get the first one
122- const firstSlot : Locator = this . availableBookingSlot . first ( ) ;
123- let slotRef = await firstSlot . getAttribute ( 'data-testid' ) ; // ie. 'event-2025-01-08 09:30'
132+ // get our slot info for the available slot that we are going to request
133+ let slotRef = await availableSlot . getAttribute ( 'data-testid' ) ; // ie. 'event-2025-01-08 09:30'
124134 if ( ! slotRef )
125135 slotRef = 'none' ;
126136 expect ( slotRef ) . toContain ( 'event-' ) ;
127137
128138 // now that we've found an availalbe slot select it and confirm
129- await firstSlot . click ( ) ;
139+ await availableSlot . click ( ) ;
130140 return slotRef ;
131141 }
132142
@@ -141,7 +151,13 @@ export class BookingPage {
141151 async finishBooking ( bookerName : string , bookerEmail : string ) {
142152 await this . bookSelectionNameInput . fill ( bookerName ) ;
143153 await this . bookSelectionEmailInput . fill ( bookerEmail ) ;
144- await this . bookApptBtn . click ( ) ;
154+ // when clicking the book appt button for some reason on android it won't click it unless we force it; but
155+ // force doesn't work on ios
156+ if ( this . testPlatform . includes ( 'android' ) ) {
157+ await this . bookApptBtn . click ( { force : true } ) ;
158+ } else {
159+ await this . bookApptBtn . click ( ) ;
160+ }
145161 }
146162
147163 /**
0 commit comments