From f4944a05c907678b4b08d0bc93a56052ec8d4cd6 Mon Sep 17 00:00:00 2001 From: Anik Dhabal Babu <81948346+anikdhabal@users.noreply.github.com> Date: Tue, 26 Aug 2025 12:40:40 +0530 Subject: [PATCH] fix: recurring event isn't working (#23346) --- apps/web/playwright/event-types.e2e.ts | 31 +++++++++++++++++++ apps/web/playwright/lib/testUtils.ts | 6 ++-- .../components/event-meta/Occurences.tsx | 13 ++++---- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/apps/web/playwright/event-types.e2e.ts b/apps/web/playwright/event-types.e2e.ts index c86bfc7a40..103a4df4a1 100644 --- a/apps/web/playwright/event-types.e2e.ts +++ b/apps/web/playwright/event-types.e2e.ts @@ -444,6 +444,37 @@ test.describe("Event Types tests", () => { await expect(currentTimezone).toHaveClass(/cursor-not-allowed/); await expect(page.getByText("New York")).toBeVisible(); }); + test("should create recurring event and successfully book multiple occurrences", async ({ page }) => { + const nonce = randomString(3); + const eventTitle = `Recurring Event Test ${nonce}`; + + await createNewUserEventType(page, { eventTitle }); + + await page.waitForSelector('[data-testid="event-title"]'); + await expect(page.getByTestId("vertical-tab-basics")).toHaveAttribute("aria-current", "page"); + await page.click("[data-testid=vertical-tab-recurring]"); + await expect(page.locator("[data-testid=recurring-event-collapsible]")).toBeHidden(); + await page.click("[data-testid=recurring-event-check]"); + await expect(page.locator("[data-testid=recurring-event-collapsible]")).toBeVisible(); + + await page.locator("[data-testid=recurring-event-collapsible] input[type=number]").nth(1).fill("3"); + + await saveEventType(page); + + await gotoBookingPage(page); + + await expect(page.locator("[data-testid=occurrence-input]")).toHaveValue("3"); + + await selectFirstAvailableTimeSlotNextMonth(page); + + await expect(page.locator("[data-testid=recurring-dates]")).toBeVisible(); + + await bookTimeSlot(page, { isRecurringEvent: true }); + + await expect(page.locator("[data-testid=success-page]")).toBeVisible(); + + await expect(page.locator("text=3 occurrences")).toBeVisible(); + }); }); test.describe("Interface Language Tests", () => { diff --git a/apps/web/playwright/lib/testUtils.ts b/apps/web/playwright/lib/testUtils.ts index a56ba0a8e3..6988f64503 100644 --- a/apps/web/playwright/lib/testUtils.ts +++ b/apps/web/playwright/lib/testUtils.ts @@ -155,6 +155,7 @@ export const bookTimeSlot = async ( title?: string; attendeePhoneNumber?: string; expectedStatusCode?: number; + isRecurringEvent?: boolean; } ) => { // --- fill form @@ -166,8 +167,9 @@ export const bookTimeSlot = async ( if (opts?.attendeePhoneNumber) { await page.fill('[name="attendeePhoneNumber"]', opts.attendeePhoneNumber ?? "+918888888888"); } - await submitAndWaitForResponse(page, "/api/book/event", { - action: () => page.locator('[name="email"]').press("Enter"), + const url = opts?.isRecurringEvent ? "/api/book/recurring-event" : "/api/book/event"; + await submitAndWaitForResponse(page, url, { + action: () => page.locator('[data-testid="confirm-book-button"]').click(), expectedStatusCode: opts?.expectedStatusCode, }); }; diff --git a/packages/features/bookings/components/event-meta/Occurences.tsx b/packages/features/bookings/components/event-meta/Occurences.tsx index adc42f9743..816fa654c3 100644 --- a/packages/features/bookings/components/event-meta/Occurences.tsx +++ b/packages/features/bookings/components/event-meta/Occurences.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from "react"; -import { useBookerStore } from "@calcom/features/bookings/Booker/store"; +import { useBookerStoreContext } from "@calcom/features/bookings/Booker/BookerStoreProvider"; import type { BookerEvent } from "@calcom/features/bookings/types"; import { useLocale } from "@calcom/lib/hooks/useLocale"; import { parseRecurringDates } from "@calcom/lib/parse-dates"; @@ -14,16 +14,15 @@ import { useBookerTime } from "../../Booker/components/hooks/useBookerTime"; export const EventOccurences = ({ event }: { event: Pick }) => { const maxOccurences = event.recurringEvent?.count || null; const { t, i18n } = useLocale(); - const [setRecurringEventCount, recurringEventCount, setOccurenceCount, occurenceCount] = useBookerStore( - (state) => [ + const [setRecurringEventCount, recurringEventCount, setOccurenceCount, occurenceCount] = + useBookerStoreContext((state) => [ state.setRecurringEventCount, state.recurringEventCount, state.setOccurenceCount, state.occurenceCount, - ] - ); - const selectedTimeslot = useBookerStore((state) => state.selectedTimeslot); - const bookerState = useBookerStore((state) => state.state); + ]); + const selectedTimeslot = useBookerStoreContext((state) => state.selectedTimeslot); + const bookerState = useBookerStoreContext((state) => state.state); const { timezone, timeFormat } = useBookerTime(); const [warning, setWarning] = useState(false); // Set initial value in booker store.