appium-webdriveragent 13.2.4 → 13.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/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [13.3.0](https://github.com/appium/WebDriverAgent/compare/v13.2.4...v13.3.0) (2026-06-09)
2
+
3
+ ### Features
4
+
5
+ * Expose native isAccessibilityElement ([#1146](https://github.com/appium/WebDriverAgent/issues/1146)) ([e615621](https://github.com/appium/WebDriverAgent/commit/e6156212e6fba6af98a69a400f5fa18b67f1e3e3))
6
+
1
7
  ## [13.2.4](https://github.com/appium/WebDriverAgent/compare/v13.2.3...v13.2.4) (2026-06-08)
2
8
 
3
9
  ### Bug Fixes
@@ -44,6 +44,7 @@ static NSString* const FBExclusionAttributeFrame = @"frame";
44
44
  static NSString* const FBExclusionAttributeEnabled = @"enabled";
45
45
  static NSString* const FBExclusionAttributeVisible = @"visible";
46
46
  static NSString* const FBExclusionAttributeAccessible = @"accessible";
47
+ static NSString* const FBExclusionAttributeNativeAccessibilityElement = @"nativeAccessibilityElement";
47
48
  static NSString* const FBExclusionAttributeFocused = @"focused";
48
49
  static NSString* const FBExclusionAttributePlaceholderValue = @"placeholderValue";
49
50
  static NSString* const FBExclusionAttributeNativeFrame = @"nativeFrame";
@@ -51,6 +52,13 @@ static NSString* const FBExclusionAttributeTraits = @"traits";
51
52
  static NSString* const FBExclusionAttributeMinValue = @"minValue";
52
53
  static NSString* const FBExclusionAttributeMaxValue = @"maxValue";
53
54
 
55
+ static NSString *FBJsonPrefixedAttributeKey(NSString *key)
56
+ {
57
+ return [NSString stringWithFormat:@"is%@%@",
58
+ [[key substringToIndex:1] uppercaseString],
59
+ [key substringFromIndex:1]];
60
+ }
61
+
54
62
  _Nullable id extractIssueProperty(id issue, NSString *propertyName) {
55
63
  SEL selector = NSSelectorFromString(propertyName);
56
64
  NSMethodSignature *methodSignature = [issue methodSignatureForSelector:selector];
@@ -223,7 +231,7 @@ NSDictionary<NSString *, NSString *> *customExclusionAttributesMap(void) {
223
231
  if ([nonPrefixedKeys containsObject:key]) {
224
232
  info[key] = value;
225
233
  } else {
226
- info[[NSString stringWithFormat:@"is%@", [key capitalizedString]]] = value;
234
+ info[FBJsonPrefixedAttributeKey(key)] = value;
227
235
  }
228
236
  }
229
237
  }
@@ -268,6 +276,9 @@ NSDictionary<NSString *, NSString *> *customExclusionAttributesMap(void) {
268
276
  },
269
277
  FBExclusionAttributeAccessible: ^{
270
278
  return [@([wrappedSnapshot isWDAccessible]) stringValue];
279
+ },
280
+ FBExclusionAttributeNativeAccessibilityElement: ^{
281
+ return [@([wrappedSnapshot isWDNativeAccessibilityElement]) stringValue];
271
282
  },
272
283
  FBExclusionAttributeFocused: ^{
273
284
  return [@([wrappedSnapshot isWDFocused]) stringValue];
@@ -202,6 +202,11 @@
202
202
  return self.hasFocus;
203
203
  }
204
204
 
205
+ - (BOOL)isWDNativeAccessibilityElement
206
+ {
207
+ return self.fb_isAccessibilityElement;
208
+ }
209
+
205
210
  - (BOOL)isWDAccessible
206
211
  {
207
212
  XCUIElementType elementType = self.elementType;
@@ -15,11 +15,11 @@
15
15
  <key>CFBundlePackageType</key>
16
16
  <string>FMWK</string>
17
17
  <key>CFBundleShortVersionString</key>
18
- <string>13.2.4</string>
18
+ <string>13.3.0</string>
19
19
  <key>CFBundleSignature</key>
20
20
  <string>????</string>
21
21
  <key>CFBundleVersion</key>
22
- <string>13.2.4</string>
22
+ <string>13.3.0</string>
23
23
  <key>NSPrincipalClass</key>
24
24
  <string/>
25
25
  </dict>
@@ -55,6 +55,9 @@ NS_ASSUME_NONNULL_BEGIN
55
55
  /*! Whether element is accessible */
56
56
  @property (nonatomic, readonly, getter = isWDAccessible) BOOL wdAccessible;
57
57
 
58
+ /*! The raw, native `isAccessibilityElement` value reported by the accessibility framework, without WebDriverAgent's custom computation applied by `wdAccessible` */
59
+ @property (nonatomic, readonly, getter = isWDNativeAccessibilityElement) BOOL wdNativeAccessibilityElement;
60
+
58
61
  /*! Whether element is an accessibility container (contains children of any depth that are accessible) */
59
62
  @property (nonatomic, readonly, getter = isWDAccessibilityContainer) BOOL wdAccessibilityContainer;
60
63
 
@@ -366,6 +366,24 @@ typedef NS_ENUM(NSInteger, FBConfigurationKeyboardPreference) {
366
366
  + (void)setIncludeNativeFrameInPageSource:(BOOL)enabled;
367
367
  + (BOOL)includeNativeFrameInPageSource;
368
368
 
369
+ /**
370
+ * Whether to include the `nativeAccessibilityElement` attribute in the XML page source.
371
+ *
372
+ * When enabled, the XML representation will contain the raw, native
373
+ * `isAccessibilityElement` value as reported by the accessibility framework,
374
+ * without the custom computation that WebDriverAgent applies to the
375
+ * `accessible` attribute (cell/text field special cases and parent absorption).
376
+ *
377
+ * This is useful for consumers that need to reason about the unmodified
378
+ * accessibility flag alongside the computed `accessible` value.
379
+ *
380
+ * The value is disabled by default to keep the default page source stable.
381
+ *
382
+ * @param enabled Either YES or NO
383
+ */
384
+ + (void)setIncludeNativeAccessibilityElementInPageSource:(BOOL)enabled;
385
+ + (BOOL)includeNativeAccessibilityElementInPageSource;
386
+
369
387
  /**
370
388
  * Whether to include `minValue`/`maxValue` attributes in the page source.
371
389
  * These attributes are retrieved from native element snapshots and represent
@@ -61,6 +61,7 @@ static UIInterfaceOrientation FBScreenshotOrientation;
61
61
  #endif
62
62
  static BOOL FBShouldIncludeHittableInPageSource = NO;
63
63
  static BOOL FBShouldIncludeNativeFrameInPageSource = NO;
64
+ static BOOL FBShouldIncludeNativeAccessibilityElementInPageSource = NO;
64
65
  static BOOL FBShouldIncludeMinMaxValueInPageSource = NO;
65
66
  static BOOL FBShouldIncludeCustomActionsInPageSource = NO;
66
67
  static BOOL FBShouldEnforceCustomSnapshots = NO;
@@ -665,6 +666,16 @@ static BOOL FBShouldEnforceCustomSnapshots = NO;
665
666
  return FBShouldIncludeNativeFrameInPageSource;
666
667
  }
667
668
 
669
+ + (void)setIncludeNativeAccessibilityElementInPageSource:(BOOL)enabled
670
+ {
671
+ FBShouldIncludeNativeAccessibilityElementInPageSource = enabled;
672
+ }
673
+
674
+ + (BOOL)includeNativeAccessibilityElementInPageSource
675
+ {
676
+ return FBShouldIncludeNativeAccessibilityElementInPageSource;
677
+ }
678
+
668
679
  + (void)setIncludeMinMaxValueInPageSource:(BOOL)enabled
669
680
  {
670
681
  FBShouldIncludeMinMaxValueInPageSource = enabled;
@@ -41,6 +41,7 @@ extern NSString* const FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE;
41
41
  extern NSString* const FB_SETTING_AUTO_CLICK_ALERT_SELECTOR;
42
42
  extern NSString *const FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE;
43
43
  extern NSString *const FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE;
44
+ extern NSString *const FB_SETTING_INCLUDE_NATIVE_ACCESSIBILITY_ELEMENT_IN_PAGE_SOURCE;
44
45
  extern NSString *const FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE;
45
46
  extern NSString *const FB_SETTING_INCLUDE_CUSTOM_ACTIONS_IN_PAGE_SOURCE;
46
47
  extern NSString *const FB_SETTING_ENFORCE_CUSTOM_SNAPSHOTS;
@@ -37,6 +37,7 @@ NSString* const FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE = @"limitXPathContextScope"
37
37
  NSString* const FB_SETTING_AUTO_CLICK_ALERT_SELECTOR = @"autoClickAlertSelector";
38
38
  NSString* const FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE = @"includeHittableInPageSource";
39
39
  NSString* const FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE = @"includeNativeFrameInPageSource";
40
+ NSString* const FB_SETTING_INCLUDE_NATIVE_ACCESSIBILITY_ELEMENT_IN_PAGE_SOURCE = @"includeNativeAccessibilityElementInPageSource";
40
41
  NSString* const FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE = @"includeMinMaxValueInPageSource";
41
42
  NSString* const FB_SETTING_INCLUDE_CUSTOM_ACTIONS_IN_PAGE_SOURCE = @"includeCustomActionsInPageSource";
42
43
  NSString* const FB_SETTING_ENFORCE_CUSTOM_SNAPSHOTS = @"enforceCustomSnapshots";
@@ -162,6 +162,10 @@ static NSSet<NSString *> *FBNilClearableSettingKeys(void)
162
162
  [FBConfiguration setIncludeNativeFrameInPageSource:[value boolValue]];
163
163
  return nil;
164
164
  };
165
+ map[FB_SETTING_INCLUDE_NATIVE_ACCESSIBILITY_ELEMENT_IN_PAGE_SOURCE] = ^FBCommandStatus *(FBSession *session, id value) {
166
+ [FBConfiguration setIncludeNativeAccessibilityElementInPageSource:[value boolValue]];
167
+ return nil;
168
+ };
165
169
  map[FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE] = ^FBCommandStatus *(FBSession *session, id value) {
166
170
  [FBConfiguration setIncludeMinMaxValueInPageSource:[value boolValue]];
167
171
  return nil;
@@ -280,6 +284,9 @@ static NSSet<NSString *> *FBNilClearableSettingKeys(void)
280
284
  map[FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE] = ^id(FBSession *session) {
281
285
  return @([FBConfiguration includeNativeFrameInPageSource]);
282
286
  };
287
+ map[FB_SETTING_INCLUDE_NATIVE_ACCESSIBILITY_ELEMENT_IN_PAGE_SOURCE] = ^id(FBSession *session) {
288
+ return @([FBConfiguration includeNativeAccessibilityElementInPageSource]);
289
+ };
283
290
  map[FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE] = ^id(FBSession *session) {
284
291
  return @([FBConfiguration includeMinMaxValueInPageSource]);
285
292
  };
@@ -120,6 +120,10 @@
120
120
 
121
121
  @end
122
122
 
123
+ @interface FBNativeAccessibilityElementAttribute : FBElementAttribute
124
+
125
+ @end
126
+
123
127
  @interface FBTraitsAttribute : FBElementAttribute
124
128
 
125
129
  @end
@@ -409,6 +413,10 @@ static NSString *const topNodeIndexPath = @"top";
409
413
  // Include nativeFrame only when requested
410
414
  [includedAttributes removeObject:FBNativeFrameAttribute.class];
411
415
  }
416
+ if (!FBConfiguration.includeNativeAccessibilityElementInPageSource) {
417
+ // Include the raw native accessibility flag only when requested
418
+ [includedAttributes removeObject:FBNativeAccessibilityElementAttribute.class];
419
+ }
412
420
  if (!FBConfiguration.includeMinMaxValueInPageSource) {
413
421
  // minValue/maxValue are retrieved from private APIs and may be slow on deep trees
414
422
  [includedAttributes removeObject:FBMinValueAttribute.class];
@@ -686,6 +694,7 @@ static NSString *const FBAbstractMethodInvocationException = @"AbstractMethodInv
686
694
  FBEnabledAttribute.class,
687
695
  FBVisibleAttribute.class,
688
696
  FBAccessibleAttribute.class,
697
+ FBNativeAccessibilityElementAttribute.class,
689
698
  #if TARGET_OS_TV
690
699
  FBFocusedAttribute.class,
691
700
  #endif
@@ -954,6 +963,19 @@ static NSString *const FBAbstractMethodInvocationException = @"AbstractMethodInv
954
963
  }
955
964
  @end
956
965
 
966
+ @implementation FBNativeAccessibilityElementAttribute
967
+
968
+ + (NSString *)name
969
+ {
970
+ return @"nativeAccessibilityElement";
971
+ }
972
+
973
+ + (NSString *)valueForElement:(id<FBElement>)element
974
+ {
975
+ return FBBoolToString(element.wdNativeAccessibilityElement);
976
+ }
977
+ @end
978
+
957
979
  @implementation FBTraitsAttribute
958
980
 
959
981
  + (NSString *)name
@@ -41,6 +41,15 @@
41
41
  XCTAssertFalse(buttonElement.isWDAccessibilityContainer);
42
42
  }
43
43
 
44
+ - (void)testNativeAccessibilityElementAttribute
45
+ {
46
+ // wdNativeAccessibilityElement must expose the raw, native isAccessibilityElement flag
47
+ // without WebDriverAgent's custom computation applied by wdAccessible
48
+ XCUIElement *buttonElement = self.testedApplication.buttons[@"Button"];
49
+ XCTAssertTrue(buttonElement.exists);
50
+ XCTAssertEqual(buttonElement.wdNativeAccessibilityElement, buttonElement.fb_isAccessibilityElement);
51
+ }
52
+
44
53
  - (void)testContainerAccessibilityAttributes
45
54
  {
46
55
  // "not_accessible" isn't accessibility element, but contains accessibility elements, so it is accessibility container
@@ -31,6 +31,7 @@
31
31
  @property (nonatomic, readwrite) NSUInteger wdIndex;
32
32
  @property (nonatomic, readwrite, getter=isWDVisible) BOOL wdVisible;
33
33
  @property (nonatomic, readwrite, getter=isWDAccessible) BOOL wdAccessible;
34
+ @property (nonatomic, readwrite, getter=isWDNativeAccessibilityElement) BOOL wdNativeAccessibilityElement;
34
35
  @property (nonatomic, readwrite, getter = isWDFocused) BOOL wdFocused;
35
36
  @property (nonatomic, readwrite, getter = isWDHittable) BOOL wdHittable;
36
37
  @property (nonatomic, copy, readwrite, nullable) NSString *wdPlaceholderValue;
@@ -28,6 +28,7 @@
28
28
  self.wdCustomActions = nil;
29
29
  self.wdVisible = YES;
30
30
  self.wdAccessible = YES;
31
+ self.wdNativeAccessibilityElement = YES;
31
32
  self.wdEnabled = YES;
32
33
  self.wdSelected = YES;
33
34
  self.wdFocused = YES;
@@ -92,8 +92,8 @@
92
92
  NSString *resultXml = [self xmlStringWithElement:(id<FBXCElementSnapshot>)element
93
93
  xpathQuery:[NSString stringWithFormat:@"//%@[@*]", element.wdType]
94
94
  excludingAttributes:@[@"visible"]];
95
- NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" value=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" hittable=\"%@\" traits=\"%@\" nativeFrame=\"%@\" customActions=\"%@\" private_indexPath=\"top\"/>\n",
96
- element.wdType, element.wdType, @"йоло&lt;&gt;&amp;&quot;", element.wdName, @"a&#10;b", FBBoolToString(element.wdEnabled), FBBoolToString(element.wdVisible), FBBoolToString(element.wdAccessible), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex, FBBoolToString(element.wdHittable), element.wdTraits, NSStringFromCGRect(element.wdNativeFrame), element.wdCustomActions];
95
+ NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" value=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" nativeAccessibilityElement=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" hittable=\"%@\" traits=\"%@\" nativeFrame=\"%@\" customActions=\"%@\" private_indexPath=\"top\"/>\n",
96
+ element.wdType, element.wdType, @"йоло&lt;&gt;&amp;&quot;", element.wdName, @"a&#10;b", FBBoolToString(element.wdEnabled), FBBoolToString(element.wdVisible), FBBoolToString(element.wdAccessible), FBBoolToString(element.wdNativeAccessibilityElement), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex, FBBoolToString(element.wdHittable), element.wdTraits, NSStringFromCGRect(element.wdNativeFrame), element.wdCustomActions];
97
97
  XCTAssertEqualObjects(expectedXml, resultXml);
98
98
  }
99
99
 
@@ -29,6 +29,7 @@
29
29
  @property (nonatomic, readwrite) NSUInteger wdIndex;
30
30
  @property (nonatomic, readwrite, getter=isWDVisible) BOOL wdVisible;
31
31
  @property (nonatomic, readwrite, getter=isWDAccessible) BOOL wdAccessible;
32
+ @property (nonatomic, readwrite, getter=isWDNativeAccessibilityElement) BOOL wdNativeAccessibilityElement;
32
33
  @property (nonatomic, readwrite, getter=isWDFocused) BOOL wdFocused;
33
34
  @property (nonatomic, readwrite, getter = isWDHittable) BOOL wdHittable;
34
35
  @property (copy, nonnull) NSArray *children;
@@ -24,6 +24,7 @@
24
24
  self.wdValue = @"magicValue";
25
25
  self.wdVisible = YES;
26
26
  self.wdAccessible = YES;
27
+ self.wdNativeAccessibilityElement = YES;
27
28
  self.wdEnabled = YES;
28
29
  self.wdSelected = YES;
29
30
  self.wdHittable = YES;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium-webdriveragent",
3
- "version": "13.2.4",
3
+ "version": "13.3.0",
4
4
  "description": "Package bundling WebDriverAgent",
5
5
  "main": "./build/lib/index.js",
6
6
  "types": "./build/lib/index.d.ts",