diff --git a/packages/pluggableWidgets/barcode-scanner-web/package.json b/packages/pluggableWidgets/barcode-scanner-web/package.json index 9b0f5ca13b..d8b4e32a3d 100644 --- a/packages/pluggableWidgets/barcode-scanner-web/package.json +++ b/packages/pluggableWidgets/barcode-scanner-web/package.json @@ -37,7 +37,7 @@ "publish-marketplace": "rui-publish-marketplace", "release": "pluggable-widgets-tools release:web", "start": "pluggable-widgets-tools start:server", - "test": "pluggable-widgets-tools test:unit:web", + "test": "pluggable-widgets-tools test:unit:web:enzyme-free", "update-changelog": "rui-update-changelog-widget", "verify": "rui-verify-package-format" }, diff --git a/packages/pluggableWidgets/calendar-web/jest.config.js b/packages/pluggableWidgets/calendar-web/jest.config.js index 4b623cc8e0..f820408aa7 100644 --- a/packages/pluggableWidgets/calendar-web/jest.config.js +++ b/packages/pluggableWidgets/calendar-web/jest.config.js @@ -1,5 +1,4 @@ -const { join } = require("path"); -const base = require("@mendix/pluggable-widgets-tools/test-config/jest.config"); +const base = require("@mendix/pluggable-widgets-tools/test-config/jest.enzyme-free.config.js"); module.exports = { ...base, diff --git a/packages/pluggableWidgets/chart-playground-web/package.json b/packages/pluggableWidgets/chart-playground-web/package.json index 7f8436f6ba..52d0f99b37 100644 --- a/packages/pluggableWidgets/chart-playground-web/package.json +++ b/packages/pluggableWidgets/chart-playground-web/package.json @@ -35,7 +35,7 @@ "publish-marketplace": "rui-publish-marketplace", "release": "pluggable-widgets-tools release:web", "start": "pluggable-widgets-tools start:server", - "test": "pluggable-widgets-tools test:unit:web", + "test": "pluggable-widgets-tools test:unit:web:enzyme-free", "update-changelog": "rui-update-changelog-widget", "verify": "rui-verify-package-format" }, diff --git a/packages/pluggableWidgets/fieldset-web/package.json b/packages/pluggableWidgets/fieldset-web/package.json index fbfc9352bd..bca2c5a23b 100644 --- a/packages/pluggableWidgets/fieldset-web/package.json +++ b/packages/pluggableWidgets/fieldset-web/package.json @@ -37,7 +37,7 @@ "publish-marketplace": "rui-publish-marketplace", "release": "pluggable-widgets-tools release:web", "start": "pluggable-widgets-tools start:server", - "test": "pluggable-widgets-tools test:unit:web", + "test": "pluggable-widgets-tools test:unit:web:enzyme-free", "update-changelog": "rui-update-changelog-widget", "verify": "rui-verify-package-format" }, diff --git a/packages/pluggableWidgets/fieldset-web/src/__tests__/Fieldset.spec.tsx b/packages/pluggableWidgets/fieldset-web/src/__tests__/Fieldset.spec.tsx index 7d20cfd5a3..b5ded80743 100644 --- a/packages/pluggableWidgets/fieldset-web/src/__tests__/Fieldset.spec.tsx +++ b/packages/pluggableWidgets/fieldset-web/src/__tests__/Fieldset.spec.tsx @@ -1,4 +1,5 @@ -import { shallow } from "enzyme"; +import "@testing-library/jest-dom"; +import { render } from "@testing-library/react"; import { createElement, Fragment, ReactNode } from "react"; import { Fieldset, FieldsetProps } from "../components/Fieldset"; @@ -20,17 +21,17 @@ describe("Fieldset", () => { ); it("renders children and legend", () => { - const fieldset = shallow(
{defaultChildren}
); + const fieldset = render(
{defaultChildren}
); - expect(fieldset).toMatchSnapshot(); + expect(fieldset.asFragment()).toMatchSnapshot(); }); it("renders only children when no legend is passed", () => { - const fieldset = shallow( + const fieldset = render(
{defaultChildren}
); - expect(fieldset).toMatchSnapshot(); + expect(fieldset.asFragment()).toMatchSnapshot(); }); }); diff --git a/packages/pluggableWidgets/fieldset-web/src/__tests__/__snapshots__/Fieldset.spec.tsx.snap b/packages/pluggableWidgets/fieldset-web/src/__tests__/__snapshots__/Fieldset.spec.tsx.snap index 0176024dbb..d014dafac0 100644 --- a/packages/pluggableWidgets/fieldset-web/src/__tests__/__snapshots__/Fieldset.spec.tsx.snap +++ b/packages/pluggableWidgets/fieldset-web/src/__tests__/__snapshots__/Fieldset.spec.tsx.snap @@ -1,40 +1,42 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Fieldset renders children and legend 1`] = ` -
- - legend - - - -
+ +
+ + legend + + + +
+
`; exports[`Fieldset renders only children when no legend is passed 1`] = ` -
- - -
+ +
+ + +
+
`; diff --git a/packages/pluggableWidgets/file-uploader-web/package.json b/packages/pluggableWidgets/file-uploader-web/package.json index 5954592c10..076e822792 100644 --- a/packages/pluggableWidgets/file-uploader-web/package.json +++ b/packages/pluggableWidgets/file-uploader-web/package.json @@ -37,7 +37,7 @@ "release": "pluggable-widgets-tools release:web", "remove-nf-defaults": "node nf-defaults.mjs remove", "start": "pluggable-widgets-tools start:server", - "test": "pluggable-widgets-tools test:unit:web", + "test": "pluggable-widgets-tools test:unit:web:enzyme-free", "update-changelog": "rui-update-changelog-widget", "verify": "rui-verify-package-format" }, diff --git a/packages/pluggableWidgets/gallery-web/package.json b/packages/pluggableWidgets/gallery-web/package.json index 77cc9a1962..f488272eb7 100644 --- a/packages/pluggableWidgets/gallery-web/package.json +++ b/packages/pluggableWidgets/gallery-web/package.json @@ -36,7 +36,7 @@ "lint": "eslint src/ package.json", "release": "pluggable-widgets-tools release:web", "start": "pluggable-widgets-tools start:server", - "test": "pluggable-widgets-tools test:unit:web", + "test": "pluggable-widgets-tools test:unit:web:enzyme-free", "update-changelog": "rui-update-changelog-widget", "verify": "rui-verify-package-format" }, diff --git a/packages/pluggableWidgets/html-element-web/package.json b/packages/pluggableWidgets/html-element-web/package.json index 2f011663ad..f62b156e95 100644 --- a/packages/pluggableWidgets/html-element-web/package.json +++ b/packages/pluggableWidgets/html-element-web/package.json @@ -36,7 +36,7 @@ "publish-marketplace": "rui-publish-marketplace", "release": "pluggable-widgets-tools release:web", "start": "pluggable-widgets-tools start:server", - "test": "pluggable-widgets-tools test:unit:web", + "test": "pluggable-widgets-tools test:unit:web:enzyme-free", "update-changelog": "rui-update-changelog-widget", "verify": "rui-verify-package-format" }, diff --git a/packages/pluggableWidgets/image-web/package.json b/packages/pluggableWidgets/image-web/package.json index 6b37e0a3d4..58aa2dabb2 100644 --- a/packages/pluggableWidgets/image-web/package.json +++ b/packages/pluggableWidgets/image-web/package.json @@ -38,7 +38,7 @@ "publish-marketplace": "rui-publish-marketplace", "release": "pluggable-widgets-tools release:web", "start": "pluggable-widgets-tools start:server", - "test": "pluggable-widgets-tools test:unit:web", + "test": "pluggable-widgets-tools test:unit:web:enzyme-free", "update-changelog": "rui-update-changelog-widget", "verify": "rui-verify-package-format" }, diff --git a/packages/pluggableWidgets/image-web/src/components/Image/ui.tsx b/packages/pluggableWidgets/image-web/src/components/Image/ui.tsx index 9c6cd56879..6542248746 100644 --- a/packages/pluggableWidgets/image-web/src/components/Image/ui.tsx +++ b/packages/pluggableWidgets/image-web/src/components/Image/ui.tsx @@ -58,7 +58,9 @@ function ContentIcon(props: ImageContentIcon): ReactElement { "aria-label": props.altText, role: "img" } - : {}; + : { + role: "img" + }; const onClickProps = getImageContentOnClickProps(props.onClick, props.tabIndex); @@ -103,7 +105,9 @@ function getImageContentOnClickProps( tabIndex?: number ): HTMLAttributes { if (!onClick) { - return {}; + return { + role: "img" + }; } return { onClick, diff --git a/packages/pluggableWidgets/image-web/src/components/__tests__/Image.spec.tsx b/packages/pluggableWidgets/image-web/src/components/__tests__/Image.spec.tsx index d4aadf636a..d4ddca4e6c 100644 --- a/packages/pluggableWidgets/image-web/src/components/__tests__/Image.spec.tsx +++ b/packages/pluggableWidgets/image-web/src/components/__tests__/Image.spec.tsx @@ -1,24 +1,28 @@ -import { createElement } from "react"; -import { mount, render } from "enzyme"; -import { Image, ImageProps } from "../Image/Image"; -import { Lightbox } from "../Lightbox"; +import "@testing-library/jest-dom"; +import { render } from "@testing-library/react"; +import userEvent, { UserEvent } from "@testing-library/user-event"; +import { createElement, forwardRef } from "react"; import { ModalProps } from "react-overlays/esm/Modal"; +import { Image, ImageProps } from "../Image/Image"; jest.mock("../../assets/ic24-close.svg", () => "close-button-icon-svg"); -jest.mock("react-overlays/Modal", () => (props: ModalProps) => { - const MockName = "react-overlays-modal-mock"; - // The backdrop is rendered somewhere else in a portal, but for testing sake we put it here since we also mock. - const BackdropMockName = "react-overlays-modal-backdrop-mock"; - return ( - // @ts-expect-error lower case custom name to make clear it's a mock - - {props.children} - {/* @ts-expect-error lower case custom name to make clear it's a mock */} - {props.renderBackdrop?.({ onClick: jest.fn(), ref: jest.fn() })} - - ); -}); +jest.mock("react-overlays/Modal", () => + forwardRef((props: ModalProps, ref) => { + if (!props.show) return null; + const MockName = "react-overlays-modal-mock"; + // The backdrop is rendered somewhere else in a portal, but for testing sake we put it here since we also mock. + const BackdropMockName = "react-overlays-modal-backdrop-mock"; + return ( + // @ts-expect-error lower case custom name to make clear it's a mock + + {props.children} + {/* @ts-expect-error lower case custom name to make clear it's a mock */} + {props.renderBackdrop?.({ onClick: jest.fn(), ref: jest.fn() })} + + ); + }) +); const imageProps: ImageProps = { class: "", @@ -69,210 +73,200 @@ const iconProps: ImageProps = { }; describe("Image", () => { + let user: UserEvent; + + beforeEach(() => { + user = userEvent.setup(); + }); + it("renders the structure with an image", () => { - expect(render()).toMatchSnapshot(); + const image = render(); + expect(image.asFragment()).toMatchSnapshot(); }); it("renders the structure with an image and percentage dimensions", () => { - expect( - render() - ).toMatchSnapshot(); + const image = render( + + ); + expect(image.asFragment()).toMatchSnapshot(); }); it("renders the structure with a glyph icon", () => { - expect(render()).toMatchSnapshot(); + const image = render(); + expect(image.asFragment()).toMatchSnapshot(); }); it("renders the structure with an icon", () => { - expect(render()).toMatchSnapshot(); + const image = render(); + expect(image.asFragment()).toMatchSnapshot(); }); it("renders the structure as a background image", () => { - expect( - render(Image content} />) - ).toMatchSnapshot(); + const image = render( + Image content} /> + ); + expect(image.asFragment()).toMatchSnapshot(); }); describe("when the onClickType is action", () => { - it("calls the onClick when clicking on an image", () => { + it("calls the onClick when clicking on an image", async () => { const onClickMock = jest.fn(); - const imageRender = mount(); - - const image = imageRender.find("img"); - expect(image).toHaveLength(1); - - image.simulate("click"); + const { getByRole } = render(); + const image = getByRole("button"); + expect(image).toBeInTheDocument(); + await user.click(image); expect(onClickMock).toHaveBeenCalled(); }); it("has tabindex if there is an action with OnClick", () => { const onClickMock = jest.fn(); - const imageRender = mount( + const { getByRole } = render( ); - const image = imageRender.find("img"); - - expect(image.prop("tabIndex")).toBeDefined(); - expect(image.prop("tabIndex")).toBe(1); + const image = getByRole("button"); + expect(image.tabIndex).toBe(1); }); it("has no tabindex if there is no action with OnClick", () => { - const imageRender = mount(); - const image = imageRender.find("img"); - - expect(image.prop("tabIndex")).toBeUndefined(); + const { getByRole } = render(); + const image = getByRole("img"); + expect(image.tabIndex).toBe(-1); }); - it("calls the onClick when clicking on a glyph icon", () => { + it("calls the onClick when clicking on a glyph icon", async () => { const onClickMock = jest.fn(); - const imageRender = mount(); - - const glyphicon = imageRender.find("span"); - expect(glyphicon).toHaveLength(1); - - glyphicon.simulate("click"); + const { getByRole } = render(); + const icon = getByRole("button"); + expect(icon).toBeInTheDocument(); + await user.click(icon); expect(onClickMock).toHaveBeenCalled(); }); - it("calls the onClick when clicking on an icon", () => { + it("calls the onClick when clicking on an icon", async () => { const onClickMock = jest.fn(); - const imageRender = mount(); - - const glyphicon = imageRender.find("span"); - expect(glyphicon).toHaveLength(1); - - glyphicon.simulate("click"); + const { getByRole } = render(); + const icon = getByRole("button"); + expect(icon).toBeInTheDocument(); + await user.click(icon); expect(onClickMock).toHaveBeenCalled(); }); }); describe("when the onClickType is enlarge", () => { - it("shows a lightbox when the user clicks on the image", () => { - const imageRender = mount(); - expect(imageRender.find(Lightbox)).toHaveLength(0); - - const image = imageRender.find("img"); - expect(image).toHaveLength(1); - - image.simulate("click"); - expect(imageRender.find(Lightbox)).toHaveLength(1); + it("shows a lightbox when the user clicks on the image", async () => { + const { container, getByRole } = render(); + expect(container.querySelector(".mx-image-viewer-lightbox")).not.toBeInTheDocument(); + const image = getByRole("button"); + expect(image).toBeInTheDocument(); + await userEvent.click(image); + const lightbox = container.querySelector(".mx-image-viewer-lightbox-backdrop"); + expect(lightbox).toBeInTheDocument(); }); - it("closes the lightbox when the user clicks on the close button after opening it", () => { - const imageRender = mount(); - - const image = imageRender.find("img"); - expect(image).toHaveLength(1); - - image.simulate("click"); - expect(imageRender.find(Lightbox)).toHaveLength(1); - - const closeButton = imageRender.find("button"); - expect(closeButton).toHaveLength(1); - closeButton.simulate("click"); - - expect(imageRender.find(Lightbox)).toHaveLength(0); + it("closes the lightbox when the user clicks on the close button after opening it", async () => { + const { container, getByRole } = render(); + const image = getByRole("button"); + expect(image).toBeInTheDocument(); + await userEvent.click(image); + const lightbox = container.querySelector(".mx-image-viewer-lightbox-backdrop"); + expect(lightbox).toBeInTheDocument(); + const closeButton = container.querySelector(".close-button"); + expect(closeButton).toBeInTheDocument(); + await userEvent.click(closeButton!); + expect(lightbox).not.toBeInTheDocument(); }); }); - it("does not trigger on clicks from containers if clicked on the image", () => { + it("does not trigger on clicks from containers if clicked on the image", async () => { const onClickOuterMock = jest.fn(); const onClickImageMock = jest.fn(); - const imageRender = mount( + const { getByRole } = render(
); - - const image = imageRender.find("img"); - expect(image).toHaveLength(1); - - image.simulate("click"); + const image = getByRole("button"); + expect(image).toBeInTheDocument(); + await user.click(image); expect(onClickImageMock).toHaveBeenCalledTimes(1); expect(onClickOuterMock).not.toHaveBeenCalled(); }); describe("when there is an accessibility alt text", () => { it("is set properly on an image", () => { - const imageRender = mount(); - const image = imageRender.find("img"); - expect(image.prop("alt")).toBe("this is an awesome image"); + const { getByRole } = render(); + const image = getByRole("img"); + expect(image).toHaveAttribute("alt", "this is an awesome image"); }); it("is set properly on a glyphicon", () => { - const imageRender = mount(); - const image = imageRender.find("span"); - expect(image.prop("aria-label")).toBe("this is an awesome glyphicon"); - expect(image.prop("role")).toBe("img"); + const { getByRole } = render(); + const icon = getByRole("img"); + expect(icon).toHaveAttribute("aria-label", "this is an awesome glyphicon"); + expect(icon).toHaveAttribute("role", "img"); }); it("is set properly on an icon", () => { - const imageRender = mount(); - const image = imageRender.find("span"); - expect(image.prop("aria-label")).toBe("this is an awesome icon"); - expect(image.prop("role")).toBe("img"); + const { getByRole } = render(); + const icon = getByRole("img"); + expect(icon).toHaveAttribute("aria-label", "this is an awesome icon"); + expect(icon).toHaveAttribute("role", "img"); }); }); describe("when there is no accessibility alt text", () => { it("nothing is set on an image", () => { - const imageRender = mount(); - const image = imageRender.find("img"); - expect(image.prop("alt")).toBe(undefined); + const { getByRole } = render(); + const image = getByRole("img"); + expect(image).not.toHaveAttribute("alt"); }); it("nothing is set on a glyphicon", () => { - const imageRender = mount(); - const image = imageRender.find("span"); - expect(image).not.toHaveProperty("aria-label"); - expect(image).not.toHaveProperty("role"); + const { getByRole } = render(); + const icon = getByRole("img"); + expect(icon).not.toHaveAttribute("aria-label"); }); it("nothing is set on an icon", () => { - const imageRender = mount(); - const image = imageRender.find("span"); - expect(image).not.toHaveProperty("aria-label"); - expect(image).not.toHaveProperty("role"); + const { getByRole } = render(); + const icon = getByRole("img"); + expect(icon).not.toHaveAttribute("aria-label"); }); }); describe("when showing an image as a thumbnail", () => { it("includes the thumb=true URL param in the image", () => { - const imageRender = mount(); - const image = imageRender.find("img"); - expect(image.prop("src")).toContain("thumb=true"); + const { getByRole } = render(); + const image = getByRole("img") as HTMLImageElement; + expect(image.src).toContain("thumb=true"); }); - it("does not include the thumb=true URL param in the lightbox image", () => { - const imageRender = mount(); - - const image = imageRender.find("img"); - expect(image.prop("src")).toContain("thumb=true"); - expect(image).toHaveLength(1); - - image.simulate("click"); - - const allImages = imageRender.findWhere( - node => node.type() === "img" && node.prop("src").startsWith(imageProps.image) + it("does not include the thumb=true URL param in the lightbox image", async () => { + const { getByRole, getAllByRole } = render( + ); - expect(allImages).toHaveLength(2); - - expect(allImages.at(0).prop("src")).toContain("thumb=true"); - expect(allImages.at(1).prop("src")).not.toContain("thumb=true"); + const image = getByRole("button") as HTMLImageElement; + expect(image.src).toContain("thumb=true"); + await user.click(image); + + const allImages = getAllByRole("img") as HTMLImageElement[]; + expect(allImages.length).toBeGreaterThanOrEqual(2); + expect(allImages[0].src).not.toContain("thumb=true"); + expect(allImages[1].src).not.toContain("thumb=true"); }); }); describe("when showing as a background image", () => { it("shows the content", () => { - const imageRender = mount( + const { getByText } = render( Image content} /> ); - expect(imageRender.text()).toContain("Image content"); + expect(getByText("Image content")).toBeInTheDocument(); }); - it("properly handles on click event if configured by the user", () => { + it("properly handles on click event if configured by the user", async () => { const onClickMock = jest.fn(); - const imageRender = mount( + const { container } = render( { onClickType="action" /> ); - const backgroundImage = imageRender.find(".mx-image-viewer.mx-image-background"); - expect(backgroundImage).toHaveLength(1); - - backgroundImage.simulate("click"); + const backgroundImage = container.querySelector(".mx-image-viewer.mx-image-background"); + expect(backgroundImage).toBeInTheDocument(); + await user.click(backgroundImage!); expect(onClickMock).toHaveBeenCalledTimes(1); }); }); diff --git a/packages/pluggableWidgets/image-web/src/components/__tests__/__snapshots__/Image.spec.tsx.snap b/packages/pluggableWidgets/image-web/src/components/__tests__/__snapshots__/Image.spec.tsx.snap index 8a767eeb2a..7105b7bfe0 100644 --- a/packages/pluggableWidgets/image-web/src/components/__tests__/__snapshots__/Image.spec.tsx.snap +++ b/packages/pluggableWidgets/image-web/src/components/__tests__/__snapshots__/Image.spec.tsx.snap @@ -1,58 +1,72 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Image renders the structure as a background image 1`] = ` -
-
- Image content + +
+
+ Image content +
-
+ `; exports[`Image renders the structure with a glyph icon 1`] = ` -
- -
+ +
+ +
+
`; exports[`Image renders the structure with an icon 1`] = ` -
- -
+ +
+ +
+
`; exports[`Image renders the structure with an image 1`] = ` -
- -
+ +
+ +
+
`; exports[`Image renders the structure with an image and percentage dimensions 1`] = ` -
- -
+ +
+ +
+
`; diff --git a/packages/pluggableWidgets/maps-web/jest.config.js b/packages/pluggableWidgets/maps-web/jest.config.js index d01e24c5a0..6c49746721 100644 --- a/packages/pluggableWidgets/maps-web/jest.config.js +++ b/packages/pluggableWidgets/maps-web/jest.config.js @@ -1,6 +1,4 @@ -const base = require("@mendix/pluggable-widgets-tools/test-config/jest.config"); - module.exports = { - ...base, + ...require("@mendix/pluggable-widgets-tools/test-config/jest.enzyme-free.config.js"), transformIgnorePatterns: ["node_modules/(?!(.*leaflet.*))"] }; diff --git a/packages/pluggableWidgets/maps-web/src/components/__tests__/GoogleMap.spec.ts b/packages/pluggableWidgets/maps-web/src/components/__tests__/GoogleMap.spec.tsx similarity index 59% rename from packages/pluggableWidgets/maps-web/src/components/__tests__/GoogleMap.spec.ts rename to packages/pluggableWidgets/maps-web/src/components/__tests__/GoogleMap.spec.tsx index 678d8221ad..623e280ae8 100644 --- a/packages/pluggableWidgets/maps-web/src/components/__tests__/GoogleMap.spec.ts +++ b/packages/pluggableWidgets/maps-web/src/components/__tests__/GoogleMap.spec.tsx @@ -1,4 +1,5 @@ -import { shallow, ShallowWrapper } from "enzyme"; +import "@testing-library/jest-dom"; +import { render, RenderResult } from "@testing-library/react"; import { createElement } from "react"; import { GoogleMapContainer, GoogleMapsProps } from "../GoogleMap"; import { initialize } from "@googlemaps/jest-mocks"; @@ -35,52 +36,32 @@ describe("Google maps", () => { jest.clearAllMocks(); }); - const renderGoogleMap = (props: GoogleMapsProps): ShallowWrapper => - shallow(createElement(GoogleMapContainer, props)); + function renderGoogleMap(props: Partial = {}): RenderResult { + return render(); + } it("renders a map with right structure", () => { - const googleMaps = renderGoogleMap(defaultProps); - googleMaps.setProps({ - heightUnit: "percentageOfWidth", - widthUnit: "pixels" - }); - - expect(googleMaps).toMatchSnapshot(); + const { asFragment } = renderGoogleMap({ heightUnit: "percentageOfWidth", widthUnit: "pixels" }); + expect(asFragment()).toMatchSnapshot(); }); it("renders a map with pixels renders structure correctly", () => { - const googleMaps = renderGoogleMap(defaultProps); - googleMaps.setProps({ - heightUnit: "pixels", - widthUnit: "pixels" - }); - - expect(googleMaps).toMatchSnapshot(); + const { asFragment } = renderGoogleMap({ heightUnit: "pixels", widthUnit: "pixels" }); + expect(asFragment()).toMatchSnapshot(); }); it("renders a map with percentage of width and height units renders the structure correctly", () => { - const googleMaps = renderGoogleMap(defaultProps); - googleMaps.setProps({ - heightUnit: "percentageOfWidth", - widthUnit: "percentage" - }); - - expect(googleMaps).toMatchSnapshot(); + const { asFragment } = renderGoogleMap({ heightUnit: "percentageOfWidth", widthUnit: "percentage" }); + expect(asFragment()).toMatchSnapshot(); }); it("renders a map with percentage of parent units renders the structure correctly", () => { - const googleMaps = renderGoogleMap(defaultProps); - googleMaps.setProps({ - heightUnit: "percentageOfParent", - widthUnit: "percentage" - }); - - expect(googleMaps).toMatchSnapshot(); + const { asFragment } = renderGoogleMap({ heightUnit: "percentageOfParent", widthUnit: "percentage" }); + expect(asFragment()).toMatchSnapshot(); }); it("renders a map with markers", () => { - const googleMaps = renderGoogleMap(defaultProps); - googleMaps.setProps({ + const { asFragment } = renderGoogleMap({ locations: [ { title: "Mendix HQ", @@ -96,13 +77,11 @@ describe("Google maps", () => { } ] }); - - expect(googleMaps).toMatchSnapshot(); + expect(asFragment()).toMatchSnapshot(); }); it("renders a map with current location", () => { - const googleMaps = renderGoogleMap(defaultProps); - googleMaps.setProps({ + const { asFragment } = renderGoogleMap({ showCurrentLocation: true, currentLocation: { latitude: 51.906688, @@ -110,7 +89,6 @@ describe("Google maps", () => { url: "image:url" } }); - - expect(googleMaps).toMatchSnapshot(); + expect(asFragment()).toMatchSnapshot(); }); }); diff --git a/packages/pluggableWidgets/maps-web/src/components/__tests__/LeafletMap.spec.ts b/packages/pluggableWidgets/maps-web/src/components/__tests__/LeafletMap.spec.tsx similarity index 50% rename from packages/pluggableWidgets/maps-web/src/components/__tests__/LeafletMap.spec.ts rename to packages/pluggableWidgets/maps-web/src/components/__tests__/LeafletMap.spec.tsx index 33b71c2992..b6ec986bf8 100644 --- a/packages/pluggableWidgets/maps-web/src/components/__tests__/LeafletMap.spec.ts +++ b/packages/pluggableWidgets/maps-web/src/components/__tests__/LeafletMap.spec.tsx @@ -1,4 +1,5 @@ -import { shallow, ShallowWrapper } from "enzyme"; +import "@testing-library/jest-dom"; +import { render, RenderResult } from "@testing-library/react"; import { createElement } from "react"; import { LeafletMap, LeafletProps } from "../LeafletMap"; @@ -23,79 +24,47 @@ describe("Leaflet maps", () => { zoomLevel: 10 }; - const renderLeafletMap = (props: LeafletProps): ShallowWrapper => - shallow(createElement(LeafletMap, props)); + function renderLeafletMap(props: Partial = {}): RenderResult { + return render(); + } it("renders a map with right structure", () => { - const leafletMaps = renderLeafletMap(defaultProps); - leafletMaps.setProps({ - heightUnit: "percentageOfWidth", - widthUnit: "pixels" - }); - - expect(leafletMaps).toMatchSnapshot(); + const { asFragment } = renderLeafletMap({ heightUnit: "percentageOfWidth", widthUnit: "pixels" }); + expect(asFragment()).toMatchSnapshot(); }); it("renders a map with pixels renders structure correctly", () => { - const leafletMaps = renderLeafletMap(defaultProps); - leafletMaps.setProps({ - heightUnit: "pixels", - widthUnit: "pixels" - }); - - expect(leafletMaps).toMatchSnapshot(); + const { asFragment } = renderLeafletMap({ heightUnit: "pixels", widthUnit: "pixels" }); + expect(asFragment()).toMatchSnapshot(); }); it("renders a map with percentage of width and height units renders the structure correctly", () => { - const leafletMaps = renderLeafletMap(defaultProps); - leafletMaps.setProps({ - heightUnit: "percentageOfWidth", - widthUnit: "percentage" - }); - - expect(leafletMaps).toMatchSnapshot(); + const { asFragment } = renderLeafletMap({ heightUnit: "percentageOfWidth", widthUnit: "percentage" }); + expect(asFragment()).toMatchSnapshot(); }); it("renders a map with percentage of parent units renders the structure correctly", () => { - const leafletMaps = renderLeafletMap(defaultProps); - leafletMaps.setProps({ - heightUnit: "percentageOfParent", - widthUnit: "percentage" - }); - - expect(leafletMaps).toMatchSnapshot(); + const { asFragment } = renderLeafletMap({ heightUnit: "percentageOfParent", widthUnit: "percentage" }); + expect(asFragment()).toMatchSnapshot(); }); it("renders a map with HERE maps as provider", () => { - const leafletMaps = renderLeafletMap(defaultProps); - leafletMaps.setProps({ - mapProvider: "hereMaps" - }); - - expect(leafletMaps).toMatchSnapshot(); + const { asFragment } = renderLeafletMap({ mapProvider: "hereMaps" }); + expect(asFragment()).toMatchSnapshot(); }); it("renders a map with MapBox maps as provider", () => { - const leafletMaps = renderLeafletMap(defaultProps); - leafletMaps.setProps({ - mapProvider: "mapBox" - }); - - expect(leafletMaps).toMatchSnapshot(); + const { asFragment } = renderLeafletMap({ mapProvider: "mapBox" }); + expect(asFragment()).toMatchSnapshot(); }); it("renders a map with attribution", () => { - const leafletMaps = renderLeafletMap(defaultProps); - leafletMaps.setProps({ - attributionControl: true - }); - - expect(leafletMaps).toMatchSnapshot(); + const { asFragment } = renderLeafletMap({ attributionControl: true }); + expect(asFragment()).toMatchSnapshot(); }); it("renders a map with markers", () => { - const leafletMaps = renderLeafletMap(defaultProps); - leafletMaps.setProps({ + const { asFragment } = renderLeafletMap({ locations: [ { title: "Mendix HQ", @@ -111,13 +80,11 @@ describe("Leaflet maps", () => { } ] }); - - expect(leafletMaps).toMatchSnapshot(); + expect(asFragment()).toMatchSnapshot(); }); it("renders a map with current location", () => { - const leafletMaps = renderLeafletMap(defaultProps); - leafletMaps.setProps({ + const { asFragment } = renderLeafletMap({ showCurrentLocation: true, currentLocation: { latitude: 51.906688, @@ -125,7 +92,6 @@ describe("Leaflet maps", () => { url: "image:url" } }); - - expect(leafletMaps).toMatchSnapshot(); + expect(asFragment()).toMatchSnapshot(); }); }); diff --git a/packages/pluggableWidgets/maps-web/src/components/__tests__/__snapshots__/GoogleMap.spec.ts.snap b/packages/pluggableWidgets/maps-web/src/components/__tests__/__snapshots__/GoogleMap.spec.ts.snap deleted file mode 100644 index 4d3aa54aa8..0000000000 --- a/packages/pluggableWidgets/maps-web/src/components/__tests__/__snapshots__/GoogleMap.spec.ts.snap +++ /dev/null @@ -1,191 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Google maps renders a map with current location 1`] = ` - - - -`; - -exports[`Google maps renders a map with markers 1`] = ` - - - -`; - -exports[`Google maps renders a map with percentage of parent units renders the structure correctly 1`] = ` - - - -`; - -exports[`Google maps renders a map with percentage of width and height units renders the structure correctly 1`] = ` - - - -`; - -exports[`Google maps renders a map with pixels renders structure correctly 1`] = ` - - - -`; - -exports[`Google maps renders a map with right structure 1`] = ` - - - -`; diff --git a/packages/pluggableWidgets/maps-web/src/components/__tests__/__snapshots__/GoogleMap.spec.tsx.snap b/packages/pluggableWidgets/maps-web/src/components/__tests__/__snapshots__/GoogleMap.spec.tsx.snap new file mode 100644 index 0000000000..760c5e5c89 --- /dev/null +++ b/packages/pluggableWidgets/maps-web/src/components/__tests__/__snapshots__/GoogleMap.spec.tsx.snap @@ -0,0 +1,103 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Google maps renders a map with current location 1`] = ` + +
+
+
+
+
+ +`; + +exports[`Google maps renders a map with markers 1`] = ` + +
+
+
+
+
+ +`; + +exports[`Google maps renders a map with percentage of parent units renders the structure correctly 1`] = ` + +
+
+
+
+
+ +`; + +exports[`Google maps renders a map with percentage of width and height units renders the structure correctly 1`] = ` + +
+
+
+
+
+ +`; + +exports[`Google maps renders a map with pixels renders structure correctly 1`] = ` + +
+
+
+
+
+ +`; + +exports[`Google maps renders a map with right structure 1`] = ` + +
+
+
+
+
+ +`; diff --git a/packages/pluggableWidgets/maps-web/src/components/__tests__/__snapshots__/LeafletMap.spec.ts.snap b/packages/pluggableWidgets/maps-web/src/components/__tests__/__snapshots__/LeafletMap.spec.ts.snap deleted file mode 100644 index f286ffeca3..0000000000 --- a/packages/pluggableWidgets/maps-web/src/components/__tests__/__snapshots__/LeafletMap.spec.ts.snap +++ /dev/null @@ -1,503 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Leaflet maps renders a map with HERE maps as provider 1`] = ` -
-
- - - - -
-
-`; - -exports[`Leaflet maps renders a map with MapBox maps as provider 1`] = ` -
-
- - - - -
-
-`; - -exports[`Leaflet maps renders a map with attribution 1`] = ` -
-
- - - - -
-
-`; - -exports[`Leaflet maps renders a map with current location 1`] = ` -
-
- - - ", - }, - } - } - interactive={false} - key="marker_0" - position={ - { - "lat": 51.906688, - "lng": 4.48837, - } - } - /> - - -
-
-`; - -exports[`Leaflet maps renders a map with markers 1`] = ` -
-
- - - ", - }, - } - } - interactive={true} - key="marker_0" - position={ - { - "lat": 51.906688, - "lng": 4.48837, - } - } - title="Mendix HQ" - > - - - Mendix HQ - - - - ", - }, - } - } - interactive={true} - key="marker_1" - position={ - { - "lat": 51.922823, - "lng": 4.479632, - } - } - title="Gementee Rotterdam" - > - - - Gementee Rotterdam - - - - - -
-
-`; - -exports[`Leaflet maps renders a map with percentage of parent units renders the structure correctly 1`] = ` -
-
- - - - -
-
-`; - -exports[`Leaflet maps renders a map with percentage of width and height units renders the structure correctly 1`] = ` -
-
- - - - -
-
-`; - -exports[`Leaflet maps renders a map with pixels renders structure correctly 1`] = ` -
-
- - - - -
-
-`; - -exports[`Leaflet maps renders a map with right structure 1`] = ` -
-
- - - - -
-
-`; diff --git a/packages/pluggableWidgets/maps-web/src/components/__tests__/__snapshots__/LeafletMap.spec.tsx.snap b/packages/pluggableWidgets/maps-web/src/components/__tests__/__snapshots__/LeafletMap.spec.tsx.snap new file mode 100644 index 0000000000..3ae4c90fa0 --- /dev/null +++ b/packages/pluggableWidgets/maps-web/src/components/__tests__/__snapshots__/LeafletMap.spec.tsx.snap @@ -0,0 +1,1046 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Leaflet maps renders a map with HERE maps as provider 1`] = ` + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +`; + +exports[`Leaflet maps renders a map with MapBox maps as provider 1`] = ` + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +`; + +exports[`Leaflet maps renders a map with attribution 1`] = ` + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+ + Leaflet + + + + © + + OpenStreetMap + + contributors +
+
+
+
+
+
+ +`; + +exports[`Leaflet maps renders a map with current location 1`] = ` + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ map marker +
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +`; + +exports[`Leaflet maps renders a map with markers 1`] = ` + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ map marker +
+
+ map marker +
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +`; + +exports[`Leaflet maps renders a map with percentage of parent units renders the structure correctly 1`] = ` + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +`; + +exports[`Leaflet maps renders a map with percentage of width and height units renders the structure correctly 1`] = ` + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +`; + +exports[`Leaflet maps renders a map with pixels renders structure correctly 1`] = ` + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +`; + +exports[`Leaflet maps renders a map with right structure 1`] = ` + +
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +`; diff --git a/packages/pluggableWidgets/progress-bar-web/package.json b/packages/pluggableWidgets/progress-bar-web/package.json index c37ebffa13..3f78ab5643 100644 --- a/packages/pluggableWidgets/progress-bar-web/package.json +++ b/packages/pluggableWidgets/progress-bar-web/package.json @@ -38,7 +38,7 @@ "publish-marketplace": "rui-publish-marketplace", "release": "cross-env MPKOUTPUT=ProgressBar.mpk pluggable-widgets-tools release:web", "start": "cross-env MPKOUTPUT=ProgressBar.mpk pluggable-widgets-tools start:server", - "test": "pluggable-widgets-tools test:unit:web", + "test": "pluggable-widgets-tools test:unit:web:enzyme-free", "update-changelog": "rui-update-changelog-widget", "verify": "rui-verify-package-format" }, diff --git a/packages/pluggableWidgets/progress-bar-web/src/components/__tests__/ProgressBar.spec.tsx b/packages/pluggableWidgets/progress-bar-web/src/components/__tests__/ProgressBar.spec.tsx index e453ea0c0f..8696daa8fe 100644 --- a/packages/pluggableWidgets/progress-bar-web/src/components/__tests__/ProgressBar.spec.tsx +++ b/packages/pluggableWidgets/progress-bar-web/src/components/__tests__/ProgressBar.spec.tsx @@ -1,247 +1,138 @@ -import { Alert } from "@mendix/widget-plugin-component-kit/Alert"; -import { HTMLAttributes, mount, ReactWrapper, shallow } from "enzyme"; -import { createElement, CSSProperties, FunctionComponent } from "react"; +import "@testing-library/jest-dom"; +import { render, RenderResult } from "@testing-library/react"; +import userEvent, { UserEvent } from "@testing-library/user-event"; +import { createElement, ReactElement } from "react"; import { ProgressBar, ProgressBarProps } from "../ProgressBar"; -const RandomComponent: FunctionComponent = () =>
This is a random component
; -const progressBarSmallClassName = "progress-bar-small"; - describe("Progress bar", () => { - function getProgressBarLabelElement(progressBar: ReactWrapper): ReactWrapper { - return progressBar.find(".progress-bar"); - } - function getProgressBarStyle(progressBar: ReactWrapper): CSSProperties | undefined { - return getProgressBarLabelElement(progressBar).prop("style"); - } - const progress = 23; - const maximumValue = 100; const onClickSpy = jest.fn(); + const progress = 23; + let user: UserEvent; - it("has progress bar structure", () => { - const progressBar = shallow( + function renderProgressBar(props: Partial = {}): RenderResult { + return render( ); - expect(progressBar).toMatchSnapshot(); + } + + beforeEach(() => { + user = userEvent.setup(); }); - it("shows a positive progress", () => { - const progressBar = mount( - - ); + it("has progress bar structure", () => { + const progressBar = renderProgressBar(); + expect(progressBar.asFragment()).toMatchSnapshot(); + }); - expect(getProgressBarStyle(progressBar)).toEqual({ width: "23%" }); + it("shows a positive progress", () => { + const { container } = renderProgressBar(); + expect(container.querySelector(".progress-bar")).toHaveStyle({ width: "23%" }); }); - it("triggers an event when a clickable progress bar is clicked", () => { - const progressBar = mount( - - ); - const progressElement = progressBar.find(".progress"); - expect(progressElement.hasClass("widget-progress-bar-clickable")).toBe(true); - progressElement.simulate("click"); + it("triggers an event when a clickable progress bar is clicked", async () => { + const { container } = renderProgressBar(); + const progressElement = container.querySelector(".progress"); + expect(progressElement?.className.includes("widget-progress-bar-clickable")).toBe(true); + await user.click(progressElement!); expect(onClickSpy).toHaveBeenCalledTimes(1); }); it("handles a different range", () => { - const progressBar = mount( - - ); - + const { container } = renderProgressBar({ minValue: 20, maxValue: 30 }); // 23 on a range from 20 to 30 is 30% progress. - expect(getProgressBarStyle(progressBar)).toEqual({ width: "30%" }); + expect(container.querySelector(".progress-bar")).toHaveStyle({ width: "30%" }); }); it("clamps a current value lower than the minimum value to 0% progress", () => { - const progressBar = mount( - - ); - - expect(getProgressBarStyle(progressBar)).toEqual({ width: "0%" }); + const { container } = renderProgressBar({ currentValue: -20 }); + expect(container.querySelector(".progress-bar")).toHaveStyle({ width: "0%" }); }); it("clamps a current value higher than the maximum value to 100% progress", () => { - const progressBar = mount( - - ); - - expect(getProgressBarStyle(progressBar)).toEqual({ width: "100%" }); + const { container } = renderProgressBar({ currentValue: 110 }); + expect(container.querySelector(".progress-bar")).toHaveStyle({ width: "100%" }); }); it("is not clickable when there is no onClick handler provided", () => { - const progressBar = mount( - - ); - expect(progressBar.find(".progress").hasClass("widget-progress-bar-clickable")).toBe(false); + const { container } = renderProgressBar({ currentValue: 50, onClick: undefined }); + expect(container.querySelector(".progress")?.className.includes("widget-progress-bar-clickable")).toBe(false); }); describe("shows a runtime error Alert", () => { it("when the current value is lower than the minimum value", () => { - const progressBar = mount( - - ); - const alert = progressBar.find(Alert); - expect(alert).toHaveLength(1); - expect(alert.text()).toBe( + const { container } = renderProgressBar({ currentValue: -20 }); + const alert = container.querySelector(".alert-danger"); + expect(alert).toBeInTheDocument(); + expect(alert?.textContent).toBe( "Error in progress bar values: The progress value is lower than the minimum value." ); }); it("when the current value is higher than the maximum value", () => { - const progressBar = mount( - - ); - const alert = progressBar.find(Alert); - expect(alert).toHaveLength(1); - expect(alert.text()).toBe( + const { container } = renderProgressBar({ currentValue: 110 }); + const alert = container.querySelector(".alert-danger"); + expect(alert).toBeInTheDocument(); + expect(alert?.textContent).toBe( "Error in progress bar values: The progress value is higher than the maximum value." ); }); it("when the range of the progress bar is negative", () => { - const progressBar = mount( - - ); - const alert = progressBar.find(Alert); - expect(alert).toHaveLength(1); - expect(alert.text()).toBe( + const { container } = renderProgressBar({ minValue: 40, maxValue: 30, currentValue: 50 }); + const alert = container.querySelector(".alert-danger"); + expect(alert).toBeInTheDocument(); + expect(alert?.textContent).toBe( "Error in progress bar values: The maximum value is lower than the minimum value." ); }); }); describe("the label of the progressbar", () => { + const RandomComponent = (): ReactElement =>
This is a random component
; + const progressBarSmallClassName = "progress-bar-small"; + it("should accept static text", () => { - const progressBar = mount( - - ); - expect(progressBar.text()).toBe("This is your progress"); + const { container } = renderProgressBar({ label: "This is your progress" }); + expect(container.textContent).toBe("This is your progress"); }); it("should accept a component", () => { - const progressBar = mount( - } - class="" - /> - ); - expect(progressBar.find(RandomComponent)).toHaveLength(1); - expect(progressBar.text()).toContain("This is a random component"); + const { container, getByText } = renderProgressBar({ label: }); + expect(getByText("This is a random component")).toBeInTheDocument(); + expect(container.textContent).toContain("This is a random component"); }); it("should accept nothing", () => { - const progressBar = mount( - - ); - expect(progressBar.text()).toHaveLength(0); + const { container } = renderProgressBar({ label: null }); + // Should not render any label text + // Remove whitespace for strict check + expect(container.textContent?.trim()).toHaveLength(0); }); it("has a tooltip with the label text when the size is small and label type is textual", () => { - const progressBar = mount( - - ); - expect(getProgressBarLabelElement(progressBar).prop("title")).toBe("This is a label text"); + const { container } = renderProgressBar({ + label: "This is a label text", + class: progressBarSmallClassName + }); + const label = container.querySelector(".progress-bar"); + expect(label).toHaveAttribute("title", "This is a label text"); }); it("does not have a tooltip nor a label when the size is small and label type is custom", () => { - const progressBar = mount( - } - class={`${progressBarSmallClassName}`} - /> - ); - expect(getProgressBarLabelElement(progressBar).prop("title")).toBe(undefined); + const { container } = renderProgressBar({ + label: , + class: progressBarSmallClassName + }); + const label = container.querySelector(".progress-bar"); + expect(label).not.toHaveAttribute("title"); }); }); }); diff --git a/packages/pluggableWidgets/progress-bar-web/src/components/__tests__/__snapshots__/ProgressBar.spec.tsx.snap b/packages/pluggableWidgets/progress-bar-web/src/components/__tests__/__snapshots__/ProgressBar.spec.tsx.snap index 4d3bf64600..aad4f3ba7f 100644 --- a/packages/pluggableWidgets/progress-bar-web/src/components/__tests__/__snapshots__/ProgressBar.spec.tsx.snap +++ b/packages/pluggableWidgets/progress-bar-web/src/components/__tests__/__snapshots__/ProgressBar.spec.tsx.snap @@ -1,24 +1,21 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Progress bar has progress bar structure 1`] = ` -
+
- 23% +
+ 23% +
-
+ `;