11import { expect , type Page , type Locator } from '@playwright/test' ;
2+ import { APPT_PROD_PENDING_BOOKINGS_PAGE } from '../const/constants' ;
3+
24
35export class DashboardPage {
46 readonly page : Page ;
@@ -7,6 +9,10 @@ export class DashboardPage {
79 readonly logOutMenuItem : Locator ;
810 readonly shareMyLink : Locator ;
911 readonly nextMonthArrow : Locator ;
12+ readonly pendingBookingsPageHeader : Locator ;
13+ readonly pendingBookingsFilterSelect : Locator ;
14+ readonly allFutureBookingsOptionText : string = 'All future bookings' ;
15+ readonly apptsFilterInput : Locator ;
1016
1117 constructor ( page : Page ) {
1218 this . page = page ;
@@ -15,56 +21,47 @@ export class DashboardPage {
1521 this . logOutMenuItem = this . page . getByTestId ( 'user-nav-logout-menu' ) ;
1622 this . shareMyLink = this . page . getByTestId ( 'dashboard-share-quick-link-btn' ) ;
1723 this . nextMonthArrow = this . page . locator ( '[data-icon="chevron-right"]' ) ;
24+ this . pendingBookingsPageHeader = this . page . getByText ( 'Bookings' ) ;
25+ this . pendingBookingsFilterSelect = this . page . getByTestId ( 'bookings-filter-select' ) ;
26+ this . apptsFilterInput = this . page . getByPlaceholder ( 'Search bookings' ) ;
1827 }
1928
2029 /**
21- * With the booking page week view already displayed, go forward to the next week.
30+ * Navigate to the pending bookings page and display all future pending bookings
2231 */
23- async goForwardOneMonth ( ) {
24- console . log ( 'skipping ahead to the next calendar month' ) ;
25- await this . nextMonthArrow . click ( ) ;
32+ async gotoPendingBookings ( ) {
33+ await this . page . goto ( APPT_PROD_PENDING_BOOKINGS_PAGE ) ;
2634 await this . page . waitForLoadState ( 'domcontentloaded' ) ;
27- await expect ( this . shareMyLink ) . toBeVisible ( { timeout : 30_000 } ) ;
35+ // ensure all future bookings are displayed
36+ await this . pendingBookingsFilterSelect . selectOption ( this . allFutureBookingsOptionText , { timeout : 60_000 } ) ;
2837 }
2938
39+ /**
40+ * With pending bookings list displayed, enter a filter string to narrow down the list
41+ */
42+ async filterPendingBookings ( filterString : string ) {
43+ await this . apptsFilterInput . fill ( filterString ) ;
44+ }
45+
3046 /**
3147 * Given a requested booking's time slot reference, verify that a corresponding hold event
32- * was created in the host calendar dashboard month view.
33- * @param requestedBookingTimeSlotRef String containing the requested booking time slot ref
34- * taken from the DOM on the share link page at the time when the slot was chosen. Will be in
35- * the format of: 'event-2025-01-14 14:30'.
48+ * exists in the host account's list of future pending bookings
3649 * @param hostUserDisplayName String containing the host account's user display name
3750 * @param requsterName String containing the name of the requester (provided at booking request)
51+ * @param slotDate String containing date of the requested slot (format e.g: 'February 7, 2025')
52+ * @param slotTime String containg the time of the requested slot (format e.g: '03:30 PM')
3853 */
39- async verifyHoldEventCreated ( requestedBookingTimeSlotRef : string , hostUserDisplayName : string , requsterName : string ) {
40- // on the host calendar view, hold appointment dom elements contain ids that look like this:
41- // 'calendar-month__event-HOLD: Appointment - tbautomation1 and Automated-Test-Bot2025-01-09'
42- // in this case 'tbautomation1' is the appointment host user who shares the booking link; and
43- // `Automated-Test-Bot` is the booking requester's name. First build a search string to match.
44- const eventDate = requestedBookingTimeSlotRef . substring ( 6 , 16 ) ; // i.e. '2025-01-14'
45- const eventSearchId = `calendar-month__event-HOLD: Appointment - ${ hostUserDisplayName } and ${ requsterName } ${ eventDate } ` ;
46- console . log ( `searching for calendar event with dom element id: ${ eventSearchId } ` ) ;
47-
48- // todo: the hold event dom element id only contains the event date and not time slot so if we
49- // search we will get all events on that date for the given users but won't be able to tell if
50- // hold event was created for the correct time slot; for now just ensure at lest one hold event
51- // was created on the booking request date, but update this later (see github issue #820).
54+ async verifyHoldEventCreated ( hostUserDisplayName : string , requsterName : string , slotDate : string , slotTime : string ) {
55+ // switch to the 'bookings' tab and display all future pending bookings; use the URL instead of UI
56+ await this . gotoPendingBookings ( ) ;
5257
53- // check if the hold event is found on current month view
54- const holdEvent : Locator = this . page . locator ( `id=${ eventSearchId } ` ) ;
55- const firstHoldEvent : Locator = holdEvent . first ( ) ;
56- var eventText = await firstHoldEvent . innerText ( ) ;
57- if ( ! eventText ) {
58- // hold event not found in current month view so skip ahead to the next month and check again
59- console . log ( 'no matching hold event found in current month' ) ;
60- await this . goForwardOneMonth ( ) ;
61- eventText = await firstHoldEvent . innerText ( ) ;
62- expect ( eventText . length , 'matching hold event was not found on host calendar!' ) . toBeGreaterThan ( 4 ) ;
63- }
58+ // with all future pending bookings now displayed, filter by appointments for our host user and requester
59+ const eventFilter = `HOLD: Appointment - ${ hostUserDisplayName } and ${ requsterName } ` ;
60+ await this . filterPendingBookings ( eventFilter ) ;
6461
65- // at least one matching hold event found
66- console . log ( `matching hold event found, has text: ${ eventText } ` ) ;
67- const expHoldEventText = `HOLD: Appointment - ${ hostUserDisplayName } and ${ requsterName } ` ;
68- expect ( eventText ) . toContain ( expHoldEventText ) ;
62+ // now we have a list of future pending appointments for our host and requster; now ensure one
63+ // of them matches the slot that was selected by the test
64+ const apptLocator = this . page . getByRole ( 'cell' , { name : ` ${ slotDate } ` } ) . locator ( 'div' , { hasText : ` ${ slotTime } to` } ) ;
65+ await expect ( apptLocator ) . toBeVisible ( { timeout : 60_000 } ) ;
6966 }
7067}
0 commit comments