execbro 1.10.23 → 1.10.25
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 +2 -1
- package/build/__tests__/helpers/fake-cdp-server.d.ts +9 -0
- package/build/__tests__/helpers/fake-cdp-server.d.ts.map +1 -1
- package/build/__tests__/helpers/fake-cdp-server.js +20 -2
- package/build/__tests__/helpers/fake-cdp-server.js.map +1 -1
- package/build/__tests__/integration/connection-health.test.js +8 -1
- package/build/__tests__/integration/connection-health.test.js.map +1 -1
- package/build/__tests__/integration/socket-close-midflight.test.d.ts +2 -0
- package/build/__tests__/integration/socket-close-midflight.test.d.ts.map +1 -0
- package/build/__tests__/integration/socket-close-midflight.test.js +106 -0
- package/build/__tests__/integration/socket-close-midflight.test.js.map +1 -0
- package/build/__tests__/integration/stale-target-probe.test.d.ts +2 -0
- package/build/__tests__/integration/stale-target-probe.test.d.ts.map +1 -0
- package/build/__tests__/integration/stale-target-probe.test.js +85 -0
- package/build/__tests__/integration/stale-target-probe.test.js.map +1 -0
- package/build/__tests__/unit/componentSource.test.d.ts +2 -0
- package/build/__tests__/unit/componentSource.test.d.ts.map +1 -0
- package/build/__tests__/unit/componentSource.test.js +67 -0
- package/build/__tests__/unit/componentSource.test.js.map +1 -0
- package/build/__tests__/unit/componentSourceResolve.test.d.ts +2 -0
- package/build/__tests__/unit/componentSourceResolve.test.d.ts.map +1 -0
- package/build/__tests__/unit/componentSourceResolve.test.js +91 -0
- package/build/__tests__/unit/componentSourceResolve.test.js.map +1 -0
- package/build/__tests__/unit/deviceResolution.test.d.ts +2 -0
- package/build/__tests__/unit/deviceResolution.test.d.ts.map +1 -0
- package/build/__tests__/unit/deviceResolution.test.js +108 -0
- package/build/__tests__/unit/deviceResolution.test.js.map +1 -0
- package/build/__tests__/unit/executor.test.js +48 -12
- package/build/__tests__/unit/executor.test.js.map +1 -1
- package/build/__tests__/unit/getLogsEmptyContract.test.d.ts +2 -0
- package/build/__tests__/unit/getLogsEmptyContract.test.d.ts.map +1 -0
- package/build/__tests__/unit/getLogsEmptyContract.test.js +99 -0
- package/build/__tests__/unit/getLogsEmptyContract.test.js.map +1 -0
- package/build/__tests__/unit/inspectorHarvest.test.d.ts +2 -0
- package/build/__tests__/unit/inspectorHarvest.test.d.ts.map +1 -0
- package/build/__tests__/unit/inspectorHarvest.test.js +61 -0
- package/build/__tests__/unit/inspectorHarvest.test.js.map +1 -0
- package/build/__tests__/unit/inspectorSource.test.d.ts +2 -0
- package/build/__tests__/unit/inspectorSource.test.d.ts.map +1 -0
- package/build/__tests__/unit/inspectorSource.test.js +74 -0
- package/build/__tests__/unit/inspectorSource.test.js.map +1 -0
- package/build/__tests__/unit/logDiagnosis.test.d.ts +2 -0
- package/build/__tests__/unit/logDiagnosis.test.d.ts.map +1 -0
- package/build/__tests__/unit/logDiagnosis.test.js +81 -0
- package/build/__tests__/unit/logDiagnosis.test.js.map +1 -0
- package/build/__tests__/unit/pendingExecutions.test.d.ts +2 -0
- package/build/__tests__/unit/pendingExecutions.test.d.ts.map +1 -0
- package/build/__tests__/unit/pendingExecutions.test.js +70 -0
- package/build/__tests__/unit/pendingExecutions.test.js.map +1 -0
- package/build/__tests__/unit/reloadAppAutoConnect.test.d.ts +2 -0
- package/build/__tests__/unit/reloadAppAutoConnect.test.d.ts.map +1 -0
- package/build/__tests__/unit/reloadAppAutoConnect.test.js +63 -0
- package/build/__tests__/unit/reloadAppAutoConnect.test.js.map +1 -0
- package/build/__tests__/unit/selectionBuffer.test.d.ts +2 -0
- package/build/__tests__/unit/selectionBuffer.test.d.ts.map +1 -0
- package/build/__tests__/unit/selectionBuffer.test.js +86 -0
- package/build/__tests__/unit/selectionBuffer.test.js.map +1 -0
- package/build/__tests__/unit/selectionPoller.test.d.ts +2 -0
- package/build/__tests__/unit/selectionPoller.test.d.ts.map +1 -0
- package/build/__tests__/unit/selectionPoller.test.js +109 -0
- package/build/__tests__/unit/selectionPoller.test.js.map +1 -0
- package/build/__tests__/unit/symbolicate.test.d.ts +2 -0
- package/build/__tests__/unit/symbolicate.test.d.ts.map +1 -0
- package/build/__tests__/unit/symbolicate.test.js +154 -0
- package/build/__tests__/unit/symbolicate.test.js.map +1 -0
- package/build/__tests__/unit/transportClassify.test.js +108 -7
- package/build/__tests__/unit/transportClassify.test.js.map +1 -1
- package/build/core/componentSource.d.ts +62 -0
- package/build/core/componentSource.d.ts.map +1 -0
- package/build/core/componentSource.js +268 -0
- package/build/core/componentSource.js.map +1 -0
- package/build/core/connection.d.ts +30 -0
- package/build/core/connection.d.ts.map +1 -1
- package/build/core/connection.js +101 -28
- package/build/core/connection.js.map +1 -1
- package/build/core/debugGlobals.d.ts.map +1 -1
- package/build/core/debugGlobals.js +89 -32
- package/build/core/debugGlobals.js.map +1 -1
- package/build/core/errors.d.ts +7 -1
- package/build/core/errors.d.ts.map +1 -1
- package/build/core/errors.js +8 -1
- package/build/core/errors.js.map +1 -1
- package/build/core/guides.js +1 -1
- package/build/core/index.d.ts +4 -1
- package/build/core/index.d.ts.map +1 -1
- package/build/core/index.js +4 -1
- package/build/core/index.js.map +1 -1
- package/build/core/inspector.d.ts +24 -0
- package/build/core/inspector.d.ts.map +1 -1
- package/build/core/inspector.js +58 -0
- package/build/core/inspector.js.map +1 -1
- package/build/core/jsExecute.d.ts +76 -1
- package/build/core/jsExecute.d.ts.map +1 -1
- package/build/core/jsExecute.js +193 -32
- package/build/core/jsExecute.js.map +1 -1
- package/build/core/logDiagnosis.d.ts +65 -0
- package/build/core/logDiagnosis.d.ts.map +1 -0
- package/build/core/logDiagnosis.js +51 -0
- package/build/core/logDiagnosis.js.map +1 -0
- package/build/core/register.d.ts.map +1 -1
- package/build/core/register.js +22 -6
- package/build/core/register.js.map +1 -1
- package/build/core/selectionBuffer.d.ts +42 -0
- package/build/core/selectionBuffer.d.ts.map +1 -0
- package/build/core/selectionBuffer.js +51 -0
- package/build/core/selectionBuffer.js.map +1 -0
- package/build/core/selectionPoller.d.ts +13 -0
- package/build/core/selectionPoller.d.ts.map +1 -0
- package/build/core/selectionPoller.js +102 -0
- package/build/core/selectionPoller.js.map +1 -0
- package/build/core/state.d.ts +10 -0
- package/build/core/state.d.ts.map +1 -1
- package/build/core/state.js +21 -0
- package/build/core/state.js.map +1 -1
- package/build/core/symbolicate.d.ts +18 -0
- package/build/core/symbolicate.d.ts.map +1 -0
- package/build/core/symbolicate.js +119 -0
- package/build/core/symbolicate.js.map +1 -0
- package/build/core/types.d.ts +8 -0
- package/build/core/types.d.ts.map +1 -1
- package/build/tools/componentTools.d.ts.map +1 -1
- package/build/tools/componentTools.js +78 -9
- package/build/tools/componentTools.js.map +1 -1
- package/build/tools/connectionTools.d.ts.map +1 -1
- package/build/tools/connectionTools.js +10 -4
- package/build/tools/connectionTools.js.map +1 -1
- package/build/tools/executionTools.js +7 -7
- package/build/tools/executionTools.js.map +1 -1
- package/build/tools/interactionTools.d.ts.map +1 -1
- package/build/tools/interactionTools.js +1 -0
- package/build/tools/interactionTools.js.map +1 -1
- package/build/tools/logTools.d.ts.map +1 -1
- package/build/tools/logTools.js +77 -69
- package/build/tools/logTools.js.map +1 -1
- package/build/tools/networkTools.d.ts.map +1 -1
- package/build/tools/networkTools.js +63 -13
- package/build/tools/networkTools.js.map +1 -1
- package/build/tools/screenshotTools.d.ts.map +1 -1
- package/build/tools/screenshotTools.js +3 -0
- package/build/tools/screenshotTools.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, jest } from "@jest/globals";
|
|
2
|
+
import { parseStackString, symbolicateFrames, firstUserFrame, clearSymbolicateCache, } from "../../core/symbolicate.js";
|
|
3
|
+
const BUNDLE = "http://192.168.0.102:8081/node_modules/expo/AppEntry.bundle//&platform=ios&dev=true&hot=false&lazy=true&transform.engine=hermes";
|
|
4
|
+
const REAL_STACK = [
|
|
5
|
+
"Error: react-stack-top-frame",
|
|
6
|
+
` at anonymous (${BUNDLE}:19648:90)`,
|
|
7
|
+
` at HomeScreen (${BUNDLE}:342013:64)`,
|
|
8
|
+
` at react_stack_bottom_frame (${BUNDLE}:31478:29)`,
|
|
9
|
+
].join("\n");
|
|
10
|
+
describe("parseStackString", () => {
|
|
11
|
+
it("parses named frames with URL, line and column", () => {
|
|
12
|
+
const frames = parseStackString(REAL_STACK);
|
|
13
|
+
expect(frames[0]).toEqual({
|
|
14
|
+
file: BUNDLE,
|
|
15
|
+
lineNumber: 19648,
|
|
16
|
+
column: 90,
|
|
17
|
+
methodName: "anonymous",
|
|
18
|
+
});
|
|
19
|
+
expect(frames[1].methodName).toBe("HomeScreen");
|
|
20
|
+
expect(frames[1].lineNumber).toBe(342013);
|
|
21
|
+
});
|
|
22
|
+
it("does not split on the colon inside http://", () => {
|
|
23
|
+
const frames = parseStackString(REAL_STACK);
|
|
24
|
+
expect(frames[0].file).toBe(BUNDLE);
|
|
25
|
+
expect(frames[0].file.startsWith("http://")).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
it("skips the leading Error: line", () => {
|
|
28
|
+
const frames = parseStackString(REAL_STACK);
|
|
29
|
+
expect(frames.every((f) => f.methodName !== null)).toBe(true);
|
|
30
|
+
expect(frames.length).toBe(3);
|
|
31
|
+
});
|
|
32
|
+
it("parses anonymous frames with no method name", () => {
|
|
33
|
+
const frames = parseStackString(` at ${BUNDLE}:100:5`);
|
|
34
|
+
expect(frames[0]).toEqual({
|
|
35
|
+
file: BUNDLE,
|
|
36
|
+
lineNumber: 100,
|
|
37
|
+
column: 5,
|
|
38
|
+
methodName: null,
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
it("honours the limit argument", () => {
|
|
42
|
+
expect(parseStackString(REAL_STACK, 2).length).toBe(2);
|
|
43
|
+
});
|
|
44
|
+
it("returns an empty array for junk input", () => {
|
|
45
|
+
expect(parseStackString("")).toEqual([]);
|
|
46
|
+
expect(parseStackString("not a stack at all")).toEqual([]);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
describe("firstUserFrame", () => {
|
|
50
|
+
it("returns the first frame not marked collapse", () => {
|
|
51
|
+
const frame = firstUserFrame([
|
|
52
|
+
{ file: "/x/node_modules/react/a.js", lineNumber: 1, column: 1, methodName: "jsx", collapse: true },
|
|
53
|
+
{ file: "/x/src/Home.tsx", lineNumber: 105, column: 10, methodName: "HomeScreen", collapse: false },
|
|
54
|
+
]);
|
|
55
|
+
expect(frame.file).toBe("/x/src/Home.tsx");
|
|
56
|
+
expect(frame.lineNumber).toBe(105);
|
|
57
|
+
});
|
|
58
|
+
it("returns null when every frame is collapsed", () => {
|
|
59
|
+
const frame = firstUserFrame([
|
|
60
|
+
{ file: "/x/node_modules/react/a.js", lineNumber: 1, column: 1, methodName: "jsx", collapse: true },
|
|
61
|
+
]);
|
|
62
|
+
expect(frame).toBeNull();
|
|
63
|
+
});
|
|
64
|
+
it("returns null for an empty list", () => {
|
|
65
|
+
expect(firstUserFrame([])).toBeNull();
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe("symbolicateFrames", () => {
|
|
69
|
+
beforeEach(() => {
|
|
70
|
+
clearSymbolicateCache();
|
|
71
|
+
globalThis.fetch = jest.fn();
|
|
72
|
+
});
|
|
73
|
+
it("POSTs to localhost on the port taken from the frame URL", async () => {
|
|
74
|
+
globalThis.fetch.mockResolvedValue({
|
|
75
|
+
ok: true,
|
|
76
|
+
json: async () => ({
|
|
77
|
+
stack: [
|
|
78
|
+
{ file: "/x/src/Home.tsx", lineNumber: 105, column: 10, methodName: "HomeScreen", collapse: false },
|
|
79
|
+
],
|
|
80
|
+
}),
|
|
81
|
+
});
|
|
82
|
+
await symbolicateFrames([
|
|
83
|
+
{ file: BUNDLE, lineNumber: 342013, column: 64, methodName: "HomeScreen" },
|
|
84
|
+
]);
|
|
85
|
+
const [url, init] = globalThis.fetch.mock.calls[0];
|
|
86
|
+
expect(url).toBe("http://127.0.0.1:8081/symbolicate");
|
|
87
|
+
expect(init.method).toBe("POST");
|
|
88
|
+
// The file field must be sent verbatim — Metro matches it against its bundle registry.
|
|
89
|
+
expect(JSON.parse(init.body).stack[0].file).toBe(BUNDLE);
|
|
90
|
+
});
|
|
91
|
+
it("returns symbolicated frames with the collapse flag", async () => {
|
|
92
|
+
globalThis.fetch.mockResolvedValue({
|
|
93
|
+
ok: true,
|
|
94
|
+
json: async () => ({
|
|
95
|
+
stack: [
|
|
96
|
+
{ file: "/x/src/Home.tsx", lineNumber: 105, column: 10, methodName: "HomeScreen", collapse: false },
|
|
97
|
+
],
|
|
98
|
+
}),
|
|
99
|
+
});
|
|
100
|
+
const out = await symbolicateFrames([
|
|
101
|
+
{ file: BUNDLE, lineNumber: 342013, column: 64, methodName: "HomeScreen" },
|
|
102
|
+
]);
|
|
103
|
+
expect(out).toEqual([
|
|
104
|
+
{ file: "/x/src/Home.tsx", lineNumber: 105, column: 10, methodName: "HomeScreen", collapse: false },
|
|
105
|
+
]);
|
|
106
|
+
});
|
|
107
|
+
it("defaults collapse to false when Metro omits it", async () => {
|
|
108
|
+
globalThis.fetch.mockResolvedValue({
|
|
109
|
+
ok: true,
|
|
110
|
+
json: async () => ({ stack: [{ file: "/x/a.tsx", lineNumber: 1, column: 2, methodName: "A" }] }),
|
|
111
|
+
});
|
|
112
|
+
const out = await symbolicateFrames([{ file: BUNDLE, lineNumber: 1, column: 2, methodName: "A" }]);
|
|
113
|
+
expect(out[0].collapse).toBe(false);
|
|
114
|
+
});
|
|
115
|
+
it("serves a repeated frame from cache without a second fetch", async () => {
|
|
116
|
+
globalThis.fetch.mockResolvedValue({
|
|
117
|
+
ok: true,
|
|
118
|
+
json: async () => ({
|
|
119
|
+
stack: [{ file: "/x/src/Home.tsx", lineNumber: 105, column: 10, methodName: "HomeScreen", collapse: false }],
|
|
120
|
+
}),
|
|
121
|
+
});
|
|
122
|
+
const frame = { file: BUNDLE, lineNumber: 342013, column: 64, methodName: "HomeScreen" };
|
|
123
|
+
await symbolicateFrames([frame]);
|
|
124
|
+
const second = await symbolicateFrames([frame]);
|
|
125
|
+
expect(globalThis.fetch.mock.calls.length).toBe(1);
|
|
126
|
+
expect(second[0].file).toBe("/x/src/Home.tsx");
|
|
127
|
+
});
|
|
128
|
+
it("returns null when Metro is unreachable", async () => {
|
|
129
|
+
globalThis.fetch.mockRejectedValue(new Error("ECONNREFUSED"));
|
|
130
|
+
const out = await symbolicateFrames([{ file: BUNDLE, lineNumber: 1, column: 1, methodName: "A" }]);
|
|
131
|
+
expect(out).toBeNull();
|
|
132
|
+
});
|
|
133
|
+
it("returns null on a non-ok response", async () => {
|
|
134
|
+
globalThis.fetch.mockResolvedValue({ ok: false, status: 500, json: async () => ({}) });
|
|
135
|
+
const out = await symbolicateFrames([{ file: BUNDLE, lineNumber: 1, column: 1, methodName: "A" }]);
|
|
136
|
+
expect(out).toBeNull();
|
|
137
|
+
});
|
|
138
|
+
it("returns an empty array without fetching when given no frames", async () => {
|
|
139
|
+
const out = await symbolicateFrames([]);
|
|
140
|
+
expect(out).toEqual([]);
|
|
141
|
+
expect(globalThis.fetch.mock.calls.length).toBe(0);
|
|
142
|
+
});
|
|
143
|
+
it("falls back to the frame origin when the URL has no port", async () => {
|
|
144
|
+
globalThis.fetch.mockResolvedValue({
|
|
145
|
+
ok: true,
|
|
146
|
+
json: async () => ({ stack: [{ file: "/a.tsx", lineNumber: 1, column: 1, methodName: "A", collapse: false }] }),
|
|
147
|
+
});
|
|
148
|
+
await symbolicateFrames([
|
|
149
|
+
{ file: "http://example.com/bundle.js", lineNumber: 1, column: 1, methodName: "A" },
|
|
150
|
+
]);
|
|
151
|
+
expect(globalThis.fetch.mock.calls[0][0]).toBe("http://example.com/symbolicate");
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
//# sourceMappingURL=symbolicate.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"symbolicate.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/symbolicate.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,93 @@
|
|
|
1
1
|
import { describe, expect, it } from "@jest/globals";
|
|
2
|
-
import {
|
|
2
|
+
import { jest } from "@jest/globals";
|
|
3
|
+
import { classifyTransportError, isEvalTimeoutOnLiveSocket, classifyWithLivenessProbe, isTargetStillAdvertised } from "../../core/jsExecute.js";
|
|
4
|
+
// A "took too long" on a socket that is still OPEN is ambiguous: either the
|
|
5
|
+
// expression really was slow, or the CDP target went stale while the
|
|
6
|
+
// device-level socket kept answering pings. Only these cases are worth paying
|
|
7
|
+
// for a probe to disambiguate.
|
|
8
|
+
describe("isEvalTimeoutOnLiveSocket", () => {
|
|
9
|
+
const timeoutMsg = (ws) => `Timeout: Expression took too long to evaluate.\n\nConnection state: ws=${ws}, device="iPhone"`;
|
|
10
|
+
it("is true for a server-timer timeout on an open socket", () => {
|
|
11
|
+
expect(isEvalTimeoutOnLiveSocket(timeoutMsg("OPEN"), "server-timer")).toBe(true);
|
|
12
|
+
});
|
|
13
|
+
it("is false when the socket was closed (already a transport error)", () => {
|
|
14
|
+
expect(isEvalTimeoutOnLiveSocket(timeoutMsg("CLOSED"), "server-timer")).toBe(false);
|
|
15
|
+
});
|
|
16
|
+
it("is false for errors that did not come from the server timer", () => {
|
|
17
|
+
expect(isEvalTimeoutOnLiveSocket(timeoutMsg("OPEN"), "cdp")).toBe(false);
|
|
18
|
+
});
|
|
19
|
+
it("is false for unrelated failures", () => {
|
|
20
|
+
expect(isEvalTimeoutOnLiveSocket("ReferenceError: x is not defined", "logical")).toBe(false);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
// The probe-backed upgrade lives behind an injectable seam so this can be
|
|
24
|
+
// exercised without a real socket. Driving it through executeInApp instead
|
|
25
|
+
// would reach attemptQuickReconnect -> scanMetroPorts(), which scans real
|
|
26
|
+
// localhost ports and would latch onto whatever Metro the developer has running.
|
|
27
|
+
describe("classifyWithLivenessProbe", () => {
|
|
28
|
+
const timeoutMsg = (ws) => `Timeout: Expression took too long to evaluate.\n\nConnection state: ws=${ws}, device="iPhone"`;
|
|
29
|
+
const fakeApp = { ws: {}, port: 8081, deviceInfo: { id: "page-1" } };
|
|
30
|
+
const listed = async () => true;
|
|
31
|
+
const gone = async () => false;
|
|
32
|
+
it("keeps a ws=OPEN timeout logical when the probe answers", async () => {
|
|
33
|
+
const probe = jest.fn(async () => true);
|
|
34
|
+
const result = await classifyWithLivenessProbe(timeoutMsg("OPEN"), "server-timer", fakeApp, probe, gone);
|
|
35
|
+
expect(result).toEqual({ kind: "logical" });
|
|
36
|
+
expect(probe).toHaveBeenCalledTimes(1);
|
|
37
|
+
});
|
|
38
|
+
// The case that bit us on-device: a 15s busy loop silences the probe just
|
|
39
|
+
// like a dead context would. Metro still lists the page, so this must stay
|
|
40
|
+
// logical — upgrading it triggers a retry that re-runs the expression.
|
|
41
|
+
it("keeps a blocked JS thread logical while Metro still lists the target", async () => {
|
|
42
|
+
const probe = jest.fn(async () => false);
|
|
43
|
+
const result = await classifyWithLivenessProbe(timeoutMsg("OPEN"), "server-timer", fakeApp, probe, listed);
|
|
44
|
+
expect(result).toEqual({ kind: "logical" });
|
|
45
|
+
});
|
|
46
|
+
it("upgrades to stale_target only when the probe is silent AND the target is gone", async () => {
|
|
47
|
+
const probe = jest.fn(async () => false);
|
|
48
|
+
const result = await classifyWithLivenessProbe(timeoutMsg("OPEN"), "server-timer", fakeApp, probe, gone);
|
|
49
|
+
expect(result).toEqual({ kind: "transport", pattern: "stale_target" });
|
|
50
|
+
});
|
|
51
|
+
it("does not spend a probe when the socket was already closed", async () => {
|
|
52
|
+
const probe = jest.fn(async () => false);
|
|
53
|
+
const result = await classifyWithLivenessProbe(timeoutMsg("CLOSED"), "server-timer", fakeApp, probe, gone);
|
|
54
|
+
expect(result).toMatchObject({ kind: "transport", pattern: "ws_closed" });
|
|
55
|
+
expect(probe).not.toHaveBeenCalled();
|
|
56
|
+
});
|
|
57
|
+
it("does not spend a probe on unrelated logical errors", async () => {
|
|
58
|
+
const probe = jest.fn(async () => false);
|
|
59
|
+
const result = await classifyWithLivenessProbe("ReferenceError: x", "logical", fakeApp, probe, gone);
|
|
60
|
+
expect(result).toEqual({ kind: "logical" });
|
|
61
|
+
expect(probe).not.toHaveBeenCalled();
|
|
62
|
+
});
|
|
63
|
+
it("stays logical when there is no app to probe", async () => {
|
|
64
|
+
const probe = jest.fn(async () => false);
|
|
65
|
+
const result = await classifyWithLivenessProbe(timeoutMsg("OPEN"), "server-timer", null, probe, gone);
|
|
66
|
+
expect(result).toEqual({ kind: "logical" });
|
|
67
|
+
expect(probe).not.toHaveBeenCalled();
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
describe("isTargetStillAdvertised", () => {
|
|
71
|
+
const app = { port: 8081, deviceInfo: { id: "page-1" } };
|
|
72
|
+
it("is true when Metro still lists our page id", async () => {
|
|
73
|
+
const fetchTargets = async () => [{ id: "page-1" }, { id: "page-2" }];
|
|
74
|
+
expect(await isTargetStillAdvertised(app, fetchTargets)).toBe(true);
|
|
75
|
+
});
|
|
76
|
+
it("is false when Metro lists other pages but not ours", async () => {
|
|
77
|
+
const fetchTargets = async () => [{ id: "page-9" }];
|
|
78
|
+
expect(await isTargetStillAdvertised(app, fetchTargets)).toBe(false);
|
|
79
|
+
});
|
|
80
|
+
// fetchDevices returns [] on any network error. Treating that as "gone"
|
|
81
|
+
// would let a Metro blip trigger a reconnect that re-runs the expression.
|
|
82
|
+
it("is true when the target list comes back empty", async () => {
|
|
83
|
+
const fetchTargets = async () => [];
|
|
84
|
+
expect(await isTargetStillAdvertised(app, fetchTargets)).toBe(true);
|
|
85
|
+
});
|
|
86
|
+
it("is true when we have no page id to compare", async () => {
|
|
87
|
+
const fetchTargets = async () => [{ id: "page-9" }];
|
|
88
|
+
expect(await isTargetStillAdvertised({ port: 8081, deviceInfo: {} }, fetchTargets)).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
3
91
|
describe("classifyTransportError — positive cases", () => {
|
|
4
92
|
it("matches 'No apps connected'", () => {
|
|
5
93
|
expect(classifyTransportError("No apps connected. Run 'scan_metro' first.", "logical")).toMatchObject({
|
|
@@ -31,18 +119,31 @@ describe("classifyTransportError — positive cases", () => {
|
|
|
31
119
|
pattern: "target_closed",
|
|
32
120
|
});
|
|
33
121
|
});
|
|
34
|
-
it("matches CDP-side 'Expression took too long to evaluate'", () => {
|
|
35
|
-
expect(classifyTransportError("Expression took too long to evaluate", "cdp")).toMatchObject({
|
|
36
|
-
kind: "transport",
|
|
37
|
-
pattern: "cdp_eval_too_long",
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
122
|
});
|
|
41
123
|
describe("classifyTransportError — negative cases (must NOT auto-retry)", () => {
|
|
42
124
|
it("does NOT match server-side timer text", () => {
|
|
43
125
|
const serverTimerMsg = "Timeout: Expression took too long to evaluate.\n\nConnection state: ws=OPEN...";
|
|
44
126
|
expect(classifyTransportError(serverTimerMsg, "server-timer")).toEqual({ kind: "logical" });
|
|
45
127
|
});
|
|
128
|
+
// Backstop for the race where our timer fires before the socket's close
|
|
129
|
+
// handler has failed the in-flight call. A timer expiry is only "logical"
|
|
130
|
+
// if the transport was actually alive when it fired.
|
|
131
|
+
it("DOES match server-timer text when the socket was already closed", () => {
|
|
132
|
+
const closedMsg = "Timeout: Expression took too long to evaluate.\n\nConnection state: ws=CLOSED, device=\"iPhone\"";
|
|
133
|
+
expect(classifyTransportError(closedMsg, "server-timer")).toMatchObject({
|
|
134
|
+
kind: "transport",
|
|
135
|
+
pattern: "ws_closed",
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
// "took too long" on a live socket is a slow expression, not a dead
|
|
139
|
+
// transport — the 1s ping/pong keepalive terminates genuinely dead sockets
|
|
140
|
+
// within ~2s, so anything still OPEN after a multi-second timeout had a
|
|
141
|
+
// working transport the whole time. Retrying it just burns the timeout again.
|
|
142
|
+
it("does NOT match an eval-too-long message while the socket is alive", () => {
|
|
143
|
+
expect(classifyTransportError("Expression took too long to evaluate", "cdp")).toEqual({
|
|
144
|
+
kind: "logical",
|
|
145
|
+
});
|
|
146
|
+
});
|
|
46
147
|
it("does NOT match 'no component matched'", () => {
|
|
47
148
|
expect(classifyTransportError("No component matched pattern Foo", "logical")).toEqual({ kind: "logical" });
|
|
48
149
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transportClassify.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/transportClassify.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"transportClassify.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/transportClassify.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ComponentStack, SelectionFrame } from "./selectionBuffer.js";
|
|
2
|
+
export interface ProbeResult {
|
|
3
|
+
active: boolean;
|
|
4
|
+
selected: boolean;
|
|
5
|
+
changed: boolean;
|
|
6
|
+
element?: string;
|
|
7
|
+
path?: string;
|
|
8
|
+
hierarchy?: string[];
|
|
9
|
+
frame?: SelectionFrame | null;
|
|
10
|
+
style?: Record<string, unknown> | null;
|
|
11
|
+
}
|
|
12
|
+
export interface HarvestResult {
|
|
13
|
+
stacks: ComponentStack[];
|
|
14
|
+
error?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Cheap per-tick probe. Deliberately does NO measurement — it runs every
|
|
18
|
+
* 500-2000ms and must stay inexpensive. Reports whether RN's inspector is
|
|
19
|
+
* mounted and whether its selection changed since the previous tick.
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildSelectionProbeExpression(): string;
|
|
22
|
+
/**
|
|
23
|
+
* Hit-tests at (x, y) and harvests raw _debugStack strings up the return chain.
|
|
24
|
+
* Measures host fibers, so this runs only when the probe reports a change -
|
|
25
|
+
* once per tap, never per tick.
|
|
26
|
+
*
|
|
27
|
+
* Prefers _debugSource when present (React < 19, already source coordinates);
|
|
28
|
+
* otherwise emits the raw _debugStack string for host-side symbolication.
|
|
29
|
+
*
|
|
30
|
+
* The cap is deliberately generous. Real trees bury the nearest user component
|
|
31
|
+
* deep behind library wrappers - measured on a production app, a tapped SearchBar
|
|
32
|
+
* sat 12 ancestors above the hit fiber (SVG icon, Pressable and View wrappers in
|
|
33
|
+
* between) and HomeScreen sat at 22. Collapsed library frames are dropped
|
|
34
|
+
* host-side, so a larger walk improves recall without bloating the output; the
|
|
35
|
+
* extra frames cost nothing beyond one batched, cached symbolicate request.
|
|
36
|
+
*/
|
|
37
|
+
export declare function buildDebugStackHarvestExpression(x: number, y: number, maxAncestors?: number): string;
|
|
38
|
+
export interface RawComponentStack {
|
|
39
|
+
component: string;
|
|
40
|
+
stack: string;
|
|
41
|
+
/** Present only on React < 19, where _debugSource still exists. */
|
|
42
|
+
file?: string;
|
|
43
|
+
lineNumber?: number;
|
|
44
|
+
column?: number;
|
|
45
|
+
}
|
|
46
|
+
export interface SourceLocation {
|
|
47
|
+
file: string;
|
|
48
|
+
line: number;
|
|
49
|
+
column: number;
|
|
50
|
+
}
|
|
51
|
+
export interface ResolvedAncestor {
|
|
52
|
+
component: string;
|
|
53
|
+
file: string;
|
|
54
|
+
line: number;
|
|
55
|
+
}
|
|
56
|
+
export interface ResolvedSource {
|
|
57
|
+
source: SourceLocation | null;
|
|
58
|
+
ancestors: ResolvedAncestor[];
|
|
59
|
+
sourceUnavailable?: string;
|
|
60
|
+
}
|
|
61
|
+
export declare function resolveStacksToSource(stacks: RawComponentStack[]): Promise<ResolvedSource>;
|
|
62
|
+
//# sourceMappingURL=componentSource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"componentSource.d.ts","sourceRoot":"","sources":["../../src/core/componentSource.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAI3E,MAAM,WAAW,WAAW;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1C;AAED,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAkBD;;;;GAIG;AACH,wBAAgB,6BAA6B,IAAI,MAAM,CAmEtD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gCAAgC,CAC5C,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,YAAY,GAAE,MAAW,GAC1B,MAAM,CAwGR;AAED,MAAM,WAAW,iBAAiB;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B;AASD,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CA2DhG"}
|