i want to test dynamic import component with jest, but every time i get error ” Unable to find an element”, i have tried to mock dynamic import with different ways, and also tried to increase test time out but nothing works for me yet.
here is how i imported the component:
"use client";
import React, { FC, useEffect, useMemo, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { AppDispatch } from "../../../../redux/store";
import { Row } from "react-bootstrap";
import { useTranslation, i18n } from "next-i18next";
import { hasMemberPermission } from "../../../../utils/utils";
import { fetchBountyList } from "../../../../redux/features/getBountyListSlice";
import { fetchAssetsList } from "../../../../redux/features/getAssetListDetails";
import { InternalPageTitle } from "../../../internalPagesCommons/ui";
import { PremiumSubscription } from "../../../ui/reusable/premiumSubscriptionBox";
import TLSpinner from "../../../ui/reusable/tlSpinner/TLSpinner";
import Spinner from "../../../ui/reusable/spinner/Spinner";
import {
EngagementSubscriptionSkeleton,
ListTableSkeleton,
} from "../../../internalPagesCommons/costumSkelton";
import dynamic from "next/dynamic";
// import EngagementList from "./../engagementList";
// import EngagementSubscription from "./../engagementSubscription";
const Bounty: FC<{
accessByUnitTest?: boolean;
assetsByUnitTest?: any;
saveData?: any;
bountiesByUnitTest?: any;
}> = ({
accessByUnitTest = false,
assetsByUnitTest,
saveData = () => {
return;
},
bountiesByUnitTest,
}) => {
const EngagementList = useMemo(
() =>
dynamic(() => import("./../engagementList"), {
ssr: false,
loading: () => <ListTableSkeleton title="AllBounty" />,
}),
[]
);
const EngagementSubscription = useMemo(
() =>
dynamic(() => import("./../engagementSubscription"), {
ssr: false,
loading: () => <EngagementSubscriptionSkeleton />,
}),
[]
);
and here the test file:
import "@testing-library/jest-dom";
import user from "@testing-library/user-event";
import {
findByTestId,
fireEvent,
render,
screen,
waitFor,
} from "../../../../../testUtils/testUtils";
import { useRouter } from "../../../../../__mocks__/nextRouter.mock";
import { store } from "../../../../../redux/store";
import { useTranslation } from "../../../../../__mocks__/next-i18next.mock";
import { Provider } from "react-redux";
import Reports from "..";
import Bounty from "..";
import BountyDetailsComponent from "../BountyDetails";
import { setPermissionsByUnitTest } from "../../../../../utils/utils";
jest.mock("next/router", () => ({
useRouter: () => useRouter({ route: "/organization-setting" }),
}));
jest.mock("next-i18next", () => ({
useTranslation: () => useTranslation(),
}));
beforeEach(() => {
jest.clearAllMocks();
});
describe("Member bounty", () => {
it("Should not be able to access bounties", async () => {
setPermissionsByUnitTest(["NONE"]);
render(
<Provider store={store}>
<Bounty accessByUnitTest={true} />
</Provider>
);
const bountyContainer = screen.queryByTestId("bounty-container");
await waitFor(() => expect(bountyContainer).toBeNull());
});
it("Should be able to access & create bounty", async () => {
setPermissionsByUnitTest(["can_access_bounties_list", "can_create_bounty"]);
const saveData = jest.fn();
render(
<Provider store={store}>
<Bounty
accessByUnitTest={true}
assetsByUnitTest={{
assets: [
{
name: "other",
uuid: "17fb0eba-0f6e-47e0-9b2a-23ae4d87039x",
platform: "OTHER",
},
],
}}
saveData={saveData}
/>
</Provider>
);
user.setup();
const createBountyButton = await screen.findByTestId("create-program");
await user.click(createBountyButton);
const inputName = await screen.findByTestId("inputName");
await user.click(inputName);
await user.type(inputName, "bounty by unit test");
const inputWebsite = await screen.findByTestId("inputWebsite");
await user.click(inputWebsite);
await user.type(inputWebsite, "website by unit test");
const inputTwitter = await screen.findByTestId("inputTwitter");
await user.click(inputTwitter);
await user.type(inputTwitter, "twitter by unit test");
const datePickerInput = await screen.findByPlaceholderText("Select a date");
await user.click(datePickerInput);
fireEvent.keyDown(datePickerInput, { key: "Enter", charCode: 13 });
const assets = screen.getAllByRole("combobox");
await user.click(assets[0]);
await user.type(assets[0], "other");
fireEvent.keyDown(assets[0], { key: "Enter", charCode: 13 });
const bountyEligible = screen.getAllByRole("combobox");
await user.click(bountyEligible[1]);
await user.type(bountyEligible[1], "Eligible");
fireEvent.keyDown(bountyEligible[1], { key: "Enter", charCode: 13 });
const addAssetButton = await screen.findByTestId(
"add-asset-button-for-program"
);
await user.click(addAssetButton);
const nextButton = await screen.findByTestId("next-program");
await user.click(nextButton);
const programTypes = screen.getAllByRole("combobox");
await user.click(programTypes[2]);
await user.type(programTypes[2], "Public");
fireEvent.keyDown(programTypes[2], { key: "Enter", charCode: 13 });
await user.click(nextButton);
const submitProgram = await screen.findByTestId("submit-program");
await user.click(submitProgram);
const newDate = new Date();
await waitFor(() =>
expect(saveData).toHaveBeenCalledWith({
title: "bounty by unit test",
start_date: `${newDate.getFullYear()}-${
newDate.getMonth() + 1 > 9
? String(newDate.getMonth() + 1)
: "0" + String(newDate.getMonth() + 1)
}-${
newDate.getDate() > 9
? String(newDate.getDate())
: "0" + String(newDate.getDate())
}`,
website: "website by unit test",
twitter: "twitter by unit test",
targets: [
{
asset: "17fb0eba-0f6e-47e0-9b2a-23ae4d87039x",
bounty: {
critical_severity: "800",
high_severity: "500",
low_severity: "100",
max_critical_severity: "900",
max_high_severity: "600",
max_low_severity: "200",
max_medium_severity: "400",
medium_severity: "300",
},
is_eligible_for_bounty: false,
},
],
is_public: true,
})
);
});
it("Should be able to access bounty details", async () => {
const saveData = jest.fn();
setPermissionsByUnitTest([
"can_access_bounties_list",
"can_create_bounty",
"can_access_program_details",
"can_access_program_security",
"can_access_program_reports",
"can_access_program_scope",
"can_access_program_attachments",
"can_access_program_settings",
]);
render(
<Provider store={store}>
<BountyDetailsComponent
uuid="57fb0eba-0f6e-47e0-9b2a-23ae4d87039p"
accessByUnitTest={true}
programByUnitTest={{
uuid: "57fb0eba-0f6e-47e0-9b2a-23ae4d87039p",
title: "Test unit test",
name: "Test unit test",
status: "Active",
range_of_bounty: "100-800",
phase_description: "Test",
vulnerabilities_reports: [],
severity_of_findings: [],
policy: "<p>DON'T REMOVE</p>",
type: "BUGBOUNTYPROGRAM",
program_image: null,
targets: [
{
uuid: "57fb0eba-0f6e-47e0-9b2a-23ae4d87039x",
asset: {
platform: "OTHER",
description: "By unit test",
target: "www.unit.com",
},
},
],
}}
saveData={saveData}
/>
</Provider>
);
user.setup();
const tabs = await screen.findAllByRole("tab");
await user.click(tabs[1]);
await user.click(tabs[2]);
await user.click(tabs[3]);
await user.click(tabs[4]);
await user.click(tabs[5]);
const programName = await screen.findByTestId("ProgramName");
await user.click(programName);
await user.type(programName, "Test unit test");
const programDescription = await screen.findByTestId("Description");
await user.click(programDescription);
await user.type(programDescription, "Test description unit test");
const inputWebsite = await screen.findByTestId("Website");
await user.click(inputWebsite);
await user.type(inputWebsite, "website by unit test");
const inputTwitter = await screen.findByTestId("Twitter/X");
await user.click(inputTwitter);
await user.type(inputTwitter, "twitter by unit test");
const saveUpdateProgramButton = await screen.findByTestId(
"save-update-program"
);
await user.click(saveUpdateProgramButton);
await waitFor(() =>
expect(saveData).toHaveBeenCalledWith({
title: "Test unit test",
description: "Test description unit test",
website: "website by unit test",
twitter: "twitter by unit test",
})
);
});
});
and here the jest setup file:
import '@testing-library/jest-dom'
jest.mock('next/dynamic', () => () => {
const DynamicComponent = () => null;
DynamicComponent.displayName = 'LoadableComponent';
DynamicComponent.preload = jest.fn();
return DynamicComponent;
});