@atomic-testing/react-legacy 0.73.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Tianzhen Lin (Tangent)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,91 @@
1
+ # @atomic-testing/react-legacy
2
+
3
+ Adapter for integrating [Atomic Testing](https://atomic-testing.dev) with [React 16/17](https://react.dev).
4
+ It maps React components to the core scene part APIs.
5
+
6
+ ## The problem
7
+
8
+ Writing maintainable tests for UIs built with third–party component libraries
9
+ like Material UI or Bootstrap can be tricky. Documentation on how a test
10
+ should communicate with these components is often lacking, so tests easily end
11
+ up coupled to implementation details. As your application grows you need your
12
+ tests to scale without constantly reworking them.
13
+
14
+ ## The solution
15
+
16
+ [Atomic Testing](https://atomic-testing.dev) provides a consistent way to interact with both third–party and
17
+ first–party components across different test environments. It focuses on
18
+ **reusability**, **composability** and **adaptability**, letting you build
19
+ higher–level test strategies that work for DOM or end–to–end testing alike.
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ npm install @atomic-testing/core @atomic-testing/react-legacy --save-dev
25
+ ```
26
+
27
+ Refer to the [React integration guide](https://atomic-testing.dev/) for examples.
28
+
29
+ ## Example
30
+
31
+ If you use MUI/Material UI components, have a look at the
32
+ [@atomic-testing/component-driver-mui-v5](https://www.npmjs.com/package/@atomic-testing/component-driver-mui-v5)
33
+ package for a dedicated example.
34
+
35
+ 1. Install the core library and basic HTML drivers along with this React adapter:
36
+
37
+ ```bash
38
+ npm install @atomic-testing/core @atomic-testing/react-legacy @atomic-testing/component-driver-html --save-dev
39
+ ```
40
+
41
+ 2. Create a small component and assign `data-testid` values to the elements you want to interact with:
42
+
43
+ ```tsx title="Counter.tsx"
44
+ import { useState } from 'react';
45
+
46
+ export function Counter() {
47
+ const [count, setCount] = useState(0);
48
+ return (
49
+ <div>
50
+ <span data-testid='count'>{count}</span>
51
+ <button data-testid='increment' onClick={() => setCount(c => c + 1)}>
52
+ Increment
53
+ </button>
54
+ </div>
55
+ );
56
+ }
57
+ ```
58
+
59
+ 3. Define a `ScenePart` describing the count display and button using the HTML drivers:
60
+
61
+ ```ts title="counterScenePart.ts"
62
+ import { HTMLButtonDriver, HTMLElementDriver } from '@atomic-testing/component-driver-html';
63
+ import { byDataTestId, ScenePart } from '@atomic-testing/core';
64
+
65
+ export const counterScenePart = {
66
+ count: { locator: byDataTestId('count'), driver: HTMLElementDriver },
67
+ increment: { locator: byDataTestId('increment'), driver: HTMLButtonDriver },
68
+ } satisfies ScenePart;
69
+ ```
70
+
71
+ 4. Write a test using `createTestEngine` to render the component and interact with it:
72
+
73
+ ```ts title="Counter.test.tsx"
74
+ import { createTestEngine } from '@atomic-testing/react-19';
75
+
76
+ import { Counter } from './Counter';
77
+ import { counterScenePart } from './counterScenePart';
78
+
79
+ test('increments when the button is clicked', async () => {
80
+ const engine = createTestEngine(<Counter />, counterScenePart);
81
+
82
+ expect(await engine.parts.count.getText()).toBe('0');
83
+ await engine.parts.increment.click();
84
+ expect(await engine.parts.count.getText()).toBe('1');
85
+
86
+ await engine.cleanUp();
87
+ });
88
+ ```
89
+
90
+ For more in‑depth information, visit
91
+ [https://atomic-testing.dev](https://atomic-testing.dev).
@@ -0,0 +1,31 @@
1
+ import { IComponentDriverOption, ScenePart, TestEngine } from "@atomic-testing/core";
2
+
3
+ //#region src/types.d.ts
4
+ interface IReactTestEngineOption extends IComponentDriverOption {
5
+ rootElement?: Element;
6
+ }
7
+ //#endregion
8
+ //#region src/createTestEngine.d.ts
9
+ /**
10
+ * Create test engine for React 17 or before, for React 18 or later, use @atomic-testing/react-18 or @atomic-testing/react-19
11
+ * This function takes a react node and render it into a container element. For rendered
12
+ * components, use createRenderedLegacyTestEngine
13
+ * @param node The React node to render
14
+ * @param partDefinitions The scene part definitions
15
+ * @param option
16
+ * @returns The test engine
17
+ */
18
+ declare function createTestEngine<T extends ScenePart>(node: JSX.Element, partDefinitions: T, option?: Readonly<Partial<IReactTestEngineOption>>): TestEngine<T>;
19
+ /**
20
+ * Create test engine for React 17 or before, for React 18 or later, use @atomic-testing/react-18 or @atomic-testing/react-19
21
+ * This function takes an html element purportedly rendered by React and create a test engine for it, it
22
+ * can be useful in environment such as Storybook where Storybook renders the component and the test
23
+ * @param rootElement The React node to render
24
+ * @param partDefinitions The scene part definitions
25
+ * @param option
26
+ * @returns The test engine
27
+ */
28
+ declare function createRenderedTestEngine<T extends ScenePart>(rootElement: HTMLElement, partDefinitions: T, _option?: Readonly<Partial<IReactTestEngineOption>>): TestEngine<T>;
29
+ //#endregion
30
+ export { IReactTestEngineOption, createRenderedTestEngine, createTestEngine };
31
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1,31 @@
1
+ import { IComponentDriverOption, ScenePart, TestEngine } from "@atomic-testing/core";
2
+
3
+ //#region src/types.d.ts
4
+ interface IReactTestEngineOption extends IComponentDriverOption {
5
+ rootElement?: Element;
6
+ }
7
+ //#endregion
8
+ //#region src/createTestEngine.d.ts
9
+ /**
10
+ * Create test engine for React 17 or before, for React 18 or later, use @atomic-testing/react-18 or @atomic-testing/react-19
11
+ * This function takes a react node and render it into a container element. For rendered
12
+ * components, use createRenderedLegacyTestEngine
13
+ * @param node The React node to render
14
+ * @param partDefinitions The scene part definitions
15
+ * @param option
16
+ * @returns The test engine
17
+ */
18
+ declare function createTestEngine<T extends ScenePart>(node: JSX.Element, partDefinitions: T, option?: Readonly<Partial<IReactTestEngineOption>>): TestEngine<T>;
19
+ /**
20
+ * Create test engine for React 17 or before, for React 18 or later, use @atomic-testing/react-18 or @atomic-testing/react-19
21
+ * This function takes an html element purportedly rendered by React and create a test engine for it, it
22
+ * can be useful in environment such as Storybook where Storybook renders the component and the test
23
+ * @param rootElement The React node to render
24
+ * @param partDefinitions The scene part definitions
25
+ * @param option
26
+ * @returns The test engine
27
+ */
28
+ declare function createRenderedTestEngine<T extends ScenePart>(rootElement: HTMLElement, partDefinitions: T, _option?: Readonly<Partial<IReactTestEngineOption>>): TestEngine<T>;
29
+ //#endregion
30
+ export { IReactTestEngineOption, createRenderedTestEngine, createTestEngine };
31
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,83 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+ const react_dom = __toESM(require("react-dom"));
25
+ const react_dom_test_utils = __toESM(require("react-dom/test-utils"));
26
+ const __atomic_testing_core = __toESM(require("@atomic-testing/core"));
27
+ const __atomic_testing_react_core = __toESM(require("@atomic-testing/react-core"));
28
+
29
+ //#region src/createTestEngine.ts
30
+ let _rootId = 0;
31
+ function getNextRootElementId() {
32
+ return `${_rootId++}`;
33
+ }
34
+ const rootElementAttributeName = "data-atomic-testing-react-legacy";
35
+ /**
36
+ * Create test engine for React 17 or before, for React 18 or later, use @atomic-testing/react-18 or @atomic-testing/react-19
37
+ * This function takes a react node and render it into a container element. For rendered
38
+ * components, use createRenderedLegacyTestEngine
39
+ * @param node The React node to render
40
+ * @param partDefinitions The scene part definitions
41
+ * @param option
42
+ * @returns The test engine
43
+ */
44
+ function createTestEngine(node, partDefinitions, option) {
45
+ const rootEl = option?.rootElement ?? document.body;
46
+ const container = rootEl.appendChild(document.createElement("div"));
47
+ const rootId = getNextRootElementId();
48
+ container.setAttribute(rootElementAttributeName, rootId);
49
+ (0, react_dom_test_utils.act)(() => {
50
+ react_dom.default.render(node, container);
51
+ });
52
+ const cleanup = () => {
53
+ react_dom.default.unmountComponentAtNode(container);
54
+ rootEl.removeChild(container);
55
+ return Promise.resolve();
56
+ };
57
+ const engine = new __atomic_testing_core.TestEngine((0, __atomic_testing_core.byAttribute)(rootElementAttributeName, rootId), new __atomic_testing_react_core.ReactInteractor(), { parts: partDefinitions }, cleanup);
58
+ return engine;
59
+ }
60
+ /**
61
+ * Create test engine for React 17 or before, for React 18 or later, use @atomic-testing/react-18 or @atomic-testing/react-19
62
+ * This function takes an html element purportedly rendered by React and create a test engine for it, it
63
+ * can be useful in environment such as Storybook where Storybook renders the component and the test
64
+ * @param rootElement The React node to render
65
+ * @param partDefinitions The scene part definitions
66
+ * @param option
67
+ * @returns The test engine
68
+ */
69
+ function createRenderedTestEngine(rootElement, partDefinitions, _option) {
70
+ const rootId = getNextRootElementId();
71
+ rootElement.setAttribute(rootElementAttributeName, rootId);
72
+ const cleanup = () => {
73
+ rootElement.removeAttribute(rootElementAttributeName);
74
+ return Promise.resolve();
75
+ };
76
+ const engine = new __atomic_testing_core.TestEngine((0, __atomic_testing_core.byAttribute)(rootElementAttributeName, rootId), new __atomic_testing_react_core.ReactInteractor(), { parts: partDefinitions }, cleanup);
77
+ return engine;
78
+ }
79
+
80
+ //#endregion
81
+ exports.createRenderedTestEngine = createRenderedTestEngine;
82
+ exports.createTestEngine = createTestEngine;
83
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["node: JSX.Element","partDefinitions: T","option?: Readonly<Partial<IReactTestEngineOption>>","TestEngine","ReactInteractor","rootElement: HTMLElement","_option?: Readonly<Partial<IReactTestEngineOption>>"],"sources":["../src/createTestEngine.ts"],"sourcesContent":["import ReactDOM from 'react-dom';\nimport { act } from 'react-dom/test-utils';\n\nimport { byAttribute, ScenePart, TestEngine } from '@atomic-testing/core';\nimport { ReactInteractor } from '@atomic-testing/react-core';\n\nimport { IReactTestEngineOption } from './types';\n\nlet _rootId = 0;\nfunction getNextRootElementId() {\n return `${_rootId++}`;\n}\n\nconst rootElementAttributeName = 'data-atomic-testing-react-legacy';\n\n/**\n * Create test engine for React 17 or before, for React 18 or later, use @atomic-testing/react-18 or @atomic-testing/react-19\n * This function takes a react node and render it into a container element. For rendered\n * components, use createRenderedLegacyTestEngine\n * @param node The React node to render\n * @param partDefinitions The scene part definitions\n * @param option\n * @returns The test engine\n */\nexport function createTestEngine<T extends ScenePart>(\n node: JSX.Element,\n partDefinitions: T,\n option?: Readonly<Partial<IReactTestEngineOption>>\n): TestEngine<T> {\n const rootEl = option?.rootElement ?? document.body;\n const container = rootEl.appendChild(document.createElement('div'));\n const rootId = getNextRootElementId();\n container.setAttribute(rootElementAttributeName, rootId);\n\n act(() => {\n ReactDOM.render(node, container);\n });\n const cleanup = () => {\n ReactDOM.unmountComponentAtNode(container);\n rootEl.removeChild(container);\n return Promise.resolve();\n };\n\n const engine = new TestEngine(\n byAttribute(rootElementAttributeName, rootId),\n new ReactInteractor(),\n {\n parts: partDefinitions,\n },\n cleanup\n );\n\n return engine;\n}\n\n/**\n * Create test engine for React 17 or before, for React 18 or later, use @atomic-testing/react-18 or @atomic-testing/react-19\n * This function takes an html element purportedly rendered by React and create a test engine for it, it\n * can be useful in environment such as Storybook where Storybook renders the component and the test\n * @param rootElement The React node to render\n * @param partDefinitions The scene part definitions\n * @param option\n * @returns The test engine\n */\nexport function createRenderedTestEngine<T extends ScenePart>(\n rootElement: HTMLElement,\n partDefinitions: T,\n _option?: Readonly<Partial<IReactTestEngineOption>>\n): TestEngine<T> {\n const rootId = getNextRootElementId();\n rootElement.setAttribute(rootElementAttributeName, rootId);\n\n const cleanup = () => {\n rootElement.removeAttribute(rootElementAttributeName);\n return Promise.resolve();\n };\n\n const engine = new TestEngine(\n byAttribute(rootElementAttributeName, rootId),\n new ReactInteractor(),\n {\n parts: partDefinitions,\n },\n cleanup\n );\n\n return engine;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,IAAI,UAAU;AACd,SAAS,uBAAuB;AAC9B,SAAQ,EAAE,UAAU;AACrB;AAED,MAAM,2BAA2B;;;;;;;;;;AAWjC,SAAgB,iBACdA,MACAC,iBACAC,QACe;CACf,MAAM,SAAS,QAAQ,eAAe,SAAS;CAC/C,MAAM,YAAY,OAAO,YAAY,SAAS,cAAc,MAAM,CAAC;CACnE,MAAM,SAAS,sBAAsB;AACrC,WAAU,aAAa,0BAA0B,OAAO;AAExD,+BAAI,MAAM;AACR,oBAAS,OAAO,MAAM,UAAU;CACjC,EAAC;CACF,MAAM,UAAU,MAAM;AACpB,oBAAS,uBAAuB,UAAU;AAC1C,SAAO,YAAY,UAAU;AAC7B,SAAO,QAAQ,SAAS;CACzB;CAED,MAAM,SAAS,IAAIC,iCACjB,uCAAY,0BAA0B,OAAO,EAC7C,IAAIC,+CACJ,EACE,OAAO,gBACR,GACD;AAGF,QAAO;AACR;;;;;;;;;;AAWD,SAAgB,yBACdC,aACAJ,iBACAK,SACe;CACf,MAAM,SAAS,sBAAsB;AACrC,aAAY,aAAa,0BAA0B,OAAO;CAE1D,MAAM,UAAU,MAAM;AACpB,cAAY,gBAAgB,yBAAyB;AACrD,SAAO,QAAQ,SAAS;CACzB;CAED,MAAM,SAAS,IAAIH,iCACjB,uCAAY,0BAA0B,OAAO,EAC7C,IAAIC,+CACJ,EACE,OAAO,gBACR,GACD;AAGF,QAAO;AACR"}
package/dist/index.mjs ADDED
@@ -0,0 +1,59 @@
1
+ import ReactDOM from "react-dom";
2
+ import { act } from "react-dom/test-utils";
3
+ import { TestEngine, byAttribute } from "@atomic-testing/core";
4
+ import { ReactInteractor } from "@atomic-testing/react-core";
5
+
6
+ //#region src/createTestEngine.ts
7
+ let _rootId = 0;
8
+ function getNextRootElementId() {
9
+ return `${_rootId++}`;
10
+ }
11
+ const rootElementAttributeName = "data-atomic-testing-react-legacy";
12
+ /**
13
+ * Create test engine for React 17 or before, for React 18 or later, use @atomic-testing/react-18 or @atomic-testing/react-19
14
+ * This function takes a react node and render it into a container element. For rendered
15
+ * components, use createRenderedLegacyTestEngine
16
+ * @param node The React node to render
17
+ * @param partDefinitions The scene part definitions
18
+ * @param option
19
+ * @returns The test engine
20
+ */
21
+ function createTestEngine(node, partDefinitions, option) {
22
+ const rootEl = option?.rootElement ?? document.body;
23
+ const container = rootEl.appendChild(document.createElement("div"));
24
+ const rootId = getNextRootElementId();
25
+ container.setAttribute(rootElementAttributeName, rootId);
26
+ act(() => {
27
+ ReactDOM.render(node, container);
28
+ });
29
+ const cleanup = () => {
30
+ ReactDOM.unmountComponentAtNode(container);
31
+ rootEl.removeChild(container);
32
+ return Promise.resolve();
33
+ };
34
+ const engine = new TestEngine(byAttribute(rootElementAttributeName, rootId), new ReactInteractor(), { parts: partDefinitions }, cleanup);
35
+ return engine;
36
+ }
37
+ /**
38
+ * Create test engine for React 17 or before, for React 18 or later, use @atomic-testing/react-18 or @atomic-testing/react-19
39
+ * This function takes an html element purportedly rendered by React and create a test engine for it, it
40
+ * can be useful in environment such as Storybook where Storybook renders the component and the test
41
+ * @param rootElement The React node to render
42
+ * @param partDefinitions The scene part definitions
43
+ * @param option
44
+ * @returns The test engine
45
+ */
46
+ function createRenderedTestEngine(rootElement, partDefinitions, _option) {
47
+ const rootId = getNextRootElementId();
48
+ rootElement.setAttribute(rootElementAttributeName, rootId);
49
+ const cleanup = () => {
50
+ rootElement.removeAttribute(rootElementAttributeName);
51
+ return Promise.resolve();
52
+ };
53
+ const engine = new TestEngine(byAttribute(rootElementAttributeName, rootId), new ReactInteractor(), { parts: partDefinitions }, cleanup);
54
+ return engine;
55
+ }
56
+
57
+ //#endregion
58
+ export { createRenderedTestEngine, createTestEngine };
59
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["node: JSX.Element","partDefinitions: T","option?: Readonly<Partial<IReactTestEngineOption>>","rootElement: HTMLElement","_option?: Readonly<Partial<IReactTestEngineOption>>"],"sources":["../src/createTestEngine.ts"],"sourcesContent":["import ReactDOM from 'react-dom';\nimport { act } from 'react-dom/test-utils';\n\nimport { byAttribute, ScenePart, TestEngine } from '@atomic-testing/core';\nimport { ReactInteractor } from '@atomic-testing/react-core';\n\nimport { IReactTestEngineOption } from './types';\n\nlet _rootId = 0;\nfunction getNextRootElementId() {\n return `${_rootId++}`;\n}\n\nconst rootElementAttributeName = 'data-atomic-testing-react-legacy';\n\n/**\n * Create test engine for React 17 or before, for React 18 or later, use @atomic-testing/react-18 or @atomic-testing/react-19\n * This function takes a react node and render it into a container element. For rendered\n * components, use createRenderedLegacyTestEngine\n * @param node The React node to render\n * @param partDefinitions The scene part definitions\n * @param option\n * @returns The test engine\n */\nexport function createTestEngine<T extends ScenePart>(\n node: JSX.Element,\n partDefinitions: T,\n option?: Readonly<Partial<IReactTestEngineOption>>\n): TestEngine<T> {\n const rootEl = option?.rootElement ?? document.body;\n const container = rootEl.appendChild(document.createElement('div'));\n const rootId = getNextRootElementId();\n container.setAttribute(rootElementAttributeName, rootId);\n\n act(() => {\n ReactDOM.render(node, container);\n });\n const cleanup = () => {\n ReactDOM.unmountComponentAtNode(container);\n rootEl.removeChild(container);\n return Promise.resolve();\n };\n\n const engine = new TestEngine(\n byAttribute(rootElementAttributeName, rootId),\n new ReactInteractor(),\n {\n parts: partDefinitions,\n },\n cleanup\n );\n\n return engine;\n}\n\n/**\n * Create test engine for React 17 or before, for React 18 or later, use @atomic-testing/react-18 or @atomic-testing/react-19\n * This function takes an html element purportedly rendered by React and create a test engine for it, it\n * can be useful in environment such as Storybook where Storybook renders the component and the test\n * @param rootElement The React node to render\n * @param partDefinitions The scene part definitions\n * @param option\n * @returns The test engine\n */\nexport function createRenderedTestEngine<T extends ScenePart>(\n rootElement: HTMLElement,\n partDefinitions: T,\n _option?: Readonly<Partial<IReactTestEngineOption>>\n): TestEngine<T> {\n const rootId = getNextRootElementId();\n rootElement.setAttribute(rootElementAttributeName, rootId);\n\n const cleanup = () => {\n rootElement.removeAttribute(rootElementAttributeName);\n return Promise.resolve();\n };\n\n const engine = new TestEngine(\n byAttribute(rootElementAttributeName, rootId),\n new ReactInteractor(),\n {\n parts: partDefinitions,\n },\n cleanup\n );\n\n return engine;\n}\n"],"mappings":";;;;;;AAQA,IAAI,UAAU;AACd,SAAS,uBAAuB;AAC9B,SAAQ,EAAE,UAAU;AACrB;AAED,MAAM,2BAA2B;;;;;;;;;;AAWjC,SAAgB,iBACdA,MACAC,iBACAC,QACe;CACf,MAAM,SAAS,QAAQ,eAAe,SAAS;CAC/C,MAAM,YAAY,OAAO,YAAY,SAAS,cAAc,MAAM,CAAC;CACnE,MAAM,SAAS,sBAAsB;AACrC,WAAU,aAAa,0BAA0B,OAAO;AAExD,KAAI,MAAM;AACR,WAAS,OAAO,MAAM,UAAU;CACjC,EAAC;CACF,MAAM,UAAU,MAAM;AACpB,WAAS,uBAAuB,UAAU;AAC1C,SAAO,YAAY,UAAU;AAC7B,SAAO,QAAQ,SAAS;CACzB;CAED,MAAM,SAAS,IAAI,WACjB,YAAY,0BAA0B,OAAO,EAC7C,IAAI,mBACJ,EACE,OAAO,gBACR,GACD;AAGF,QAAO;AACR;;;;;;;;;;AAWD,SAAgB,yBACdC,aACAF,iBACAG,SACe;CACf,MAAM,SAAS,sBAAsB;AACrC,aAAY,aAAa,0BAA0B,OAAO;CAE1D,MAAM,UAAU,MAAM;AACpB,cAAY,gBAAgB,yBAAyB;AACrD,SAAO,QAAQ,SAAS;CACzB;CAED,MAAM,SAAS,IAAI,WACjB,YAAY,0BAA0B,OAAO,EAC7C,IAAI,mBACJ,EACE,OAAO,gBACR,GACD;AAGF,QAAO;AACR"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@atomic-testing/react-legacy",
3
+ "version": "0.73.0",
4
+ "description": "Adapter for testing React 17 and earlier",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "typings": "dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "src"
11
+ ],
12
+ "author": "Tianzhen Lin <tangent@usa.net>",
13
+ "keywords": [
14
+ "testing",
15
+ "react",
16
+ "legacy"
17
+ ],
18
+ "license": "MIT",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/atomic-testing/atomic-testing.git",
22
+ "directory": "packages/react-legacy"
23
+ },
24
+ "dependencies": {
25
+ "react-dom": "^17.0.0",
26
+ "@atomic-testing/dom-core": "0.73.0",
27
+ "@atomic-testing/core": "0.73.0",
28
+ "@atomic-testing/react-core": "0.73.0"
29
+ },
30
+ "devDependencies": {
31
+ "@types/react": "^17.0.0",
32
+ "@types/react-dom": "^17.0.0",
33
+ "react": "^17.0.0",
34
+ "react-dom": "^17.0.0"
35
+ },
36
+ "peerDependencies": {
37
+ "@testing-library/dom": ">=9.2.0",
38
+ "@testing-library/react": ">=12.0.0",
39
+ "@testing-library/user-event": ">=14.0.0",
40
+ "react": "^16 || ^17",
41
+ "react-dom": "^16 || ^17"
42
+ },
43
+ "scripts": {
44
+ "build": "tsdown",
45
+ "check:type": "tsc --noEmit"
46
+ }
47
+ }
@@ -0,0 +1,88 @@
1
+ import ReactDOM from 'react-dom';
2
+ import { act } from 'react-dom/test-utils';
3
+
4
+ import { byAttribute, ScenePart, TestEngine } from '@atomic-testing/core';
5
+ import { ReactInteractor } from '@atomic-testing/react-core';
6
+
7
+ import { IReactTestEngineOption } from './types';
8
+
9
+ let _rootId = 0;
10
+ function getNextRootElementId() {
11
+ return `${_rootId++}`;
12
+ }
13
+
14
+ const rootElementAttributeName = 'data-atomic-testing-react-legacy';
15
+
16
+ /**
17
+ * Create test engine for React 17 or before, for React 18 or later, use @atomic-testing/react-18 or @atomic-testing/react-19
18
+ * This function takes a react node and render it into a container element. For rendered
19
+ * components, use createRenderedLegacyTestEngine
20
+ * @param node The React node to render
21
+ * @param partDefinitions The scene part definitions
22
+ * @param option
23
+ * @returns The test engine
24
+ */
25
+ export function createTestEngine<T extends ScenePart>(
26
+ node: JSX.Element,
27
+ partDefinitions: T,
28
+ option?: Readonly<Partial<IReactTestEngineOption>>
29
+ ): TestEngine<T> {
30
+ const rootEl = option?.rootElement ?? document.body;
31
+ const container = rootEl.appendChild(document.createElement('div'));
32
+ const rootId = getNextRootElementId();
33
+ container.setAttribute(rootElementAttributeName, rootId);
34
+
35
+ act(() => {
36
+ ReactDOM.render(node, container);
37
+ });
38
+ const cleanup = () => {
39
+ ReactDOM.unmountComponentAtNode(container);
40
+ rootEl.removeChild(container);
41
+ return Promise.resolve();
42
+ };
43
+
44
+ const engine = new TestEngine(
45
+ byAttribute(rootElementAttributeName, rootId),
46
+ new ReactInteractor(),
47
+ {
48
+ parts: partDefinitions,
49
+ },
50
+ cleanup
51
+ );
52
+
53
+ return engine;
54
+ }
55
+
56
+ /**
57
+ * Create test engine for React 17 or before, for React 18 or later, use @atomic-testing/react-18 or @atomic-testing/react-19
58
+ * This function takes an html element purportedly rendered by React and create a test engine for it, it
59
+ * can be useful in environment such as Storybook where Storybook renders the component and the test
60
+ * @param rootElement The React node to render
61
+ * @param partDefinitions The scene part definitions
62
+ * @param option
63
+ * @returns The test engine
64
+ */
65
+ export function createRenderedTestEngine<T extends ScenePart>(
66
+ rootElement: HTMLElement,
67
+ partDefinitions: T,
68
+ _option?: Readonly<Partial<IReactTestEngineOption>>
69
+ ): TestEngine<T> {
70
+ const rootId = getNextRootElementId();
71
+ rootElement.setAttribute(rootElementAttributeName, rootId);
72
+
73
+ const cleanup = () => {
74
+ rootElement.removeAttribute(rootElementAttributeName);
75
+ return Promise.resolve();
76
+ };
77
+
78
+ const engine = new TestEngine(
79
+ byAttribute(rootElementAttributeName, rootId),
80
+ new ReactInteractor(),
81
+ {
82
+ parts: partDefinitions,
83
+ },
84
+ cleanup
85
+ );
86
+
87
+ return engine;
88
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { createTestEngine, createRenderedTestEngine } from './createTestEngine';
2
+ export type { IReactTestEngineOption } from './types';
package/src/types.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { IComponentDriverOption } from '@atomic-testing/core';
2
+
3
+ export interface IReactTestEngineOption extends IComponentDriverOption {
4
+ rootElement?: Element;
5
+ }