diff --git a/packages/generator-widget/generators/app/lib/prompttexts.js b/packages/generator-widget/generators/app/lib/prompttexts.js index 8887c594..4decd73c 100644 --- a/packages/generator-widget/generators/app/lib/prompttexts.js +++ b/packages/generator-widget/generators/app/lib/prompttexts.js @@ -31,7 +31,7 @@ function promptWidgetProperties(mxProjectDir, widgetName) { type: "input", name: "copyright", message: "Add a copyright", - default: "© Mendix Technology BV 2022. All rights reserved.", + default: `© Mendix Technology BV ${new Date().getFullYear()}. All rights reserved.`, store: true }, { diff --git a/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-js-e2e.json b/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-js-e2e.json index 2a1e1f37..f3ff1a44 100644 --- a/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-js-e2e.json +++ b/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-js-e2e.json @@ -34,10 +34,12 @@ }, "resolutions": { "react": "^18.2.0", + "react-dom": "18.2.0", "react-native": "0.72.7" }, "overrides": { "react": "^18.2.0", + "react-dom": "18.2.0", "react-native": "0.72.7" } } diff --git a/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-js-unit-e2e.json b/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-js-unit-e2e.json index ee1ca013..d21302f8 100644 --- a/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-js-unit-e2e.json +++ b/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-js-unit-e2e.json @@ -21,8 +21,8 @@ "build": "pluggable-widgets-tools build:web", "lint": "pluggable-widgets-tools lint", "lint:fix": "pluggable-widgets-tools lint:fix", - "test": "pluggable-widgets-tools test:unit:web --no-cache --ci && npm run test:e2e", - "test:unit": "pluggable-widgets-tools test:unit:web --coverage", + "test": "pluggable-widgets-tools test:unit:web && npm run test:e2e", + "test:unit": "pluggable-widgets-tools test:unit:web", "test:e2e": "npx cypress open --browser chrome --e2e", "prerelease": "npm run lint", "release": "pluggable-widgets-tools release:web" @@ -36,10 +36,12 @@ }, "resolutions": { "react": "^18.2.0", + "react-dom": "18.2.0", "react-native": "0.72.7" }, "overrides": { "react": "^18.2.0", + "react-dom": "18.2.0", "react-native": "0.72.7" } } diff --git a/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-js-unit.json b/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-js-unit.json index bd78587f..ee6b1205 100644 --- a/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-js-unit.json +++ b/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-js-unit.json @@ -21,8 +21,8 @@ "build": "pluggable-widgets-tools build:web", "lint": "pluggable-widgets-tools lint", "lint:fix": "pluggable-widgets-tools lint:fix", - "test": "pluggable-widgets-tools test:unit:web --no-cache --ci", - "test:unit": "pluggable-widgets-tools test:unit:web --coverage", + "test": "pluggable-widgets-tools test:unit:web", + "test:unit": "pluggable-widgets-tools test:unit:web", "prerelease": "npm run lint", "release": "pluggable-widgets-tools release:web" }, @@ -34,10 +34,12 @@ }, "resolutions": { "react": "^18.2.0", + "react-dom": "18.2.0", "react-native": "0.72.7" }, "overrides": { "react": "^18.2.0", + "react-dom": "18.2.0", "react-native": "0.72.7" } } diff --git a/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-js.json b/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-js.json index 69943348..08e814a4 100644 --- a/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-js.json +++ b/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-js.json @@ -32,10 +32,12 @@ }, "resolutions": { "react": "^18.2.0", + "react-dom": "18.2.0", "react-native": "0.72.7" }, "overrides": { "react": "^18.2.0", + "react-dom": "18.2.0", "react-native": "0.72.7" } } diff --git a/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-ts-e2e.json b/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-ts-e2e.json index 60b3b6f9..ab1d41b4 100644 --- a/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-ts-e2e.json +++ b/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-ts-e2e.json @@ -28,7 +28,6 @@ "devDependencies": { "@mendix/pluggable-widgets-tools": "^10.15.0", "@types/big.js": "^6.0.2", - "@types/enzyme": "^3.10.8", "@types/jasmine": "^3.6.9", "cypress": "^10.10.0" }, @@ -37,12 +36,16 @@ }, "resolutions": { "react": "^18.2.0", + "react-dom": "18.2.0", "@types/react": "^18.2.0", + "@types/react-dom": "18.2.0", "react-native": "0.72.7" }, "overrides": { "react": "^18.2.0", + "react-dom": "18.2.0", "@types/react": "^18.2.0", + "@types/react-dom": "18.2.0", "react-native": "0.72.7" } } diff --git a/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-ts-unit-e2e.json b/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-ts-unit-e2e.json index a320996e..712ce011 100644 --- a/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-ts-unit-e2e.json +++ b/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-ts-unit-e2e.json @@ -21,8 +21,8 @@ "build": "pluggable-widgets-tools build:web", "lint": "pluggable-widgets-tools lint", "lint:fix": "pluggable-widgets-tools lint:fix", - "test": "pluggable-widgets-tools test:unit:web --no-cache --ci && npm run test:e2e", - "test:unit": "pluggable-widgets-tools test:unit:web --coverage", + "test": "pluggable-widgets-tools test:unit:web && npm run test:e2e", + "test:unit": "pluggable-widgets-tools test:unit:web", "test:e2e": "npx cypress open --browser chrome --e2e", "prerelease": "npm run lint", "release": "pluggable-widgets-tools release:web" @@ -30,10 +30,8 @@ "devDependencies": { "@mendix/pluggable-widgets-tools": "^10.15.0", "@types/big.js": "^6.0.2", - "@types/enzyme": "^3.10.8", "@types/jasmine": "^3.6.9", "@types/jest": "^29.0.0", - "@types/react-test-renderer": "~18.0.0", "cypress": "^10.10.0" }, "dependencies": { @@ -41,12 +39,16 @@ }, "resolutions": { "react": "^18.2.0", + "react-dom": "18.2.0", "@types/react": "^18.2.0", + "@types/react-dom": "18.2.0", "react-native": "0.72.7" }, "overrides": { "react": "^18.2.0", + "react-dom": "18.2.0", "@types/react": "^18.2.0", + "@types/react-dom": "18.2.0", "react-native": "0.72.7" } } diff --git a/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-ts-unit.json b/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-ts-unit.json index f0fecca7..38959e57 100644 --- a/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-ts-unit.json +++ b/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-ts-unit.json @@ -21,29 +21,31 @@ "build": "pluggable-widgets-tools build:web", "lint": "pluggable-widgets-tools lint", "lint:fix": "pluggable-widgets-tools lint:fix", - "test": "pluggable-widgets-tools test:unit:web --no-cache --ci", - "test:unit": "pluggable-widgets-tools test:unit:web --coverage", + "test": "pluggable-widgets-tools test:unit:web", + "test:unit": "pluggable-widgets-tools test:unit:web", "prerelease": "npm run lint", "release": "pluggable-widgets-tools release:web" }, "devDependencies": { "@mendix/pluggable-widgets-tools": "^10.15.0", "@types/big.js": "^6.0.2", - "@types/enzyme": "^3.10.8", - "@types/jest": "^29.0.0", - "@types/react-test-renderer": "~18.0.0" + "@types/jest": "^29.0.0" }, "dependencies": { "classnames": "^2.2.6" }, "resolutions": { "react": "^18.2.0", + "react-dom": "18.2.0", "@types/react": "^18.2.0", + "@types/react-dom": "18.2.0", "react-native": "0.72.7" }, "overrides": { "react": "^18.2.0", + "react-dom": "18.2.0", "@types/react": "^18.2.0", + "@types/react-dom": "18.2.0", "react-native": "0.72.7" } } diff --git a/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-ts.json b/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-ts.json index 4fdf5650..638f36fb 100644 --- a/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-ts.json +++ b/packages/generator-widget/generators/app/templates/packages/__tests__/outputs/package_web.json-ts.json @@ -33,12 +33,16 @@ }, "resolutions": { "react": "^18.2.0", + "react-dom": "18.2.0", "@types/react": "^18.2.0", + "@types/react-dom": "18.2.0", "react-native": "0.72.7" }, "overrides": { "react": "^18.2.0", + "react-dom": "18.2.0", "@types/react": "^18.2.0", + "@types/react-dom": "18.2.0", "react-native": "0.72.7" } } diff --git a/packages/generator-widget/generators/app/templates/packages/package_web.json.ejs b/packages/generator-widget/generators/app/templates/packages/package_web.json.ejs index 45e04258..71d0e29d 100644 --- a/packages/generator-widget/generators/app/templates/packages/package_web.json.ejs +++ b/packages/generator-widget/generators/app/templates/packages/package_web.json.ejs @@ -21,32 +21,34 @@ "build": "pluggable-widgets-tools build:web", "lint": "pluggable-widgets-tools lint", "lint:fix": "pluggable-widgets-tools lint:fix",<% if (hasUnitTests) { %> - "test": "pluggable-widgets-tools test:unit:web --no-cache --ci<% if (hasE2eTests) { %> && npm run test:e2e<% } %>", - "test:unit": "pluggable-widgets-tools test:unit:web --coverage",<% } %><% if (hasE2eTests) { %> + "test": "pluggable-widgets-tools test:unit:web<% if (hasE2eTests) { %> && npm run test:e2e<% } %>", + "test:unit": "pluggable-widgets-tools test:unit:web",<% } %><% if (hasE2eTests) { %> "test:e2e": "npx cypress open --browser chrome --e2e",<% } %> "prerelease": "npm run lint", "release": "pluggable-widgets-tools release:web" }, "devDependencies": { "@mendix/pluggable-widgets-tools": "^10.15.0"<% if (isLanguageTS) { %>, - "@types/big.js": "^6.0.2"<% if (hasUnitTests || hasE2eTests) { %>, - "@types/enzyme": "^3.10.8"<% } %><% if (hasE2eTests) { %>, + "@types/big.js": "^6.0.2"<% if (hasE2eTests) { %>, "@types/jasmine": "^3.6.9"<% } %><% if (hasUnitTests) { %>, - "@types/jest": "^29.0.0", - "@types/react-test-renderer": "~18.0.0"<% } %><% } %><% if (hasE2eTests) { %>, + "@types/jest": "^29.0.0"<% } %><% } %><% if (hasE2eTests) { %>, "cypress": "^10.10.0"<% } %> }, "dependencies": { "classnames": "^2.2.6" }, "resolutions": { - "react": "^18.2.0",<% if (isLanguageTS) { %> - "@types/react": "^18.2.0",<% } %> + "react": "^18.2.0", + "react-dom": "18.2.0",<% if (isLanguageTS) { %> + "@types/react": "^18.2.0", + "@types/react-dom": "18.2.0",<% } %> "react-native": "0.72.7" }, "overrides": { - "react": "^18.2.0",<% if (isLanguageTS) { %> - "@types/react": "^18.2.0",<% } %> + "react": "^18.2.0", + "react-dom": "18.2.0",<% if (isLanguageTS) { %> + "@types/react": "^18.2.0", + "@types/react-dom": "18.2.0",<% } %> "react-native": "0.72.7" } } diff --git a/packages/generator-widget/generators/app/templates/pluggable/web/emptyTemplateJs/src/components/__tests__/HelloWorldSample.spec.jsx.ejs b/packages/generator-widget/generators/app/templates/pluggable/web/emptyTemplateJs/src/components/__tests__/HelloWorldSample.spec.jsx.ejs index 30aeae86..2e475334 100644 --- a/packages/generator-widget/generators/app/templates/pluggable/web/emptyTemplateJs/src/components/__tests__/HelloWorldSample.spec.jsx.ejs +++ b/packages/generator-widget/generators/app/templates/pluggable/web/emptyTemplateJs/src/components/__tests__/HelloWorldSample.spec.jsx.ejs @@ -1,21 +1,19 @@ import { createElement } from "react"; -import { shallow } from "enzyme"; +import { render } from "@testing-library/react"; +import "@testing-library/jest-dom"; import { HelloWorldSample } from "../HelloWorldSample"; describe("HelloWorldSample", () => { - const createHelloWorld = (props) => shallow(); - it("should render the structure correctly", () => { const helloWorldProps = { sampleText: "World" }; - const helloWorld = createHelloWorld(helloWorldProps); - expect( - helloWorld.equals( -
Hello {helloWorldProps.sampleText}
- ) - ).toEqual(true); + const { container } = render(); + + const helloWorld = container.querySelector(".widget-hello-world"); + expect(helloWorld).toBeInTheDocument(); + expect(helloWorld).toHaveTextContent(`Hello ${helloWorldProps.sampleText}`); }); }); diff --git a/packages/generator-widget/generators/app/templates/pluggable/web/emptyTemplateJsFn/src/components/__tests__/HelloWorldSample.spec.jsx.ejs b/packages/generator-widget/generators/app/templates/pluggable/web/emptyTemplateJsFn/src/components/__tests__/HelloWorldSample.spec.jsx.ejs index 30aeae86..2e475334 100644 --- a/packages/generator-widget/generators/app/templates/pluggable/web/emptyTemplateJsFn/src/components/__tests__/HelloWorldSample.spec.jsx.ejs +++ b/packages/generator-widget/generators/app/templates/pluggable/web/emptyTemplateJsFn/src/components/__tests__/HelloWorldSample.spec.jsx.ejs @@ -1,21 +1,19 @@ import { createElement } from "react"; -import { shallow } from "enzyme"; +import { render } from "@testing-library/react"; +import "@testing-library/jest-dom"; import { HelloWorldSample } from "../HelloWorldSample"; describe("HelloWorldSample", () => { - const createHelloWorld = (props) => shallow(); - it("should render the structure correctly", () => { const helloWorldProps = { sampleText: "World" }; - const helloWorld = createHelloWorld(helloWorldProps); - expect( - helloWorld.equals( -
Hello {helloWorldProps.sampleText}
- ) - ).toEqual(true); + const { container } = render(); + + const helloWorld = container.querySelector(".widget-hello-world"); + expect(helloWorld).toBeInTheDocument(); + expect(helloWorld).toHaveTextContent(`Hello ${helloWorldProps.sampleText}`); }); }); diff --git a/packages/generator-widget/generators/app/templates/pluggable/web/emptyTemplateTs/src/components/__tests__/HelloWorldSample.spec.tsx.ejs b/packages/generator-widget/generators/app/templates/pluggable/web/emptyTemplateTs/src/components/__tests__/HelloWorldSample.spec.tsx.ejs index 28e402ca..2b7d9f0e 100644 --- a/packages/generator-widget/generators/app/templates/pluggable/web/emptyTemplateTs/src/components/__tests__/HelloWorldSample.spec.tsx.ejs +++ b/packages/generator-widget/generators/app/templates/pluggable/web/emptyTemplateTs/src/components/__tests__/HelloWorldSample.spec.tsx.ejs @@ -1,22 +1,19 @@ import { createElement } from "react"; -import { shallow, ShallowWrapper } from "enzyme"; +import { render } from "@testing-library/react"; +import "@testing-library/jest-dom"; import { HelloWorldSample, HelloWorldSampleProps } from "../HelloWorldSample"; describe("HelloWorldSample", () => { - const createHelloWorld = (props: HelloWorldSampleProps): ShallowWrapper => shallow(); - it("should render the structure correctly", () => { const helloWorldProps: HelloWorldSampleProps = { sampleText: "World" }; - const helloWorld = createHelloWorld(helloWorldProps); + const { container } = render(); - expect( - helloWorld.equals( -
Hello {helloWorldProps.sampleText}
- ) - ).toEqual(true); + const helloWorld = container.querySelector(".widget-hello-world"); + expect(helloWorld).toBeInTheDocument(); + expect(helloWorld).toHaveTextContent(`Hello ${helloWorldProps.sampleText}`); }); }); diff --git a/packages/generator-widget/generators/app/templates/pluggable/web/emptyTemplateTsFn/src/components/__tests__/HelloWorldSample.spec.tsx.ejs b/packages/generator-widget/generators/app/templates/pluggable/web/emptyTemplateTsFn/src/components/__tests__/HelloWorldSample.spec.tsx.ejs index 28e402ca..2b7d9f0e 100644 --- a/packages/generator-widget/generators/app/templates/pluggable/web/emptyTemplateTsFn/src/components/__tests__/HelloWorldSample.spec.tsx.ejs +++ b/packages/generator-widget/generators/app/templates/pluggable/web/emptyTemplateTsFn/src/components/__tests__/HelloWorldSample.spec.tsx.ejs @@ -1,22 +1,19 @@ import { createElement } from "react"; -import { shallow, ShallowWrapper } from "enzyme"; +import { render } from "@testing-library/react"; +import "@testing-library/jest-dom"; import { HelloWorldSample, HelloWorldSampleProps } from "../HelloWorldSample"; describe("HelloWorldSample", () => { - const createHelloWorld = (props: HelloWorldSampleProps): ShallowWrapper => shallow(); - it("should render the structure correctly", () => { const helloWorldProps: HelloWorldSampleProps = { sampleText: "World" }; - const helloWorld = createHelloWorld(helloWorldProps); + const { container } = render(); - expect( - helloWorld.equals( -
Hello {helloWorldProps.sampleText}
- ) - ).toEqual(true); + const helloWorld = container.querySelector(".widget-hello-world"); + expect(helloWorld).toBeInTheDocument(); + expect(helloWorld).toHaveTextContent(`Hello ${helloWorldProps.sampleText}`); }); }); diff --git a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/WidgetName.editorPreview.jsx.ejs b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/WidgetName.editorPreview.jsx.ejs index 4dc56bee..abe5cd0a 100644 --- a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/WidgetName.editorPreview.jsx.ejs +++ b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/WidgetName.editorPreview.jsx.ejs @@ -1,8 +1,6 @@ import { Component, createElement } from "react"; - -import { parseInlineStyle } from "@mendix/pluggable-widgets-tools"; - import { BadgeSample } from "./components/BadgeSample"; +import { parseInlineStyle } from "@mendix/pluggable-widgets-tools"; export class preview extends Component { render() { diff --git a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/WidgetName.jsx.ejs b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/WidgetName.jsx.ejs index f104f86d..c904ab38 100644 --- a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/WidgetName.jsx.ejs +++ b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/WidgetName.jsx.ejs @@ -1,7 +1,7 @@ +import "./ui/<%- name %>.css"; import { Component, createElement } from "react"; import { BadgeSample } from "./components/BadgeSample"; -import "./ui/<%- name %>.css"; export class <%- name %> extends Component { diff --git a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/components/Alert.jsx.ejs b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/components/Alert.jsx.ejs index afa24aa2..82675ead 100644 --- a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/components/Alert.jsx.ejs +++ b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/components/Alert.jsx.ejs @@ -1,4 +1,4 @@ -import { Component, ReactNode, createElement } from "react"; +import { Component, createElement } from "react"; import classNames from "classnames"; export class Alert extends Component { diff --git a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/components/__tests__/Alert.spec.jsx.ejs b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/components/__tests__/Alert.spec.jsx.ejs index 35d240cf..2a166139 100644 --- a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/components/__tests__/Alert.spec.jsx.ejs +++ b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/components/__tests__/Alert.spec.jsx.ejs @@ -1,24 +1,27 @@ -import { createElement } from "react"; -import { shallow } from "enzyme"; - +import "@testing-library/jest-dom"; import { Alert } from "../Alert"; +import { createElement } from "react"; +import { render } from "@testing-library/react"; describe("Alert", () => { it("renders the structure when an alert message is specified", () => { const message = "This is an error"; - const alert = shallow(); + const { container } = render( + + ); - expect(alert.equals( -
{message}
- )).toEqual(true); + const alertElement = container.querySelector(".alert.alert-danger.widget-badge-alert"); + expect(alertElement).toBeInTheDocument(); + expect(alertElement).toHaveTextContent(message); }); it("renders no structure when the alert message is not specified", () => { - const alert = shallow(); + const { container } = render(); - expect(alert.isEmptyRender()).toEqual(true); + expect(container.firstChild).toBeNull(); }); }); diff --git a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/components/__tests__/BadgeSample.spec.jsx.ejs b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/components/__tests__/BadgeSample.spec.jsx.ejs index 0fc2c057..fa70f623 100644 --- a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/components/__tests__/BadgeSample.spec.jsx.ejs +++ b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJs/src/components/__tests__/BadgeSample.spec.jsx.ejs @@ -1,101 +1,99 @@ -import { createElement } from "react"; -import { shallow } from "enzyme"; - +import "@testing-library/jest-dom"; import { BadgeSample } from "../BadgeSample"; +import { createElement } from "react"; +import { render } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; describe("Badge", () => { - const createBadge = (props) => shallow(); - it("should render the structure", () => { const badgeProps = { type: "badge", bootstrapStyle: "default", value: "0" }; - const badge = createBadge(badgeProps); + const { container } = render(); - expect( - badge.equals( - 0 - ) - ).toEqual(true); + const badge = container.querySelector("span.widget-<%- packageName %>.badge.label-default"); + expect(badge).toBeInTheDocument(); + expect(badge).toHaveTextContent("0"); }); it("should show value when no value or default value provided", () => { const value = "value"; - const badge = createBadge({ type: "label", value, defaultValue: "default value" }); + const { container } = render(); - expect(badge.text()).toBe(value); + expect(container.querySelector("span")).toHaveTextContent(value); }); it("should show default value when no value is provided", () => { const defaultValue = "default"; - const badge = createBadge({ type: "label", value: undefined, defaultValue }); + const { container } = render(); - expect(badge.text()).toBe(defaultValue); + expect(container.querySelector("span")).toHaveTextContent(defaultValue); }); it("should show no value when no value or default value provided", () => { - const badge = createBadge({ type: "label", value: undefined }); + const { container } = render(); - expect(badge.text()).toBe(""); + expect(container.querySelector("span")).toHaveTextContent(""); }); it("configured as a label should have the class label", () => { - const badge = createBadge({ type: "label" }); + const { container } = render(); - expect(badge.hasClass("label")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label"); }); it("configured as a badge should have the class badge", () => { - const badge = createBadge({ type: "badge" }); + const { container } = render(); - expect(badge.hasClass("badge")).toBe(true); + expect(container.querySelector("span")).toHaveClass("badge"); }); - it("with a click action should respond to click events", () => { - const badgeProps = { onClickAction: jest.fn(), type: "badge" }; - const onClick = badgeProps.onClickAction = jest.fn(); - const badge = createBadge(badgeProps); + it("with a click action should respond to click events", async () => { + const user = userEvent.setup(); + const onClick = jest.fn(); + const { container } = render(); - badge.simulate("click"); + const badge = container.querySelector("span"); + await user.click(badge); expect(onClick).toHaveBeenCalledTimes(1); }); it("with the Bootstrap style default should have the class label-default", () => { - const badge = createBadge({ bootstrapStyle: "default", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-default")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-default"); }); it("with the Bootstrap style primary should have the class label-primary", () => { - const badge = createBadge({ bootstrapStyle: "primary", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-primary")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-primary"); }); it("with the Bootstrap style success should have the class label-success", () => { - const badge = createBadge({ bootstrapStyle: "success", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-success")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-success"); }); it("with the Bootstrap style info should have the class label-info", () => { - const badge = createBadge({ bootstrapStyle: "info", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-info")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-info"); }); it("with the Bootstrap style warning should have the class label-warning", () => { - const badge = createBadge({ bootstrapStyle: "warning", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-warning")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-warning"); }); it("with the Bootstrap style danger should have the class label-danger", () => { - const badge = createBadge({ bootstrapStyle: "danger", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-danger")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-danger"); }); }); diff --git a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJsFn/src/components/__tests__/Alert.spec.jsx.ejs b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJsFn/src/components/__tests__/Alert.spec.jsx.ejs index 35d240cf..66ae1cdd 100644 --- a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJsFn/src/components/__tests__/Alert.spec.jsx.ejs +++ b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJsFn/src/components/__tests__/Alert.spec.jsx.ejs @@ -1,24 +1,28 @@ import { createElement } from "react"; -import { shallow } from "enzyme"; +import { render } from "@testing-library/react"; +import "@testing-library/jest-dom"; import { Alert } from "../Alert"; describe("Alert", () => { it("renders the structure when an alert message is specified", () => { const message = "This is an error"; - const alert = shallow(); + const { container } = render( + + ); - expect(alert.equals( -
{message}
- )).toEqual(true); + const alertElement = container.querySelector(".alert.alert-danger.widget-badge-alert"); + expect(alertElement).toBeInTheDocument(); + expect(alertElement).toHaveTextContent(message); }); it("renders no structure when the alert message is not specified", () => { - const alert = shallow(); + const { container } = render(); - expect(alert.isEmptyRender()).toEqual(true); + expect(container.firstChild).toBeNull(); }); }); diff --git a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJsFn/src/components/__tests__/BadgeSample.spec.jsx.ejs b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJsFn/src/components/__tests__/BadgeSample.spec.jsx.ejs index 0fc2c057..e65f0047 100644 --- a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJsFn/src/components/__tests__/BadgeSample.spec.jsx.ejs +++ b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateJsFn/src/components/__tests__/BadgeSample.spec.jsx.ejs @@ -1,101 +1,100 @@ import { createElement } from "react"; -import { shallow } from "enzyme"; +import { render } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import "@testing-library/jest-dom"; import { BadgeSample } from "../BadgeSample"; describe("Badge", () => { - const createBadge = (props) => shallow(); - it("should render the structure", () => { const badgeProps = { type: "badge", bootstrapStyle: "default", value: "0" }; - const badge = createBadge(badgeProps); + const { container } = render(); - expect( - badge.equals( - 0 - ) - ).toEqual(true); + const badge = container.querySelector("span.widget-<%- packageName %>.badge.label-default"); + expect(badge).toBeInTheDocument(); + expect(badge).toHaveTextContent("0"); }); it("should show value when no value or default value provided", () => { const value = "value"; - const badge = createBadge({ type: "label", value, defaultValue: "default value" }); + const { container } = render(); - expect(badge.text()).toBe(value); + expect(container.querySelector("span")).toHaveTextContent(value); }); it("should show default value when no value is provided", () => { const defaultValue = "default"; - const badge = createBadge({ type: "label", value: undefined, defaultValue }); + const { container } = render(); - expect(badge.text()).toBe(defaultValue); + expect(container.querySelector("span")).toHaveTextContent(defaultValue); }); it("should show no value when no value or default value provided", () => { - const badge = createBadge({ type: "label", value: undefined }); + const { container } = render(); - expect(badge.text()).toBe(""); + expect(container.querySelector("span")).toHaveTextContent(""); }); it("configured as a label should have the class label", () => { - const badge = createBadge({ type: "label" }); + const { container } = render(); - expect(badge.hasClass("label")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label"); }); it("configured as a badge should have the class badge", () => { - const badge = createBadge({ type: "badge" }); + const { container } = render(); - expect(badge.hasClass("badge")).toBe(true); + expect(container.querySelector("span")).toHaveClass("badge"); }); - it("with a click action should respond to click events", () => { - const badgeProps = { onClickAction: jest.fn(), type: "badge" }; - const onClick = badgeProps.onClickAction = jest.fn(); - const badge = createBadge(badgeProps); + it("with a click action should respond to click events", async () => { + const user = userEvent.setup(); + const onClick = jest.fn(); + const { container } = render(); - badge.simulate("click"); + const badge = container.querySelector("span"); + await user.click(badge); expect(onClick).toHaveBeenCalledTimes(1); }); it("with the Bootstrap style default should have the class label-default", () => { - const badge = createBadge({ bootstrapStyle: "default", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-default")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-default"); }); it("with the Bootstrap style primary should have the class label-primary", () => { - const badge = createBadge({ bootstrapStyle: "primary", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-primary")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-primary"); }); it("with the Bootstrap style success should have the class label-success", () => { - const badge = createBadge({ bootstrapStyle: "success", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-success")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-success"); }); it("with the Bootstrap style info should have the class label-info", () => { - const badge = createBadge({ bootstrapStyle: "info", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-info")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-info"); }); it("with the Bootstrap style warning should have the class label-warning", () => { - const badge = createBadge({ bootstrapStyle: "warning", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-warning")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-warning"); }); it("with the Bootstrap style danger should have the class label-danger", () => { - const badge = createBadge({ bootstrapStyle: "danger", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-danger")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-danger"); }); }); diff --git a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateTs/src/components/__tests__/Alert.spec.tsx.ejs b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateTs/src/components/__tests__/Alert.spec.tsx.ejs index 35d240cf..a8f1b29d 100644 --- a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateTs/src/components/__tests__/Alert.spec.tsx.ejs +++ b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateTs/src/components/__tests__/Alert.spec.tsx.ejs @@ -1,24 +1,28 @@ import { createElement } from "react"; -import { shallow } from "enzyme"; +import { render, screen } from "@testing-library/react"; +import "@testing-library/jest-dom"; import { Alert } from "../Alert"; describe("Alert", () => { it("renders the structure when an alert message is specified", () => { const message = "This is an error"; - const alert = shallow(); + const { container } = render( + + ); - expect(alert.equals( -
{message}
- )).toEqual(true); + const alertElement = container.querySelector(".alert.alert-danger.widget-badge-alert"); + expect(alertElement).toBeInTheDocument(); + expect(alertElement).toHaveTextContent(message); }); it("renders no structure when the alert message is not specified", () => { - const alert = shallow(); + const { container } = render(); - expect(alert.isEmptyRender()).toEqual(true); + expect(container.firstChild).toBeNull(); }); }); diff --git a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateTs/src/components/__tests__/BadgeSample.spec.tsx.ejs b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateTs/src/components/__tests__/BadgeSample.spec.tsx.ejs index 0e55954f..12038ed3 100644 --- a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateTs/src/components/__tests__/BadgeSample.spec.tsx.ejs +++ b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateTs/src/components/__tests__/BadgeSample.spec.tsx.ejs @@ -1,101 +1,100 @@ import { createElement } from "react"; -import { shallow, ShallowWrapper } from "enzyme"; +import { render } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import "@testing-library/jest-dom"; import { BadgeSample, BadgeSampleProps } from "../BadgeSample"; describe("Badge", () => { - const createBadge = (props: BadgeSampleProps): ShallowWrapper => shallow(); - it("should render the structure", () => { const badgeProps: BadgeSampleProps = { type: "badge", bootstrapStyle: "default", value: "0" }; - const badge = createBadge(badgeProps); + const { container } = render(); - expect( - badge.equals( - 0 - ) - ).toEqual(true); + const badge = container.querySelector("span.widget-<%- packageName %>.badge.label-default"); + expect(badge).toBeInTheDocument(); + expect(badge).toHaveTextContent("0"); }); it("should show value when no value or default value provided", () => { const value = "value"; - const badge = createBadge({ type: "label", value, defaultValue: "default value" }); + const { container } = render(); - expect(badge.text()).toBe(value); + expect(container.querySelector("span")).toHaveTextContent(value); }); it("should show default value when no value is provided", () => { const defaultValue = "default"; - const badge = createBadge({ type: "label", value: undefined, defaultValue }); + const { container } = render(); - expect(badge.text()).toBe(defaultValue); + expect(container.querySelector("span")).toHaveTextContent(defaultValue); }); it("should show no value when no value or default value provided", () => { - const badge = createBadge({ type: "label", value: undefined }); + const { container } = render(); - expect(badge.text()).toBe(""); + expect(container.querySelector("span")).toHaveTextContent(""); }); it("configured as a label should have the class label", () => { - const badge = createBadge({ type: "label" }); + const { container } = render(); - expect(badge.hasClass("label")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label"); }); it("configured as a badge should have the class badge", () => { - const badge = createBadge({ type: "badge" }); + const { container } = render(); - expect(badge.hasClass("badge")).toBe(true); + expect(container.querySelector("span")).toHaveClass("badge"); }); - it("with a click action should respond to click events", () => { - const badgeProps: BadgeSampleProps = { onClickAction: jest.fn(), type: "badge" }; - const onClick = badgeProps.onClickAction = jest.fn(); - const badge = createBadge(badgeProps); + it("with a click action should respond to click events", async () => { + const user = userEvent.setup(); + const onClick = jest.fn(); + const { container } = render(); - badge.simulate("click"); + const badge = container.querySelector("span"); + await user.click(badge!); expect(onClick).toHaveBeenCalledTimes(1); }); it("with the Bootstrap style default should have the class label-default", () => { - const badge = createBadge({ bootstrapStyle: "default", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-default")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-default"); }); it("with the Bootstrap style primary should have the class label-primary", () => { - const badge = createBadge({ bootstrapStyle: "primary", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-primary")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-primary"); }); it("with the Bootstrap style success should have the class label-success", () => { - const badge = createBadge({ bootstrapStyle: "success", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-success")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-success"); }); it("with the Bootstrap style info should have the class label-info", () => { - const badge = createBadge({ bootstrapStyle: "info", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-info")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-info"); }); it("with the Bootstrap style warning should have the class label-warning", () => { - const badge = createBadge({ bootstrapStyle: "warning", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-warning")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-warning"); }); it("with the Bootstrap style danger should have the class label-danger", () => { - const badge = createBadge({ bootstrapStyle: "danger", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-danger")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-danger"); }); }); diff --git a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateTsFn/src/components/__tests__/Alert.spec.tsx.ejs b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateTsFn/src/components/__tests__/Alert.spec.tsx.ejs index 35d240cf..66ae1cdd 100644 --- a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateTsFn/src/components/__tests__/Alert.spec.tsx.ejs +++ b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateTsFn/src/components/__tests__/Alert.spec.tsx.ejs @@ -1,24 +1,28 @@ import { createElement } from "react"; -import { shallow } from "enzyme"; +import { render } from "@testing-library/react"; +import "@testing-library/jest-dom"; import { Alert } from "../Alert"; describe("Alert", () => { it("renders the structure when an alert message is specified", () => { const message = "This is an error"; - const alert = shallow(); + const { container } = render( + + ); - expect(alert.equals( -
{message}
- )).toEqual(true); + const alertElement = container.querySelector(".alert.alert-danger.widget-badge-alert"); + expect(alertElement).toBeInTheDocument(); + expect(alertElement).toHaveTextContent(message); }); it("renders no structure when the alert message is not specified", () => { - const alert = shallow(); + const { container } = render(); - expect(alert.isEmptyRender()).toEqual(true); + expect(container.firstChild).toBeNull(); }); }); diff --git a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateTsFn/src/components/__tests__/BadgeSample.spec.tsx.ejs b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateTsFn/src/components/__tests__/BadgeSample.spec.tsx.ejs index 0e55954f..12038ed3 100644 --- a/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateTsFn/src/components/__tests__/BadgeSample.spec.tsx.ejs +++ b/packages/generator-widget/generators/app/templates/pluggable/web/fullTemplateTsFn/src/components/__tests__/BadgeSample.spec.tsx.ejs @@ -1,101 +1,100 @@ import { createElement } from "react"; -import { shallow, ShallowWrapper } from "enzyme"; +import { render } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import "@testing-library/jest-dom"; import { BadgeSample, BadgeSampleProps } from "../BadgeSample"; describe("Badge", () => { - const createBadge = (props: BadgeSampleProps): ShallowWrapper => shallow(); - it("should render the structure", () => { const badgeProps: BadgeSampleProps = { type: "badge", bootstrapStyle: "default", value: "0" }; - const badge = createBadge(badgeProps); + const { container } = render(); - expect( - badge.equals( - 0 - ) - ).toEqual(true); + const badge = container.querySelector("span.widget-<%- packageName %>.badge.label-default"); + expect(badge).toBeInTheDocument(); + expect(badge).toHaveTextContent("0"); }); it("should show value when no value or default value provided", () => { const value = "value"; - const badge = createBadge({ type: "label", value, defaultValue: "default value" }); + const { container } = render(); - expect(badge.text()).toBe(value); + expect(container.querySelector("span")).toHaveTextContent(value); }); it("should show default value when no value is provided", () => { const defaultValue = "default"; - const badge = createBadge({ type: "label", value: undefined, defaultValue }); + const { container } = render(); - expect(badge.text()).toBe(defaultValue); + expect(container.querySelector("span")).toHaveTextContent(defaultValue); }); it("should show no value when no value or default value provided", () => { - const badge = createBadge({ type: "label", value: undefined }); + const { container } = render(); - expect(badge.text()).toBe(""); + expect(container.querySelector("span")).toHaveTextContent(""); }); it("configured as a label should have the class label", () => { - const badge = createBadge({ type: "label" }); + const { container } = render(); - expect(badge.hasClass("label")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label"); }); it("configured as a badge should have the class badge", () => { - const badge = createBadge({ type: "badge" }); + const { container } = render(); - expect(badge.hasClass("badge")).toBe(true); + expect(container.querySelector("span")).toHaveClass("badge"); }); - it("with a click action should respond to click events", () => { - const badgeProps: BadgeSampleProps = { onClickAction: jest.fn(), type: "badge" }; - const onClick = badgeProps.onClickAction = jest.fn(); - const badge = createBadge(badgeProps); + it("with a click action should respond to click events", async () => { + const user = userEvent.setup(); + const onClick = jest.fn(); + const { container } = render(); - badge.simulate("click"); + const badge = container.querySelector("span"); + await user.click(badge!); expect(onClick).toHaveBeenCalledTimes(1); }); it("with the Bootstrap style default should have the class label-default", () => { - const badge = createBadge({ bootstrapStyle: "default", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-default")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-default"); }); it("with the Bootstrap style primary should have the class label-primary", () => { - const badge = createBadge({ bootstrapStyle: "primary", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-primary")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-primary"); }); it("with the Bootstrap style success should have the class label-success", () => { - const badge = createBadge({ bootstrapStyle: "success", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-success")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-success"); }); it("with the Bootstrap style info should have the class label-info", () => { - const badge = createBadge({ bootstrapStyle: "info", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-info")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-info"); }); it("with the Bootstrap style warning should have the class label-warning", () => { - const badge = createBadge({ bootstrapStyle: "warning", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-warning")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-warning"); }); it("with the Bootstrap style danger should have the class label-danger", () => { - const badge = createBadge({ bootstrapStyle: "danger", type: "badge" }); + const { container } = render(); - expect(badge.hasClass("label-danger")).toBe(true); + expect(container.querySelector("span")).toHaveClass("label-danger"); }); }); diff --git a/packages/pluggable-widgets-tools/CHANGELOG.md b/packages/pluggable-widgets-tools/CHANGELOG.md index b84531e2..38cd7240 100644 --- a/packages/pluggable-widgets-tools/CHANGELOG.md +++ b/packages/pluggable-widgets-tools/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +### Breaking changes + +- We removed Enzyme testing library and associated dependencies from pluggable-widgets-tools. Tests using Enzyme should be updated to use React Testing Library. See the [migration guide](https://testing-library.com/docs/react-testing-library/migrate-from-enzyme) for more information. The `test:unit:web:enzyme-free` command has been removed; use `test:unit:web` instead. + ## [11.3.0] - 2025-11-12 ### Changed diff --git a/packages/pluggable-widgets-tools/bin/mx-scripts.js b/packages/pluggable-widgets-tools/bin/mx-scripts.js index 673e0b2e..386ff15f 100755 --- a/packages/pluggable-widgets-tools/bin/mx-scripts.js +++ b/packages/pluggable-widgets-tools/bin/mx-scripts.js @@ -3,6 +3,7 @@ const { execSync, spawnSync } = require("child_process"); const { existsSync } = require("fs"); const { delimiter, dirname, join, parse } = require("path"); const { checkMigration } = require("../utils/migration"); +const { checkForEnzymeUsage } = require("../dist/utils/enzyme-detector"); const { red } = require("ansi-colors"); checkNodeVersion(); @@ -21,6 +22,11 @@ checkNodeVersion(); if (args.indexOf("--subprojectPath") > -1) { args.splice(args.indexOf("--subprojectPath"), 2); } + + if (cmd && cmd.startsWith("test:unit")) { + checkForEnzymeUsage(); + } + const realCommand = getRealCommand(cmd, toolsRoot) + " " + args.join(" "); console.log(`Running MX Widgets Tools script ${cmd}...`); @@ -90,13 +96,12 @@ function getRealCommand(cmd, toolsRoot) { return `jest --projects "${join(toolsRoot, "test-config/jest.config.js")}"`; case "test:unit:native": return `jest --projects "${join(toolsRoot, "test-config/jest.native.config.js")}"`; - case "test:unit:web:enzyme-free": - return `jest --projects "${join(toolsRoot, "test-config/jest.enzyme-free.config.js")}"`; case "test:e2e": case "test:e2e:ts": case "test:e2e:web:cypress": case "test:e2e:web:cypress:local": - return "echo This command has been removed."; + case "test:unit:web:enzyme-free": + return "echo This command has been removed, use test:unit:web instead!"; case "start:js": case "start:ts": return "echo This command has no effect, use pluggable-widgets-tools start:web instead!"; diff --git a/packages/pluggable-widgets-tools/configs/eslint.js.base.json b/packages/pluggable-widgets-tools/configs/eslint.js.base.json index 56b5dfbc..f614583f 100644 --- a/packages/pluggable-widgets-tools/configs/eslint.js.base.json +++ b/packages/pluggable-widgets-tools/configs/eslint.js.base.json @@ -265,7 +265,11 @@ "sort-keys": "off", "sort-vars": "off", "space-before-blocks": "error", - "space-before-function-paren": ["error", "never"], + "space-before-function-paren": ["error", { + "anonymous": "never", + "named": "never", + "asyncArrow": "always" + }], "space-in-parens": ["error", "never"], "space-infix-ops": "error", "space-unary-ops": "off", diff --git a/packages/pluggable-widgets-tools/package.json b/packages/pluggable-widgets-tools/package.json index 40efb0cf..45711613 100644 --- a/packages/pluggable-widgets-tools/package.json +++ b/packages/pluggable-widgets-tools/package.json @@ -32,7 +32,6 @@ "@babel/preset-env": "^7.26.0", "@babel/preset-react": "^7.25.9", "@react-native/babel-preset": "0.77.3", - "@cfaester/enzyme-adapter-react-18": "^0.6.0", "@prettier/plugin-xml": "^1.2.0", "@rollup/plugin-alias": "^5.1.1", "@rollup/plugin-babel": "^6.0.4", @@ -61,8 +60,6 @@ "concurrently": "^6.0.0", "core-js": "^3.6.5", "dotenv": "^8.2.0", - "enzyme": "^3.11.0", - "enzyme-to-json": "^3.6.1", "eslint": "^7.20.0", "eslint-config-prettier": "^8.0.0", "eslint-plugin-jest": "^24.1.5", @@ -80,7 +77,6 @@ "jest-environment-jsdom": "^29.4.1", "jest-jasmine2": "^29.0.3", "jest-junit": "^13.0.0", - "jest-react-hooks-shallow": "^1.5.1", "make-dir": "^3.1.0", "mendix": "^10.21.64362", "mime": "^3.0.0", diff --git a/packages/pluggable-widgets-tools/src/utils/enzyme-detector.ts b/packages/pluggable-widgets-tools/src/utils/enzyme-detector.ts new file mode 100644 index 00000000..c401fd15 --- /dev/null +++ b/packages/pluggable-widgets-tools/src/utils/enzyme-detector.ts @@ -0,0 +1,65 @@ +import { existsSync, readdirSync, readFileSync, statSync } from "fs"; +import { join } from "path"; +import { yellow } from "ansi-colors"; + +export function checkForEnzymeUsage(srcDir: string = "src"): void { + const projectRoot = process.cwd(); + const srcPath = join(projectRoot, srcDir); + + if (!existsSync(srcPath)) { + return; + } + + const enzymeFiles: string[] = []; + + function scanDirectory(dir: string): void { + try { + const entries = readdirSync(dir); + + for (const entry of entries) { + const fullPath = join(dir, entry); + const stat = statSync(fullPath); + + if (stat.isDirectory()) { + scanDirectory(fullPath); + continue; + } + + const isJsOrTsFile = /\.(jsx?|tsx?)$/.test(entry); + if (!stat.isFile() || !isJsOrTsFile) { + continue; + } + + const content = readFileSync(fullPath, "utf8"); + if ( + /(from|require\s*\()\s*['"]enzyme['"]|enzyme.*(?:shallow|mount|render)|(?:shallow|mount|render).*enzyme/.test( + content + ) + ) { + enzymeFiles.push(fullPath.replace(projectRoot, ".")); + } + } + } catch (error) { + console.error(`Error scanning directory ${dir}:`, error); + } + } + + scanDirectory(srcPath); + + if (enzymeFiles.length > 0) { + console.log(yellow("\n WARNING: Enzyme usage detected in your tests")); + console.log( + yellow( + "Enzyme is no longer supported. Please migrate your tests to React Testing Library." + ) + ); + console.log(yellow("\nFiles with potential Enzyme usage:")); + enzymeFiles.forEach(file => console.log(yellow(` ${file}`))); + console.log( + yellow( + "\nFor migration guidance, see: https://testing-library.com/docs/react-testing-library/migrate-from-enzyme" + ) + ); + console.log(); + } +} diff --git a/packages/pluggable-widgets-tools/test-config/jest.config.js b/packages/pluggable-widgets-tools/test-config/jest.config.js index 4501bc2d..3df733c1 100644 --- a/packages/pluggable-widgets-tools/test-config/jest.config.js +++ b/packages/pluggable-widgets-tools/test-config/jest.config.js @@ -7,7 +7,6 @@ module.exports = { testRunner: "jest-jasmine2", rootDir: join(projectDir, "src"), setupFilesAfterEnv: [join(__dirname, "test-index.js")], - snapshotSerializers: ["enzyme-to-json/serializer"], testMatch: ["/**/*.spec.{js,jsx,ts,tsx}"], transform: { "^.+\\.tsx?$": [ diff --git a/packages/pluggable-widgets-tools/test-config/jest.enzyme-free.config.js b/packages/pluggable-widgets-tools/test-config/jest.enzyme-free.config.js deleted file mode 100644 index 12dbce6d..00000000 --- a/packages/pluggable-widgets-tools/test-config/jest.enzyme-free.config.js +++ /dev/null @@ -1,32 +0,0 @@ -const { join } = require("path"); - -const projectDir = process.cwd(); - -module.exports = { - clearMocks: true, - testRunner: "jest-jasmine2", - rootDir: join(projectDir, "src"), - setupFilesAfterEnv: [join(__dirname, "test-index-no-enzyme.js")], - testMatch: ["/**/*.spec.{js,jsx,ts,tsx}"], - transform: { - "^.+\\.tsx?$": [ - "ts-jest", - { - tsconfig: { module: "commonjs", target: "ES2019" }, - } - ], - "^.+\\.jsx?$": join(__dirname, "transform.js"), - "^.+\\.svg$": join(__dirname, "jest-svg-transformer") - }, - moduleNameMapper: { - "\\.(css|less|scss|sass)$": "identity-obj-proxy", - "mendix/components/web/Icon": join(__dirname, "__mocks__/WebIcon"), - "mendix/filters/builders": join(__dirname, "__mocks__/FilterBuilders"), - "\\.png$": join(__dirname, "assetsTransformer.js"), - "react-hot-loader/root": join(__dirname, "__mocks__/hot") - }, - moduleDirectories: ["node_modules", join(projectDir, "node_modules")], - collectCoverage: !process.env.CI, - coverageDirectory: join(projectDir, "dist/coverage"), - testEnvironment: "jsdom" -}; diff --git a/packages/pluggable-widgets-tools/test-config/test-index-native.js b/packages/pluggable-widgets-tools/test-config/test-index-native.js index eec51722..0cf852ae 100644 --- a/packages/pluggable-widgets-tools/test-config/test-index-native.js +++ b/packages/pluggable-widgets-tools/test-config/test-index-native.js @@ -1,5 +1,4 @@ const { TextEncoder, TextDecoder } = require("util"); -const enableHooks = require("jest-react-hooks-shallow").default; Object.defineProperties(global, { TextEncoder: { @@ -10,7 +9,6 @@ Object.defineProperties(global, { } }); -enableHooks(jest); global.setImmediate = global.setTimeout; const origConsole = console.error; diff --git a/packages/pluggable-widgets-tools/test-config/test-index-no-enzyme.js b/packages/pluggable-widgets-tools/test-config/test-index-no-enzyme.js deleted file mode 100644 index dcff3c94..00000000 --- a/packages/pluggable-widgets-tools/test-config/test-index-no-enzyme.js +++ /dev/null @@ -1,11 +0,0 @@ -require("@testing-library/jest-dom"); -const { TextEncoder, TextDecoder } = require("util"); - -Object.defineProperties(global, { - TextEncoder: { - value: TextEncoder - }, - TextDecoder: { - value: TextDecoder - } -}); diff --git a/packages/pluggable-widgets-tools/test-config/test-index.js b/packages/pluggable-widgets-tools/test-config/test-index.js index 621ddcc0..dcff3c94 100644 --- a/packages/pluggable-widgets-tools/test-config/test-index.js +++ b/packages/pluggable-widgets-tools/test-config/test-index.js @@ -1,8 +1,5 @@ require("@testing-library/jest-dom"); const { TextEncoder, TextDecoder } = require("util"); -const { configure: configureEnzyme } = require("enzyme"); -const Adapter = require("@cfaester/enzyme-adapter-react-18").default; -const enableHooks = require("jest-react-hooks-shallow").default; Object.defineProperties(global, { TextEncoder: { @@ -12,7 +9,3 @@ Object.defineProperties(global, { value: TextDecoder } }); - -configureEnzyme({ adapter: new Adapter() }); -enableHooks(jest); -global.setImmediate = global.setTimeout; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e7ae32e2..e2bc8124 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -118,7 +118,7 @@ importers: version: 8.10.0(eslint@7.32.0) eslint-plugin-jest: specifier: ^27.1.3 - version: 27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0)(jest@29.7.0(@types/node@16.18.126)(ts-node@10.9.2(@types/node@16.18.126)(typescript@5.8.3)))(typescript@5.8.3) + version: 27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0)(jest@29.7.0)(typescript@5.8.3) eslint-plugin-prettier: specifier: ^3.3.1 version: 3.4.1(eslint-config-prettier@8.10.0(eslint@7.32.0))(eslint@7.32.0)(prettier@2.8.8) @@ -155,9 +155,6 @@ importers: '@babel/preset-react': specifier: ^7.25.9 version: 7.27.1(@babel/core@7.28.0) - '@cfaester/enzyme-adapter-react-18': - specifier: ^0.6.0 - version: 0.6.0(enzyme@3.11.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@prettier/plugin-xml': specifier: ^1.2.0 version: 1.2.0 @@ -245,12 +242,6 @@ importers: dotenv: specifier: ^8.2.0 version: 8.6.0 - enzyme: - specifier: ^3.11.0 - version: 3.11.0 - enzyme-to-json: - specifier: ^3.6.1 - version: 3.6.2(enzyme@3.11.0) eslint: specifier: ^7.20.0 version: 7.32.0 @@ -302,9 +293,6 @@ importers: jest-junit: specifier: ^13.0.0 version: 13.2.0 - jest-react-hooks-shallow: - specifier: ^1.5.1 - version: 1.5.1 make-dir: specifier: ^3.1.0 version: 3.1.0 @@ -1216,13 +1204,6 @@ packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - '@cfaester/enzyme-adapter-react-18@0.6.0': - resolution: {integrity: sha512-68pqLvXsH0OVr6vWYvjTybEAM4piLqpeIYR5wuPnFzjPGKy7oZdIjJAMwMoBCvvio1zMjyzBzj5dCbg4O2JQnA==} - peerDependencies: - enzyme: ^3.0.0 - react: ^18.0.0 - react-dom: ^18.0.0 - '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -1997,9 +1978,6 @@ packages: '@types/big.js@6.2.2': resolution: {integrity: sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA==} - '@types/cheerio@0.22.35': - resolution: {integrity: sha512-yD57BchKRvTV+JD53UZ6PD8KWY5g5rvvMLRnZR3EQBCZXiDT/HR+pKpMzFGlWNhFrXlo7VPZXtKvIEwZkAWOIA==} - '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -2374,10 +2352,6 @@ packages: resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} engines: {node: '>=0.10.0'} - array.prototype.filter@1.0.4: - resolution: {integrity: sha512-r+mCJ7zXgXElgR4IRC+fkvNCeoaavWBs6EdCso5Tbcf+iEMKzBU/His60lt34WEZ9vlb8wDkZvQGcVI5GwkfoQ==} - engines: {node: '>= 0.4'} - array.prototype.findlast@1.2.5: resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} engines: {node: '>= 0.4'} @@ -2656,13 +2630,6 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - cheerio-select@2.1.0: - resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} - - cheerio@1.0.0-rc.12: - resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} - engines: {node: '>= 6'} - chevrotain@7.1.1: resolution: {integrity: sha512-wy3mC1x4ye+O+QkEinVJkPf5u2vsrDIYW9G7ZuwFl6v/Yu0LwUuT2POsb+NUWApebyxfkQq6+yDfRExbnI5rcw==} @@ -2905,9 +2872,6 @@ packages: css-select@4.3.0: resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} - css-select@5.2.2: - resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} - css-tree@1.1.3: resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} engines: {node: '>=8.0.0'} @@ -3103,9 +3067,6 @@ packages: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} - discontinuous-range@1.0.0: - resolution: {integrity: sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==} - doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -3120,9 +3081,6 @@ packages: dom-serializer@1.4.1: resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} - dom-serializer@2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} @@ -3135,16 +3093,9 @@ packages: resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} engines: {node: '>= 4'} - domhandler@5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} - domutils@2.8.0: resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} - domutils@3.2.2: - resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} - dotenv@8.6.0: resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} engines: {node: '>=10'} @@ -3198,10 +3149,6 @@ packages: entities@2.2.0: resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - entities@6.0.1: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} @@ -3215,18 +3162,6 @@ packages: engines: {node: '>=4'} hasBin: true - enzyme-shallow-equal@1.0.7: - resolution: {integrity: sha512-/um0GFqUXnpM9SvKtje+9Tjoz3f1fpBC3eXRFrNs8kpYn69JljciYP7KZTqM/YQbUY9KUjvKB4jo/q+L6WGGvg==} - - enzyme-to-json@3.6.2: - resolution: {integrity: sha512-Ynm6Z6R6iwQ0g2g1YToz6DWhxVnt8Dy1ijR2zynRKxTyBGA8rCDXU3rs2Qc4OKvUvc2Qoe1bcFK6bnPs20TrTg==} - engines: {node: '>=6.0.0'} - peerDependencies: - enzyme: ^3.4.0 - - enzyme@3.11.0: - resolution: {integrity: sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw==} - err-code@2.0.3: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} @@ -3251,9 +3186,6 @@ packages: resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} engines: {node: '>= 0.4'} - es-array-method-boxes-properly@1.0.0: - resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==} - es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -3798,10 +3730,6 @@ packages: has-unicode@2.0.1: resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} - has@1.0.4: - resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==} - engines: {node: '>= 0.4.0'} - hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -3833,9 +3761,6 @@ packages: resolution: {integrity: sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - html-element-map@1.3.1: - resolution: {integrity: sha512-6XMlxrAFX4UEEGxctfFnmrFaaZFNf9i5fNuV5wZ3WWQ4FVaNP1aX1LkX9j2mfEx1NpjeE/rL3nmgEn23GdFmrg==} - html-encoding-sniffer@3.0.0: resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} engines: {node: '>=12'} @@ -3843,9 +3768,6 @@ packages: html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - htmlparser2@8.0.2: - resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} - http-cache-semantics@4.2.0: resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} @@ -4130,9 +4052,6 @@ packages: resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} engines: {node: '>= 0.4'} - is-subset@0.1.1: - resolution: {integrity: sha512-6Ybun0IkarhmEqxXCNw/C0bna6Zb/TkfUX9UbwJtK6ObwAVCxmAP308WWTHviM/zAqXk05cdhYsUsZeGQh99iw==} - is-symbol@1.1.1: resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} engines: {node: '>= 0.4'} @@ -4352,9 +4271,6 @@ packages: jest-resolve: optional: true - jest-react-hooks-shallow@1.5.1: - resolution: {integrity: sha512-tyIUh2aKLTGPxbc6aK54pymvvRlX8eGNn3GzXefXAX5BkUwj4geS1pPJijmYeCELbn8+BUP9uS9+6OG5ElVI5Q==} - jest-regex-util@27.5.1: resolution: {integrity: sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -4611,23 +4527,13 @@ packages: lodash.difference@4.5.0: resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} - lodash.escape@4.0.1: - resolution: {integrity: sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==} - lodash.flatten@4.4.0: resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} - lodash.flattendeep@4.4.0: - resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==} - lodash.get@4.4.2: resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} deprecated: This package is deprecated. Use the optional chaining (?.) operator instead. - lodash.isequal@4.5.0: - resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} - deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. - lodash.isplainobject@4.0.6: resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} @@ -4830,7 +4736,6 @@ packages: metro-react-native-babel-preset@0.76.9: resolution: {integrity: sha512-eCBtW/UkJPDr6HlMgFEGF+964DZsUEF9RGeJdZLKWE7d/0nY3ABZ9ZAGxzu9efQ35EWRox5bDMXUGaOwUe5ikQ==} engines: {node: '>=16'} - deprecated: Use @react-native/babel-preset instead peerDependencies: '@babel/core': '*' @@ -5036,9 +4941,6 @@ packages: moment@2.30.1: resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} - moo@0.5.2: - resolution: {integrity: sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==} - ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -5063,10 +4965,6 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - nearley@2.20.1: - resolution: {integrity: sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==} - hasBin: true - negotiator@0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} @@ -5396,9 +5294,6 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} - parse5-htmlparser2-tree-adapter@7.1.0: - resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} - parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} @@ -5445,9 +5340,6 @@ packages: engines: {node: '>=10'} hasBin: true - performance-now@2.1.0: - resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} - picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -5832,16 +5724,6 @@ packages: queue@6.0.2: resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==} - raf@3.4.1: - resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==} - - railroad-diagrams@1.0.0: - resolution: {integrity: sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==} - - randexp@0.4.6: - resolution: {integrity: sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==} - engines: {node: '>=0.12'} - randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} @@ -5895,10 +5777,6 @@ packages: peerDependencies: react: ^18.3.1 - react@16.14.0: - resolution: {integrity: sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==} - engines: {node: '>=0.10.0'} - react@18.3.1: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} @@ -6062,10 +5940,6 @@ packages: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} - ret@0.1.15: - resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} - engines: {node: '>=0.12'} - retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} @@ -6117,9 +5991,6 @@ packages: engines: {node: '>=14.18.0', npm: '>=8.0.0'} hasBin: true - rst-selector-parser@2.2.3: - resolution: {integrity: sha512-nDG1rZeP6oFTLN6yNDV/uiAvs1+FS/KlrEwh7+y7dpuApDBy6bI2HTBcc0/V8lv9OTqfyD34eF7au2pm8aBbhA==} - run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -8088,15 +7959,6 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} - '@cfaester/enzyme-adapter-react-18@0.6.0(enzyme@3.11.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - enzyme: 3.11.0 - enzyme-shallow-equal: 1.0.7 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-is: 18.3.1 - react-test-renderer: 18.3.1(react@18.3.1) - '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 @@ -9326,10 +9188,6 @@ snapshots: '@types/big.js@6.2.2': {} - '@types/cheerio@0.22.35': - dependencies: - '@types/node': 16.18.126 - '@types/estree@1.0.8': {} '@types/expect@1.20.4': {} @@ -9841,15 +9699,6 @@ snapshots: array-uniq@1.0.3: {} - array.prototype.filter@1.0.4: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-array-method-boxes-properly: 1.0.0 - es-object-atoms: 1.1.1 - is-string: 1.1.1 - array.prototype.findlast@1.2.5: dependencies: call-bind: 1.0.8 @@ -10269,25 +10118,6 @@ snapshots: chardet@0.7.0: {} - cheerio-select@2.1.0: - dependencies: - boolbase: 1.0.0 - css-select: 5.2.2 - css-what: 6.2.2 - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.2.2 - - cheerio@1.0.0-rc.12: - dependencies: - cheerio-select: 2.1.0 - dom-serializer: 2.0.0 - domhandler: 5.0.3 - domutils: 3.2.2 - htmlparser2: 8.0.2 - parse5: 7.3.0 - parse5-htmlparser2-tree-adapter: 7.1.0 - chevrotain@7.1.1: dependencies: regexp-to-ast: 0.5.0 @@ -10563,14 +10393,6 @@ snapshots: domutils: 2.8.0 nth-check: 2.1.1 - css-select@5.2.2: - dependencies: - boolbase: 1.0.0 - css-what: 6.2.2 - domhandler: 5.0.3 - domutils: 3.2.2 - nth-check: 2.1.1 - css-tree@1.1.3: dependencies: mdn-data: 2.0.14 @@ -10770,8 +10592,6 @@ snapshots: dependencies: path-type: 4.0.0 - discontinuous-range@1.0.0: {} - doctrine@2.1.0: dependencies: esutils: 2.0.3 @@ -10788,12 +10608,6 @@ snapshots: domhandler: 4.3.1 entities: 2.2.0 - dom-serializer@2.0.0: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - entities: 4.5.0 - domelementtype@2.3.0: {} domexception@4.0.0: @@ -10804,22 +10618,12 @@ snapshots: dependencies: domelementtype: 2.3.0 - domhandler@5.0.3: - dependencies: - domelementtype: 2.3.0 - domutils@2.8.0: dependencies: dom-serializer: 1.4.1 domelementtype: 2.3.0 domhandler: 4.3.1 - domutils@3.2.2: - dependencies: - dom-serializer: 2.0.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - dotenv@8.6.0: {} dunder-proto@1.0.1: @@ -10864,8 +10668,6 @@ snapshots: entities@2.2.0: {} - entities@4.5.0: {} - entities@6.0.1: {} env-paths@2.2.1: {} @@ -10873,43 +10675,6 @@ snapshots: envinfo@7.14.0: optional: true - enzyme-shallow-equal@1.0.7: - dependencies: - hasown: 2.0.2 - object-is: 1.1.6 - - enzyme-to-json@3.6.2(enzyme@3.11.0): - dependencies: - '@types/cheerio': 0.22.35 - enzyme: 3.11.0 - lodash: 4.17.21 - react-is: 16.13.1 - - enzyme@3.11.0: - dependencies: - array.prototype.flat: 1.3.3 - cheerio: 1.0.0-rc.12 - enzyme-shallow-equal: 1.0.7 - function.prototype.name: 1.1.8 - has: 1.0.4 - html-element-map: 1.3.1 - is-boolean-object: 1.2.2 - is-callable: 1.2.7 - is-number-object: 1.1.1 - is-regex: 1.2.1 - is-string: 1.1.1 - is-subset: 0.1.1 - lodash.escape: 4.0.1 - lodash.isequal: 4.5.0 - object-inspect: 1.13.4 - object-is: 1.1.6 - object.assign: 4.1.7 - object.entries: 1.1.9 - object.values: 1.2.1 - raf: 3.4.1 - rst-selector-parser: 2.2.3 - string.prototype.trim: 1.2.10 - err-code@2.0.3: {} errno@0.1.8: @@ -10989,8 +10754,6 @@ snapshots: unbox-primitive: 1.1.0 which-typed-array: 1.1.19 - es-array-method-boxes-properly@1.0.0: {} - es-define-property@1.0.1: {} es-errors@1.3.0: {} @@ -11083,7 +10846,7 @@ snapshots: - supports-color - typescript - eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0)(jest@29.7.0(@types/node@16.18.126)(ts-node@10.9.2(@types/node@16.18.126)(typescript@5.8.3)))(typescript@5.8.3): + eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0)(typescript@5.8.3))(eslint@7.32.0)(jest@29.7.0)(typescript@5.8.3): dependencies: '@typescript-eslint/utils': 5.62.0(eslint@7.32.0)(typescript@5.8.3) eslint: 7.32.0 @@ -11698,8 +11461,6 @@ snapshots: has-unicode@2.0.1: {} - has@1.0.4: {} - hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -11733,24 +11494,12 @@ snapshots: dependencies: lru-cache: 7.18.3 - html-element-map@1.3.1: - dependencies: - array.prototype.filter: 1.0.4 - call-bind: 1.0.8 - html-encoding-sniffer@3.0.0: dependencies: whatwg-encoding: 2.0.0 html-escaper@2.0.2: {} - htmlparser2@8.0.2: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.2.2 - entities: 4.5.0 - http-cache-semantics@4.2.0: {} http-errors@2.0.0: @@ -12035,8 +11784,6 @@ snapshots: call-bound: 1.0.4 has-tostringtag: 1.0.2 - is-subset@0.1.1: {} - is-symbol@1.1.1: dependencies: call-bound: 1.0.4 @@ -12405,10 +12152,6 @@ snapshots: optionalDependencies: jest-resolve: 29.7.0 - jest-react-hooks-shallow@1.5.1: - dependencies: - react: 16.14.0 - jest-regex-util@27.5.1: optional: true @@ -12802,16 +12545,10 @@ snapshots: lodash.difference@4.5.0: {} - lodash.escape@4.0.1: {} - lodash.flatten@4.4.0: {} - lodash.flattendeep@4.4.0: {} - lodash.get@4.4.2: {} - lodash.isequal@4.5.0: {} - lodash.isplainobject@4.0.6: {} lodash.memoize@4.1.2: {} @@ -13560,8 +13297,6 @@ snapshots: moment@2.30.1: {} - moo@0.5.2: {} - ms@2.0.0: {} ms@2.1.3: {} @@ -13582,13 +13317,6 @@ snapshots: natural-compare@1.4.0: {} - nearley@2.20.1: - dependencies: - commander: 2.20.3 - moo: 0.5.2 - railroad-diagrams: 1.0.0 - randexp: 0.4.6 - negotiator@0.6.3: {} negotiator@0.6.4: {} @@ -14029,11 +13757,6 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - parse5-htmlparser2-tree-adapter@7.1.0: - dependencies: - domhandler: 5.0.3 - parse5: 7.3.0 - parse5@7.3.0: dependencies: entities: 6.0.1 @@ -14066,8 +13789,6 @@ snapshots: peggy@1.2.0: {} - performance-now@2.1.0: {} - picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -14419,17 +14140,6 @@ snapshots: dependencies: inherits: 2.0.4 - raf@3.4.1: - dependencies: - performance-now: 2.1.0 - - railroad-diagrams@1.0.0: {} - - randexp@0.4.6: - dependencies: - discontinuous-range: 1.0.0 - ret: 0.1.15 - randombytes@2.1.0: dependencies: safe-buffer: 5.2.1 @@ -14524,12 +14234,6 @@ snapshots: react-shallow-renderer: 16.15.0(react@18.3.1) scheduler: 0.23.2 - react@16.14.0: - dependencies: - loose-envify: 1.4.0 - object-assign: 4.1.1 - prop-types: 15.8.1 - react@18.3.1: dependencies: loose-envify: 1.4.0 @@ -14727,8 +14431,6 @@ snapshots: onetime: 5.1.2 signal-exit: 3.0.7 - ret@0.1.15: {} - retry@0.12.0: {} reusify@1.1.0: {} @@ -14800,11 +14502,6 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - rst-selector-parser@2.2.3: - dependencies: - lodash.flattendeep: 4.4.0 - nearley: 2.20.1 - run-async@2.4.1: {} run-parallel@1.2.0: