From 9422e28598062d71cf1d96730c27ff65443ce3aa Mon Sep 17 00:00:00 2001 From: "gitstart-app[bot]" <57568882+gitstart-app[bot]@users.noreply.github.com> Date: Sat, 27 Jan 2024 07:50:38 -0300 Subject: [PATCH] test: check all advanced options in a managed event-type (teste2e-managedOptions) (#12294) * check all advanced options in a managed event-type * Delete apps/web/playwright/booking/managedBookingAllQuestion.e2e.ts * Delete apps/web/playwright/managedBooking/allQuestions.e2e.ts * Refactor * Refactor * check all advanced options in a managed event-type * check all advanced options in a managed event-type * Update regularBookings.ts * Update regularBookings.ts --------- Co-authored-by: gitstart-calcom Co-authored-by: GitStart-Cal.com <121884634+gitstart-calcom@users.noreply.github.com> Co-authored-by: gitstart-calcom Co-authored-by: Keith Williams --- .../components/eventtype/EventAdvancedTab.tsx | 11 +- .../RequiresConfirmationController.tsx | 1 + .../playwright/booking/allQuestions.e2e.ts | 2 +- .../playwright/fixtures/regularBookings.ts | 111 ++++++++++++++++-- .../managedBooking/advancedOptions.e2e.ts | 43 +++++++ .../teams/components/CreateANewTeamForm.tsx | 1 + .../components/CreateEventTypeDialog.tsx | 4 +- .../components/EventTypeDescription.tsx | 2 +- .../features/form-builder/FormBuilder.tsx | 4 +- .../components/form/switch/SettingsToggle.tsx | 10 +- 10 files changed, 174 insertions(+), 15 deletions(-) create mode 100644 apps/web/playwright/managedBooking/advancedOptions.e2e.ts diff --git a/apps/web/components/eventtype/EventAdvancedTab.tsx b/apps/web/components/eventtype/EventAdvancedTab.tsx index bfe7ccf9df..dc5ad32b67 100644 --- a/apps/web/components/eventtype/EventAdvancedTab.tsx +++ b/apps/web/components/eventtype/EventAdvancedTab.tsx @@ -215,6 +215,7 @@ export const EventAdvancedTab = ({ eventType, team }: Pick + )} + data-testid="redirect-url-warning"> {t("redirect_url_warning")} @@ -295,6 +300,7 @@ export const EventAdvancedTab = ({ eventType, team }: Pick @@ -398,12 +404,14 @@ export const EventAdvancedTab = ({ eventType, team }: Pick { onChange(Math.abs(Number(e.target.value))); }} + data-testid="seats-per-time-slot" />
( onChange(e)} @@ -446,6 +454,7 @@ export const EventAdvancedTab = ({ eventType, team }: Pick onChange(e)} + data-testid="lock-timezone-toggle" /> )} /> diff --git a/apps/web/components/eventtype/RequiresConfirmationController.tsx b/apps/web/components/eventtype/RequiresConfirmationController.tsx index f6249296fa..2d46a6fd74 100644 --- a/apps/web/components/eventtype/RequiresConfirmationController.tsx +++ b/apps/web/components/eventtype/RequiresConfirmationController.tsx @@ -75,6 +75,7 @@ export default function RequiresConfirmationController({ )} childrenClassName="lg:ml-0" title={t("requires_confirmation")} + data-testid="requires-confirmation" disabled={seatsEnabled || requiresConfirmationLockedProps.disabled} tooltip={seatsEnabled ? t("seat_options_doesnt_support_confirmation") : undefined} description={t("requires_confirmation_description")} diff --git a/apps/web/playwright/booking/allQuestions.e2e.ts b/apps/web/playwright/booking/allQuestions.e2e.ts index 14870f9672..f5a0959302 100644 --- a/apps/web/playwright/booking/allQuestions.e2e.ts +++ b/apps/web/playwright/booking/allQuestions.e2e.ts @@ -91,7 +91,7 @@ test.describe("Booking With All Questions", () => { } else { await bookingPage.addQuestion(question, `${question}-test`, `${question} test`, false); } - await bookingPage.checkField(question); + await bookingPage.checkField(question, { isOptional: true }); } await bookingPage.updateEventType(); diff --git a/apps/web/playwright/fixtures/regularBookings.ts b/apps/web/playwright/fixtures/regularBookings.ts index 65f8ac5baf..565340ccc7 100644 --- a/apps/web/playwright/fixtures/regularBookings.ts +++ b/apps/web/playwright/fixtures/regularBookings.ts @@ -205,9 +205,15 @@ export function createBookingPageFixture(page: Page) { goToEventType: async (eventType: string) => { await page.getByRole("link", { name: eventType }).click(); }, + goToTab: async (tabName: string) => { await page.getByTestId(`vertical-tab-${tabName}`).click(); }, + + goToEventTypesPage: async () => { + await page.goto("/event-types"); + }, + setResolution: async (width: number, height: number) => { await page.setViewportSize({ width: width, height: height }); }, @@ -253,16 +259,21 @@ export function createBookingPageFixture(page: Page) { }, updateEventType: async () => { await page.getByTestId("update-eventtype").click(); + const toast = await page.waitForSelector('[data-testid="toast-success"]'); + expect(toast).toBeTruthy(); }, + previewEventType: async () => { const eventtypePromise = page.waitForEvent("popup"); await page.getByTestId("preview-button").click(); return eventtypePromise; }, + selectTimeSlot: async (eventTypePage: Page) => { await goToNextMonthIfNoAvailabilities(eventTypePage); await eventTypePage.getByTestId("time").first().click(); }, + clickReschedule: async () => { await page.getByText("Reschedule").click(); }, @@ -290,6 +301,7 @@ export function createBookingPageFixture(page: Page) { await page.getByTestId("cancel_reason").fill("Test cancel"); await page.getByTestId("confirm_cancel").click(); }, + assertBookingCanceled: async (page: Page) => { await expect(page.getByTestId("cancelled-headline")).toBeVisible(); }, @@ -330,11 +342,9 @@ export function createBookingPageFixture(page: Page) { }, confirmBooking: async (eventTypePage: Page) => { - const confirmButton = "confirm-book-button"; - await eventTypePage.getByTestId(confirmButton).click(); - const scheduleSuccessfullyPage = eventTypePage.getByText(scheduleSuccessfullyText); - await scheduleSuccessfullyPage.waitFor({ state: "visible" }); - await expect(scheduleSuccessfullyPage).toBeVisible(); + await eventTypePage.getByTestId("confirm-book-button").click(); + await eventTypePage.waitForURL("booking/**"); + await expect(eventTypePage.getByText(scheduleSuccessfullyText)).toBeVisible(); }, fillAndConfirmBooking: async ({ @@ -390,9 +400,7 @@ export function createBookingPageFixture(page: Page) { await scheduleSuccessfullyPage.waitFor({ state: "visible" }); await expect(scheduleSuccessfullyPage).toBeVisible(); }, - checkField: async (question: string) => { - await expect(page.getByTestId(`field-${question}-test`)).toBeVisible(); - }, + fillAllQuestions: async (eventTypePage: Page, questions: string[], options: BookingOptions) => { const confirmButton = options.isReschedule ? "confirm-reschedule-button" : "confirm-book-button"; await fillAllQuestions(eventTypePage, questions, options); @@ -409,6 +417,93 @@ export function createBookingPageFixture(page: Page) { await expect(scheduleSuccessfullyPage).toBeVisible(); }, + checkField: async (question: string, options?: { isOptional: boolean }) => { + if (options?.isOptional) { + await expect(page.getByTestId(`field-${question}-test`).getByTestId("optional")).toBeVisible(); + } else { + await expect(page.getByTestId(`field-${question}-test`).getByTestId("required")).toBeVisible(); + } + await expect(page.getByTestId(`field-${question}-test`)).toBeVisible(); + }, + + checkRequiresConfirmation: async () => { + // Check existence of the icon + await expect(page.getByTestId("requires-confirmation-title").locator("svg")).toBeVisible(); + + const confirmationSwitch = page.getByTestId("requires-confirmation"); + await expect(confirmationSwitch).toBeVisible(); + await confirmationSwitch.click(); + }, + + checkRequiresBookerEmailVerification: async () => { + await expect(page.getByTestId("requires-booker-email-verification-title").locator("svg")).toBeVisible(); + + const emailSwitch = page.getByTestId("requires-booker-email-verification"); + + await expect(emailSwitch).toBeVisible(); + await emailSwitch.click(); + }, + + checkHideNotes: async () => { + await expect(page.getByTestId("disable-notes-title").locator("svg")).toBeVisible(); + + const hideNotesSwitch = page.getByTestId("disable-notes"); + + await expect(hideNotesSwitch).toBeVisible(); + await hideNotesSwitch.click(); + }, + + checkRedirectOnBooking: async () => { + await expect(page.getByTestId("redirect-success-booking-title").locator("svg")).toBeVisible(); + + const redirectSwitch = page.getByTestId("redirect-success-booking"); + await expect(redirectSwitch).toBeVisible(); + await redirectSwitch.click(); + await expect(page.getByTestId("external-redirect-url")).toBeVisible(); + await page.getByTestId("external-redirect-url").fill("https://cal.com"); + await expect(page.getByTestId("redirect-url-warning")).toBeVisible(); + }, + + checkEnablePrivateUrl: async () => { + await expect(page.getByTestId("hashedLinkCheck-title").locator("label div")).toBeVisible(); + + await expect(page.getByTestId("hashedLinkCheck-info")).toBeVisible(); + await expect(page.getByTestId("hashedLinkCheck")).toBeVisible(); + await page.getByTestId("hashedLinkCheck").click(); + await expect(page.getByTestId("generated-hash-url")).toBeVisible(); + }, + + toggleOfferSeats: async () => { + await expect(page.getByTestId("offer-seats-toggle-title").locator("svg")).toBeVisible(); + + await page.getByTestId("offer-seats-toggle").click(); + + const seatSwitchField = page.getByTestId("seats-per-time-slot"); + await seatSwitchField.fill("3"); + await expect(seatSwitchField).toHaveValue("3"); + await expect(page.getByTestId("show-attendees")).toBeVisible(); + }, + + checkLockTimezone: async () => { + await expect(page.getByTestId("lock-timezone-toggle-title").locator("svg")).toBeVisible(); + + const lockSwitch = page.getByTestId("lock-timezone-toggle"); + + await expect(lockSwitch).toBeVisible(); + await lockSwitch.click(); + }, + + checkEventType: async () => { + await expect(page.getByTestId("requires-confirmation-badge").last()).toBeVisible(); + }, + + assertBookingIsVisible: async (name: string) => { + await expect( + page.getByRole("link", { + name, + }) + ).toBeVisible(); + }, checkBufferTime: async () => { const minutes = (await localize("en"))("minutes"); const fieldPlaceholder = page.getByPlaceholder("0"); diff --git a/apps/web/playwright/managedBooking/advancedOptions.e2e.ts b/apps/web/playwright/managedBooking/advancedOptions.e2e.ts new file mode 100644 index 0000000000..75089cf2c3 --- /dev/null +++ b/apps/web/playwright/managedBooking/advancedOptions.e2e.ts @@ -0,0 +1,43 @@ +import { test } from "../lib/fixtures"; + +test.beforeEach(async ({ page, users, bookingPage }) => { + const teamEventTitle = "Test Managed Event Type"; + const userFixture = await users.create( + { name: "testuser" }, + { hasTeam: true, schedulingType: "MANAGED", teamEventTitle } + ); + await userFixture.apiLogin(); + + await page.goto("/event-types"); + await bookingPage.goToEventType(teamEventTitle); + await bookingPage.goToTab("event_advanced_tab_title"); +}); + +test.describe("Check advanced options in a managed team event type", () => { + test("Check advanced options in a managed team event type without offer seats", async ({ bookingPage }) => { + await bookingPage.checkRequiresConfirmation(); + await bookingPage.checkRequiresBookerEmailVerification(); + await bookingPage.checkHideNotes(); + await bookingPage.checkRedirectOnBooking(); + await bookingPage.checkEnablePrivateUrl(); + await bookingPage.checkLockTimezone(); + await bookingPage.updateEventType(); + await bookingPage.goToEventTypesPage(); + + await bookingPage.checkEventType(); + }); + + test("Check advanced options in a managed team event type with offer seats", async ({ bookingPage }) => { + await bookingPage.checkRequiresConfirmation(); + await bookingPage.checkRequiresBookerEmailVerification(); + await bookingPage.checkHideNotes(); + await bookingPage.checkRedirectOnBooking(); + await bookingPage.checkEnablePrivateUrl(); + await bookingPage.toggleOfferSeats(); + await bookingPage.checkLockTimezone(); + await bookingPage.updateEventType(); + await bookingPage.goToEventTypesPage(); + + await bookingPage.checkEventType(); + }); +}); diff --git a/packages/features/ee/teams/components/CreateANewTeamForm.tsx b/packages/features/ee/teams/components/CreateANewTeamForm.tsx index c4a395dbbc..beabedb1d6 100644 --- a/packages/features/ee/teams/components/CreateANewTeamForm.tsx +++ b/packages/features/ee/teams/components/CreateANewTeamForm.tsx @@ -109,6 +109,7 @@ export const CreateANewTeamForm = () => { } }} autoComplete="off" + data-testid="team-name" /> )} diff --git a/packages/features/eventtypes/components/CreateEventTypeDialog.tsx b/packages/features/eventtypes/components/CreateEventTypeDialog.tsx index 690ea196cc..3ea7bd67f8 100644 --- a/packages/features/eventtypes/components/CreateEventTypeDialog.tsx +++ b/packages/features/eventtypes/components/CreateEventTypeDialog.tsx @@ -183,6 +183,7 @@ export default function CreateEventTypeDialog({ { form.setValue("title", e?.target.value); @@ -293,7 +294,8 @@ export default function CreateEventTypeDialog({ {...register("schedulingType")} value={SchedulingType.MANAGED} className={classNames("text-sm", !isAdmin && "w-1/2")} - classNames={{ container: classNames(isAdmin && "w-full") }}> + classNames={{ container: classNames(isAdmin && "w-full") }} + data-testid="managed-event-type"> {t("managed_event")}

{t("managed_event_description")}

diff --git a/packages/features/eventtypes/components/EventTypeDescription.tsx b/packages/features/eventtypes/components/EventTypeDescription.tsx index 437e425f1d..f22e2a0ca7 100644 --- a/packages/features/eventtypes/components/EventTypeDescription.tsx +++ b/packages/features/eventtypes/components/EventTypeDescription.tsx @@ -106,7 +106,7 @@ export const EventTypeDescription = ({ )} {eventType.requiresConfirmation && ( -
  • +
  • {eventType.metadata?.requiresConfirmationThreshold ? t("may_require_confirmation") diff --git a/packages/features/form-builder/FormBuilder.tsx b/packages/features/form-builder/FormBuilder.tsx index 1b8637d0ec..679bf456b3 100644 --- a/packages/features/form-builder/FormBuilder.tsx +++ b/packages/features/form-builder/FormBuilder.tsx @@ -181,7 +181,9 @@ export const FormBuilder = function FormBuilder({ // Hidden field can't be required, so we don't need to show the Optional badge {t("hidden")} ) : ( - {isRequired ? t("required") : t("optional")} + + {isRequired ? t("required") : t("optional")} + )} {Object.entries(groupedBySourceLabel).map(([sourceLabel, sources], key) => ( // We don't know how to pluralize `sourceLabel` because it can be anything diff --git a/packages/ui/components/form/switch/SettingsToggle.tsx b/packages/ui/components/form/switch/SettingsToggle.tsx index f92b60995a..f8e2f3af13 100644 --- a/packages/ui/components/form/switch/SettingsToggle.tsx +++ b/packages/ui/components/form/switch/SettingsToggle.tsx @@ -53,7 +53,7 @@ function SettingsToggle({ switchContainerClassName )}>
    -
    +
    {Badge &&
    {Badge}
    }
    - {description &&

    {description}

    } + {description && ( +

    + {description} +

    + )}