Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jest `Cannot find module 'react-compare-slider' (v3.X) #144

Closed
stevebutler2210 opened this issue Apr 29, 2024 · 6 comments · Fixed by #143
Closed

Jest `Cannot find module 'react-compare-slider' (v3.X) #144

stevebutler2210 opened this issue Apr 29, 2024 · 6 comments · Fixed by #143
Assignees
Labels
bug Something isn't working

Comments

@stevebutler2210
Copy link

Running version 3.X of the package is working fine in Storybook etc, however when we come to write tests for our component, we get the following error:

Test suite failed to run

Cannot find module 'react-compare-slider' from 'components/BeforeAfter/BeforeAfter.test.tsx'

Reproduction
The component

// components/BeforeAfter/index.tsx

import classNames from "classnames/bind";
import { useTranslation } from "next-i18next";
import { ReactCompareSlider } from "react-compare-slider";
import Icon, { IconName } from "@/components/Icon";
import breakpoints from "@/constants/breakpoints";
import CustomImage from "../CustomImage";
import styles from "./BeforeAfter.module.scss";

const cx = classNames.bind(styles);

export type BeforeAfterProps = {
  /**
   * The title text. Required.
   */
  title: string;
  /**
   * Optional body copy.
   */
  body?: string;
  /**
   * Optional boolean prop to show/hide the divider. Defaults to false.
   */
  divider?: boolean;
  /**
   * Image to use for the 'before' view.
   */
  beforeImage: { altText: string; src: string };
  /**
   * Image to use for the 'after' view.
   */
  afterImage: { altText: string; src: string };
};

const BeforeAfter = ({
  title,
  body,
  divider = false,
  beforeImage,
  afterImage,
}: BeforeAfterProps) => {
  const { t } = useTranslation("common");

  const imageOne = (
    <div className={cx("imageWrap")}>
      <CustomImage
        alt={beforeImage.altText}
        src={`${beforeImage.src}?io=transform:fit`}
        fill
        sizes={`(max-width: ${breakpoints.s}px) 100vw, (max-width: ${breakpoints.oversize}px) 50vw, 960px`} // TODO
      />
    </div>
  );

  const imageTwo = (
    <div className={cx("imageWrap")}>
      <CustomImage
        alt={afterImage.altText}
        src={`${afterImage.src}?io=transform:fit`}
        fill
        sizes={`(max-width: ${breakpoints.s}px) 100vw, (max-width: ${breakpoints.oversize}px) 50vw, 960px`} // TODO
      />
    </div>
  );

  const CustomHandle: React.FC = () => {
    return (
      <div className={cx("customHandle")}>
        <div className={cx("line")}></div>
        <div className={cx("handle")}>
          <Icon name={IconName.DOUBLE_CHEVRON} />
        </div>
        <div className={cx("line")}></div>
      </div>
    );
  };

  return (
    <section className="u-sectionPadding-h">
      <div className={cx("contentWrap", divider && "divider")}>
        <div className={cx("textWrap")}>
          <h4 className={cx("title", "u-strong")}>{title}</h4>
          {body && <p className={cx("body")}>{body}</p>}
        </div>
        <div className={cx("compareImagesWrap")}>
          <ReactCompareSlider
            itemOne={imageOne}
            itemTwo={imageTwo}
            handle={<CustomHandle />}
          />

          <div className={cx("labels")}>
            <h5 className="h6 u-strong">{t("before-after.before")}</h5>
            <h5 className="h6 u-strong">{t("before-after.after")}</h5>
          </div>
        </div>
      </div>
    </section>
  );
};

export default BeforeAfter;

Failing test

import { render, screen } from "@testing-library/react";
import BeforeAfter from ".";

jest.mock("next-i18next", () => ({
  useTranslation: () => ({
    t: (key: string) => key,
  }),
}));

describe("BeforeAfter component", () => {
  // Basic render test
  it("renders correctly", () => {
    render(
      <BeforeAfter
        title="Test Title"
        beforeImage={{ altText: "Before Image", src: "before.jpg" }}
        afterImage={{ altText: "After Image", src: "after.jpg" }}
      />,
    );
    expect(screen.getByText("Test Title")).toBeInTheDocument();
    expect(screen.getByText("before-after.before")).toBeInTheDocument();
    expect(screen.getByText("before-after.after")).toBeInTheDocument();
  });
});

Expected Behaviour
A test using a component that utilises react-compare-slider should run without errors, using version 3.X of the library.

Actual Behaviour
When running version 3.X (tested 3.1.0 and 3.0.1), the above error occurs when running a jest test for a component that uses the library.

Downgrading to version 2.2.0 resolves the issue.

@nerdyman
Copy link
Owner

Thanks for opening this @stevebutler2210. v3 dropped the CommonJS exports and now only provides ES modules so the issue is probably to do with that.

Are you using any build system on top of Jest like typescript-eslint, custom Webpack setup, etc?

@stevebutler2210
Copy link
Author

Hey @nerdyman, thanks for the speedy response. We're using Next JS, so it's using webpack, but we've not really done much customisation of the setup etc

@nerdyman
Copy link
Owner

Thanks @stevebutler2210. I'll spin up a Next project and see if I can repro. Do you know which node and next versions you're using?

@stevebutler2210
Copy link
Author

Thanks @nerdyman, that would be great! I'm running on Next 14.1.0 and Node 20.11.1

@nerdyman
Copy link
Owner

nerdyman commented May 3, 2024

Good news is I can repro this but I'm not sure how to resolve it yet. I'd rather not start publishing CommonJS modules again just to appease Jest but ESM support isn't there yet jestjs/jest#9430.

I'll try some stuff out and if all else fails I'll add CJS modules back to the package.

@nerdyman nerdyman added the bug Something isn't working label May 3, 2024
@nerdyman nerdyman self-assigned this May 3, 2024
@nerdyman nerdyman mentioned this issue Sep 12, 2024
4 tasks
@nerdyman
Copy link
Owner

This should be resolved in v4. I need to do testing on other devices before doing a final release but there is a pre-release with the CJS modules published.

It can be installed by running:

pnpm i react-compare-slider@beta
# Or
yarn add react-compare-slider@beta
# Or
npm i react-compare-slider@beta

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants