|
| 1 | +import { test, expect } from '@playwright/test'; |
| 2 | +import { BookingPage } from '../../pages/booking-page'; |
| 3 | +import { DashboardPage } from '../../pages/dashboard-page'; |
| 4 | +import { ensureWeAreSignedIn } from '../../utils/utils'; |
| 5 | + |
| 6 | +import { |
| 7 | + APPT_DISPLAY_NAME, |
| 8 | + PLAYWRIGHT_TAG_PROD_MOBILE_NIGHTLY, |
| 9 | + PLAYWRIGHT_TAG_E2E_SUITE_MOBILE, |
| 10 | + APPT_TIMEZONE_SETTING_PRIMARY, |
| 11 | + APPT_BOOKEE_NAME, |
| 12 | + APPT_BOOKEE_EMAIL, |
| 13 | + TIMEOUT_3_SECONDS, |
| 14 | + TIMEOUT_10_SECONDS, |
| 15 | + TIMEOUT_30_SECONDS, |
| 16 | + TIMEOUT_60_SECONDS, |
| 17 | +} from '../../const/constants'; |
| 18 | + |
| 19 | +var bookingPage: BookingPage; |
| 20 | +var dashboardPage: DashboardPage; |
| 21 | + |
| 22 | +test.beforeEach(async ({ page }, testInfo) => { |
| 23 | + bookingPage = new BookingPage(page, testInfo.project.name); // i.e. 'ios-safari' |
| 24 | + dashboardPage = new DashboardPage(page); |
| 25 | +}); |
| 26 | + |
| 27 | +// the APPT_TIMEZONE_SETTING_PRIMARY is set to the local timezone where the test is running; that way |
| 28 | +// the setting in Appointment will also match what is displayed in the book appoitment page, since |
| 29 | +// the book appoitment page uses the local timezone and not a setting; in CI the tests run in BrowserStack |
| 30 | +// which is located in a different timezone than when running the tests locally, so must be dynamic |
| 31 | +test.use({ |
| 32 | + timezoneId: APPT_TIMEZONE_SETTING_PRIMARY, |
| 33 | +}); |
| 34 | + |
| 35 | +test.describe('book an appointment on mobile browser', () => { |
| 36 | + |
| 37 | + test('able to request a booking on mobile browser', { |
| 38 | + tag: [PLAYWRIGHT_TAG_E2E_SUITE_MOBILE, PLAYWRIGHT_TAG_PROD_MOBILE_NIGHTLY], |
| 39 | + }, async ({ page }) => { |
| 40 | + // in order to ensure we find an available slot we can click on, first switch to week view URL |
| 41 | + await bookingPage.gotoBookingPageWeekView(); |
| 42 | + await expect(bookingPage.titleText).toBeVisible({ timeout: TIMEOUT_30_SECONDS }); |
| 43 | + |
| 44 | + // now select an available booking time slot |
| 45 | + const selectedSlot: string|null = await bookingPage.selectAvailableBookingSlot(APPT_DISPLAY_NAME); |
| 46 | + console.log(`selected appointment time slot: ${selectedSlot}`); |
| 47 | + |
| 48 | + // now provide the bookee details for our selected time slot; when signed into Appointment this |
| 49 | + // info is provided automatically however for this test we are selecting a time slot without being |
| 50 | + // signed in / without being an Appointment user; so we must specify the bookee name and email |
| 51 | + await bookingPage.finishBooking(APPT_BOOKEE_NAME, APPT_BOOKEE_EMAIL); |
| 52 | + |
| 53 | + // now we have an availble booking time slot selected, and bookee details provided, we can click the book button |
| 54 | + await bookingPage.scrollIntoView(bookingPage.bookApptBtn); |
| 55 | + await bookingPage.bookApptBtn.click(); |
| 56 | + |
| 57 | + // verify booking request sent pop-up |
| 58 | + await expect(bookingPage.bookingConfirmedTitleText.first()).toBeVisible({ timeout: TIMEOUT_60_SECONDS }); |
| 59 | + await bookingPage.bookingConfirmedTitleText.scrollIntoViewIfNeeded(); |
| 60 | + |
| 61 | + // booking request sent dialog should display the correct time slot that was requested |
| 62 | + // our requested time slot is stored in this format, as example: 'event-2025-01-14 14:30' |
| 63 | + // the dialog reports the slot in this format, as example: 'January 14, 2025' with start time |
| 64 | + // on next line; convert our selected slot value to same format as displayed so we can verify |
| 65 | + const expDateStr = await bookingPage.getDateFromSlotString(selectedSlot); |
| 66 | + const expTimeStr = await bookingPage.getTimeFromSlotString(selectedSlot); |
| 67 | + |
| 68 | + // now verify the correct date/time is dispalyed on the booking request sent pop-up |
| 69 | + await bookingPage.verifyRequestedSlotTextDisplayed(expDateStr, expTimeStr); |
| 70 | + |
| 71 | + // now verify a corresponding pending booking was created on the host account's list of pending bookings |
| 72 | + // wait N seconds for the appointment dashboard to update, sometimes the test is so fast when it |
| 73 | + // switches back to the dashboard the new pending appointment hasn't been added/displayed yet |
| 74 | + await page.waitForTimeout(TIMEOUT_10_SECONDS); |
| 75 | + await ensureWeAreSignedIn(page); |
| 76 | + await dashboardPage.verifyEventCreated(expDateStr, expTimeStr); |
| 77 | + |
| 78 | + // also go back to main dashboard and check that pending requests link now appears |
| 79 | + await dashboardPage.gotoToDashboardMonthView(); |
| 80 | + await expect(dashboardPage.pendingBookingRequestsLink).toBeVisible(); |
| 81 | + |
| 82 | + // click the pending requests link and verify it navigates to the correct URL |
| 83 | + await dashboardPage.pendingBookingRequestsLink.click(); |
| 84 | + await page.waitForTimeout(TIMEOUT_3_SECONDS); |
| 85 | + await expect(page).toHaveURL(/.*\/bookings\?unconfirmed=true/); |
| 86 | + }); |
| 87 | +}); |
0 commit comments