@nyby/detox-component-testing 1.4.2 → 1.5.1

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.
@@ -6,7 +6,7 @@ export interface WrapperProps {
6
6
  }
7
7
 
8
8
  export interface HarnessConfig {
9
- wrapper: ComponentType<WrapperProps>;
9
+ wrapper?: ComponentType<WrapperProps>;
10
10
  }
11
11
 
12
12
  const DefaultWrapper = ({children}: WrapperProps) => children;
@@ -14,7 +14,9 @@ const DefaultWrapper = ({children}: WrapperProps) => children;
14
14
  let globalWrapper: ComponentType<WrapperProps> | null = null;
15
15
 
16
16
  export function configureHarness(config: HarnessConfig): void {
17
- globalWrapper = config.wrapper;
17
+ if (config.wrapper) {
18
+ globalWrapper = config.wrapper;
19
+ }
18
20
  }
19
21
 
20
22
  export function getWrapper(): ComponentType<WrapperProps> {
package/src/debug.ts CHANGED
@@ -2,47 +2,44 @@ import {mkdirSync, renameSync, writeFileSync} from 'fs';
2
2
  import {join} from 'path';
3
3
 
4
4
  /**
5
- * Capture a screenshot, React component tree, and native view hierarchy.
6
- * Drop this anywhere in a test to inspect the current screen state.
7
- *
8
- * Usage:
9
- * import { debug } from '@nyby/detox-component-testing/test';
10
- * await debug(); // artifacts/debug-1.png, debug-1-tree.json, debug-1-view.xml
11
- * await debug('after-tap'); // artifacts/debug-after-tap.png, etc.
5
+ * Capture a screenshot and native view hierarchy to the given directory.
6
+ * Used by both the `debug()` helper and the custom test environment.
12
7
  */
13
- let counter = 0;
14
-
15
- export async function debug(label?: string, outputDir?: string) {
16
- const name = label || String(++counter);
17
- const dir = outputDir || join(process.cwd(), 'artifacts');
18
- mkdirSync(dir, {recursive: true});
19
-
20
- const screenshotPath = join(dir, `debug-${name}.png`);
21
- const treePath = join(dir, `debug-${name}-tree.json`);
22
- const viewPath = join(dir, `debug-${name}-view.xml`);
8
+ export async function captureArtifacts(
9
+ name: string,
10
+ outputDir: string,
11
+ deviceRef: {takeScreenshot: (n: string) => Promise<string>; generateViewHierarchyXml: () => Promise<string>},
12
+ ) {
13
+ mkdirSync(outputDir, {recursive: true});
23
14
 
24
15
  // Screenshot via Detox, then move to our artifacts dir
25
16
  try {
26
- const tempPath = await device.takeScreenshot(`debug-${name}`);
17
+ const tempPath = await deviceRef.takeScreenshot(`debug-${name}`);
27
18
  if (tempPath) {
28
- renameSync(tempPath, screenshotPath);
19
+ renameSync(tempPath, join(outputDir, `debug-${name}.png`));
29
20
  }
30
21
  } catch {}
31
22
 
32
- // React component tree via DebugTree harness
33
- try {
34
- await element(by.id('debug-tree-control')).replaceText('dump');
35
- await waitFor(element(by.id('debug-tree-output')))
36
- .toExist()
37
- .withTimeout(3000);
38
- const attrs = await element(by.id('debug-tree-output')).getAttributes();
39
- const tree = (attrs as any).text || (attrs as any).label || '[]';
40
- writeFileSync(treePath, tree, 'utf8');
41
- } catch {}
42
-
43
23
  // Native view hierarchy
44
24
  try {
45
- const xml = await device.generateViewHierarchyXml();
46
- writeFileSync(viewPath, xml, 'utf8');
25
+ const xml = await deviceRef.generateViewHierarchyXml();
26
+ writeFileSync(join(outputDir, `debug-${name}-view.xml`), xml, 'utf8');
47
27
  } catch {}
48
28
  }
29
+
30
+ /**
31
+ * Capture a screenshot and native view hierarchy.
32
+ * Drop this anywhere in a test to inspect the current screen state.
33
+ *
34
+ * Usage:
35
+ * import { debug } from '@nyby/detox-component-testing/test';
36
+ * await debug(); // artifacts/debug-1.png, debug-1-view.xml
37
+ * await debug('after-tap'); // artifacts/debug-after-tap.png, etc.
38
+ */
39
+ let counter = 0;
40
+
41
+ export async function debug(label?: string, outputDir?: string) {
42
+ const name = label || String(++counter);
43
+ const dir = outputDir || join(process.cwd(), 'artifacts');
44
+ await captureArtifacts(name, dir, device);
45
+ }
@@ -1,45 +1,17 @@
1
1
  const DetoxCircusEnvironment = require('detox/runners/jest/testEnvironment');
2
- const {mkdirSync, writeFileSync} = require('fs');
3
2
  const {join} = require('path');
3
+ const {captureArtifacts} = require('./debug');
4
4
 
5
5
  class CustomDetoxEnvironment extends DetoxCircusEnvironment {
6
6
  async handleTestEvent(event, state) {
7
7
  await super.handleTestEvent(event, state);
8
8
 
9
9
  if (event.name === 'test_done' && event.test.errors.length > 0) {
10
- await this._dumpDebugInfo(event.test);
10
+ const safeName = event.test.name.replace(/[^a-zA-Z0-9_-]/g, '_');
11
+ const outputDir = join(process.cwd(), 'artifacts');
12
+ await captureArtifacts(safeName, outputDir, this.global.device);
11
13
  }
12
14
  }
13
-
14
- async _dumpDebugInfo(test) {
15
- const outputDir = join(process.cwd(), 'artifacts');
16
- const safeName = test.name.replace(/[^a-zA-Z0-9_-]/g, '_');
17
-
18
- mkdirSync(outputDir, {recursive: true});
19
-
20
- // Screenshot (saved by Detox into its own artifacts folder)
21
- try {
22
- await this.global.device.takeScreenshot(`debug-${safeName}`);
23
- } catch (_e) {}
24
-
25
- // Component tree via DebugTree
26
- try {
27
- const {element, by, waitFor} = this.global;
28
-
29
- await element(by.id('debug-tree-control')).replaceText('dump');
30
- await waitFor(element(by.id('debug-tree-output'))).toExist().withTimeout(3000);
31
-
32
- const attrs = await element(by.id('debug-tree-output')).getAttributes();
33
- const tree = attrs.text || attrs.label || '[]';
34
- writeFileSync(join(outputDir, `componenttree-${safeName}.json`), tree, 'utf8');
35
- } catch (_e) {}
36
-
37
- // Native view hierarchy
38
- try {
39
- const xml = await this.global.device.generateViewHierarchyXml();
40
- writeFileSync(join(outputDir, `viewhierarchy-${safeName}.xml`), xml, 'utf8');
41
- } catch (_e) {}
42
- }
43
15
  }
44
16
 
45
17
  module.exports = CustomDetoxEnvironment;
package/src/index.ts CHANGED
@@ -1,4 +1,3 @@
1
1
  export {registerComponent} from './ComponentRegistry';
2
2
  export {ComponentHarness} from './ComponentHarness';
3
- export {configureHarness, WrapperProps} from './configureHarness';
4
- export {DebugTree} from './DebugTree';
3
+ export {configureHarness, WrapperProps, HarnessConfig} from './configureHarness';
package/src/mount.ts CHANGED
@@ -52,37 +52,23 @@ export async function mount(componentName: string, props?: MountProps): Promise<
52
52
  });
53
53
  }
54
54
 
55
- if (!appLaunched) {
56
- const launchArgs: Record<string, any> = {detoxComponentName: componentName};
57
- Object.entries(payload.props).forEach(([key, value]) => {
58
- launchArgs[`detoxProp_${key}`] = value;
59
- });
60
- payload.spies.forEach((name) => {
61
- launchArgs[`detoxSpy_${name}`] = true;
62
- });
63
- await device.launchApp({newInstance: true, launchArgs});
64
- appLaunched = true;
65
- // Harness sets id '0' for the initial launch-args mount
66
- try {
67
- await waitFor(element(by.id('detox-mount-id')))
68
- .toHaveText('0')
69
- .withTimeout(5000);
70
- } catch (e) {
71
- await assertNoRenderError(); // Throws with the actual error if one exists
72
- throw e; // Re-throw original timeout if no render error found
73
- }
74
- await assertNoRenderError();
75
- return;
76
- }
77
-
78
- await element(by.id('detox-harness-control')).replaceText(JSON.stringify(payload));
55
+ const launchArgs: Record<string, any> = {detoxComponentName: componentName};
56
+ Object.entries(payload.props).forEach(([key, value]) => {
57
+ launchArgs[`detoxProp_${key}`] = value;
58
+ });
59
+ payload.spies.forEach((name) => {
60
+ launchArgs[`detoxSpy_${name}`] = true;
61
+ });
62
+ await device.launchApp({newInstance: true, launchArgs});
63
+ appLaunched = true;
64
+ // Harness sets id '0' for the initial launch-args mount
79
65
  try {
80
66
  await waitFor(element(by.id('detox-mount-id')))
81
- .toHaveText(payload.id)
67
+ .toHaveText('0')
82
68
  .withTimeout(5000);
83
69
  } catch (e) {
84
- await assertNoRenderError();
85
- throw e;
70
+ await assertNoRenderError(); // Throws with the actual error if one exists
71
+ throw e; // Re-throw original timeout if no render error found
86
72
  }
87
73
  await assertNoRenderError();
88
74
  }
@@ -1,20 +0,0 @@
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
@@ -1 +0,0 @@
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"}
package/dist/DebugTree.js DELETED
@@ -1,239 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.captureTree = captureTree;
37
- exports.DebugTree = DebugTree;
38
- const react_1 = __importStar(require("react"));
39
- const react_native_1 = require("react-native");
40
- // React fiber tags
41
- const FunctionComponent = 0;
42
- const ClassComponent = 1;
43
- const HostComponent = 5;
44
- const HostText = 6;
45
- const ForwardRef = 11;
46
- const MemoComponent = 14;
47
- const SimpleMemoComponent = 15;
48
- const DEFAULT_USEFUL_PROPS = new Set([
49
- 'testID',
50
- 'accessibilityLabel',
51
- 'accessibilityRole',
52
- 'title',
53
- 'name',
54
- 'variant',
55
- 'size',
56
- 'value',
57
- 'placeholder',
58
- 'disabled',
59
- 'selected',
60
- 'checked',
61
- 'visible',
62
- ]);
63
- const DEFAULT_SKIP_NAMES = new Set([
64
- 'StaticContainer',
65
- 'EnsureSingleNavigator',
66
- 'PreventRemoveProvider',
67
- 'NavigationContent',
68
- 'NavigationStateContext',
69
- 'ScreenStackHeaderConfig',
70
- 'RenderErrorBoundary',
71
- 'DebugTree',
72
- 'PressabilityDebugView',
73
- ]);
74
- const DEFAULT_NATIVE_DUPLICATES = new Set([
75
- 'RCTText',
76
- 'RCTView',
77
- 'RCTScrollView',
78
- 'RCTCustomScrollView',
79
- 'RCTScrollContentView',
80
- 'RCTSinglelineTextInputView',
81
- 'RCTUITextField',
82
- ]);
83
- function findFiberFromRef(ref) {
84
- if (!ref)
85
- return null;
86
- // React Native: __internalInstanceHandle is the fiber node
87
- if (ref.__internalInstanceHandle) {
88
- return ref.__internalInstanceHandle;
89
- }
90
- // React DEV builds
91
- if (ref._internalFiberInstanceHandleDEV) {
92
- return ref._internalFiberInstanceHandleDEV;
93
- }
94
- // React DOM style: __reactFiber$ key on the node
95
- for (const key of Object.getOwnPropertyNames(ref)) {
96
- if (key.startsWith('__reactFiber$')) {
97
- return ref[key];
98
- }
99
- }
100
- return null;
101
- }
102
- function getComponentName(fiber) {
103
- var _a, _b, _c, _d;
104
- const { type, tag } = fiber;
105
- if (tag === HostText)
106
- return null;
107
- if (tag === HostComponent) {
108
- return typeof type === 'string' ? type : null;
109
- }
110
- if (tag === FunctionComponent || tag === ClassComponent || tag === SimpleMemoComponent) {
111
- return (type === null || type === void 0 ? void 0 : type.displayName) || (type === null || type === void 0 ? void 0 : type.name) || null;
112
- }
113
- if (tag === ForwardRef) {
114
- return (type === null || type === void 0 ? void 0 : type.displayName) || ((_a = type === null || type === void 0 ? void 0 : type.render) === null || _a === void 0 ? void 0 : _a.displayName) || ((_b = type === null || type === void 0 ? void 0 : type.render) === null || _b === void 0 ? void 0 : _b.name) || null;
115
- }
116
- if (tag === MemoComponent) {
117
- return (type === null || type === void 0 ? void 0 : type.displayName) || ((_c = type === null || type === void 0 ? void 0 : type.type) === null || _c === void 0 ? void 0 : _c.displayName) || ((_d = type === null || type === void 0 ? void 0 : type.type) === null || _d === void 0 ? void 0 : _d.name) || null;
118
- }
119
- return null;
120
- }
121
- function isUserComponent(fiber) {
122
- const { tag } = fiber;
123
- return (tag === FunctionComponent ||
124
- tag === ClassComponent ||
125
- tag === ForwardRef ||
126
- tag === MemoComponent ||
127
- tag === SimpleMemoComponent);
128
- }
129
- function extractProps(fiber, usefulProps) {
130
- const { memoizedProps } = fiber;
131
- if (!memoizedProps)
132
- return undefined;
133
- const result = {};
134
- let hasProps = false;
135
- for (const key of Object.keys(memoizedProps)) {
136
- if (key === 'children' || key === 'style')
137
- continue;
138
- if (usefulProps.has(key)) {
139
- const val = memoizedProps[key];
140
- if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean') {
141
- result[key] = val;
142
- hasProps = true;
143
- }
144
- }
145
- }
146
- if (memoizedProps.onPress) {
147
- result.onPress = true;
148
- hasProps = true;
149
- }
150
- return hasProps ? result : undefined;
151
- }
152
- function getTextContent(fiber) {
153
- var _a;
154
- if (fiber.tag === HostText) {
155
- return typeof fiber.memoizedProps === 'string' ? fiber.memoizedProps : undefined;
156
- }
157
- if (typeof ((_a = fiber.memoizedProps) === null || _a === void 0 ? void 0 : _a.children) === 'string') {
158
- return fiber.memoizedProps.children;
159
- }
160
- return undefined;
161
- }
162
- function shouldShow(fiber, skipNames, nativeDuplicates) {
163
- const name = getComponentName(fiber);
164
- if (!name)
165
- return false;
166
- if (skipNames.has(name))
167
- return false;
168
- if (nativeDuplicates.has(name))
169
- return false;
170
- if (isUserComponent(fiber))
171
- return true;
172
- if (fiber.tag === HostComponent) {
173
- const props = fiber.memoizedProps;
174
- if ((props === null || props === void 0 ? void 0 : props.testID) || (props === null || props === void 0 ? void 0 : props.accessibilityLabel))
175
- return true;
176
- if (typeof (props === null || props === void 0 ? void 0 : props.children) === 'string')
177
- return true;
178
- }
179
- return false;
180
- }
181
- function walkFiber(fiber, collect, usefulProps, skipNames, nativeDuplicates) {
182
- if (!fiber)
183
- return;
184
- const name = getComponentName(fiber);
185
- const show = fiber.tag !== HostText && shouldShow(fiber, skipNames, nativeDuplicates);
186
- if (show && name) {
187
- const node = { name };
188
- const props = extractProps(fiber, usefulProps);
189
- if (props)
190
- node.props = props;
191
- const text = getTextContent(fiber);
192
- if (text)
193
- node.text = text;
194
- const childNodes = [];
195
- walkFiber(fiber.child, childNodes, usefulProps, skipNames, nativeDuplicates);
196
- if (childNodes.length > 0)
197
- node.children = childNodes;
198
- collect.push(node);
199
- }
200
- else {
201
- walkFiber(fiber.child, collect, usefulProps, skipNames, nativeDuplicates);
202
- }
203
- walkFiber(fiber.sibling, collect, usefulProps, skipNames, nativeDuplicates);
204
- }
205
- function captureTree(ref, usefulProps = DEFAULT_USEFUL_PROPS, skipNames = DEFAULT_SKIP_NAMES, nativeDuplicates = DEFAULT_NATIVE_DUPLICATES) {
206
- const fiber = findFiberFromRef(ref);
207
- if (!fiber)
208
- return '[]';
209
- const tree = [];
210
- walkFiber(fiber.child, tree, usefulProps, skipNames, nativeDuplicates);
211
- return JSON.stringify(tree);
212
- }
213
- /**
214
- * Debug component that captures the React component tree on demand.
215
- * Wrap your test content with this. Trigger via Detox:
216
- *
217
- * await element(by.id('debug-tree-control')).replaceText('dump');
218
- * const attrs = await element(by.id('debug-tree-output')).getAttributes();
219
- */
220
- function DebugTree({ children, usefulProps, skipNames, nativeDuplicates }) {
221
- const rootRef = (0, react_1.useRef)(null);
222
- const [tree, setTree] = (0, react_1.useState)('');
223
- const usefulPropsSet = usefulProps ? new Set(usefulProps) : DEFAULT_USEFUL_PROPS;
224
- const skipNamesSet = skipNames ? new Set(skipNames) : DEFAULT_SKIP_NAMES;
225
- const nativeDuplicatesSet = nativeDuplicates
226
- ? new Set(nativeDuplicates)
227
- : DEFAULT_NATIVE_DUPLICATES;
228
- const handleCommand = (0, react_1.useCallback)((text) => {
229
- if (text === 'dump' && rootRef.current) {
230
- const result = captureTree(rootRef.current, usefulPropsSet, skipNamesSet, nativeDuplicatesSet);
231
- setTree(result);
232
- }
233
- }, [usefulPropsSet, skipNamesSet, nativeDuplicatesSet]);
234
- return (react_1.default.createElement(react_1.default.Fragment, null,
235
- react_1.default.createElement(react_native_1.TextInput, { testID: "debug-tree-control", onChangeText: handleCommand, style: { height: 1 } }),
236
- react_1.default.createElement(react_native_1.View, { ref: rootRef, style: { flex: 1 }, collapsable: false }, children),
237
- tree ? (react_1.default.createElement(react_native_1.Text, { testID: "debug-tree-output", style: { height: 1 } }, tree)) : null));
238
- }
239
- //# sourceMappingURL=DebugTree.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DebugTree.js","sourceRoot":"","sources":["../src/DebugTree.tsx"],"names":[],"mappings":"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"}