diff --git a/apps/web/modules/bookings/views/bookings-single-view.tsx b/apps/web/modules/bookings/views/bookings-single-view.tsx index b9298c8c1b..94347610b1 100644 --- a/apps/web/modules/bookings/views/bookings-single-view.tsx +++ b/apps/web/modules/bookings/views/bookings-single-view.tsx @@ -321,6 +321,7 @@ export default function Success(props: PageProps) {
{t("back_to_bookings")} diff --git a/apps/web/playwright/booking/collectiveEventType/collectiveEventType.e2e.ts b/apps/web/playwright/booking/collectiveEventType/collectiveEventType.e2e.ts new file mode 100644 index 0000000000..cc01cb280c --- /dev/null +++ b/apps/web/playwright/booking/collectiveEventType/collectiveEventType.e2e.ts @@ -0,0 +1,54 @@ +import { test } from "../../lib/fixtures"; + +test.describe("Collective event type", () => { + const teamEventTitle = "Test Managed Event Type"; + let userId: number; + test.beforeEach(async ({ page, users, bookingPage }) => { + const userFixture = await users.create( + { name: "testuser" }, + { hasTeam: true, schedulingType: "COLLECTIVE", teamEventTitle } + ); + await userFixture.apiLogin(); + userId = userFixture.id; + await page.goto("/event-types"); + await bookingPage.goToEventType(teamEventTitle); + }); + test("Book a Collective event type", async ({ bookingPage }) => { + const eventTypePage = await bookingPage.previewEventType(); + await bookingPage.selectTimeSlot(eventTypePage); + await bookingPage.fillEmailAndName(eventTypePage); + await bookingPage.confirmBooking(eventTypePage); + await bookingPage.backToBookings(eventTypePage); + await bookingPage.assertLabelWithCorrectTeamName(eventTypePage, teamEventTitle); + await bookingPage.assertBookingWithCorrectTitleAndDescription(eventTypePage, { + profileName: "testuser", + bookingName: teamEventTitle, + teamName: `user-id-${userId}'s Team`, + }); + await bookingPage.clickOnBooking(eventTypePage, teamEventTitle); + await bookingPage.rescheduleBooking(eventTypePage); + await bookingPage.assertBookingRescheduled(eventTypePage); + await bookingPage.cancelBookingWithReason(eventTypePage); + await bookingPage.assertBookingCanceled(eventTypePage); + }); + test("Book a Collective event type (with added guest)", async ({ bookingPage }) => { + const eventTypePage = await bookingPage.previewEventType(); + await bookingPage.selectTimeSlot(eventTypePage); + await bookingPage.fillEmailAndName(eventTypePage); + await bookingPage.addGuests(eventTypePage, { guests: ["test@example.com"] }); + await bookingPage.confirmBooking(eventTypePage); + await bookingPage.backToBookings(eventTypePage); + await bookingPage.assertLabelWithCorrectTeamName(eventTypePage, teamEventTitle); + await bookingPage.assertBookingWithCorrectTitleAndDescription(eventTypePage, { + profileName: "testuser", + bookingName: teamEventTitle, + teamName: `user-id-${userId}'s Team`, + aditionalGuestEmail: "test@example.com", + }); + await bookingPage.clickOnBooking(eventTypePage, teamEventTitle); + await bookingPage.rescheduleBooking(eventTypePage); + await bookingPage.assertBookingRescheduled(eventTypePage); + await bookingPage.cancelBookingWithReason(eventTypePage); + await bookingPage.assertBookingCanceled(eventTypePage); + }); +}); diff --git a/apps/web/playwright/fixtures/regularBookings.ts b/apps/web/playwright/fixtures/regularBookings.ts index 565340ccc7..9b0baab023 100644 --- a/apps/web/playwright/fixtures/regularBookings.ts +++ b/apps/web/playwright/fixtures/regularBookings.ts @@ -26,6 +26,8 @@ interface QuestionActions { [key: string]: () => Promise; } +type teamBookingtypes = { isManagedType?: boolean; isRoundRobinType?: boolean; isCollectiveType?: boolean }; + type customLocators = { shouldChangeSelectLocator: boolean; shouldUseLastRadioGroupLocator: boolean; @@ -205,7 +207,12 @@ export function createBookingPageFixture(page: Page) { goToEventType: async (eventType: string) => { await page.getByRole("link", { name: eventType }).click(); }, - + goToPage: async (pageName: string, page: Page) => { + await page.getByRole("link", { name: pageName }).click(); + }, + backToBookings: async (page: Page) => { + await page.getByTestId("back-to-bookings").click(); + }, goToTab: async (tabName: string) => { await page.getByTestId(`vertical-tab-${tabName}`).click(); }, @@ -405,17 +412,102 @@ export function createBookingPageFixture(page: Page) { const confirmButton = options.isReschedule ? "confirm-reschedule-button" : "confirm-book-button"; await fillAllQuestions(eventTypePage, questions, options); await eventTypePage.getByTestId(confirmButton).click(); - await eventTypePage.waitForTimeout(400); - if (await eventTypePage.getByRole("heading", { name: "Could not book the meeting." }).isVisible()) { - await eventTypePage.getByTestId("back").click(); - await eventTypePage.getByTestId("time").last().click(); - await fillAllQuestions(eventTypePage, questions, options); - await eventTypePage.getByTestId(confirmButton).click(); - } const scheduleSuccessfullyPage = eventTypePage.getByText(scheduleSuccessfullyText); await scheduleSuccessfullyPage.waitFor({ state: "visible" }); await expect(scheduleSuccessfullyPage).toBeVisible(); }, + addGuests: async (eventTypePage: Page, options: { guests: string[] }) => { + await eventTypePage.getByTestId("add-guests").click(); + for (const guest of options.guests) { + await eventTypePage.getByPlaceholder("Email").fill(guest); + } + }, + createTeam: async (name: string) => { + await page.getByTestId("teams-test").click(); + await page.getByTestId("new-team-btn").click(); + await page.getByPlaceholder("Acme Inc.").click(); + await page.getByPlaceholder("Acme Inc.").fill(name); + await page.getByTestId("continue-button").click(); + await page.getByTestId("publish-button").click(); + + await page.getByTestId("vertical-tab-Back").click(); + }, + + createTeamEventType: async (name: string, options: teamBookingtypes) => { + await page.getByTestId("new-event-type").click(); + await page.getByTestId("option-0").click(); + + // We first simulate to create a default event type to check if managed option is not available + + const managedEventDescription = (await localize("en"))("managed_event_description"); + const roundRobinEventDescription = (await localize("en"))("round_robin_description"); + const collectiveEventDescription = (await localize("en"))("collective_description"); + const quickChatText = (await localize("en"))("quick_chat"); + await expect(page.locator("div").filter({ hasText: managedEventDescription })).toBeHidden(); + await page.getByTestId("dialog-rejection").click(); + + await page.getByTestId("new-event-type").click(); + await page.getByTestId("option-team-1").click(); + await page.getByPlaceholder(quickChatText).fill(name); + if (options.isCollectiveType) { + await page + .locator("div") + .filter({ hasText: `Collective${collectiveEventDescription}` }) + .getByRole("radio") + .first() + .click(); + } + + if (options.isRoundRobinType) { + await page + .locator("div") + .filter({ hasText: `Round Robin${roundRobinEventDescription}` }) + .getByRole("radio") + .nth(1) + .click(); + } + + if (options.isManagedType) { + await page + .locator("div") + .filter({ hasText: `Managed Event${managedEventDescription}` }) + .getByRole("radio") + .last() + .click(); + + const managedEventClarification = (await localize("en"))("managed_event_url_clarification"); + await expect(page.getByText(managedEventClarification)).toBeVisible(); + } + + const continueText = (await localize("en"))("continue"); + const toast = page.getByTestId("toast-success"); + + await page.getByRole("button", { name: continueText }).click(); + expect(toast).toBeTruthy(); + await page.getByTestId("update-eventtype").click(); + }, + assertLabelWithCorrectTeamName: async (page: Page, teamName: string) => { + await expect(page.getByRole("link", { name: teamName }).first()).toBeVisible(); + }, + assertBookingWithCorrectTitleAndDescription: async ( + page: Page, + options: { profileName: string; bookingName: string; teamName: string; aditionalGuestEmail?: string } + ) => { + options.aditionalGuestEmail + ? await expect( + page.getByRole("link", { + name: `${options.bookingName} between ${options.teamName} and ${options.profileName} You , ${options.profileName} and ${options.aditionalGuestEmail}`, + }) + ).toBeVisible() + : await expect( + page.getByRole("link", { + name: `${options.bookingName} between ${options.teamName} and ${options.profileName} You and ${options.profileName}`, + }) + ).toBeVisible(); + }, + clickOnBooking: async (page: Page, teamName: string) => { + await page.getByRole("link", { name: teamName }).first().click(); + }, checkField: async (question: string, options?: { isOptional: boolean }) => { if (options?.isOptional) { @@ -635,5 +727,12 @@ export function createBookingPageFixture(page: Page) { await page.getByTestId("booking-item").first().getByText("Reject").click(); await page.getByTestId("rejection-confirm").click(); }, + fillEmailAndName: async (eventTypePage: Page) => { + const emailLabel = (await localize("en"))("email_address"); + const nameLabel = (await localize("en"))("your_name"); + + await eventTypePage.getByLabel(emailLabel).fill(EMAIL); + await eventTypePage.getByLabel(nameLabel).fill("testuser"); + }, }; } diff --git a/packages/features/ee/teams/components/CreateANewTeamForm.tsx b/packages/features/ee/teams/components/CreateANewTeamForm.tsx index beabedb1d6..4aa012d88b 100644 --- a/packages/features/ee/teams/components/CreateANewTeamForm.tsx +++ b/packages/features/ee/teams/components/CreateANewTeamForm.tsx @@ -158,7 +158,8 @@ export const CreateANewTeamForm = () => { color="primary" EndIcon={ArrowRight} type="submit" - className="w-full justify-center"> + className="w-full justify-center" + data-testid="continue-button"> {t(flag.submitLabel)}
diff --git a/packages/features/shell/Shell.tsx b/packages/features/shell/Shell.tsx index 4511ef8418..538f9e234c 100644 --- a/packages/features/shell/Shell.tsx +++ b/packages/features/shell/Shell.tsx @@ -742,7 +742,7 @@ const NavigationItem: React.FC<{ /> )} {isLocaleReady ? ( - +
{t(item.name)}
{item.badge && item.badge}