@buoy-gg/redux 7.0.29 → 7.0.31
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/lib/commonjs/index.js +25 -0
- package/lib/commonjs/redux/components/ReduxActionButton.js +3 -1
- package/lib/commonjs/redux/components/ReduxActionDetailContent.js +60 -6
- package/lib/commonjs/redux/components/ReduxActionInfoView.js +61 -12
- package/lib/commonjs/redux/components/ReduxActionItem.js +20 -5
- package/lib/commonjs/redux/components/ReduxDetailViewToggle.js +7 -0
- package/lib/commonjs/redux/components/ReduxModal.js +168 -32
- package/lib/commonjs/redux/utils/activeStoreRegistry.js +31 -0
- package/lib/commonjs/redux/utils/autoInstrument.js +23 -40
- package/lib/commonjs/redux/utils/buoyReduxMiddleware.js +36 -9
- package/lib/commonjs/redux/utils/devtoolsHook.js +4 -0
- package/lib/commonjs/redux/utils/testIDs.js +75 -0
- package/lib/module/index.js +5 -0
- package/lib/module/redux/components/ReduxActionButton.js +3 -1
- package/lib/module/redux/components/ReduxActionDetailContent.js +60 -6
- package/lib/module/redux/components/ReduxActionInfoView.js +63 -14
- package/lib/module/redux/components/ReduxActionItem.js +20 -5
- package/lib/module/redux/components/ReduxDetailViewToggle.js +7 -0
- package/lib/module/redux/components/ReduxModal.js +170 -33
- package/lib/module/redux/utils/activeStoreRegistry.js +29 -0
- package/lib/module/redux/utils/autoInstrument.js +8 -40
- package/lib/module/redux/utils/buoyReduxMiddleware.js +32 -10
- package/lib/module/redux/utils/devtoolsHook.js +5 -1
- package/lib/module/redux/utils/testIDs.js +68 -0
- package/lib/typescript/index.d.ts +1 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/redux/components/ReduxActionButton.d.ts +2 -1
- package/lib/typescript/redux/components/ReduxActionButton.d.ts.map +1 -1
- package/lib/typescript/redux/components/ReduxActionDetailContent.d.ts.map +1 -1
- package/lib/typescript/redux/components/ReduxActionInfoView.d.ts.map +1 -1
- package/lib/typescript/redux/components/ReduxActionItem.d.ts +15 -0
- package/lib/typescript/redux/components/ReduxActionItem.d.ts.map +1 -1
- package/lib/typescript/redux/components/ReduxDetailViewToggle.d.ts.map +1 -1
- package/lib/typescript/redux/components/ReduxModal.d.ts.map +1 -1
- package/lib/typescript/redux/utils/activeStoreRegistry.d.ts +27 -0
- package/lib/typescript/redux/utils/activeStoreRegistry.d.ts.map +1 -1
- package/lib/typescript/redux/utils/autoInstrument.d.ts +7 -11
- package/lib/typescript/redux/utils/autoInstrument.d.ts.map +1 -1
- package/lib/typescript/redux/utils/buoyReduxMiddleware.d.ts +17 -3
- package/lib/typescript/redux/utils/buoyReduxMiddleware.d.ts.map +1 -1
- package/lib/typescript/redux/utils/devtoolsHook.d.ts.map +1 -1
- package/lib/typescript/redux/utils/testIDs.d.ts +51 -0
- package/lib/typescript/redux/utils/testIDs.d.ts.map +1 -0
- package/package.json +4 -4
package/lib/commonjs/index.js
CHANGED
|
@@ -21,6 +21,12 @@ Object.defineProperty(exports, "FREE_TIER_ACTION_LIMIT", {
|
|
|
21
21
|
return _ReduxModal.FREE_TIER_ACTION_LIMIT;
|
|
22
22
|
}
|
|
23
23
|
});
|
|
24
|
+
Object.defineProperty(exports, "REDUX_TEST_ID", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _testIDs.REDUX_TEST_ID;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
24
30
|
Object.defineProperty(exports, "ReduxActionDetailContent", {
|
|
25
31
|
enumerable: true,
|
|
26
32
|
get: function () {
|
|
@@ -69,6 +75,18 @@ Object.defineProperty(exports, "ReduxToolView", {
|
|
|
69
75
|
return _ReduxModal.ReduxToolView;
|
|
70
76
|
}
|
|
71
77
|
});
|
|
78
|
+
Object.defineProperty(exports, "actionRowTestID", {
|
|
79
|
+
enumerable: true,
|
|
80
|
+
get: function () {
|
|
81
|
+
return _testIDs.actionRowTestID;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
Object.defineProperty(exports, "buildActionRowTestIDs", {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
get: function () {
|
|
87
|
+
return _testIDs.buildActionRowTestIDs;
|
|
88
|
+
}
|
|
89
|
+
});
|
|
72
90
|
Object.defineProperty(exports, "buoyDevtoolsEnhancer", {
|
|
73
91
|
enumerable: true,
|
|
74
92
|
get: function () {
|
|
@@ -183,6 +201,12 @@ Object.defineProperty(exports, "replayAction", {
|
|
|
183
201
|
return _buoyReduxMiddleware.replayAction;
|
|
184
202
|
}
|
|
185
203
|
});
|
|
204
|
+
Object.defineProperty(exports, "slugForTestID", {
|
|
205
|
+
enumerable: true,
|
|
206
|
+
get: function () {
|
|
207
|
+
return _testIDs.slugForTestID;
|
|
208
|
+
}
|
|
209
|
+
});
|
|
186
210
|
Object.defineProperty(exports, "uninstrumentStore", {
|
|
187
211
|
enumerable: true,
|
|
188
212
|
get: function () {
|
|
@@ -228,4 +252,5 @@ var _ReduxActionDetailView = require("./redux/components/ReduxActionDetailView")
|
|
|
228
252
|
var _ReduxActionDetailContent = require("./redux/components/ReduxActionDetailContent");
|
|
229
253
|
var _ReduxIcon = require("./redux/components/ReduxIcon");
|
|
230
254
|
var _ReduxAutoInstrument = require("./redux/components/ReduxAutoInstrument");
|
|
255
|
+
var _testIDs = require("./redux/utils/testIDs");
|
|
231
256
|
var _reduxActionStore = require("./redux/utils/reduxActionStore");
|
|
@@ -57,10 +57,12 @@ function ReduxActionButton({
|
|
|
57
57
|
onPress,
|
|
58
58
|
text,
|
|
59
59
|
type,
|
|
60
|
-
disabled = false
|
|
60
|
+
disabled = false,
|
|
61
|
+
testID
|
|
61
62
|
}) {
|
|
62
63
|
const config = buttonConfigs[type];
|
|
63
64
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
65
|
+
testID: testID,
|
|
64
66
|
disabled: disabled,
|
|
65
67
|
onPress: onPress,
|
|
66
68
|
style: [styles.button, {
|
|
@@ -11,6 +11,8 @@ var _sharedUi = require("@buoy-gg/shared-ui");
|
|
|
11
11
|
var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
|
|
12
12
|
var _ReduxDetailViewToggle = require("./ReduxDetailViewToggle");
|
|
13
13
|
var _ReduxActionInfoView = require("./ReduxActionInfoView");
|
|
14
|
+
var _testIDs = require("../utils/testIDs");
|
|
15
|
+
var _reduxActionStore = require("../utils/reduxActionStore");
|
|
14
16
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
15
17
|
/**
|
|
16
18
|
* ReduxActionDetailContent
|
|
@@ -89,6 +91,20 @@ function ReduxActionDetailContent({
|
|
|
89
91
|
const [activeView, setActiveView] = (0, _react.useState)(initialView);
|
|
90
92
|
const [diffMode, setDiffMode] = (0, _react.useState)("tree");
|
|
91
93
|
const totalActions = actions.length;
|
|
94
|
+
/**
|
|
95
|
+
* The state trees this action was recorded with are gone.
|
|
96
|
+
*
|
|
97
|
+
* Not a failure: the store keeps raw prev/next state for the most recent
|
|
98
|
+
* actions only, because with structural sharing broken (a store switch, a
|
|
99
|
+
* rehydration) each retained action pins a distinct multi-MB subtree and a
|
|
100
|
+
* few dozen of them are enough to OOM-kill a large app. But it has to be
|
|
101
|
+
* SAID. The sentinel left behind is an ordinary object, so a state view that
|
|
102
|
+
* just rendered it showed `{ __buoyStateEvicted: true, … }` under the
|
|
103
|
+
* heading "STATE AFTER ACTION" — which reads as the app's actual state — and
|
|
104
|
+
* a diff of two identical sentinels reported "no changes", which is a lie
|
|
105
|
+
* about the app rather than about the recording.
|
|
106
|
+
*/
|
|
107
|
+
const stateEvicted = (0, _reduxActionStore.isEvictedState)(action.nextState);
|
|
92
108
|
const actionColor = getActionColor(action.type);
|
|
93
109
|
const actionLabel = getActionLabel(action.type);
|
|
94
110
|
const stateType = getValueType((0, _sharedUi.parseValue)(action.nextState));
|
|
@@ -139,9 +155,26 @@ function ReduxActionDetailContent({
|
|
|
139
155
|
|
|
140
156
|
// Render state view
|
|
141
157
|
const renderStateView = (0, _react.useCallback)(() => {
|
|
158
|
+
if (stateEvicted) {
|
|
159
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
160
|
+
style: styles.contentCard,
|
|
161
|
+
testID: `${_testIDs.REDUX_TEST_ID}-state-evicted`,
|
|
162
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
163
|
+
style: styles.valueHeader,
|
|
164
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
165
|
+
style: styles.valueLabel,
|
|
166
|
+
children: "STATE AFTER ACTION"
|
|
167
|
+
})
|
|
168
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
169
|
+
style: styles.evictedText,
|
|
170
|
+
children: `Not retained. Raw state is kept for the ${_reduxActionStore.STATE_RETENTION_LIMIT} most recent actions, so this action's before/after trees have been released.`
|
|
171
|
+
})]
|
|
172
|
+
});
|
|
173
|
+
}
|
|
142
174
|
const parsed = (0, _sharedUi.parseValue)(action.nextState);
|
|
143
175
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
144
176
|
style: styles.contentCard,
|
|
177
|
+
testID: `${_testIDs.REDUX_TEST_ID}-state-card`,
|
|
145
178
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
146
179
|
style: styles.valueHeader,
|
|
147
180
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
@@ -163,6 +196,7 @@ function ReduxActionDetailContent({
|
|
|
163
196
|
style: styles.typeBadge,
|
|
164
197
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
165
198
|
style: styles.typeText,
|
|
199
|
+
testID: `${_testIDs.REDUX_TEST_ID}-state-type`,
|
|
166
200
|
children: stateType.toUpperCase()
|
|
167
201
|
})
|
|
168
202
|
})]
|
|
@@ -178,7 +212,7 @@ function ReduxActionDetailContent({
|
|
|
178
212
|
})
|
|
179
213
|
})]
|
|
180
214
|
});
|
|
181
|
-
}, [action.nextState, actionColor, actionLabel, stateType]);
|
|
215
|
+
}, [action.nextState, actionColor, actionLabel, stateType, stateEvicted]);
|
|
182
216
|
|
|
183
217
|
// Render diff content
|
|
184
218
|
const renderDiffContent = (0, _react.useCallback)(() => {
|
|
@@ -218,7 +252,15 @@ function ReduxActionDetailContent({
|
|
|
218
252
|
const handleFooterNext = (0, _react.useCallback)(() => {
|
|
219
253
|
onIndexChange(Math.max(0, selectedIndex - 1));
|
|
220
254
|
}, [selectedIndex, onIndexChange]);
|
|
221
|
-
|
|
255
|
+
|
|
256
|
+
// A diff needs two real trees, and both live on THIS action
|
|
257
|
+
// (prevState/nextState) — no siblings needed, so the action count says
|
|
258
|
+
// nothing (gating on it greyed DIFF out for every redux event opened from
|
|
259
|
+
// the Events timeline, which passes a one-element array). Eviction of
|
|
260
|
+
// EITHER side does disable it: two identical sentinels diff cleanly to
|
|
261
|
+
// "no changes", which reads as a lie.
|
|
262
|
+
const diffDisabled = stateEvicted || (0, _reduxActionStore.isEvictedState)(action.prevState) || action.prevState === undefined;
|
|
263
|
+
const showInternalFooter = !disableInternalFooter && totalActions > 1;
|
|
222
264
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
223
265
|
style: styles.container,
|
|
224
266
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ReduxDetailViewToggle.ReduxDetailViewToggle, {
|
|
@@ -226,7 +268,7 @@ function ReduxActionDetailContent({
|
|
|
226
268
|
onViewChange: setActiveView,
|
|
227
269
|
diffDisabled: diffDisabled
|
|
228
270
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
229
|
-
style: styles.contentArea,
|
|
271
|
+
style: [styles.contentArea, showInternalFooter && styles.contentAreaFooterPad],
|
|
230
272
|
children: [activeView === "action" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_ReduxActionInfoView.ReduxActionInfoView, {
|
|
231
273
|
action: action
|
|
232
274
|
}), activeView === "state" && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
@@ -234,19 +276,22 @@ function ReduxActionDetailContent({
|
|
|
234
276
|
children: renderStateView()
|
|
235
277
|
}), activeView === "diff" && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
236
278
|
style: styles.diffContainer,
|
|
279
|
+
testID: `${_testIDs.REDUX_TEST_ID}-diff`,
|
|
237
280
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.DiffModeTabs, {
|
|
238
281
|
tabs: DIFF_MODE_TABS,
|
|
239
282
|
activeTab: diffMode,
|
|
240
|
-
onTabChange: setDiffMode
|
|
283
|
+
onTabChange: setDiffMode,
|
|
284
|
+
testIDPrefix: `${_testIDs.REDUX_TEST_ID}-diff-tab`
|
|
241
285
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CompareBar, {
|
|
242
286
|
leftEvent: leftEvent,
|
|
243
287
|
rightEvent: rightEvent
|
|
244
288
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
245
289
|
style: styles.diffContent,
|
|
290
|
+
testID: `${_testIDs.REDUX_TEST_ID}-diff-content`,
|
|
246
291
|
children: renderDiffContent()
|
|
247
292
|
})]
|
|
248
293
|
})]
|
|
249
|
-
}),
|
|
294
|
+
}), showInternalFooter && /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.EventStepperFooter, {
|
|
250
295
|
currentIndex: chronologicalNumber - 1,
|
|
251
296
|
totalItems: totalActions,
|
|
252
297
|
onPrevious: handleFooterPrevious,
|
|
@@ -286,7 +331,11 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
286
331
|
backgroundColor: "transparent"
|
|
287
332
|
},
|
|
288
333
|
contentArea: {
|
|
289
|
-
flex: 1
|
|
334
|
+
flex: 1
|
|
335
|
+
},
|
|
336
|
+
// Clearance for the absolute EventStepperFooter — only when it renders,
|
|
337
|
+
// otherwise hosts like the Events tool get a dead band at the sheet bottom.
|
|
338
|
+
contentAreaFooterPad: {
|
|
290
339
|
paddingBottom: 96
|
|
291
340
|
},
|
|
292
341
|
// State view styles
|
|
@@ -350,6 +399,11 @@ const styles = _reactNative.StyleSheet.create({
|
|
|
350
399
|
borderColor: _sharedUi.night.color.border,
|
|
351
400
|
padding: 8
|
|
352
401
|
},
|
|
402
|
+
evictedText: {
|
|
403
|
+
fontSize: 12,
|
|
404
|
+
color: _sharedUi.night.color.textSecondary,
|
|
405
|
+
lineHeight: 18
|
|
406
|
+
},
|
|
353
407
|
valueText: {
|
|
354
408
|
fontSize: 12,
|
|
355
409
|
color: _sharedUi.night.color.text,
|
|
@@ -12,6 +12,7 @@ var _dataViewer = require("@buoy-gg/shared-ui/dataViewer");
|
|
|
12
12
|
var _reduxActionStore = require("../utils/reduxActionStore");
|
|
13
13
|
var _buoyReduxMiddleware = require("../utils/buoyReduxMiddleware");
|
|
14
14
|
var _ReduxActionButton = require("./ReduxActionButton");
|
|
15
|
+
var _testIDs = require("../utils/testIDs");
|
|
15
16
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
16
17
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
17
18
|
/**
|
|
@@ -89,10 +90,12 @@ function formatDuration(duration) {
|
|
|
89
90
|
function SectionHeader({
|
|
90
91
|
icon: Icon,
|
|
91
92
|
title,
|
|
92
|
-
badge
|
|
93
|
+
badge,
|
|
94
|
+
testID
|
|
93
95
|
}) {
|
|
94
96
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
95
97
|
style: styles.sectionHeader,
|
|
98
|
+
testID: testID,
|
|
96
99
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
97
100
|
style: styles.sectionHeaderLeft,
|
|
98
101
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(Icon, {
|
|
@@ -113,7 +116,8 @@ function InfoRow({
|
|
|
113
116
|
label,
|
|
114
117
|
value,
|
|
115
118
|
valueColor,
|
|
116
|
-
mono = false
|
|
119
|
+
mono = false,
|
|
120
|
+
testID
|
|
117
121
|
}) {
|
|
118
122
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
119
123
|
style: styles.infoRow,
|
|
@@ -123,9 +127,14 @@ function InfoRow({
|
|
|
123
127
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
124
128
|
style: [styles.infoValue, mono && styles.infoValueMono, valueColor && {
|
|
125
129
|
color: valueColor
|
|
126
|
-
}]
|
|
130
|
+
}]
|
|
131
|
+
// `ellipsizeMode="middle"` truncates the RENDERED text and iOS reports
|
|
132
|
+
// the truncated string back, so anything a test reads off one of these
|
|
133
|
+
// rows has to be short enough to fit on the line.
|
|
134
|
+
,
|
|
127
135
|
numberOfLines: 1,
|
|
128
136
|
ellipsizeMode: "middle",
|
|
137
|
+
testID: testID,
|
|
129
138
|
children: value
|
|
130
139
|
})]
|
|
131
140
|
});
|
|
@@ -156,6 +165,18 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
156
165
|
}
|
|
157
166
|
}, [showProModal, isPro]);
|
|
158
167
|
const categoryInfo = getCategoryInfo(action.category);
|
|
168
|
+
// Time travel needs a REAL tree. The store releases raw state for older
|
|
169
|
+
// actions (see ReduxActionDetailContent), and `jumpToState` refuses the
|
|
170
|
+
// sentinel — but it refused into a console warning, so from the screen the
|
|
171
|
+
// button simply did nothing at all. A disabled button that says why is the
|
|
172
|
+
// difference between a limit and a bug.
|
|
173
|
+
const stateEvicted = (0, _reduxActionStore.isEvictedState)(action.nextState);
|
|
174
|
+
// Whether this app wired time travel at all. Capture and time travel are
|
|
175
|
+
// separate: an app can be fully captured through `buoyReduxMiddleware` and
|
|
176
|
+
// still have no reducer that answers a jump, in which case the press
|
|
177
|
+
// dispatched, was ignored, and left the screen exactly as it was.
|
|
178
|
+
const canTimeTravel = (0, _buoyReduxMiddleware.isTimeTravelAvailable)();
|
|
179
|
+
const jumpDisabled = stateEvicted || !canTimeTravel;
|
|
159
180
|
const hasPayload = action.payload !== undefined;
|
|
160
181
|
const hasMeta = action.meta && Object.keys(action.meta).length > 0;
|
|
161
182
|
const hasError = action.error !== undefined;
|
|
@@ -196,11 +217,13 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
196
217
|
}
|
|
197
218
|
}, [action]);
|
|
198
219
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
|
|
220
|
+
testID: `${_testIDs.REDUX_TEST_ID}-detail-scroll`,
|
|
199
221
|
style: styles.container,
|
|
200
222
|
contentContainerStyle: styles.contentContainer,
|
|
201
223
|
showsVerticalScrollIndicator: false,
|
|
202
224
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
203
225
|
style: styles.card,
|
|
226
|
+
testID: `${_testIDs.REDUX_TEST_ID}-info-card`,
|
|
204
227
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(SectionHeader, {
|
|
205
228
|
icon: _sharedUi.Info,
|
|
206
229
|
title: "ACTION INFO"
|
|
@@ -209,15 +232,18 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
209
232
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
|
|
210
233
|
label: "Type",
|
|
211
234
|
value: action.type,
|
|
212
|
-
mono: true
|
|
235
|
+
mono: true,
|
|
236
|
+
testID: `${_testIDs.REDUX_TEST_ID}-info-type`
|
|
213
237
|
}), action.sliceName && /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
|
|
214
238
|
label: "Slice",
|
|
215
239
|
value: action.sliceName,
|
|
216
|
-
mono: true
|
|
240
|
+
mono: true,
|
|
241
|
+
testID: `${_testIDs.REDUX_TEST_ID}-info-slice`
|
|
217
242
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
|
|
218
243
|
label: "Action",
|
|
219
244
|
value: action.actionName,
|
|
220
|
-
mono: true
|
|
245
|
+
mono: true,
|
|
246
|
+
testID: `${_testIDs.REDUX_TEST_ID}-info-action`
|
|
221
247
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
222
248
|
style: styles.badgeRow,
|
|
223
249
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
@@ -228,6 +254,7 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
228
254
|
style: [styles.categoryText, {
|
|
229
255
|
color: categoryInfo.color
|
|
230
256
|
}],
|
|
257
|
+
testID: `${_testIDs.REDUX_TEST_ID}-info-category`,
|
|
231
258
|
children: categoryInfo.label
|
|
232
259
|
})
|
|
233
260
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
@@ -237,6 +264,7 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
237
264
|
color: action.isSlowAction ? _sharedUi.buoyColors.error : _sharedUi.night.color.textSecondary
|
|
238
265
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
239
266
|
style: [styles.durationText, action.isSlowAction && styles.durationTextSlow],
|
|
267
|
+
testID: `${_testIDs.REDUX_TEST_ID}-info-duration`,
|
|
240
268
|
children: formatDuration(action.duration)
|
|
241
269
|
}), action.isSlowAction && /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.AlertTriangle, {
|
|
242
270
|
size: 10,
|
|
@@ -249,12 +277,14 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
249
277
|
color: _sharedUi.buoyColors.success
|
|
250
278
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
251
279
|
style: styles.changesText,
|
|
280
|
+
testID: `${_testIDs.REDUX_TEST_ID}-info-changes`,
|
|
252
281
|
children: action.diffSummary || "changed"
|
|
253
282
|
})]
|
|
254
283
|
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
255
284
|
style: styles.noChangesBadge,
|
|
256
285
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
257
286
|
style: styles.noChangesText,
|
|
287
|
+
testID: `${_testIDs.REDUX_TEST_ID}-info-no-changes`,
|
|
258
288
|
children: "no change"
|
|
259
289
|
})
|
|
260
290
|
})]
|
|
@@ -262,6 +292,7 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
262
292
|
})]
|
|
263
293
|
}), hasRelatedActions && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
264
294
|
style: styles.card,
|
|
295
|
+
testID: `${_testIDs.REDUX_TEST_ID}-async-card`,
|
|
265
296
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(SectionHeader, {
|
|
266
297
|
icon: _sharedUi.Hash,
|
|
267
298
|
title: "ASYNC FLOW",
|
|
@@ -269,6 +300,7 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
269
300
|
style: styles.asyncBadge,
|
|
270
301
|
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
271
302
|
style: styles.asyncBadgeText,
|
|
303
|
+
testID: `${_testIDs.REDUX_TEST_ID}-async-count`,
|
|
272
304
|
children: [relatedActions.length, " ACTIONS"]
|
|
273
305
|
})
|
|
274
306
|
})
|
|
@@ -276,6 +308,7 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
276
308
|
style: styles.cardContent,
|
|
277
309
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
278
310
|
style: styles.baseActionType,
|
|
311
|
+
testID: `${_testIDs.REDUX_TEST_ID}-async-base`,
|
|
279
312
|
children: baseActionType
|
|
280
313
|
}), totalDuration !== null && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
281
314
|
style: styles.totalDurationRow,
|
|
@@ -284,6 +317,7 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
284
317
|
children: "Total Duration"
|
|
285
318
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
286
319
|
style: styles.totalDurationValue,
|
|
320
|
+
testID: `${_testIDs.REDUX_TEST_ID}-async-total`,
|
|
287
321
|
children: [totalDuration, "ms"]
|
|
288
322
|
})]
|
|
289
323
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
@@ -296,6 +330,7 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
296
330
|
onPress: () => onNavigateToAction?.(relatedAction),
|
|
297
331
|
disabled: isCurrent || !onNavigateToAction,
|
|
298
332
|
activeOpacity: 0.7,
|
|
333
|
+
testID: `${_testIDs.REDUX_TEST_ID}-async-step-${index}`,
|
|
299
334
|
children: [index < relatedActions.length - 1 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
300
335
|
style: styles.timelineConnector
|
|
301
336
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
@@ -314,10 +349,12 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
314
349
|
style: [styles.timelineStatusText, {
|
|
315
350
|
color: relatedCategoryInfo.color
|
|
316
351
|
}],
|
|
352
|
+
testID: `${_testIDs.REDUX_TEST_ID}-async-step-${index}-status`,
|
|
317
353
|
children: relatedCategoryInfo.label
|
|
318
354
|
})
|
|
319
355
|
}), isCurrent && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
320
356
|
style: styles.currentBadge,
|
|
357
|
+
testID: `${_testIDs.REDUX_TEST_ID}-async-step-${index}-current`,
|
|
321
358
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
322
359
|
style: styles.currentBadgeText,
|
|
323
360
|
children: "CURRENT"
|
|
@@ -334,6 +371,7 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
334
371
|
})]
|
|
335
372
|
}), hasPayload && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
336
373
|
style: styles.card,
|
|
374
|
+
testID: `${_testIDs.REDUX_TEST_ID}-payload-card`,
|
|
337
375
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(SectionHeader, {
|
|
338
376
|
icon: _sharedUi.Box,
|
|
339
377
|
title: "PAYLOAD",
|
|
@@ -356,6 +394,7 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
356
394
|
})]
|
|
357
395
|
}), hasMeta && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
358
396
|
style: styles.card,
|
|
397
|
+
testID: `${_testIDs.REDUX_TEST_ID}-meta-card`,
|
|
359
398
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(SectionHeader, {
|
|
360
399
|
icon: _sharedUi.Hash,
|
|
361
400
|
title: "ASYNC METADATA",
|
|
@@ -379,7 +418,8 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
379
418
|
}), action.meta?.requestStatus && /*#__PURE__*/(0, _jsxRuntime.jsx)(InfoRow, {
|
|
380
419
|
label: "Status",
|
|
381
420
|
value: action.meta.requestStatus.toUpperCase(),
|
|
382
|
-
valueColor: categoryInfo.color
|
|
421
|
+
valueColor: categoryInfo.color,
|
|
422
|
+
testID: `${_testIDs.REDUX_TEST_ID}-meta-status`
|
|
383
423
|
}), action.meta?.arg !== undefined && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
384
424
|
style: styles.argSection,
|
|
385
425
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
@@ -414,6 +454,7 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
414
454
|
})]
|
|
415
455
|
}), hasError && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
416
456
|
style: [styles.card, styles.errorCard],
|
|
457
|
+
testID: `${_testIDs.REDUX_TEST_ID}-error-card`,
|
|
417
458
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(SectionHeader, {
|
|
418
459
|
icon: _sharedUi.AlertCircle,
|
|
419
460
|
title: "ERROR",
|
|
@@ -421,6 +462,7 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
421
462
|
style: styles.errorBadge,
|
|
422
463
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
423
464
|
style: styles.errorBadgeText,
|
|
465
|
+
testID: `${_testIDs.REDUX_TEST_ID}-error-badge`,
|
|
424
466
|
children: "REJECTED"
|
|
425
467
|
})
|
|
426
468
|
})
|
|
@@ -439,6 +481,7 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
439
481
|
})]
|
|
440
482
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
441
483
|
style: styles.card,
|
|
484
|
+
testID: `${_testIDs.REDUX_TEST_ID}-full-action-card`,
|
|
442
485
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(SectionHeader, {
|
|
443
486
|
icon: _sharedUi.FileText,
|
|
444
487
|
title: "FULL ACTION OBJECT"
|
|
@@ -461,7 +504,8 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
461
504
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ReduxActionButton.ReduxActionButton, {
|
|
462
505
|
type: "replay",
|
|
463
506
|
text: "REPLAY",
|
|
464
|
-
onPress: handleReplay
|
|
507
|
+
onPress: handleReplay,
|
|
508
|
+
testID: `${_testIDs.REDUX_TEST_ID}-replay`
|
|
465
509
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
466
510
|
style: styles.actionDescription,
|
|
467
511
|
children: "Dispatch again"
|
|
@@ -471,17 +515,21 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
471
515
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ReduxActionButton.ReduxActionButton, {
|
|
472
516
|
type: "jump",
|
|
473
517
|
text: "JUMP",
|
|
474
|
-
onPress: handleJump
|
|
518
|
+
onPress: handleJump,
|
|
519
|
+
disabled: jumpDisabled,
|
|
520
|
+
testID: `${_testIDs.REDUX_TEST_ID}-jump`
|
|
475
521
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
476
522
|
style: styles.actionDescription,
|
|
477
|
-
|
|
523
|
+
testID: `${_testIDs.REDUX_TEST_ID}-jump-description`,
|
|
524
|
+
children: stateEvicted ? "State not retained" : canTimeTravel ? "Restore this state" : "Time travel not wired"
|
|
478
525
|
})]
|
|
479
526
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
480
527
|
style: styles.actionButtonWrapper,
|
|
481
528
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ReduxActionButton.ReduxActionButton, {
|
|
482
529
|
type: "copy",
|
|
483
530
|
text: "COPY ACTION",
|
|
484
|
-
onPress: handleCopyAction
|
|
531
|
+
onPress: handleCopyAction,
|
|
532
|
+
testID: `${_testIDs.REDUX_TEST_ID}-copy-action`
|
|
485
533
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
486
534
|
style: styles.actionDescription,
|
|
487
535
|
children: isPro ? "Copy to clipboard" : "Pro feature"
|
|
@@ -491,7 +539,8 @@ const ReduxActionInfoView = exports.ReduxActionInfoView = /*#__PURE__*/(0, _reac
|
|
|
491
539
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_ReduxActionButton.ReduxActionButton, {
|
|
492
540
|
type: "copy",
|
|
493
541
|
text: "COPY PAYLOAD",
|
|
494
|
-
onPress: handleCopyPayload
|
|
542
|
+
onPress: handleCopyPayload,
|
|
543
|
+
testID: `${_testIDs.REDUX_TEST_ID}-copy-payload`
|
|
495
544
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
496
545
|
style: styles.actionDescription,
|
|
497
546
|
children: isPro ? "Copy payload only" : "Pro feature"
|
|
@@ -214,7 +214,9 @@ function getPrimaryText(action) {
|
|
|
214
214
|
// tick re-renders only that Text, not this row.
|
|
215
215
|
const ReduxActionItem = exports.ReduxActionItem = /*#__PURE__*/(0, _react.memo)(function ReduxActionItem({
|
|
216
216
|
action,
|
|
217
|
-
onPress
|
|
217
|
+
onPress,
|
|
218
|
+
linkedCount,
|
|
219
|
+
testID
|
|
218
220
|
}) {
|
|
219
221
|
const sliceName = action.sliceName ?? undefined;
|
|
220
222
|
const statusColor = getStatusColor(action.category, action.hasStateChange, sliceName);
|
|
@@ -223,10 +225,11 @@ const ReduxActionItem = exports.ReduxActionItem = /*#__PURE__*/(0, _react.memo)(
|
|
|
223
225
|
const primaryText = getPrimaryText(action);
|
|
224
226
|
const actionBadge = getActionBadge(action);
|
|
225
227
|
|
|
226
|
-
// Check for linked async actions
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
const hasLinkedActions = linkedCount > 1;
|
|
228
|
+
// Check for linked async actions. The COUNT comes from the list (see the
|
|
229
|
+
// prop's doc); the ordered list is only needed to say where in the flow this
|
|
230
|
+
// action sits, and only when there is a flow at all.
|
|
231
|
+
const hasLinkedActions = (linkedCount ?? 0) > 1;
|
|
232
|
+
const linkedActions = hasLinkedActions ? _reduxActionStore.reduxActionStore.getLinkedActions(action) : [];
|
|
230
233
|
|
|
231
234
|
// Get position in async sequence (1/2, 2/2, etc.)
|
|
232
235
|
const asyncPosition = hasLinkedActions ? linkedActions.findIndex(a => a.id === action.id) + 1 : 0;
|
|
@@ -251,10 +254,12 @@ const ReduxActionItem = exports.ReduxActionItem = /*#__PURE__*/(0, _react.memo)(
|
|
|
251
254
|
style: [styles.asyncSequenceText, {
|
|
252
255
|
color: opColor.text
|
|
253
256
|
}],
|
|
257
|
+
testID: testID ? `${testID}-seq` : undefined,
|
|
254
258
|
children: [asyncPosition, "/", linkedCount, " #", operationIndex]
|
|
255
259
|
})
|
|
256
260
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
257
261
|
style: styles.slowBadge,
|
|
262
|
+
testID: testID ? `${testID}-slow` : undefined,
|
|
258
263
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Clock, {
|
|
259
264
|
size: 12,
|
|
260
265
|
color: _sharedUi.buoyColors.error
|
|
@@ -273,10 +278,12 @@ const ReduxActionItem = exports.ReduxActionItem = /*#__PURE__*/(0, _react.memo)(
|
|
|
273
278
|
style: [styles.asyncSequenceText, {
|
|
274
279
|
color: opColor.text
|
|
275
280
|
}],
|
|
281
|
+
testID: testID ? `${testID}-seq` : undefined,
|
|
276
282
|
children: [asyncPosition, "/", linkedCount, " #", operationIndex]
|
|
277
283
|
})
|
|
278
284
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
279
285
|
style: styles.errorBadge,
|
|
286
|
+
testID: testID ? `${testID}-error` : undefined,
|
|
280
287
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.AlertCircle, {
|
|
281
288
|
size: 12,
|
|
282
289
|
color: _sharedUi.buoyColors.error
|
|
@@ -295,10 +302,12 @@ const ReduxActionItem = exports.ReduxActionItem = /*#__PURE__*/(0, _react.memo)(
|
|
|
295
302
|
style: [styles.asyncSequenceText, {
|
|
296
303
|
color: opColor.text
|
|
297
304
|
}],
|
|
305
|
+
testID: testID ? `${testID}-seq` : undefined,
|
|
298
306
|
children: [asyncPosition, "/", linkedCount, " #", operationIndex]
|
|
299
307
|
})
|
|
300
308
|
}), action.hasStateChange && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
301
309
|
style: styles.changeBadge,
|
|
310
|
+
testID: testID ? `${testID}-change` : undefined,
|
|
302
311
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Zap, {
|
|
303
312
|
size: 12,
|
|
304
313
|
color: _sharedUi.buoyColors.warning
|
|
@@ -313,9 +322,11 @@ const ReduxActionItem = exports.ReduxActionItem = /*#__PURE__*/(0, _react.memo)(
|
|
|
313
322
|
style: [styles.actionBadgeText, {
|
|
314
323
|
color: statusColor
|
|
315
324
|
}],
|
|
325
|
+
testID: testID ? `${testID}-badge` : undefined,
|
|
316
326
|
children: actionBadge
|
|
317
327
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
318
328
|
style: styles.changeBadge,
|
|
329
|
+
testID: testID ? `${testID}-change` : undefined,
|
|
319
330
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.Zap, {
|
|
320
331
|
size: 12,
|
|
321
332
|
color: _sharedUi.buoyColors.warning
|
|
@@ -324,6 +335,10 @@ const ReduxActionItem = exports.ReduxActionItem = /*#__PURE__*/(0, _react.memo)(
|
|
|
324
335
|
});
|
|
325
336
|
}
|
|
326
337
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CompactRow, {
|
|
338
|
+
testID: testID,
|
|
339
|
+
statusTestID: testID ? `${testID}-status` : undefined,
|
|
340
|
+
statusSublabelTestID: testID ? `${testID}-sublabel` : undefined,
|
|
341
|
+
accessibilityLabel: `${primaryText}, ${statusLabel}, ${sublabel}`,
|
|
327
342
|
statusDotColor: statusColor,
|
|
328
343
|
statusLabel: statusLabel,
|
|
329
344
|
statusSublabel: sublabel,
|
|
@@ -55,6 +55,13 @@ const ReduxDetailViewToggle = exports.ReduxDetailViewToggle = /*#__PURE__*/(0, _
|
|
|
55
55
|
onPress: () => !isDisabled && onViewChange(config.key),
|
|
56
56
|
activeOpacity: isDisabled ? 1 : 0.8,
|
|
57
57
|
disabled: isDisabled,
|
|
58
|
+
testID: `buoy-redux-view-${config.key}`,
|
|
59
|
+
accessibilityRole: "button",
|
|
60
|
+
accessibilityLabel: config.label,
|
|
61
|
+
accessibilityState: {
|
|
62
|
+
selected: isActive,
|
|
63
|
+
disabled: isDisabled
|
|
64
|
+
},
|
|
58
65
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
59
66
|
style: styles.cardContent,
|
|
60
67
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(IconComponent, {
|