@nyby/detox-component-testing 1.2.0 → 1.3.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/ComponentHarness.d.ts.map +1 -1
- package/dist/ComponentHarness.js +18 -1
- package/dist/ComponentHarness.js.map +1 -1
- package/dist/mount.d.ts +1 -0
- package/dist/mount.d.ts.map +1 -1
- package/dist/mount.js +16 -0
- package/dist/mount.js.map +1 -1
- package/dist/test.d.ts +1 -1
- package/dist/test.d.ts.map +1 -1
- package/dist/test.js +2 -1
- package/dist/test.js.map +1 -1
- package/package.json +1 -1
- package/src/ComponentHarness.tsx +30 -3
- package/src/mount.ts +15 -0
- package/src/test.ts +1 -1
|
@@ -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,KAAgF,MAAM,OAAO,CAAC;AAsDrG,wBAAgB,gBAAgB,sBAmC/B"}
|
package/dist/ComponentHarness.js
CHANGED
|
@@ -39,6 +39,22 @@ 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
|
+
class RenderErrorBoundary extends react_1.Component {
|
|
43
|
+
constructor() {
|
|
44
|
+
super(...arguments);
|
|
45
|
+
this.state = { error: null };
|
|
46
|
+
}
|
|
47
|
+
static getDerivedStateFromError(error) {
|
|
48
|
+
return { error };
|
|
49
|
+
}
|
|
50
|
+
render() {
|
|
51
|
+
if (this.state.error) {
|
|
52
|
+
return (react_1.default.createElement(react_native_1.ScrollView, { testID: "detox-render-error" },
|
|
53
|
+
react_1.default.createElement(react_native_1.Text, { testID: "detox-render-error-message" }, this.state.error.message)));
|
|
54
|
+
}
|
|
55
|
+
return this.props.children;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
42
58
|
const PROP_PREFIX = 'detoxProp_';
|
|
43
59
|
const SPY_PREFIX = 'detoxSpy_';
|
|
44
60
|
function parseLaunchArgs(args) {
|
|
@@ -112,7 +128,8 @@ function ComponentRenderer({ mount }) {
|
|
|
112
128
|
return (react_1.default.createElement(Wrapper, { launchArgs: mount.props || {} },
|
|
113
129
|
react_1.default.createElement(react_native_1.View, { testID: "component-harness-root", style: { flex: 1 } },
|
|
114
130
|
react_1.default.createElement(react_native_1.Text, { testID: "detox-mount-id", style: { height: 1 } }, mount.id),
|
|
115
|
-
react_1.default.createElement(
|
|
131
|
+
react_1.default.createElement(RenderErrorBoundary, null,
|
|
132
|
+
react_1.default.createElement(Component, { ...props })),
|
|
116
133
|
spyNames.map(name => (react_1.default.createElement(react_native_1.View, { key: name },
|
|
117
134
|
react_1.default.createElement(react_native_1.Text, { testID: `spy-${name}-count` }, String(spyData[name].count)),
|
|
118
135
|
react_1.default.createElement(react_native_1.Text, { testID: `spy-${name}-lastArgs` }, JSON.stringify(spyData[name].lastArgs))))))));
|
|
@@ -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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"}
|
package/dist/mount.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export interface SpyExpectation {
|
|
|
9
9
|
}
|
|
10
10
|
export declare function spy(name: string): SpyMarker;
|
|
11
11
|
type MountProps = Record<string, string | number | boolean | SpyMarker>;
|
|
12
|
+
export declare function assertNoRenderError(): Promise<void>;
|
|
12
13
|
export declare function mount(componentName: string, props?: MountProps): Promise<void>;
|
|
13
14
|
export declare function expectSpy(name: string): SpyExpectation;
|
|
14
15
|
export {};
|
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,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,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,CAUzD;AAED,wBAAsB,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAqCpF;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAetD"}
|
package/dist/mount.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.spy = spy;
|
|
4
|
+
exports.assertNoRenderError = assertNoRenderError;
|
|
4
5
|
exports.mount = mount;
|
|
5
6
|
exports.expectSpy = expectSpy;
|
|
6
7
|
const SPY_MARKER = '__detoxSpy__';
|
|
@@ -9,6 +10,18 @@ let appLaunched = false;
|
|
|
9
10
|
function spy(name) {
|
|
10
11
|
return { [SPY_MARKER]: true, name };
|
|
11
12
|
}
|
|
13
|
+
async function assertNoRenderError() {
|
|
14
|
+
try {
|
|
15
|
+
await waitFor(element(by.id('detox-render-error'))).toExist().withTimeout(0);
|
|
16
|
+
}
|
|
17
|
+
catch (_a) {
|
|
18
|
+
return; // Element not found — no render error, all good
|
|
19
|
+
}
|
|
20
|
+
// Element exists — read the error message and throw
|
|
21
|
+
const attrs = await element(by.id('detox-render-error-message')).getAttributes();
|
|
22
|
+
const message = attrs.text || attrs.label || 'Unknown render error';
|
|
23
|
+
throw new Error(`Component render error: ${message}`);
|
|
24
|
+
}
|
|
12
25
|
async function mount(componentName, props) {
|
|
13
26
|
const payload = {
|
|
14
27
|
id: String(++mountCounter),
|
|
@@ -36,10 +49,13 @@ async function mount(componentName, props) {
|
|
|
36
49
|
});
|
|
37
50
|
await device.launchApp({ newInstance: true, launchArgs });
|
|
38
51
|
appLaunched = true;
|
|
52
|
+
await waitFor(element(by.id('detox-mount-id'))).toHaveText(payload.id).withTimeout(5000);
|
|
53
|
+
await assertNoRenderError();
|
|
39
54
|
return;
|
|
40
55
|
}
|
|
41
56
|
await element(by.id('detox-harness-control')).replaceText(JSON.stringify(payload));
|
|
42
57
|
await waitFor(element(by.id('detox-mount-id'))).toHaveText(payload.id).withTimeout(5000);
|
|
58
|
+
await assertNoRenderError();
|
|
43
59
|
}
|
|
44
60
|
function expectSpy(name) {
|
|
45
61
|
// Detox's expect is injected as a global by the test environment.
|
package/dist/mount.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mount.js","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":";;AAgBA,kBAEC;AAID,
|
|
1
|
+
{"version":3,"file":"mount.js","sourceRoot":"","sources":["../src/mount.ts"],"names":[],"mappings":"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"}
|
package/dist/test.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { mount, spy, expectSpy, SpyMarker, SpyExpectation } from './mount';
|
|
1
|
+
export { mount, spy, expectSpy, assertNoRenderError, SpyMarker, SpyExpectation } from './mount';
|
|
2
2
|
//# sourceMappingURL=test.d.ts.map
|
package/dist/test.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,mBAAmB,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/test.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.expectSpy = exports.spy = exports.mount = void 0;
|
|
3
|
+
exports.assertNoRenderError = exports.expectSpy = exports.spy = exports.mount = void 0;
|
|
4
4
|
var mount_1 = require("./mount");
|
|
5
5
|
Object.defineProperty(exports, "mount", { enumerable: true, get: function () { return mount_1.mount; } });
|
|
6
6
|
Object.defineProperty(exports, "spy", { enumerable: true, get: function () { return mount_1.spy; } });
|
|
7
7
|
Object.defineProperty(exports, "expectSpy", { enumerable: true, get: function () { return mount_1.expectSpy; } });
|
|
8
|
+
Object.defineProperty(exports, "assertNoRenderError", { enumerable: true, get: function () { return mount_1.assertNoRenderError; } });
|
|
8
9
|
//# sourceMappingURL=test.js.map
|
package/dist/test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.js","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../src/test.ts"],"names":[],"mappings":";;;AAAA,iCAAgG;AAAvF,8FAAA,KAAK,OAAA;AAAE,4FAAA,GAAG,OAAA;AAAE,kGAAA,SAAS,OAAA;AAAE,4GAAA,mBAAmB,OAAA"}
|
package/package.json
CHANGED
package/src/ComponentHarness.tsx
CHANGED
|
@@ -1,9 +1,34 @@
|
|
|
1
|
-
import React, { useState, useRef, useCallback } from 'react';
|
|
2
|
-
import { View, Text, TextInput } from 'react-native';
|
|
1
|
+
import React, { Component as ReactComponent, useState, useRef, useCallback, ReactNode } from 'react';
|
|
2
|
+
import { View, Text, TextInput, ScrollView } from 'react-native';
|
|
3
3
|
import { LaunchArguments } from 'react-native-launch-arguments';
|
|
4
4
|
import { getComponent } from './ComponentRegistry';
|
|
5
5
|
import { getWrapper } from './configureHarness';
|
|
6
6
|
|
|
7
|
+
interface ErrorBoundaryState {
|
|
8
|
+
error: Error | null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
class RenderErrorBoundary extends ReactComponent<{ children: ReactNode }, ErrorBoundaryState> {
|
|
12
|
+
state: ErrorBoundaryState = { error: null };
|
|
13
|
+
|
|
14
|
+
static getDerivedStateFromError(error: Error) {
|
|
15
|
+
return { error };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
render() {
|
|
19
|
+
if (this.state.error) {
|
|
20
|
+
return (
|
|
21
|
+
<ScrollView testID="detox-render-error">
|
|
22
|
+
<Text testID="detox-render-error-message">
|
|
23
|
+
{this.state.error.message}
|
|
24
|
+
</Text>
|
|
25
|
+
</ScrollView>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
return this.props.children;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
7
32
|
const PROP_PREFIX = 'detoxProp_';
|
|
8
33
|
const SPY_PREFIX = 'detoxSpy_';
|
|
9
34
|
|
|
@@ -104,7 +129,9 @@ function ComponentRenderer({ mount }: { mount: MountPayload }) {
|
|
|
104
129
|
<Wrapper launchArgs={mount.props || {}}>
|
|
105
130
|
<View testID="component-harness-root" style={{ flex: 1 }}>
|
|
106
131
|
<Text testID="detox-mount-id" style={{ height: 1 }}>{mount.id}</Text>
|
|
107
|
-
<
|
|
132
|
+
<RenderErrorBoundary>
|
|
133
|
+
<Component {...props} />
|
|
134
|
+
</RenderErrorBoundary>
|
|
108
135
|
{spyNames.map(name => (
|
|
109
136
|
<View key={name}>
|
|
110
137
|
<Text testID={`spy-${name}-count`}>{String(spyData[name].count)}</Text>
|
package/src/mount.ts
CHANGED
|
@@ -20,6 +20,18 @@ export function spy(name: string): SpyMarker {
|
|
|
20
20
|
|
|
21
21
|
type MountProps = Record<string, string | number | boolean | SpyMarker>;
|
|
22
22
|
|
|
23
|
+
export async function assertNoRenderError(): Promise<void> {
|
|
24
|
+
try {
|
|
25
|
+
await waitFor(element(by.id('detox-render-error'))).toExist().withTimeout(0);
|
|
26
|
+
} catch {
|
|
27
|
+
return; // Element not found — no render error, all good
|
|
28
|
+
}
|
|
29
|
+
// Element exists — read the error message and throw
|
|
30
|
+
const attrs = await element(by.id('detox-render-error-message')).getAttributes() as any;
|
|
31
|
+
const message = attrs.text || attrs.label || 'Unknown render error';
|
|
32
|
+
throw new Error(`Component render error: ${message}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
23
35
|
export async function mount(componentName: string, props?: MountProps): Promise<void> {
|
|
24
36
|
|
|
25
37
|
const payload = {
|
|
@@ -49,11 +61,14 @@ export async function mount(componentName: string, props?: MountProps): Promise<
|
|
|
49
61
|
});
|
|
50
62
|
await device.launchApp({ newInstance: true, launchArgs });
|
|
51
63
|
appLaunched = true;
|
|
64
|
+
await waitFor(element(by.id('detox-mount-id'))).toHaveText(payload.id).withTimeout(5000);
|
|
65
|
+
await assertNoRenderError();
|
|
52
66
|
return;
|
|
53
67
|
}
|
|
54
68
|
|
|
55
69
|
await element(by.id('detox-harness-control')).replaceText(JSON.stringify(payload));
|
|
56
70
|
await waitFor(element(by.id('detox-mount-id'))).toHaveText(payload.id).withTimeout(5000);
|
|
71
|
+
await assertNoRenderError();
|
|
57
72
|
}
|
|
58
73
|
|
|
59
74
|
export function expectSpy(name: string): SpyExpectation {
|
package/src/test.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { mount, spy, expectSpy, SpyMarker, SpyExpectation } from './mount';
|
|
1
|
+
export { mount, spy, expectSpy, assertNoRenderError, SpyMarker, SpyExpectation } from './mount';
|