Files
calendar/packages/ui/components/test-setup.tsx
T
Rajiv SahalGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>Peer RichelsenHariom Balhara
8c39210a12 fix: scroll issues in Embed (#26583)
* chore: add new view for two step slot selection for embed

* fix: make sure two step slot selection is false by default

* chore: update embed playground to showcase two step slot selection

* chore: add tests

* chore: update embed snippet generator code to include two step slot selection

* chore: update docs

* fix: back button styling

* chore: implement feedback from cubic

* fix: add missing isEnableTwoStepSlotSelectionVisible properties to test mock store

Co-Authored-By: unknown <>

* chore: implement PR feedback

* chore: update slot selection modal

* chore: add prop to hide available times header

* fix: scope two-step slot selection visibility to mobile only

Restores the isMobile check in the timeslot visibility guard to ensure
desktop embeds continue to show the booking UI when two-step slot
selection is enabled. The feature should only hide the timeslot list
on mobile devices.

Addresses Cubic AI review feedback (confidence 9/10).

Co-Authored-By: unknown <>

* fixup: use translations for loading instead of actual word

* fix: type check

* fix: add window.matchMedia mock for jsdom test environment

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: add window.matchMedia mock to packages/testing/src/setupVitest.ts

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: unit tests failing

* add a width style to the two-step slot selection embed container.

* refactor: rename enableTwoStepSlotSelection to useSlotsViewOnSmallScreen

- Rename external-facing embed config option from enableTwoStepSlotSelection to useSlotsViewOnSmallScreen
- Update URL parameter parsing in embed-iframe.ts
- Update type definitions in types.ts and index.d.ts
- Update internal variable names to slotsViewOnSmallScreen for consistency
- Update documentation, playground examples, and tests

Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com>

* Add config to prefill all booking fields so that slot has confirm button along with it

* chore: implement PR feedback

* fix: move twoStepSlotSelection embed outside misc-embeds div to fix e2e test

The e2e test was failing because the misc-embeds div content was
intercepting pointer events on mobile viewport. This follows the same
pattern used for skeletonDemo - the embed is now outside misc-embeds
and the div is hidden when testing this namespace.

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: prevent pointer event interception in twoStepSlotSelection embed

Hide heading and note elements and set pointer-events: none on container
elements while keeping pointer-events: auto on the iframe container.
This prevents the container from intercepting clicks on the iframe
during mobile viewport e2e tests.

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: hide all non-essential content for twoStepSlotSelection e2e test

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: disable pointer-events on body for twoStepSlotSelection e2e test

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: remove pointer-events: auto on container to let clicks pass through to iframe

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: explicitly set pointer-events: none on container and inline-embed-container

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: also set pointer-events: none on html element to prevent interception

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: make .place div fill viewport for twoStepSlotSelection e2e test

Co-Authored-By: rajiv@cal.com <sahalrajiv6900@gmail.com>

* fix: failing embed tests

* fixup

* fixup fixup

* fix: failing tests

* fix: update checks for verifying prefilled date

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
2026-01-21 15:44:33 -03:00

126 lines
3.0 KiB
TypeScript

import matchers from "@testing-library/jest-dom/matchers";
import { cleanup } from "@testing-library/react";
import React from "react";
import { afterEach, expect, vi } from "vitest";
// For next.js webapp compponent that use "preserve" for jsx in tsconfig.json
global.React = React;
vi.mock("framer-motion", () => ({
AnimatePresence: ({ children }: { children: React.ReactNode }) => <>{children}</>,
LazyMotion: ({ children }: { children: React.ReactNode }) => <>{children}</>,
m: {
span: ({ children }: { children: React.ReactNode }) => <span>{children}</span>,
div: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
},
useReducedMotion: () => false,
useAnimate: () => [null, vi.fn()],
}));
// Add new mocks
vi.mock("next-seo", () => ({
NextSeo: () => null,
LogoJsonLd: () => null,
}));
vi.mock("@calcom/features/ee/organizations/hooks", () => ({
useOrgBrandingValues() {
return {};
},
}));
vi.mock("react-sticky-box", () => ({
default: ({ children }: { children: React.ReactNode }) => <div data-testid="sticky-box">{children}</div>,
}));
vi.mock("@calcom/features/ee/organizations/context/provider", () => ({
useOrgBranding() {
return {};
},
}));
vi.mock("next/navigation", async () => ({
...((await vi.importActual("next/navigation")) as object),
useRouter() {
return {
route: "/",
pathname: "",
query: {},
asPath: "",
push: vi.fn(),
};
},
useSearchParams() {
return new URLSearchParams();
},
}));
vi.mock("@calcom/lib/OgImages", async () => {
return {};
});
vi.mock("@calcom/lib/hooks/useLocale", () => ({
useLocale: () => {
return {
t: (str: string) => str,
isLocaleReady: true,
i18n: {
language: "en",
defaultLocale: "en",
locales: ["en"],
exists: () => false,
},
};
},
}));
vi.mock("@calcom/atoms/hooks/useIsPlatform", () => ({
useIsPlatform: () => {
return false;
},
}));
vi.mock("@calcom/features/eventtypes/lib/getEventTypesByViewer", () => ({}));
vi.mock("@calcom/features/eventtypes/lib/getEventTypesPublic", () => ({}));
vi.mock("@calcom/ui/classNames", () => ({
default: (...args: string[]) => {
return args.filter(Boolean).join(" ");
},
}));
expect.extend({
tabToBeDisabled(received) {
const isDisabled = received.classList.contains("pointer-events-none");
return {
pass: isDisabled,
message: () => `Expected tab to be disabled`,
};
},
});
global.ResizeObserver = vi.fn().mockImplementation(() => ({
observe: vi.fn(),
unobserve: vi.fn(),
disconnect: vi.fn(),
}));
Object.defineProperty(window, "matchMedia", {
writable: true,
value: vi.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: vi.fn(),
removeListener: vi.fn(),
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
dispatchEvent: vi.fn(),
})),
});
expect.extend(matchers);
afterEach(() => {
cleanup();
});