@nyby/detox-component-testing 1.3.0 → 1.4.2
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 +19 -3
- package/dist/ComponentHarness.d.ts.map +1 -1
- package/dist/ComponentHarness.js +9 -8
- package/dist/ComponentHarness.js.map +1 -1
- package/dist/ComponentRegistry.d.ts.map +1 -1
- package/dist/ComponentRegistry.js.map +1 -1
- package/dist/DebugTree.d.ts +20 -0
- package/dist/DebugTree.d.ts.map +1 -0
- package/dist/DebugTree.js +239 -0
- package/dist/DebugTree.js.map +1 -0
- package/dist/configureHarness.d.ts.map +1 -1
- package/dist/configureHarness.js.map +1 -1
- package/dist/debug.d.ts +2 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +49 -0
- package/dist/debug.js.map +1 -0
- package/dist/environment.js +45 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/mount.d.ts.map +1 -1
- package/dist/mount.js +24 -5
- package/dist/mount.js.map +1 -1
- package/dist/test.d.ts +2 -1
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +3 -2
- package/dist/test.js.map +1 -1
- package/package.json +13 -5
- package/src/ComponentHarness.tsx +35 -34
- package/src/ComponentRegistry.ts +2 -5
- package/src/DebugTree.tsx +280 -0
- package/src/configureHarness.ts +2 -2
- package/src/debug.ts +48 -0
- package/src/detox-env.d.ts +6 -2
- package/src/environment.js +45 -0
- package/src/index.ts +4 -3
- package/src/mount.ts +25 -9
- package/src/test.ts +2 -1
package/README.md
CHANGED
|
@@ -78,12 +78,22 @@ Add a component test configuration to `detox.config.js`:
|
|
|
78
78
|
|
|
79
79
|
```js
|
|
80
80
|
module.exports = {
|
|
81
|
-
// ... existing config
|
|
81
|
+
// ... existing app and device config
|
|
82
82
|
configurations: {
|
|
83
83
|
// ... existing configurations
|
|
84
|
-
"
|
|
84
|
+
"ios.sim.component": {
|
|
85
|
+
device: "simulator",
|
|
86
|
+
app: "ios",
|
|
87
|
+
testRunner: {
|
|
88
|
+
args: {
|
|
89
|
+
config: "component-tests/jest.config.js",
|
|
90
|
+
_: ["src/components"]
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"android.emu.component": {
|
|
85
95
|
device: "emulator",
|
|
86
|
-
app: "android
|
|
96
|
+
app: "android",
|
|
87
97
|
testRunner: {
|
|
88
98
|
args: {
|
|
89
99
|
config: "component-tests/jest.config.js",
|
|
@@ -220,6 +230,10 @@ Returns an assertion object for a spy:
|
|
|
220
230
|
- `.toHaveBeenCalledTimes(n)` — spy was called exactly `n` times
|
|
221
231
|
- `.lastCalledWith(...args)` — the last call's arguments match
|
|
222
232
|
|
|
233
|
+
#### `assertNoRenderError()`
|
|
234
|
+
|
|
235
|
+
Check whether the mounted component threw a render error. Called automatically by `mount()`, but can be used standalone after interactions that may trigger a re-render error.
|
|
236
|
+
|
|
223
237
|
## Limitations
|
|
224
238
|
|
|
225
239
|
- **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 +262,5 @@ app.component-test.js # Component test entry (harness)
|
|
|
248
262
|
index.js # Switches entry based on launch args
|
|
249
263
|
detox.config.js # Detox config with component test configuration
|
|
250
264
|
```
|
|
265
|
+
|
|
266
|
+
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,
|
|
1
|
+
{"version":3,"file":"ComponentHarness.d.ts","sourceRoot":"","sources":["../src/ComponentHarness.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8E,MAAM,OAAO,CAAC;AAuDnG,wBAAgB,gBAAgB,sBAsC/B"}
|
package/dist/ComponentHarness.js
CHANGED
|
@@ -94,22 +94,25 @@ function ComponentHarness() {
|
|
|
94
94
|
}
|
|
95
95
|
return (react_1.default.createElement(react_native_1.View, { style: { flex: 1 } },
|
|
96
96
|
react_1.default.createElement(react_native_1.TextInput, { testID: "detox-harness-control", onChangeText: handleControl, style: { height: 1 } }),
|
|
97
|
-
activeMount && (react_1.default.createElement(
|
|
97
|
+
activeMount && (react_1.default.createElement(react_1.default.Fragment, null,
|
|
98
|
+
react_1.default.createElement(react_native_1.Text, { testID: "detox-mount-id", style: { height: 1 } }, activeMount.id),
|
|
99
|
+
react_1.default.createElement(RenderErrorBoundary, null,
|
|
100
|
+
react_1.default.createElement(ComponentRenderer, { key: activeMount.id, mount: activeMount }))))));
|
|
98
101
|
}
|
|
99
102
|
function ComponentRenderer({ mount }) {
|
|
100
103
|
const { Component, defaultProps } = (0, ComponentRegistry_1.getComponent)(mount.name);
|
|
101
104
|
const spyNames = mount.spies || [];
|
|
102
105
|
const initialData = {};
|
|
103
|
-
spyNames.forEach(name => {
|
|
106
|
+
spyNames.forEach((name) => {
|
|
104
107
|
initialData[name] = { count: 0, lastArgs: [] };
|
|
105
108
|
});
|
|
106
109
|
const [spyData, setSpyData] = (0, react_1.useState)(initialData);
|
|
107
110
|
const spyFnsRef = (0, react_1.useRef)({});
|
|
108
111
|
const spyProps = {};
|
|
109
|
-
spyNames.forEach(name => {
|
|
112
|
+
spyNames.forEach((name) => {
|
|
110
113
|
if (!spyFnsRef.current[name]) {
|
|
111
114
|
spyFnsRef.current[name] = (...callArgs) => {
|
|
112
|
-
setSpyData(prev => {
|
|
115
|
+
setSpyData((prev) => {
|
|
113
116
|
var _a;
|
|
114
117
|
return ({
|
|
115
118
|
...prev,
|
|
@@ -127,10 +130,8 @@ function ComponentRenderer({ mount }) {
|
|
|
127
130
|
const Wrapper = (0, configureHarness_1.getWrapper)();
|
|
128
131
|
return (react_1.default.createElement(Wrapper, { launchArgs: mount.props || {} },
|
|
129
132
|
react_1.default.createElement(react_native_1.View, { testID: "component-harness-root", style: { flex: 1 } },
|
|
130
|
-
react_1.default.createElement(
|
|
131
|
-
react_1.default.createElement(
|
|
132
|
-
react_1.default.createElement(Component, { ...props })),
|
|
133
|
-
spyNames.map(name => (react_1.default.createElement(react_native_1.View, { key: name },
|
|
133
|
+
react_1.default.createElement(Component, { ...props }),
|
|
134
|
+
spyNames.map((name) => (react_1.default.createElement(react_native_1.View, { key: name },
|
|
134
135
|
react_1.default.createElement(react_native_1.Text, { testID: `spy-${name}-count` }, String(spyData[name].count)),
|
|
135
136
|
react_1.default.createElement(react_native_1.Text, { testID: `spy-${name}-lastArgs` }, JSON.stringify(spyData[name].lastArgs))))))));
|
|
136
137
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ComponentHarness.js","sourceRoot":"","sources":["../src/ComponentHarness.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
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,
|
|
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":";;
|
|
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"}
|
|
@@ -0,0 +1,239 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DebugTree.js","sourceRoot":"","sources":["../src/DebugTree.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configureHarness.d.ts","sourceRoot":"","sources":["../src/configureHarness.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"configureHarness.d.ts","sourceRoot":"","sources":["../src/configureHarness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,aAAa,EAAE,SAAS,EAAC,MAAM,OAAO,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,SAAS,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,aAAa,CAAC,YAAY,CAAC,CAAC;CACtC;AAMD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAE5D;AAED,wBAAgB,UAAU,IAAI,aAAa,CAAC,YAAY,CAAC,CAExD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configureHarness.js","sourceRoot":"","sources":["../src/configureHarness.ts"],"names":[],"mappings":";;AAeA,4CAEC;AAED,gCAEC;AAVD,MAAM,cAAc,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"configureHarness.js","sourceRoot":"","sources":["../src/configureHarness.ts"],"names":[],"mappings":";;AAeA,4CAEC;AAED,gCAEC;AAVD,MAAM,cAAc,GAAG,CAAC,EAAC,QAAQ,EAAe,EAAE,EAAE,CAAC,QAAQ,CAAC;AAE9D,IAAI,aAAa,GAAuC,IAAI,CAAC;AAE7D,SAAgB,gBAAgB,CAAC,MAAqB;IACpD,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC;AACjC,CAAC;AAED,SAAgB,UAAU;IACxB,OAAO,aAAa,IAAI,cAAc,CAAC;AACzC,CAAC"}
|
package/dist/debug.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":"AAcA,wBAAsB,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,iBAiC7D"}
|
package/dist/debug.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.debug = debug;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
/**
|
|
7
|
+
* Capture a screenshot, React component tree, and native view hierarchy.
|
|
8
|
+
* Drop this anywhere in a test to inspect the current screen state.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* import { debug } from '@nyby/detox-component-testing/test';
|
|
12
|
+
* await debug(); // artifacts/debug-1.png, debug-1-tree.json, debug-1-view.xml
|
|
13
|
+
* await debug('after-tap'); // artifacts/debug-after-tap.png, etc.
|
|
14
|
+
*/
|
|
15
|
+
let counter = 0;
|
|
16
|
+
async function debug(label, outputDir) {
|
|
17
|
+
const name = label || String(++counter);
|
|
18
|
+
const dir = outputDir || (0, path_1.join)(process.cwd(), 'artifacts');
|
|
19
|
+
(0, fs_1.mkdirSync)(dir, { recursive: true });
|
|
20
|
+
const screenshotPath = (0, path_1.join)(dir, `debug-${name}.png`);
|
|
21
|
+
const treePath = (0, path_1.join)(dir, `debug-${name}-tree.json`);
|
|
22
|
+
const viewPath = (0, path_1.join)(dir, `debug-${name}-view.xml`);
|
|
23
|
+
// Screenshot via Detox, then move to our artifacts dir
|
|
24
|
+
try {
|
|
25
|
+
const tempPath = await device.takeScreenshot(`debug-${name}`);
|
|
26
|
+
if (tempPath) {
|
|
27
|
+
(0, fs_1.renameSync)(tempPath, screenshotPath);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch (_a) { }
|
|
31
|
+
// React component tree via DebugTree harness
|
|
32
|
+
try {
|
|
33
|
+
await element(by.id('debug-tree-control')).replaceText('dump');
|
|
34
|
+
await waitFor(element(by.id('debug-tree-output')))
|
|
35
|
+
.toExist()
|
|
36
|
+
.withTimeout(3000);
|
|
37
|
+
const attrs = await element(by.id('debug-tree-output')).getAttributes();
|
|
38
|
+
const tree = attrs.text || attrs.label || '[]';
|
|
39
|
+
(0, fs_1.writeFileSync)(treePath, tree, 'utf8');
|
|
40
|
+
}
|
|
41
|
+
catch (_b) { }
|
|
42
|
+
// Native view hierarchy
|
|
43
|
+
try {
|
|
44
|
+
const xml = await device.generateViewHierarchyXml();
|
|
45
|
+
(0, fs_1.writeFileSync)(viewPath, xml, 'utf8');
|
|
46
|
+
}
|
|
47
|
+
catch (_c) { }
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=debug.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debug.js","sourceRoot":"","sources":["../src/debug.ts"],"names":[],"mappings":";;AAcA,sBAiCC;AA/CD,2BAAwD;AACxD,+BAA0B;AAE1B;;;;;;;;GAQG;AACH,IAAI,OAAO,GAAG,CAAC,CAAC;AAET,KAAK,UAAU,KAAK,CAAC,KAAc,EAAE,SAAkB;IAC5D,MAAM,IAAI,GAAG,KAAK,IAAI,MAAM,CAAC,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,SAAS,IAAI,IAAA,WAAI,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;IAC1D,IAAA,cAAS,EAAC,GAAG,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC;IAElC,MAAM,cAAc,GAAG,IAAA,WAAI,EAAC,GAAG,EAAE,SAAS,IAAI,MAAM,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,GAAG,EAAE,SAAS,IAAI,YAAY,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,GAAG,EAAE,SAAS,IAAI,WAAW,CAAC,CAAC;IAErD,uDAAuD;IACvD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QAC9D,IAAI,QAAQ,EAAE,CAAC;YACb,IAAA,eAAU,EAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAAC,WAAM,CAAC,CAAA,CAAC;IAEV,6CAA6C;IAC7C,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAC/D,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;aAC/C,OAAO,EAAE;aACT,WAAW,CAAC,IAAI,CAAC,CAAC;QACrB,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC;QACxE,MAAM,IAAI,GAAI,KAAa,CAAC,IAAI,IAAK,KAAa,CAAC,KAAK,IAAI,IAAI,CAAC;QACjE,IAAA,kBAAa,EAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAAC,WAAM,CAAC,CAAA,CAAC;IAEV,wBAAwB;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,wBAAwB,EAAE,CAAC;QACpD,IAAA,kBAAa,EAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAAC,WAAM,CAAC,CAAA,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const DetoxCircusEnvironment = require('detox/runners/jest/testEnvironment');
|
|
2
|
+
const {mkdirSync, writeFileSync} = require('fs');
|
|
3
|
+
const {join} = require('path');
|
|
4
|
+
|
|
5
|
+
class CustomDetoxEnvironment extends DetoxCircusEnvironment {
|
|
6
|
+
async handleTestEvent(event, state) {
|
|
7
|
+
await super.handleTestEvent(event, state);
|
|
8
|
+
|
|
9
|
+
if (event.name === 'test_done' && event.test.errors.length > 0) {
|
|
10
|
+
await this._dumpDebugInfo(event.test);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
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
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = CustomDetoxEnvironment;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
export { registerComponent
|
|
1
|
+
export { registerComponent } from './ComponentRegistry';
|
|
2
2
|
export { ComponentHarness } from './ComponentHarness';
|
|
3
|
-
export { configureHarness, WrapperProps
|
|
3
|
+
export { configureHarness, WrapperProps } from './configureHarness';
|
|
4
|
+
export { DebugTree } from './DebugTree';
|
|
4
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAC,gBAAgB,EAAC,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAC,gBAAgB,EAAE,YAAY,EAAC,MAAM,oBAAoB,CAAC;AAClE,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.DebugTree = exports.configureHarness = exports.ComponentHarness = exports.registerComponent = void 0;
|
|
4
4
|
var ComponentRegistry_1 = require("./ComponentRegistry");
|
|
5
5
|
Object.defineProperty(exports, "registerComponent", { enumerable: true, get: function () { return ComponentRegistry_1.registerComponent; } });
|
|
6
|
-
Object.defineProperty(exports, "getComponent", { enumerable: true, get: function () { return ComponentRegistry_1.getComponent; } });
|
|
7
|
-
Object.defineProperty(exports, "getAll", { enumerable: true, get: function () { return ComponentRegistry_1.getAll; } });
|
|
8
6
|
var ComponentHarness_1 = require("./ComponentHarness");
|
|
9
7
|
Object.defineProperty(exports, "ComponentHarness", { enumerable: true, get: function () { return ComponentHarness_1.ComponentHarness; } });
|
|
10
8
|
var configureHarness_1 = require("./configureHarness");
|
|
11
9
|
Object.defineProperty(exports, "configureHarness", { enumerable: true, get: function () { return configureHarness_1.configureHarness; } });
|
|
10
|
+
var DebugTree_1 = require("./DebugTree");
|
|
11
|
+
Object.defineProperty(exports, "DebugTree", { enumerable: true, get: function () { return DebugTree_1.DebugTree; } });
|
|
12
12
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,yDAAsD;AAA9C,sHAAA,iBAAiB,OAAA;AACzB,uDAAoD;AAA5C,oHAAA,gBAAgB,OAAA;AACxB,uDAAkE;AAA1D,oHAAA,gBAAgB,OAAA;AACxB,yCAAsC;AAA9B,sGAAA,SAAS,OAAA"}
|
package/dist/mount.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,qBAAqB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,cAAc,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAOD,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAE3C;AAED,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;AAExE,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,qBAAqB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,cAAc,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C;AAOD,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAE3C;AAED,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;AAExE,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAYzD;AAED,wBAAsB,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDpF;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAetD"}
|
package/dist/mount.js
CHANGED
|
@@ -12,13 +12,15 @@ function spy(name) {
|
|
|
12
12
|
}
|
|
13
13
|
async function assertNoRenderError() {
|
|
14
14
|
try {
|
|
15
|
-
await waitFor(element(by.id('detox-render-error')))
|
|
15
|
+
await waitFor(element(by.id('detox-render-error')))
|
|
16
|
+
.toExist()
|
|
17
|
+
.withTimeout(500);
|
|
16
18
|
}
|
|
17
19
|
catch (_a) {
|
|
18
20
|
return; // Element not found — no render error, all good
|
|
19
21
|
}
|
|
20
22
|
// Element exists — read the error message and throw
|
|
21
|
-
const attrs = await element(by.id('detox-render-error-message')).getAttributes();
|
|
23
|
+
const attrs = (await element(by.id('detox-render-error-message')).getAttributes());
|
|
22
24
|
const message = attrs.text || attrs.label || 'Unknown render error';
|
|
23
25
|
throw new Error(`Component render error: ${message}`);
|
|
24
26
|
}
|
|
@@ -44,17 +46,34 @@ async function mount(componentName, props) {
|
|
|
44
46
|
Object.entries(payload.props).forEach(([key, value]) => {
|
|
45
47
|
launchArgs[`detoxProp_${key}`] = value;
|
|
46
48
|
});
|
|
47
|
-
payload.spies.forEach(name => {
|
|
49
|
+
payload.spies.forEach((name) => {
|
|
48
50
|
launchArgs[`detoxSpy_${name}`] = true;
|
|
49
51
|
});
|
|
50
52
|
await device.launchApp({ newInstance: true, launchArgs });
|
|
51
53
|
appLaunched = true;
|
|
52
|
-
|
|
54
|
+
// Harness sets id '0' for the initial launch-args mount
|
|
55
|
+
try {
|
|
56
|
+
await waitFor(element(by.id('detox-mount-id')))
|
|
57
|
+
.toHaveText('0')
|
|
58
|
+
.withTimeout(5000);
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
await assertNoRenderError(); // Throws with the actual error if one exists
|
|
62
|
+
throw e; // Re-throw original timeout if no render error found
|
|
63
|
+
}
|
|
53
64
|
await assertNoRenderError();
|
|
54
65
|
return;
|
|
55
66
|
}
|
|
56
67
|
await element(by.id('detox-harness-control')).replaceText(JSON.stringify(payload));
|
|
57
|
-
|
|
68
|
+
try {
|
|
69
|
+
await waitFor(element(by.id('detox-mount-id')))
|
|
70
|
+
.toHaveText(payload.id)
|
|
71
|
+
.withTimeout(5000);
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
await assertNoRenderError();
|
|
75
|
+
throw e;
|
|
76
|
+
}
|
|
58
77
|
await assertNoRenderError();
|
|
59
78
|
}
|
|
60
79
|
function expectSpy(name) {
|