@nyby/detox-component-testing 1.4.0 → 1.5.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/README.md CHANGED
@@ -31,10 +31,18 @@ npm install @nyby/detox-component-testing react-native-launch-arguments
31
31
  Create `app.component-test.js` alongside your app entry:
32
32
 
33
33
  ```js
34
- import { AppRegistry } from 'react-native';
35
- import { ComponentHarness } from '@nyby/detox-component-testing';
34
+ import React from 'react';
35
+ import {AppRegistry, View} from 'react-native';
36
+ import {ComponentHarness, configureHarness} from '@nyby/detox-component-testing';
36
37
  import './component-tests/registry';
37
38
 
39
+ configureHarness({
40
+ wrapper: ({children}) => (
41
+ <View style={{flex: 1}}>{children}</View>
42
+ ),
43
+ debugTree: true,
44
+ });
45
+
38
46
  AppRegistry.registerComponent('example', () => ComponentHarness);
39
47
  ```
40
48
 
@@ -43,16 +51,16 @@ AppRegistry.registerComponent('example', () => ComponentHarness);
43
51
  Create `component-tests/registry.ts` to register components for testing:
44
52
 
45
53
  ```ts
46
- import { registerComponent } from '@nyby/detox-component-testing';
47
- import { Stepper } from '../src/components/Stepper';
48
- import { LoginForm } from '../src/components/LoginForm';
54
+ import {registerComponent} from '@nyby/detox-component-testing';
55
+ import {Stepper} from '../src/components/Stepper';
56
+ import {LoginForm} from '../src/components/LoginForm';
49
57
 
50
58
  // Auto-infer name from Component.name
51
- registerComponent(Stepper, { initial: 0 });
59
+ registerComponent(Stepper, {initial: 0});
52
60
  registerComponent(LoginForm);
53
61
 
54
62
  // Or use an explicit name
55
- registerComponent('MyComponent', MyComponent, { someProp: 'default' });
63
+ registerComponent('MyComponent', MyComponent, {someProp: 'default'});
56
64
  ```
57
65
 
58
66
  ### 4. Switch entry point for component tests
@@ -61,7 +69,7 @@ Update your index file to load the component test entry when running component t
61
69
 
62
70
  ```js
63
71
  // index.js
64
- const { LaunchArguments } = require('react-native-launch-arguments');
72
+ const {LaunchArguments} = require('react-native-launch-arguments');
65
73
 
66
74
  if (LaunchArguments.value().detoxComponentName) {
67
75
  require('./app.component-test');
@@ -78,20 +86,30 @@ Add a component test configuration to `detox.config.js`:
78
86
 
79
87
  ```js
80
88
  module.exports = {
81
- // ... existing config
89
+ // ... existing app and device config
82
90
  configurations: {
83
91
  // ... existing configurations
84
- "android.emu.component.debug": {
85
- device: "emulator",
86
- app: "android.debug",
92
+ 'ios.sim.component': {
93
+ device: 'simulator',
94
+ app: 'ios',
87
95
  testRunner: {
88
96
  args: {
89
- config: "component-tests/jest.config.js",
90
- _: ["src/components"]
91
- }
92
- }
93
- }
94
- }
97
+ config: 'component-tests/jest.config.js',
98
+ _: ['src/components'],
99
+ },
100
+ },
101
+ },
102
+ 'android.emu.component': {
103
+ device: 'emulator',
104
+ app: 'android',
105
+ testRunner: {
106
+ args: {
107
+ config: 'component-tests/jest.config.js',
108
+ _: ['src/components'],
109
+ },
110
+ },
111
+ },
112
+ },
95
113
  };
96
114
  ```
97
115
 
@@ -102,19 +120,19 @@ Create `component-tests/jest.config.js`:
102
120
  ```js
103
121
  module.exports = {
104
122
  maxWorkers: 1,
105
- globalSetup: "detox/runners/jest/globalSetup",
106
- globalTeardown: "detox/runners/jest/globalTeardown",
107
- testEnvironment: "detox/runners/jest/testEnvironment",
108
- setupFilesAfterEnv: ["./setup.ts"],
109
- testRunner: "jest-circus/runner",
123
+ globalSetup: 'detox/runners/jest/globalSetup',
124
+ globalTeardown: 'detox/runners/jest/globalTeardown',
125
+ testEnvironment: '@nyby/detox-component-testing/environment',
126
+ setupFilesAfterEnv: ['./setup.ts'],
127
+ testRunner: 'jest-circus/runner',
110
128
  testTimeout: 120000,
111
- roots: ["<rootDir>/../src"],
112
- testMatch: ["**/*.component.test.ts"],
129
+ roots: ['<rootDir>/../src'],
130
+ testMatch: ['**/*.component.test.ts'],
113
131
  transform: {
114
- "\\.tsx?$": ["ts-jest", { tsconfig: "<rootDir>/../tsconfig.json" }]
132
+ '\\.tsx?$': ['ts-jest', {tsconfig: '<rootDir>/../tsconfig.json'}],
115
133
  },
116
- reporters: ["detox/runners/jest/reporter"],
117
- verbose: true
134
+ reporters: ['detox/runners/jest/reporter'],
135
+ verbose: true,
118
136
  };
119
137
  ```
120
138
 
@@ -123,8 +141,8 @@ module.exports = {
123
141
  ### Basic mounting
124
142
 
125
143
  ```ts
126
- import { by, element, expect } from 'detox';
127
- import { mount } from '@nyby/detox-component-testing/test';
144
+ import {by, element, expect} from 'detox';
145
+ import {mount} from '@nyby/detox-component-testing/test';
128
146
 
129
147
  describe('Stepper', () => {
130
148
  it('renders with default props', async () => {
@@ -133,7 +151,7 @@ describe('Stepper', () => {
133
151
  });
134
152
 
135
153
  it('renders with custom props', async () => {
136
- await mount('Stepper', { initial: 100 });
154
+ await mount('Stepper', {initial: 100});
137
155
  await expect(element(by.id('counter'))).toHaveText('100');
138
156
  });
139
157
  });
@@ -144,10 +162,10 @@ describe('Stepper', () => {
144
162
  Use `spy()` to create a recording function for callback props, and `expectSpy()` to assert on it:
145
163
 
146
164
  ```ts
147
- import { mount, spy, expectSpy } from '@nyby/detox-component-testing/test';
165
+ import {mount, spy, expectSpy} from '@nyby/detox-component-testing/test';
148
166
 
149
167
  it('fires onChange when incremented', async () => {
150
- await mount('Stepper', { initial: 0, onChange: spy('onChange') });
168
+ await mount('Stepper', {initial: 0, onChange: spy('onChange')});
151
169
  await element(by.id('increment')).tap();
152
170
 
153
171
  await expectSpy('onChange').toHaveBeenCalled();
@@ -172,6 +190,7 @@ Subsequent mounts: ~100ms (in-place swap)
172
190
  ### App-side (import from `@nyby/detox-component-testing`)
173
191
 
174
192
  #### `registerComponent(Component, defaultProps?)`
193
+
175
194
  #### `registerComponent(name, Component, defaultProps?)`
176
195
 
177
196
  Register a component for testing. When called with just a component, the name is inferred from `Component.name` or `Component.displayName`.
@@ -180,28 +199,31 @@ Register a component for testing. When called with just a component, the name is
180
199
 
181
200
  Root component for the test harness. Register as your app's root component in the component test entry point.
182
201
 
183
- #### `configureHarness({ wrapper })`
202
+ #### `configureHarness({ wrapper?, debugTree? })`
184
203
 
185
- Set a global wrapper component for all mounted components (e.g. Redux Provider, theme provider):
204
+ Set a global wrapper component and/or enable debug tree capture for all mounted components:
186
205
 
187
206
  ```js
188
- import { Provider } from 'react-redux';
189
- import { configureHarness } from '@nyby/detox-component-testing';
190
- import { createStore } from './store';
207
+ import {Provider} from 'react-redux';
208
+ import {configureHarness} from '@nyby/detox-component-testing';
209
+ import {createStore} from './store';
191
210
 
192
211
  configureHarness({
193
- wrapper: ({ children, launchArgs }) => {
212
+ wrapper: ({children, launchArgs}) => {
194
213
  const store = createStore();
195
214
  if (launchArgs.reduxState) {
196
215
  store.dispatch(loadState(JSON.parse(launchArgs.reduxState)));
197
216
  }
198
217
  return <Provider store={store}>{children}</Provider>;
199
218
  },
219
+ debugTree: true,
200
220
  });
201
221
  ```
202
222
 
203
223
  The wrapper receives `launchArgs` — the props passed to `mount()` — so you can configure per-test state.
204
224
 
225
+ The `debugTree` option enables component tree capture for `debug()` and the custom test environment. Pass `true` for defaults, or an object with `usefulProps`, `skipNames`, and/or `nativeDuplicates` to customize filtering (see [DebugTree](#debugtree) below).
226
+
205
227
  ### Test-side (import from `@nyby/detox-component-testing/test`)
206
228
 
207
229
  #### `mount(componentName, props?)`
@@ -220,6 +242,87 @@ Returns an assertion object for a spy:
220
242
  - `.toHaveBeenCalledTimes(n)` — spy was called exactly `n` times
221
243
  - `.lastCalledWith(...args)` — the last call's arguments match
222
244
 
245
+ #### `debug(label?, outputDir?)`
246
+
247
+ Capture a screenshot, React component tree, and native view hierarchy for the current screen state. Useful for debugging test failures or inspecting what's on screen at any point in a test.
248
+
249
+ ```ts
250
+ import {mount, debug} from '@nyby/detox-component-testing/test';
251
+
252
+ it('renders the event screen', async () => {
253
+ await mount('EventScreen', {eventId: 'event_1'});
254
+ await debug('after-mount'); // writes to artifacts/debug-after-mount.{png,json,xml}
255
+ });
256
+ ```
257
+
258
+ Each call writes up to three files to the output directory (defaults to `<cwd>/artifacts`):
259
+
260
+ - `debug-<label>.png` — screenshot
261
+ - `debug-<label>-tree.json` — React component tree (requires `DebugTree` wrapper)
262
+ - `debug-<label>-view.xml` — native view hierarchy
263
+
264
+ If no label is provided, calls are numbered automatically (`1`, `2`, `3`, ...).
265
+
266
+ ### Debugging
267
+
268
+ #### `DebugTree`
269
+
270
+ A component that captures the React fiber tree on demand. Enable it via `configureHarness({ debugTree: true })` to get component tree capture in `debug()` and the custom test environment.
271
+
272
+ ```js
273
+ import {configureHarness} from '@nyby/detox-component-testing';
274
+
275
+ configureHarness({
276
+ wrapper: ({children}) => (
277
+ <Provider store={store}>{children}</Provider>
278
+ ),
279
+ debugTree: true,
280
+ });
281
+ ```
282
+
283
+ You can also pass filtering options directly:
284
+
285
+ ```js
286
+ configureHarness({
287
+ debugTree: {
288
+ usefulProps: ['testID', 'accessibilityLabel', 'title'],
289
+ skipNames: ['MyInternalWrapper'],
290
+ },
291
+ });
292
+ ```
293
+
294
+ `DebugTree` walks the React fiber tree and produces a JSON snapshot of component names, key props (`testID`, `accessibilityLabel`, `variant`, `onPress`, etc.), and text content. The output filters noise — internal wrappers and native duplicates are excluded by default.
295
+
296
+ The `DebugTree` component is also exported for advanced use cases where you need direct control.
297
+
298
+ All filtering lists are configurable:
299
+
300
+ | Prop | Type | Description |
301
+ | ------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------- |
302
+ | `usefulProps` | `string[]` | Props to include in output. Defaults to `testID`, `accessibilityLabel`, `title`, `value`, `placeholder`, `disabled`, etc. |
303
+ | `skipNames` | `string[]` | Component names to skip. Defaults to internal wrappers like `StaticContainer`, `PressabilityDebugView`, etc. |
304
+ | `nativeDuplicates` | `string[]` | Native components that duplicate their parent. Defaults to `RCTText`, `RCTView`, etc. |
305
+
306
+ #### Custom test environment
307
+
308
+ A Detox Jest environment that automatically captures debug artifacts when a test fails. Use it instead of the default Detox environment:
309
+
310
+ ```js
311
+ // jest.config.js
312
+ module.exports = {
313
+ testEnvironment: '@nyby/detox-component-testing/environment',
314
+ // ...
315
+ };
316
+ ```
317
+
318
+ On test failure, it captures:
319
+
320
+ - A screenshot
321
+ - The React component tree (if `DebugTree` is in the wrapper)
322
+ - The native view hierarchy
323
+
324
+ All artifacts are written to `<cwd>/artifacts/`.
325
+
223
326
  ## Limitations
224
327
 
225
328
  - **No JSX in tests** — Tests run in Node.js, not the React Native runtime. You cannot import components or use JSX in test files. Reference components by their registered name string.
@@ -248,3 +351,5 @@ app.component-test.js # Component test entry (harness)
248
351
  index.js # Switches entry based on launch args
249
352
  detox.config.js # Detox config with component test configuration
250
353
  ```
354
+
355
+ See the [`example/`](./example) directory for a complete working setup.
@@ -1 +1 @@
1
- {"version":3,"file":"ComponentHarness.d.ts","sourceRoot":"","sources":["../src/ComponentHarness.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAgF,MAAM,OAAO,CAAC;AAsDrG,wBAAgB,gBAAgB,sBAwC/B"}
1
+ {"version":3,"file":"ComponentHarness.d.ts","sourceRoot":"","sources":["../src/ComponentHarness.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8E,MAAM,OAAO,CAAC;AAwDnG,wBAAgB,gBAAgB,sBAkD/B"}
@@ -39,6 +39,7 @@ const react_native_1 = require("react-native");
39
39
  const react_native_launch_arguments_1 = require("react-native-launch-arguments");
40
40
  const ComponentRegistry_1 = require("./ComponentRegistry");
41
41
  const configureHarness_1 = require("./configureHarness");
42
+ const DebugTree_1 = require("./DebugTree");
42
43
  class RenderErrorBoundary extends react_1.Component {
43
44
  constructor() {
44
45
  super(...arguments);
@@ -73,9 +74,9 @@ function parseLaunchArgs(args) {
73
74
  function ComponentHarness() {
74
75
  const launchArgs = react_native_launch_arguments_1.LaunchArguments.value();
75
76
  const [mountPayload, setMountPayload] = (0, react_1.useState)(null);
76
- const handleControl = (0, react_1.useCallback)((text) => {
77
+ const handleControl = (0, react_1.useCallback)((e) => {
77
78
  try {
78
- setMountPayload(JSON.parse(text));
79
+ setMountPayload(JSON.parse(e.nativeEvent.text));
79
80
  }
80
81
  catch (_e) { }
81
82
  }, []);
@@ -93,7 +94,15 @@ function ComponentHarness() {
93
94
  };
94
95
  }
95
96
  return (react_1.default.createElement(react_native_1.View, { style: { flex: 1 } },
96
- react_1.default.createElement(react_native_1.TextInput, { testID: "detox-harness-control", onChangeText: handleControl, style: { height: 1 } }),
97
+ react_1.default.createElement(react_native_1.TextInput, { testID: "detox-harness-control", onEndEditing: handleControl, style: {
98
+ position: 'absolute',
99
+ bottom: 0,
100
+ left: 0,
101
+ right: 0,
102
+ height: 44,
103
+ opacity: 0.01,
104
+ zIndex: 9999,
105
+ } }),
97
106
  activeMount && (react_1.default.createElement(react_1.default.Fragment, null,
98
107
  react_1.default.createElement(react_native_1.Text, { testID: "detox-mount-id", style: { height: 1 } }, activeMount.id),
99
108
  react_1.default.createElement(RenderErrorBoundary, null,
@@ -103,16 +112,16 @@ function ComponentRenderer({ mount }) {
103
112
  const { Component, defaultProps } = (0, ComponentRegistry_1.getComponent)(mount.name);
104
113
  const spyNames = mount.spies || [];
105
114
  const initialData = {};
106
- spyNames.forEach(name => {
115
+ spyNames.forEach((name) => {
107
116
  initialData[name] = { count: 0, lastArgs: [] };
108
117
  });
109
118
  const [spyData, setSpyData] = (0, react_1.useState)(initialData);
110
119
  const spyFnsRef = (0, react_1.useRef)({});
111
120
  const spyProps = {};
112
- spyNames.forEach(name => {
121
+ spyNames.forEach((name) => {
113
122
  if (!spyFnsRef.current[name]) {
114
123
  spyFnsRef.current[name] = (...callArgs) => {
115
- setSpyData(prev => {
124
+ setSpyData((prev) => {
116
125
  var _a;
117
126
  return ({
118
127
  ...prev,
@@ -128,11 +137,12 @@ function ComponentRenderer({ mount }) {
128
137
  });
129
138
  const props = { ...defaultProps, ...(mount.props || {}), ...spyProps };
130
139
  const Wrapper = (0, configureHarness_1.getWrapper)();
131
- return (react_1.default.createElement(Wrapper, { launchArgs: mount.props || {} },
132
- react_1.default.createElement(react_native_1.View, { testID: "component-harness-root", style: { flex: 1 } },
133
- react_1.default.createElement(Component, { ...props }),
134
- spyNames.map(name => (react_1.default.createElement(react_native_1.View, { key: name },
135
- react_1.default.createElement(react_native_1.Text, { testID: `spy-${name}-count` }, String(spyData[name].count)),
136
- react_1.default.createElement(react_native_1.Text, { testID: `spy-${name}-lastArgs` }, JSON.stringify(spyData[name].lastArgs))))))));
140
+ const debugTreeConfig = (0, configureHarness_1.getDebugTreeConfig)();
141
+ const content = (react_1.default.createElement(react_native_1.View, { testID: "component-harness-root", style: { flex: 1 } },
142
+ react_1.default.createElement(Component, { ...props }),
143
+ spyNames.map((name) => (react_1.default.createElement(react_native_1.View, { key: name },
144
+ react_1.default.createElement(react_native_1.Text, { testID: `spy-${name}-count` }, String(spyData[name].count)),
145
+ react_1.default.createElement(react_native_1.Text, { testID: `spy-${name}-lastArgs` }, JSON.stringify(spyData[name].lastArgs)))))));
146
+ return (react_1.default.createElement(Wrapper, { launchArgs: mount.props || {} }, debugTreeConfig ? react_1.default.createElement(DebugTree_1.DebugTree, { ...debugTreeConfig }, content) : content));
137
147
  }
138
148
  //# sourceMappingURL=ComponentHarness.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ComponentHarness.js","sourceRoot":"","sources":["../src/ComponentHarness.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ComponentHarness.js","sourceRoot":"","sources":["../src/ComponentHarness.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ComponentRegistry.d.ts","sourceRoot":"","sources":["../src/ComponentRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,GAAG;IACrC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAC1B;AAID,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GACxB,IAAI,CAAC;AACR,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GACxB,IAAI,CAAC;AA0BR,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAQzD;AAED,wBAAgB,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAEvD"}
1
+ {"version":3,"file":"ComponentRegistry.d.ts","sourceRoot":"","sources":["../src/ComponentRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAC,MAAM,OAAO,CAAC;AAEpC,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,GAAG;IACrC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAC1B;AAID,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GACxB,IAAI,CAAC;AACR,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;AA0BnG,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAQzD;AAED,wBAAgB,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAEvD"}
@@ -1 +1 @@
1
- {"version":3,"file":"ComponentRegistry.js","sourceRoot":"","sources":["../src/ComponentRegistry.ts"],"names":[],"mappings":";;AAkBA,8CAuBC;AAED,oCAQC;AAED,wBAEC;AAhDD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;AAWnD,SAAgB,iBAAiB,CAC/B,eAA0C,EAC1C,gBAAgD,EAChD,YAAyB;IAEzB,IAAI,OAAO,eAAe,KAAK,QAAQ,EAAE,CAAC;QACxC,QAAQ,CAAC,GAAG,CAAC,eAAe,EAAE;YAC5B,SAAS,EAAE,gBAAoC;YAC/C,YAAY,EAAE,CAAC,YAAY,IAAI,EAAE,CAAe;SACjD,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,SAAS,GAAG,eAAe,CAAC;QAClC,MAAM,IAAI,GAAG,SAAS,CAAC,WAAW,IAAI,SAAS,CAAC,IAAI,CAAC;QACrD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CACb,2GAA2G,CAC5G,CAAC;QACJ,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE;YACjB,SAAS;YACT,YAAY,EAAE,CAAE,gBAA+B,IAAI,EAAE,CAAe;SACrE,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,SAAgB,YAAY,CAAC,IAAY;IACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,wCAAwC,IAAI,4DAA4D,CACzG,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAgB,MAAM;IACpB,OAAO,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AACtC,CAAC"}
1
+ {"version":3,"file":"ComponentRegistry.js","sourceRoot":"","sources":["../src/ComponentRegistry.ts"],"names":[],"mappings":";;AAeA,8CAuBC;AAED,oCAQC;AAED,wBAEC;AA7CD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA0B,CAAC;AAQnD,SAAgB,iBAAiB,CAC/B,eAA0C,EAC1C,gBAAgD,EAChD,YAAyB;IAEzB,IAAI,OAAO,eAAe,KAAK,QAAQ,EAAE,CAAC;QACxC,QAAQ,CAAC,GAAG,CAAC,eAAe,EAAE;YAC5B,SAAS,EAAE,gBAAoC;YAC/C,YAAY,EAAE,CAAC,YAAY,IAAI,EAAE,CAAe;SACjD,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,SAAS,GAAG,eAAe,CAAC;QAClC,MAAM,IAAI,GAAG,SAAS,CAAC,WAAW,IAAI,SAAS,CAAC,IAAI,CAAC;QACrD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CACb,2GAA2G,CAC5G,CAAC;QACJ,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE;YACjB,SAAS;YACT,YAAY,EAAE,CAAE,gBAA+B,IAAI,EAAE,CAAe;SACrE,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED,SAAgB,YAAY,CAAC,IAAY;IACvC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,wCAAwC,IAAI,4DAA4D,CACzG,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAgB,MAAM;IACpB,OAAO,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;AACtC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ export declare function captureTree(ref: any, usefulProps?: Set<string>, skipNames?: Set<string>, nativeDuplicates?: Set<string>): string;
3
+ export interface DebugTreeProps {
4
+ children: React.ReactNode;
5
+ /** Props to include in tree output. Defaults to testID, accessibilityLabel, etc. */
6
+ usefulProps?: string[];
7
+ /** Component names to skip (internal wrappers that add noise). */
8
+ skipNames?: string[];
9
+ /** Native component names that duplicate their parent (e.g. RCTText inside Text). */
10
+ nativeDuplicates?: string[];
11
+ }
12
+ /**
13
+ * Debug component that captures the React component tree on demand.
14
+ * Wrap your test content with this. Trigger via Detox:
15
+ *
16
+ * await element(by.id('debug-tree-control')).replaceText('dump');
17
+ * const attrs = await element(by.id('debug-tree-output')).getAttributes();
18
+ */
19
+ export declare function DebugTree({ children, usefulProps, skipNames, nativeDuplicates }: DebugTreeProps): React.JSX.Element;
20
+ //# sourceMappingURL=DebugTree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DebugTree.d.ts","sourceRoot":"","sources":["../src/DebugTree.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAiN3D,wBAAgB,WAAW,CACzB,GAAG,EAAE,GAAG,EACR,WAAW,GAAE,GAAG,CAAC,MAAM,CAAwB,EAC/C,SAAS,GAAE,GAAG,CAAC,MAAM,CAAsB,EAC3C,gBAAgB,GAAE,GAAG,CAAC,MAAM,CAA6B,GACxD,MAAM,CAQR;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,oFAAoF;IACpF,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,EAAC,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,gBAAgB,EAAC,EAAE,cAAc,qBAsC7F"}