@atomic-testing/react-legacy 0.89.0 → 0.90.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/dist/index.cjs CHANGED
@@ -39,7 +39,7 @@ let _atomic_testing_dom_core = require("@atomic-testing/dom-core");
39
39
  * `react-dom/test-utils` (the React ≤17 act), react-legacy stays on a coherent
40
40
  * React-16/17 dependency graph.
41
41
  */
42
- var LegacyReactInteractor = class LegacyReactInteractor extends _atomic_testing_dom_core.DOMInteractor {
42
+ var LegacyReactInteractor = class extends _atomic_testing_dom_core.DOMInteractor {
43
43
  async enterText(locator, text, option) {
44
44
  await (0, react_dom_test_utils_js.act)(async () => {
45
45
  await super.enterText(locator, text, option);
@@ -150,11 +150,6 @@ var LegacyReactInteractor = class LegacyReactInteractor extends _atomic_testing_
150
150
  await super.drag(locator, delta);
151
151
  });
152
152
  }
153
- async wait(ms) {
154
- await (0, react_dom_test_utils_js.act)(async () => {
155
- await super.wait(ms);
156
- });
157
- }
158
153
  async waitUntilComponentState(locator, option = _atomic_testing_core.defaultWaitForOption) {
159
154
  await (0, react_dom_test_utils_js.act)(async () => {
160
155
  await super.waitUntilComponentState(locator, option);
@@ -167,9 +162,6 @@ var LegacyReactInteractor = class LegacyReactInteractor extends _atomic_testing_
167
162
  });
168
163
  return result;
169
164
  }
170
- clone() {
171
- return new LegacyReactInteractor(this.rootEl);
172
- }
173
165
  };
174
166
  //#endregion
175
167
  //#region src/createTestEngine.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["DOMInteractor","defaultWaitForOption","TestEngine"],"sources":["../src/LegacyReactInteractor.ts","../src/createTestEngine.ts"],"sourcesContent":["import {\n BlurOption,\n ClickOption,\n defaultWaitForOption,\n EnterTextOption,\n FocusOption,\n HoverOption,\n Interactor,\n MouseDownOption,\n MouseEnterOption,\n MouseLeaveOption,\n MouseMoveOption,\n MouseOutOption,\n MouseUpOption,\n PartLocator,\n Point,\n PressKeyOption,\n WaitForOption,\n WaitUntilOption,\n} from '@atomic-testing/core';\nimport { DOMInteractor } from '@atomic-testing/dom-core';\nimport { act } from 'react-dom/test-utils';\n\n/**\n * React 16/17 counterpart of `@atomic-testing/react-core`'s `ReactInteractor`.\n *\n * It is a deliberate parallel implementation rather than a subclass of the\n * react-core interactor: react-core wraps actions with `act` from\n * `@testing-library/react@16`, whose peer range is React 18/19. Reusing it would\n * drag that dependency into react-legacy and make the package impossible to\n * install on React 16/17 (the very versions this adapter exists to support). By\n * extending `DOMInteractor` directly and wrapping with `act` from\n * `react-dom/test-utils` (the React ≤17 act), react-legacy stays on a coherent\n * React-16/17 dependency graph.\n */\nexport class LegacyReactInteractor extends DOMInteractor {\n override async enterText(locator: PartLocator, text: string, option?: Partial<EnterTextOption>): Promise<void> {\n await act(async () => {\n await super.enterText(locator, text, option);\n });\n }\n\n override async setRangeValue(locator: PartLocator, value: number): Promise<void> {\n await act(async () => {\n await super.setRangeValue(locator, value);\n });\n }\n\n override async click(locator: PartLocator, option?: Partial<ClickOption>): Promise<void> {\n await act(async () => {\n await super.click(locator, option);\n });\n }\n\n override async hover(locator: PartLocator, option?: Partial<HoverOption>): Promise<void> {\n await act(async () => {\n await super.hover(locator, option);\n });\n }\n\n override async mouseMove(locator: PartLocator, option?: Partial<MouseMoveOption>): Promise<void> {\n await act(async () => {\n await super.mouseMove(locator, option);\n });\n }\n\n override async mouseDown(locator: PartLocator, option?: Partial<MouseDownOption>): Promise<void> {\n await act(async () => {\n await super.mouseDown(locator, option);\n });\n }\n\n override async mouseUp(locator: PartLocator, option?: Partial<MouseUpOption>): Promise<void> {\n await act(async () => {\n await super.mouseUp(locator, option);\n });\n }\n\n override async mouseOver(locator: PartLocator, option?: Partial<HoverOption>): Promise<void> {\n await act(async () => {\n await super.mouseOver(locator, option);\n });\n }\n\n override async mouseOut(locator: PartLocator, option?: Partial<MouseOutOption>): Promise<void> {\n await act(async () => {\n await super.mouseOut(locator, option);\n });\n }\n\n override async mouseEnter(locator: PartLocator, option?: Partial<MouseEnterOption>): Promise<void> {\n await act(async () => {\n await super.mouseEnter(locator, option);\n });\n }\n\n override async mouseLeave(locator: PartLocator, option?: Partial<MouseLeaveOption>): Promise<void> {\n await act(async () => {\n await super.mouseLeave(locator, option);\n });\n }\n\n override async focus(locator: PartLocator, option?: Partial<FocusOption>): Promise<void> {\n await act(async () => {\n await super.focus(locator, option);\n });\n }\n\n override async blur(locator: PartLocator, option?: Partial<BlurOption>): Promise<void> {\n await act(async () => {\n await super.blur(locator, option);\n });\n }\n\n override async pressKey(locator: PartLocator, key: string, option?: Partial<PressKeyOption>): Promise<void> {\n await act(async () => {\n await super.pressKey(locator, key, option);\n });\n }\n\n override async contextMenu(locator: PartLocator): Promise<void> {\n await act(async () => {\n await super.contextMenu(locator);\n });\n }\n\n override async activate(locator: PartLocator): Promise<void> {\n await act(async () => {\n await super.activate(locator);\n });\n }\n\n override async selectOptionValue(locator: PartLocator, values: string[]): Promise<void> {\n await act(async () => {\n await super.selectOptionValue(locator, values);\n });\n }\n\n override async setInputFiles(locator: PartLocator, files: string | string[]): Promise<void> {\n await act(async () => {\n await super.setInputFiles(locator, files);\n });\n }\n\n override async scrollIntoView(locator: PartLocator): Promise<void> {\n await act(async () => {\n await super.scrollIntoView(locator);\n });\n }\n\n override async scrollBy(locator: PartLocator, delta: Point): Promise<void> {\n await act(async () => {\n await super.scrollBy(locator, delta);\n });\n }\n\n override async dragTo(source: PartLocator, target: PartLocator): Promise<void> {\n await act(async () => {\n await super.dragTo(source, target);\n });\n }\n\n override async drag(locator: PartLocator, delta: Point): Promise<void> {\n await act(async () => {\n await super.drag(locator, delta);\n });\n }\n\n //#region wait condition\n override async wait(ms: number): Promise<void> {\n await act(async () => {\n await super.wait(ms);\n });\n }\n\n override async waitUntilComponentState(\n locator: PartLocator,\n option: Partial<Readonly<WaitForOption>> = defaultWaitForOption\n ): Promise<void> {\n await act(async () => {\n await super.waitUntilComponentState(locator, option);\n });\n }\n\n override async waitUntil<T>(option: WaitUntilOption<T>): Promise<T> {\n // The React ≤17 `act` async overload resolves to `undefined`, not the\n // callback's value (unlike React 18's act), so capture the result via a\n // closure instead of returning it through `act`.\n let result!: T;\n await act(async () => {\n result = await super.waitUntil(option);\n });\n return result;\n }\n //#endregion\n\n override clone(): Interactor {\n return new LegacyReactInteractor(this.rootEl);\n }\n}\n","import { byAttribute, ScenePart, TestEngine } from '@atomic-testing/core';\nimport { ReactElement } from 'react';\nimport ReactDOM from 'react-dom';\nimport { act } from 'react-dom/test-utils';\n\nimport { LegacyReactInteractor } from './LegacyReactInteractor';\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: ReactElement,\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 LegacyReactInteractor(),\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 LegacyReactInteractor(),\n {\n parts: partDefinitions,\n },\n cleanup\n );\n\n return engine;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["DOMInteractor","defaultWaitForOption","TestEngine"],"sources":["../src/LegacyReactInteractor.ts","../src/createTestEngine.ts"],"sourcesContent":["import {\n BlurOption,\n ClickOption,\n defaultWaitForOption,\n EnterTextOption,\n FocusOption,\n HoverOption,\n MouseDownOption,\n MouseEnterOption,\n MouseLeaveOption,\n MouseMoveOption,\n MouseOutOption,\n MouseUpOption,\n PartLocator,\n Point,\n PressKeyOption,\n WaitForOption,\n WaitUntilOption,\n} from '@atomic-testing/core';\nimport { DOMInteractor } from '@atomic-testing/dom-core';\nimport { act } from 'react-dom/test-utils';\n\n/**\n * React 16/17 counterpart of `@atomic-testing/react-core`'s `ReactInteractor`.\n *\n * It is a deliberate parallel implementation rather than a subclass of the\n * react-core interactor: react-core wraps actions with `act` from\n * `@testing-library/react@16`, whose peer range is React 18/19. Reusing it would\n * drag that dependency into react-legacy and make the package impossible to\n * install on React 16/17 (the very versions this adapter exists to support). By\n * extending `DOMInteractor` directly and wrapping with `act` from\n * `react-dom/test-utils` (the React ≤17 act), react-legacy stays on a coherent\n * React-16/17 dependency graph.\n */\nexport class LegacyReactInteractor extends DOMInteractor {\n override async enterText(locator: PartLocator, text: string, option?: Partial<EnterTextOption>): Promise<void> {\n await act(async () => {\n await super.enterText(locator, text, option);\n });\n }\n\n override async setRangeValue(locator: PartLocator, value: number): Promise<void> {\n await act(async () => {\n await super.setRangeValue(locator, value);\n });\n }\n\n override async click(locator: PartLocator, option?: Partial<ClickOption>): Promise<void> {\n await act(async () => {\n await super.click(locator, option);\n });\n }\n\n override async hover(locator: PartLocator, option?: Partial<HoverOption>): Promise<void> {\n await act(async () => {\n await super.hover(locator, option);\n });\n }\n\n override async mouseMove(locator: PartLocator, option?: Partial<MouseMoveOption>): Promise<void> {\n await act(async () => {\n await super.mouseMove(locator, option);\n });\n }\n\n override async mouseDown(locator: PartLocator, option?: Partial<MouseDownOption>): Promise<void> {\n await act(async () => {\n await super.mouseDown(locator, option);\n });\n }\n\n override async mouseUp(locator: PartLocator, option?: Partial<MouseUpOption>): Promise<void> {\n await act(async () => {\n await super.mouseUp(locator, option);\n });\n }\n\n override async mouseOver(locator: PartLocator, option?: Partial<HoverOption>): Promise<void> {\n await act(async () => {\n await super.mouseOver(locator, option);\n });\n }\n\n override async mouseOut(locator: PartLocator, option?: Partial<MouseOutOption>): Promise<void> {\n await act(async () => {\n await super.mouseOut(locator, option);\n });\n }\n\n override async mouseEnter(locator: PartLocator, option?: Partial<MouseEnterOption>): Promise<void> {\n await act(async () => {\n await super.mouseEnter(locator, option);\n });\n }\n\n override async mouseLeave(locator: PartLocator, option?: Partial<MouseLeaveOption>): Promise<void> {\n await act(async () => {\n await super.mouseLeave(locator, option);\n });\n }\n\n override async focus(locator: PartLocator, option?: Partial<FocusOption>): Promise<void> {\n await act(async () => {\n await super.focus(locator, option);\n });\n }\n\n override async blur(locator: PartLocator, option?: Partial<BlurOption>): Promise<void> {\n await act(async () => {\n await super.blur(locator, option);\n });\n }\n\n override async pressKey(locator: PartLocator, key: string, option?: Partial<PressKeyOption>): Promise<void> {\n await act(async () => {\n await super.pressKey(locator, key, option);\n });\n }\n\n override async contextMenu(locator: PartLocator): Promise<void> {\n await act(async () => {\n await super.contextMenu(locator);\n });\n }\n\n override async activate(locator: PartLocator): Promise<void> {\n await act(async () => {\n await super.activate(locator);\n });\n }\n\n override async selectOptionValue(locator: PartLocator, values: string[]): Promise<void> {\n await act(async () => {\n await super.selectOptionValue(locator, values);\n });\n }\n\n override async setInputFiles(locator: PartLocator, files: string | string[]): Promise<void> {\n await act(async () => {\n await super.setInputFiles(locator, files);\n });\n }\n\n override async scrollIntoView(locator: PartLocator): Promise<void> {\n await act(async () => {\n await super.scrollIntoView(locator);\n });\n }\n\n override async scrollBy(locator: PartLocator, delta: Point): Promise<void> {\n await act(async () => {\n await super.scrollBy(locator, delta);\n });\n }\n\n override async dragTo(source: PartLocator, target: PartLocator): Promise<void> {\n await act(async () => {\n await super.dragTo(source, target);\n });\n }\n\n override async drag(locator: PartLocator, delta: Point): Promise<void> {\n await act(async () => {\n await super.drag(locator, delta);\n });\n }\n\n //#region wait condition\n override async waitUntilComponentState(\n locator: PartLocator,\n option: Partial<Readonly<WaitForOption>> = defaultWaitForOption\n ): Promise<void> {\n await act(async () => {\n await super.waitUntilComponentState(locator, option);\n });\n }\n\n override async waitUntil<T>(option: WaitUntilOption<T>): Promise<T> {\n // The React ≤17 `act` async overload resolves to `undefined`, not the\n // callback's value (unlike React 18's act), so capture the result via a\n // closure instead of returning it through `act`.\n let result!: T;\n await act(async () => {\n result = await super.waitUntil(option);\n });\n return result;\n }\n //#endregion\n}\n","import { byAttribute, ScenePart, TestEngine } from '@atomic-testing/core';\nimport { ReactElement } from 'react';\nimport ReactDOM from 'react-dom';\nimport { act } from 'react-dom/test-utils';\n\nimport { LegacyReactInteractor } from './LegacyReactInteractor';\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: ReactElement,\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 LegacyReactInteractor(),\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 LegacyReactInteractor(),\n {\n parts: partDefinitions,\n },\n cleanup\n );\n\n return engine;\n}\n"],"mappings":"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"}
package/dist/index.d.cts CHANGED
@@ -1,10 +1,11 @@
1
- import { IComponentDriverOption, ScenePart, TestEngine } from "@atomic-testing/core";
1
+ import { ITestEngineOption, ScenePart, TestEngine } from "@atomic-testing/core";
2
2
  import { ReactElement } from "react";
3
3
 
4
4
  //#region src/types.d.ts
5
- interface IReactTestEngineOption extends IComponentDriverOption {
6
- rootElement?: Element;
7
- }
5
+ /**
6
+ * @deprecated Use {@link ITestEngineOption} from `@atomic-testing/core`.
7
+ */
8
+ type IReactTestEngineOption = ITestEngineOption;
8
9
  //#endregion
9
10
  //#region src/createTestEngine.d.ts
10
11
  /**
package/dist/index.d.mts CHANGED
@@ -1,10 +1,11 @@
1
- import { IComponentDriverOption, ScenePart, TestEngine } from "@atomic-testing/core";
1
+ import { ITestEngineOption, ScenePart, TestEngine } from "@atomic-testing/core";
2
2
  import { ReactElement } from "react";
3
3
 
4
4
  //#region src/types.d.ts
5
- interface IReactTestEngineOption extends IComponentDriverOption {
6
- rootElement?: Element;
7
- }
5
+ /**
6
+ * @deprecated Use {@link ITestEngineOption} from `@atomic-testing/core`.
7
+ */
8
+ type IReactTestEngineOption = ITestEngineOption;
8
9
  //#endregion
9
10
  //#region src/createTestEngine.d.ts
10
11
  /**
package/dist/index.mjs CHANGED
@@ -15,7 +15,7 @@ import { DOMInteractor } from "@atomic-testing/dom-core";
15
15
  * `react-dom/test-utils` (the React ≤17 act), react-legacy stays on a coherent
16
16
  * React-16/17 dependency graph.
17
17
  */
18
- var LegacyReactInteractor = class LegacyReactInteractor extends DOMInteractor {
18
+ var LegacyReactInteractor = class extends DOMInteractor {
19
19
  async enterText(locator, text, option) {
20
20
  await act(async () => {
21
21
  await super.enterText(locator, text, option);
@@ -126,11 +126,6 @@ var LegacyReactInteractor = class LegacyReactInteractor extends DOMInteractor {
126
126
  await super.drag(locator, delta);
127
127
  });
128
128
  }
129
- async wait(ms) {
130
- await act(async () => {
131
- await super.wait(ms);
132
- });
133
- }
134
129
  async waitUntilComponentState(locator, option = defaultWaitForOption) {
135
130
  await act(async () => {
136
131
  await super.waitUntilComponentState(locator, option);
@@ -143,9 +138,6 @@ var LegacyReactInteractor = class LegacyReactInteractor extends DOMInteractor {
143
138
  });
144
139
  return result;
145
140
  }
146
- clone() {
147
- return new LegacyReactInteractor(this.rootEl);
148
- }
149
141
  };
150
142
  //#endregion
151
143
  //#region src/createTestEngine.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/LegacyReactInteractor.ts","../src/createTestEngine.ts"],"sourcesContent":["import {\n BlurOption,\n ClickOption,\n defaultWaitForOption,\n EnterTextOption,\n FocusOption,\n HoverOption,\n Interactor,\n MouseDownOption,\n MouseEnterOption,\n MouseLeaveOption,\n MouseMoveOption,\n MouseOutOption,\n MouseUpOption,\n PartLocator,\n Point,\n PressKeyOption,\n WaitForOption,\n WaitUntilOption,\n} from '@atomic-testing/core';\nimport { DOMInteractor } from '@atomic-testing/dom-core';\nimport { act } from 'react-dom/test-utils';\n\n/**\n * React 16/17 counterpart of `@atomic-testing/react-core`'s `ReactInteractor`.\n *\n * It is a deliberate parallel implementation rather than a subclass of the\n * react-core interactor: react-core wraps actions with `act` from\n * `@testing-library/react@16`, whose peer range is React 18/19. Reusing it would\n * drag that dependency into react-legacy and make the package impossible to\n * install on React 16/17 (the very versions this adapter exists to support). By\n * extending `DOMInteractor` directly and wrapping with `act` from\n * `react-dom/test-utils` (the React ≤17 act), react-legacy stays on a coherent\n * React-16/17 dependency graph.\n */\nexport class LegacyReactInteractor extends DOMInteractor {\n override async enterText(locator: PartLocator, text: string, option?: Partial<EnterTextOption>): Promise<void> {\n await act(async () => {\n await super.enterText(locator, text, option);\n });\n }\n\n override async setRangeValue(locator: PartLocator, value: number): Promise<void> {\n await act(async () => {\n await super.setRangeValue(locator, value);\n });\n }\n\n override async click(locator: PartLocator, option?: Partial<ClickOption>): Promise<void> {\n await act(async () => {\n await super.click(locator, option);\n });\n }\n\n override async hover(locator: PartLocator, option?: Partial<HoverOption>): Promise<void> {\n await act(async () => {\n await super.hover(locator, option);\n });\n }\n\n override async mouseMove(locator: PartLocator, option?: Partial<MouseMoveOption>): Promise<void> {\n await act(async () => {\n await super.mouseMove(locator, option);\n });\n }\n\n override async mouseDown(locator: PartLocator, option?: Partial<MouseDownOption>): Promise<void> {\n await act(async () => {\n await super.mouseDown(locator, option);\n });\n }\n\n override async mouseUp(locator: PartLocator, option?: Partial<MouseUpOption>): Promise<void> {\n await act(async () => {\n await super.mouseUp(locator, option);\n });\n }\n\n override async mouseOver(locator: PartLocator, option?: Partial<HoverOption>): Promise<void> {\n await act(async () => {\n await super.mouseOver(locator, option);\n });\n }\n\n override async mouseOut(locator: PartLocator, option?: Partial<MouseOutOption>): Promise<void> {\n await act(async () => {\n await super.mouseOut(locator, option);\n });\n }\n\n override async mouseEnter(locator: PartLocator, option?: Partial<MouseEnterOption>): Promise<void> {\n await act(async () => {\n await super.mouseEnter(locator, option);\n });\n }\n\n override async mouseLeave(locator: PartLocator, option?: Partial<MouseLeaveOption>): Promise<void> {\n await act(async () => {\n await super.mouseLeave(locator, option);\n });\n }\n\n override async focus(locator: PartLocator, option?: Partial<FocusOption>): Promise<void> {\n await act(async () => {\n await super.focus(locator, option);\n });\n }\n\n override async blur(locator: PartLocator, option?: Partial<BlurOption>): Promise<void> {\n await act(async () => {\n await super.blur(locator, option);\n });\n }\n\n override async pressKey(locator: PartLocator, key: string, option?: Partial<PressKeyOption>): Promise<void> {\n await act(async () => {\n await super.pressKey(locator, key, option);\n });\n }\n\n override async contextMenu(locator: PartLocator): Promise<void> {\n await act(async () => {\n await super.contextMenu(locator);\n });\n }\n\n override async activate(locator: PartLocator): Promise<void> {\n await act(async () => {\n await super.activate(locator);\n });\n }\n\n override async selectOptionValue(locator: PartLocator, values: string[]): Promise<void> {\n await act(async () => {\n await super.selectOptionValue(locator, values);\n });\n }\n\n override async setInputFiles(locator: PartLocator, files: string | string[]): Promise<void> {\n await act(async () => {\n await super.setInputFiles(locator, files);\n });\n }\n\n override async scrollIntoView(locator: PartLocator): Promise<void> {\n await act(async () => {\n await super.scrollIntoView(locator);\n });\n }\n\n override async scrollBy(locator: PartLocator, delta: Point): Promise<void> {\n await act(async () => {\n await super.scrollBy(locator, delta);\n });\n }\n\n override async dragTo(source: PartLocator, target: PartLocator): Promise<void> {\n await act(async () => {\n await super.dragTo(source, target);\n });\n }\n\n override async drag(locator: PartLocator, delta: Point): Promise<void> {\n await act(async () => {\n await super.drag(locator, delta);\n });\n }\n\n //#region wait condition\n override async wait(ms: number): Promise<void> {\n await act(async () => {\n await super.wait(ms);\n });\n }\n\n override async waitUntilComponentState(\n locator: PartLocator,\n option: Partial<Readonly<WaitForOption>> = defaultWaitForOption\n ): Promise<void> {\n await act(async () => {\n await super.waitUntilComponentState(locator, option);\n });\n }\n\n override async waitUntil<T>(option: WaitUntilOption<T>): Promise<T> {\n // The React ≤17 `act` async overload resolves to `undefined`, not the\n // callback's value (unlike React 18's act), so capture the result via a\n // closure instead of returning it through `act`.\n let result!: T;\n await act(async () => {\n result = await super.waitUntil(option);\n });\n return result;\n }\n //#endregion\n\n override clone(): Interactor {\n return new LegacyReactInteractor(this.rootEl);\n }\n}\n","import { byAttribute, ScenePart, TestEngine } from '@atomic-testing/core';\nimport { ReactElement } from 'react';\nimport ReactDOM from 'react-dom';\nimport { act } from 'react-dom/test-utils';\n\nimport { LegacyReactInteractor } from './LegacyReactInteractor';\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: ReactElement,\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 LegacyReactInteractor(),\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 LegacyReactInteractor(),\n {\n parts: partDefinitions,\n },\n cleanup\n );\n\n return engine;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAmCA,IAAa,wBAAb,MAAa,8BAA8B,cAAc;CACvD,MAAe,UAAU,SAAsB,MAAc,QAAkD;EAC7G,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,UAAU,SAAS,MAAM,MAAM;EAC7C,CAAC;CACH;CAEA,MAAe,cAAc,SAAsB,OAA8B;EAC/E,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,cAAc,SAAS,KAAK;EAC1C,CAAC;CACH;CAEA,MAAe,MAAM,SAAsB,QAA8C;EACvF,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,MAAM,SAAS,MAAM;EACnC,CAAC;CACH;CAEA,MAAe,MAAM,SAAsB,QAA8C;EACvF,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,MAAM,SAAS,MAAM;EACnC,CAAC;CACH;CAEA,MAAe,UAAU,SAAsB,QAAkD;EAC/F,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,UAAU,SAAS,MAAM;EACvC,CAAC;CACH;CAEA,MAAe,UAAU,SAAsB,QAAkD;EAC/F,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,UAAU,SAAS,MAAM;EACvC,CAAC;CACH;CAEA,MAAe,QAAQ,SAAsB,QAAgD;EAC3F,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,QAAQ,SAAS,MAAM;EACrC,CAAC;CACH;CAEA,MAAe,UAAU,SAAsB,QAA8C;EAC3F,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,UAAU,SAAS,MAAM;EACvC,CAAC;CACH;CAEA,MAAe,SAAS,SAAsB,QAAiD;EAC7F,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,SAAS,SAAS,MAAM;EACtC,CAAC;CACH;CAEA,MAAe,WAAW,SAAsB,QAAmD;EACjG,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,WAAW,SAAS,MAAM;EACxC,CAAC;CACH;CAEA,MAAe,WAAW,SAAsB,QAAmD;EACjG,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,WAAW,SAAS,MAAM;EACxC,CAAC;CACH;CAEA,MAAe,MAAM,SAAsB,QAA8C;EACvF,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,MAAM,SAAS,MAAM;EACnC,CAAC;CACH;CAEA,MAAe,KAAK,SAAsB,QAA6C;EACrF,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,KAAK,SAAS,MAAM;EAClC,CAAC;CACH;CAEA,MAAe,SAAS,SAAsB,KAAa,QAAiD;EAC1G,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,SAAS,SAAS,KAAK,MAAM;EAC3C,CAAC;CACH;CAEA,MAAe,YAAY,SAAqC;EAC9D,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,YAAY,OAAO;EACjC,CAAC;CACH;CAEA,MAAe,SAAS,SAAqC;EAC3D,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,SAAS,OAAO;EAC9B,CAAC;CACH;CAEA,MAAe,kBAAkB,SAAsB,QAAiC;EACtF,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,kBAAkB,SAAS,MAAM;EAC/C,CAAC;CACH;CAEA,MAAe,cAAc,SAAsB,OAAyC;EAC1F,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,cAAc,SAAS,KAAK;EAC1C,CAAC;CACH;CAEA,MAAe,eAAe,SAAqC;EACjE,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,eAAe,OAAO;EACpC,CAAC;CACH;CAEA,MAAe,SAAS,SAAsB,OAA6B;EACzE,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,SAAS,SAAS,KAAK;EACrC,CAAC;CACH;CAEA,MAAe,OAAO,QAAqB,QAAoC;EAC7E,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,OAAO,QAAQ,MAAM;EACnC,CAAC;CACH;CAEA,MAAe,KAAK,SAAsB,OAA6B;EACrE,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,KAAK,SAAS,KAAK;EACjC,CAAC;CACH;CAGA,MAAe,KAAK,IAA2B;EAC7C,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,KAAK,EAAE;EACrB,CAAC;CACH;CAEA,MAAe,wBACb,SACA,SAA2C,sBAC5B;EACf,MAAM,IAAI,YAAY;GACpB,MAAM,MAAM,wBAAwB,SAAS,MAAM;EACrD,CAAC;CACH;CAEA,MAAe,UAAa,QAAwC;EAIlE,IAAI;EACJ,MAAM,IAAI,YAAY;GACpB,SAAS,MAAM,MAAM,UAAU,MAAM;EACvC,CAAC;EACD,OAAO;CACT;CAGA,QAA6B;EAC3B,OAAO,IAAI,sBAAsB,KAAK,MAAM;CAC9C;AACF;;;AC/LA,IAAI,UAAU;AACd,SAAS,uBAAuB;CAC9B,OAAO,GAAG;AACZ;AAEA,MAAM,2BAA2B;;;;;;;;;;AAWjC,SAAgB,iBACd,MACA,iBACA,QACe;CACf,MAAM,SAAS,QAAQ,eAAe,SAAS;CAC/C,MAAM,YAAY,OAAO,YAAY,SAAS,cAAc,KAAK,CAAC;CAClE,MAAM,SAAS,qBAAqB;CACpC,UAAU,aAAa,0BAA0B,MAAM;CAEvD,UAAU;EACR,SAAS,OAAO,MAAM,SAAS;CACjC,CAAC;CACD,MAAM,gBAAgB;EACpB,SAAS,uBAAuB,SAAS;EACzC,OAAO,YAAY,SAAS;EAC5B,OAAO,QAAQ,QAAQ;CACzB;CAWA,OAAO,IATY,WACjB,YAAY,0BAA0B,MAAM,GAC5C,IAAI,sBAAsB,GAC1B,EACE,OAAO,gBACT,GACA,OAGU;AACd;;;;;;;;;;AAWA,SAAgB,yBACd,aACA,iBACA,SACe;CACf,MAAM,SAAS,qBAAqB;CACpC,YAAY,aAAa,0BAA0B,MAAM;CAEzD,MAAM,gBAAgB;EACpB,YAAY,gBAAgB,wBAAwB;EACpD,OAAO,QAAQ,QAAQ;CACzB;CAWA,OAAO,IATY,WACjB,YAAY,0BAA0B,MAAM,GAC5C,IAAI,sBAAsB,GAC1B,EACE,OAAO,gBACT,GACA,OAGU;AACd"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/LegacyReactInteractor.ts","../src/createTestEngine.ts"],"sourcesContent":["import {\n BlurOption,\n ClickOption,\n defaultWaitForOption,\n EnterTextOption,\n FocusOption,\n HoverOption,\n MouseDownOption,\n MouseEnterOption,\n MouseLeaveOption,\n MouseMoveOption,\n MouseOutOption,\n MouseUpOption,\n PartLocator,\n Point,\n PressKeyOption,\n WaitForOption,\n WaitUntilOption,\n} from '@atomic-testing/core';\nimport { DOMInteractor } from '@atomic-testing/dom-core';\nimport { act } from 'react-dom/test-utils';\n\n/**\n * React 16/17 counterpart of `@atomic-testing/react-core`'s `ReactInteractor`.\n *\n * It is a deliberate parallel implementation rather than a subclass of the\n * react-core interactor: react-core wraps actions with `act` from\n * `@testing-library/react@16`, whose peer range is React 18/19. Reusing it would\n * drag that dependency into react-legacy and make the package impossible to\n * install on React 16/17 (the very versions this adapter exists to support). By\n * extending `DOMInteractor` directly and wrapping with `act` from\n * `react-dom/test-utils` (the React ≤17 act), react-legacy stays on a coherent\n * React-16/17 dependency graph.\n */\nexport class LegacyReactInteractor extends DOMInteractor {\n override async enterText(locator: PartLocator, text: string, option?: Partial<EnterTextOption>): Promise<void> {\n await act(async () => {\n await super.enterText(locator, text, option);\n });\n }\n\n override async setRangeValue(locator: PartLocator, value: number): Promise<void> {\n await act(async () => {\n await super.setRangeValue(locator, value);\n });\n }\n\n override async click(locator: PartLocator, option?: Partial<ClickOption>): Promise<void> {\n await act(async () => {\n await super.click(locator, option);\n });\n }\n\n override async hover(locator: PartLocator, option?: Partial<HoverOption>): Promise<void> {\n await act(async () => {\n await super.hover(locator, option);\n });\n }\n\n override async mouseMove(locator: PartLocator, option?: Partial<MouseMoveOption>): Promise<void> {\n await act(async () => {\n await super.mouseMove(locator, option);\n });\n }\n\n override async mouseDown(locator: PartLocator, option?: Partial<MouseDownOption>): Promise<void> {\n await act(async () => {\n await super.mouseDown(locator, option);\n });\n }\n\n override async mouseUp(locator: PartLocator, option?: Partial<MouseUpOption>): Promise<void> {\n await act(async () => {\n await super.mouseUp(locator, option);\n });\n }\n\n override async mouseOver(locator: PartLocator, option?: Partial<HoverOption>): Promise<void> {\n await act(async () => {\n await super.mouseOver(locator, option);\n });\n }\n\n override async mouseOut(locator: PartLocator, option?: Partial<MouseOutOption>): Promise<void> {\n await act(async () => {\n await super.mouseOut(locator, option);\n });\n }\n\n override async mouseEnter(locator: PartLocator, option?: Partial<MouseEnterOption>): Promise<void> {\n await act(async () => {\n await super.mouseEnter(locator, option);\n });\n }\n\n override async mouseLeave(locator: PartLocator, option?: Partial<MouseLeaveOption>): Promise<void> {\n await act(async () => {\n await super.mouseLeave(locator, option);\n });\n }\n\n override async focus(locator: PartLocator, option?: Partial<FocusOption>): Promise<void> {\n await act(async () => {\n await super.focus(locator, option);\n });\n }\n\n override async blur(locator: PartLocator, option?: Partial<BlurOption>): Promise<void> {\n await act(async () => {\n await super.blur(locator, option);\n });\n }\n\n override async pressKey(locator: PartLocator, key: string, option?: Partial<PressKeyOption>): Promise<void> {\n await act(async () => {\n await super.pressKey(locator, key, option);\n });\n }\n\n override async contextMenu(locator: PartLocator): Promise<void> {\n await act(async () => {\n await super.contextMenu(locator);\n });\n }\n\n override async activate(locator: PartLocator): Promise<void> {\n await act(async () => {\n await super.activate(locator);\n });\n }\n\n override async selectOptionValue(locator: PartLocator, values: string[]): Promise<void> {\n await act(async () => {\n await super.selectOptionValue(locator, values);\n });\n }\n\n override async setInputFiles(locator: PartLocator, files: string | string[]): Promise<void> {\n await act(async () => {\n await super.setInputFiles(locator, files);\n });\n }\n\n override async scrollIntoView(locator: PartLocator): Promise<void> {\n await act(async () => {\n await super.scrollIntoView(locator);\n });\n }\n\n override async scrollBy(locator: PartLocator, delta: Point): Promise<void> {\n await act(async () => {\n await super.scrollBy(locator, delta);\n });\n }\n\n override async dragTo(source: PartLocator, target: PartLocator): Promise<void> {\n await act(async () => {\n await super.dragTo(source, target);\n });\n }\n\n override async drag(locator: PartLocator, delta: Point): Promise<void> {\n await act(async () => {\n await super.drag(locator, delta);\n });\n }\n\n //#region wait condition\n override async waitUntilComponentState(\n locator: PartLocator,\n option: Partial<Readonly<WaitForOption>> = defaultWaitForOption\n ): Promise<void> {\n await act(async () => {\n await super.waitUntilComponentState(locator, option);\n });\n }\n\n override async waitUntil<T>(option: WaitUntilOption<T>): Promise<T> {\n // The React ≤17 `act` async overload resolves to `undefined`, not the\n // callback's value (unlike React 18's act), so capture the result via a\n // closure instead of returning it through `act`.\n let result!: T;\n await act(async () => {\n result = await super.waitUntil(option);\n });\n return result;\n }\n //#endregion\n}\n","import { byAttribute, ScenePart, TestEngine } from '@atomic-testing/core';\nimport { ReactElement } from 'react';\nimport ReactDOM from 'react-dom';\nimport { act } from 'react-dom/test-utils';\n\nimport { LegacyReactInteractor } from './LegacyReactInteractor';\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: ReactElement,\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 LegacyReactInteractor(),\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 LegacyReactInteractor(),\n {\n parts: partDefinitions,\n },\n cleanup\n );\n\n return engine;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atomic-testing/react-legacy",
3
- "version": "0.89.0",
3
+ "version": "0.90.0",
4
4
  "description": "Adapter for testing React 17 and earlier",
5
5
  "keywords": [
6
6
  "legacy",
@@ -29,15 +29,15 @@
29
29
  }
30
30
  },
31
31
  "dependencies": {
32
- "@atomic-testing/core": "0.89.0",
33
- "@atomic-testing/dom-core": "0.89.0"
32
+ "@atomic-testing/core": "0.90.0",
33
+ "@atomic-testing/dom-core": "0.90.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@types/react": "^17.0.0",
37
37
  "@types/react-dom": "^17.0.0",
38
38
  "react": "^17.0.0",
39
39
  "react-dom": "^17.0.0",
40
- "@atomic-testing/component-driver-html": "0.89.0"
40
+ "@atomic-testing/component-driver-html": "0.90.0"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "@testing-library/dom": ">=10.4.1",
@@ -5,7 +5,6 @@ import {
5
5
  EnterTextOption,
6
6
  FocusOption,
7
7
  HoverOption,
8
- Interactor,
9
8
  MouseDownOption,
10
9
  MouseEnterOption,
11
10
  MouseLeaveOption,
@@ -167,12 +166,6 @@ export class LegacyReactInteractor extends DOMInteractor {
167
166
  }
168
167
 
169
168
  //#region wait condition
170
- override async wait(ms: number): Promise<void> {
171
- await act(async () => {
172
- await super.wait(ms);
173
- });
174
- }
175
-
176
169
  override async waitUntilComponentState(
177
170
  locator: PartLocator,
178
171
  option: Partial<Readonly<WaitForOption>> = defaultWaitForOption
@@ -193,8 +186,4 @@ export class LegacyReactInteractor extends DOMInteractor {
193
186
  return result;
194
187
  }
195
188
  //#endregion
196
-
197
- override clone(): Interactor {
198
- return new LegacyReactInteractor(this.rootEl);
199
- }
200
189
  }
package/src/types.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { IComponentDriverOption } from '@atomic-testing/core';
1
+ import { ITestEngineOption } from '@atomic-testing/core';
2
2
 
3
- export interface IReactTestEngineOption extends IComponentDriverOption {
4
- rootElement?: Element;
5
- }
3
+ /**
4
+ * @deprecated Use {@link ITestEngineOption} from `@atomic-testing/core`.
5
+ */
6
+ export type IReactTestEngineOption = ITestEngineOption;