@ansight/react-native 1.2.0-preview.2 → 1.3.0-preview.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 CHANGED
@@ -77,8 +77,8 @@ bundle; its API requires the native Ansight module.
77
77
 
78
78
  This package version expects matching native SDK packages:
79
79
 
80
- - CocoaPods: `Ansight`, `AnsightObjC` version `1.2.0-preview.2`
81
- - Maven: `ai.ansight:ansight-android:1.2.0-preview.2`
80
+ - CocoaPods: `Ansight`, `AnsightObjC` version `1.3.0-preview.2`
81
+ - Maven: `ai.ansight:ansight-android:1.3.0-preview.2`
82
82
 
83
83
  ## Quickstart
84
84
 
@@ -67,6 +67,6 @@ repositories {
67
67
  dependencies {
68
68
  implementation("com.facebook.react:react-android")
69
69
  def ansightAndroidVersion =
70
- findProperty("ansightAndroidVersion") ?: "1.2.0-preview.2"
71
- implementation("ai.ansight:ansight-android:1.2.0-preview.2")
70
+ findProperty("ansightAndroidVersion") ?: "1.3.0-preview.2"
71
+ implementation("ai.ansight:ansight-android:1.3.0-preview.2")
72
72
  }
@@ -16,6 +16,7 @@ import ai.ansight.runtime.AnsightOptionsBuilder
16
16
  import ai.ansight.runtime.AnsightRuntime
17
17
  import ai.ansight.runtime.AnsightSecureStorageOptions
18
18
  import ai.ansight.runtime.AnsightSessionJpegCaptureOptions
19
+ import ai.ansight.runtime.AnsightSessionJpegCaptureMode
19
20
  import ai.ansight.runtime.AnsightToolGuard
20
21
  import ai.ansight.runtime.AnsightTouchCaptureOptions
21
22
  import ai.ansight.runtime.AppLifecycleState
@@ -749,6 +750,7 @@ class AnsightReactNativeModule(
749
750
  "captureGpuBackedSurfaces",
750
751
  AnsightSessionJpegCaptureOptions.DefaultCaptureGpuBackedSurfaces,
751
752
  ),
753
+ mode = sessionJpegCaptureMode(jpeg.stringValue("mode")),
752
754
  )
753
755
  },
754
756
  )
@@ -928,9 +930,17 @@ class AnsightReactNativeModule(
928
930
  "captureGpuBackedSurfaces",
929
931
  AnsightSessionJpegCaptureOptions.DefaultCaptureGpuBackedSurfaces,
930
932
  ),
933
+ mode = sessionJpegCaptureMode(map.stringValue("mode")),
931
934
  )
932
935
  }
933
936
 
937
+ private fun sessionJpegCaptureMode(value: String?): AnsightSessionJpegCaptureMode =
938
+ if (value == "screenshotAndVisualTree") {
939
+ AnsightSessionJpegCaptureMode.ScreenshotAndVisualTree
940
+ } else {
941
+ AnsightSessionJpegCaptureMode.ScreenshotOnly
942
+ }
943
+
934
944
  private fun toolDefinition(map: ReadableMap): ToolDefinition =
935
945
  ToolDefinition(
936
946
  id = map.stringValue("id") ?: "",
@@ -1117,6 +1127,11 @@ class AnsightReactNativeModule(
1117
1127
  "quality" to capture.quality,
1118
1128
  "maxWidth" to capture.maxWidth,
1119
1129
  "captureGpuBackedSurfaces" to capture.captureGpuBackedSurfaces,
1130
+ "mode" to if (capture.mode == AnsightSessionJpegCaptureMode.ScreenshotAndVisualTree) {
1131
+ "screenshotAndVisualTree"
1132
+ } else {
1133
+ "screenshotOnly"
1134
+ },
1120
1135
  ).toWritableMap())
1121
1136
  } ?: putNull("sessionJpegCapture")
1122
1137
  options.touchCapture?.let { touch ->
package/index.d.ts CHANGED
@@ -37,6 +37,7 @@ export interface AnsightSessionJpegCaptureOptions {
37
37
  quality?: number;
38
38
  maxWidth?: number;
39
39
  captureGpuBackedSurfaces?: boolean;
40
+ mode?: "screenshotOnly" | "screenshotAndVisualTree";
40
41
  }
41
42
 
42
43
  export interface AnsightTouchCaptureOptions {
@@ -262,7 +263,8 @@ export class AnsightOptionsBuilder {
262
263
  intervalMilliseconds: number,
263
264
  quality?: number,
264
265
  maxWidth?: number | null,
265
- captureGpuBackedSurfaces?: boolean
266
+ captureGpuBackedSurfaces?: boolean,
267
+ mode?: "screenshotOnly" | "screenshotAndVisualTree"
266
268
  ): this;
267
269
  withoutSessionJpegCapture(): this;
268
270
  withTouchCapture(touchCapture?: AnsightTouchCaptureOptions): this;
package/index.js CHANGED
@@ -268,6 +268,7 @@ class AnsightOptionsBuilder {
268
268
  quality: arguments.length > 1 ? arguments[1] : 60,
269
269
  maxWidth: arguments.length > 2 ? arguments[2] : 480,
270
270
  captureGpuBackedSurfaces: arguments.length > 3 ? arguments[3] : true,
271
+ mode: arguments.length > 4 ? arguments[4] : "screenshotOnly",
271
272
  };
272
273
  return this;
273
274
  }
@@ -275,6 +276,7 @@ class AnsightOptionsBuilder {
275
276
  intervalMilliseconds: 2000,
276
277
  quality: 60,
277
278
  maxWidth: 480,
279
+ mode: "screenshotOnly",
278
280
  ...(optionsOrIntervalMilliseconds || {}),
279
281
  };
280
282
  return this;
@@ -1389,7 +1391,7 @@ function summarizeProps(props) {
1389
1391
  }
1390
1392
  const keys = Object.keys(props).filter((key) => key !== "children");
1391
1393
  const summary = { keys };
1392
- ["testID", "nativeID", "accessibilityLabel", "role"].forEach((key) => {
1394
+ ["testID", "nativeID", "accessibilityLabel", "accessibilityRole", "role"].forEach((key) => {
1393
1395
  if (props[key] != null && !isSensitiveKey(key)) {
1394
1396
  summary[key] = String(props[key]);
1395
1397
  }
@@ -1401,6 +1403,42 @@ function summarizeProps(props) {
1401
1403
  return summary;
1402
1404
  }
1403
1405
 
1406
+ function reactSemanticRole(type, props, fiberTag) {
1407
+ const declared = props && (props.accessibilityRole || props.role);
1408
+ if (declared) return String(declared).toLowerCase();
1409
+ if (fiberTag === 6 || /text/i.test(type)) return "text";
1410
+ if (/button|pressable|touchable/i.test(type)) return "button";
1411
+ if (/textinput/i.test(type)) return "textbox";
1412
+ if (/switch/i.test(type)) return "switch";
1413
+ if (/scrollview|flatlist|sectionlist/i.test(type)) return "scrollview";
1414
+ return "view";
1415
+ }
1416
+
1417
+ function reactSupportedActions(type, props) {
1418
+ const actions = [];
1419
+ if (props && typeof props.onPress === "function") actions.push("tap");
1420
+ if (props && (typeof props.onChangeText === "function" || /textinput/i.test(type))) {
1421
+ actions.push("typeText", "focus");
1422
+ }
1423
+ if (/scrollview|flatlist|sectionlist/i.test(type) || (props && typeof props.onScroll === "function")) {
1424
+ actions.push("scroll", "swipe");
1425
+ }
1426
+ return actions;
1427
+ }
1428
+
1429
+ function applyReactTargetability(node, fiber, props, type) {
1430
+ const style = StyleSheet && typeof StyleSheet.flatten === "function"
1431
+ ? StyleSheet.flatten(props && props.style)
1432
+ : props && props.style;
1433
+ node.text = node.label || (node.visual && node.visual.text) || null;
1434
+ node.role = reactSemanticRole(type, props, fiber.tag);
1435
+ node.supportedActions = reactSupportedActions(type, props);
1436
+ node.visible = !(style && style.display === "none") && !(props && props.accessibilityElementsHidden);
1437
+ node.enabled = !(props && (props.disabled === true || props.accessibilityState && props.accessibilityState.disabled === true));
1438
+ node.focusable = !!(props && props.focusable) || node.supportedActions.includes("focus");
1439
+ node.interactable = node.visible && node.enabled && node.supportedActions.length > 0;
1440
+ }
1441
+
1404
1442
  function reactColorToArgbHex(value) {
1405
1443
  if (value == null) {
1406
1444
  return undefined;
@@ -1575,6 +1613,8 @@ function serializeFiber(fiber, context, depth) {
1575
1613
  node.state = sanitizeValue(fiber.memoizedState, context);
1576
1614
  }
1577
1615
 
1616
+ applyReactTargetability(node, fiber, props, type);
1617
+
1578
1618
  if (depth < context.maxDepth) {
1579
1619
  let child = fiber.child;
1580
1620
  while (child) {
@@ -1598,9 +1638,10 @@ function isShadowTreeFiber(fiber) {
1598
1638
 
1599
1639
  function createShadowTreeNode(fiber, context, depth) {
1600
1640
  const props = fiber.memoizedProps || fiber.pendingProps || {};
1641
+ const type = reactFiberTypeName(fiber);
1601
1642
  const node = {
1602
1643
  id: reactFiberId(fiber),
1603
- type: reactFiberTypeName(fiber),
1644
+ type,
1604
1645
  kind: fiber.tag === 3 ? "root" : fiber.tag === 6 ? "text" : "host",
1605
1646
  tag: fiber.tag,
1606
1647
  key: fiber.key == null ? null : String(fiber.key),
@@ -1633,6 +1674,8 @@ function createShadowTreeNode(fiber, context, depth) {
1633
1674
  }
1634
1675
  }
1635
1676
 
1677
+ applyReactTargetability(node, fiber, props, type);
1678
+
1636
1679
  return node;
1637
1680
  }
1638
1681
 
@@ -941,7 +941,10 @@ final class AnsightReactNative: RCTEventEmitter {
941
941
  jpeg,
942
942
  "captureGpuBackedSurfaces",
943
943
  defaultValue: AnsightSessionJpegCaptureOptions.defaultCaptureGpuBackedSurfaces
944
- )
944
+ ),
945
+ mode: stringValue(jpeg, "mode") == "screenshotAndVisualTree"
946
+ ? .screenshotAndVisualTree
947
+ : .screenshotOnly
945
948
  )
946
949
  }
947
950
  }
@@ -1267,7 +1270,10 @@ final class AnsightReactNative: RCTEventEmitter {
1267
1270
  dictionary,
1268
1271
  "captureGpuBackedSurfaces",
1269
1272
  defaultValue: AnsightSessionJpegCaptureOptions.defaultCaptureGpuBackedSurfaces
1270
- )
1273
+ ),
1274
+ mode: stringValue(dictionary, "mode") == "screenshotAndVisualTree"
1275
+ ? .screenshotAndVisualTree
1276
+ : .screenshotOnly
1271
1277
  )
1272
1278
  }
1273
1279
 
@@ -1316,6 +1322,7 @@ final class AnsightReactNative: RCTEventEmitter {
1316
1322
  "quality": capture.quality,
1317
1323
  "maxWidth": capture.maxWidth as Any,
1318
1324
  "captureGpuBackedSurfaces": capture.captureGpuBackedSurfaces,
1325
+ "mode": capture.mode.rawValue,
1319
1326
  ]
1320
1327
  } else {
1321
1328
  dictionary["sessionJpegCapture"] = NSNull()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ansight/react-native",
3
- "version": "1.2.0-preview.2",
3
+ "version": "1.3.0-preview.2",
4
4
  "description": "React Native bridge for the Ansight mobile SDK.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",