appium-webdriveragent 9.11.0 → 9.13.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,15 @@
1
+ ## [9.13.0](https://github.com/appium/WebDriverAgent/compare/v9.12.0...v9.13.0) (2025-06-05)
2
+
3
+ ### Features
4
+
5
+ * expose nativeFrame attribute in XML page source ([#1029](https://github.com/appium/WebDriverAgent/issues/1029)) ([5b56a45](https://github.com/appium/WebDriverAgent/commit/5b56a453f836cbc4358ce24ae43032658467c35c))
6
+
7
+ ## [9.12.0](https://github.com/appium/WebDriverAgent/compare/v9.11.0...v9.12.0) (2025-06-04)
8
+
9
+ ### Features
10
+
11
+ * add accessibility traits to XML page source ([#1028](https://github.com/appium/WebDriverAgent/issues/1028)) ([2df6649](https://github.com/appium/WebDriverAgent/commit/2df6649cb532d65a8c14633591b76c90185644cb))
12
+
1
13
  ## [9.11.0](https://github.com/appium/WebDriverAgent/compare/v9.10.1...v9.11.0) (2025-06-03)
2
14
 
3
15
  ### Features
@@ -354,6 +354,7 @@
354
354
  FB_SETTING_RESPECT_SYSTEM_ALERTS: @([FBConfiguration shouldRespectSystemAlerts]),
355
355
  FB_SETTING_USE_CLEAR_TEXT_SHORTCUT: @([FBConfiguration useClearTextShortcut]),
356
356
  FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE: @([FBConfiguration includeHittableInPageSource]),
357
+ FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE: @([FBConfiguration includeNativeFrameInPageSource]),
357
358
  FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE: @([FBConfiguration limitXpathContextScope]),
358
359
  #if !TARGET_OS_TV
359
360
  FB_SETTING_SCREENSHOT_ORIENTATION: [FBConfiguration humanReadableScreenshotOrientation],
@@ -457,7 +458,10 @@
457
458
  [FBConfiguration setUseClearTextShortcut:[[settings objectForKey:FB_SETTING_USE_CLEAR_TEXT_SHORTCUT] boolValue]];
458
459
  }
459
460
  if (nil != [settings objectForKey:FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE]) {
460
- [FBConfiguration setincludeHittableInPageSource:[[settings objectForKey:FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE] boolValue]];
461
+ [FBConfiguration setIncludeHittableInPageSource:[[settings objectForKey:FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE] boolValue]];
462
+ }
463
+ if (nil != [settings objectForKey:FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE]) {
464
+ [FBConfiguration setIncludeNativeFrameInPageSource:[[settings objectForKey:FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE] boolValue]];
461
465
  }
462
466
  if (nil != [settings objectForKey:FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE]) {
463
467
  [FBConfiguration setLimitXpathContextScope:[[settings objectForKey:FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE] boolValue]];
@@ -15,11 +15,11 @@
15
15
  <key>CFBundlePackageType</key>
16
16
  <string>FMWK</string>
17
17
  <key>CFBundleShortVersionString</key>
18
- <string>9.11.0</string>
18
+ <string>9.13.0</string>
19
19
  <key>CFBundleSignature</key>
20
20
  <string>????</string>
21
21
  <key>CFBundleVersion</key>
22
- <string>9.11.0</string>
22
+ <string>9.13.0</string>
23
23
  <key>NSPrincipalClass</key>
24
24
  <string/>
25
25
  </dict>
@@ -340,9 +340,25 @@ typedef NS_ENUM(NSInteger, FBConfigurationKeyboardPreference) {
340
340
  *
341
341
  * @param enabled Either YES or NO
342
342
  */
343
- + (void)setincludeHittableInPageSource:(BOOL)enabled;
343
+ + (void)setIncludeHittableInPageSource:(BOOL)enabled;
344
344
  + (BOOL)includeHittableInPageSource;
345
345
 
346
+ /**
347
+ * Whether to include `nativeFrame` attribute in the XML page source.
348
+ *
349
+ * When enabled, the XML representation will contain the precise rendered
350
+ * frame of the UI element.
351
+ *
352
+ * This value is more accurate than the legacy `wdFrame`, which applies rounding
353
+ * and may introduce inconsistencies in size and position calculations.
354
+ *
355
+ * The value is disabled by default to avoid potential performance overhead.
356
+ *
357
+ * @param enabled Either YES or NO
358
+ */
359
+ + (void)setIncludeNativeFrameInPageSource:(BOOL)enabled;
360
+ + (BOOL)includeNativeFrameInPageSource;
361
+
346
362
  @end
347
363
 
348
364
  NS_ASSUME_NONNULL_END
@@ -61,7 +61,8 @@ static BOOL FBLimitXpathContextScope = YES;
61
61
  #if !TARGET_OS_TV
62
62
  static UIInterfaceOrientation FBScreenshotOrientation;
63
63
  #endif
64
- static BOOL FBShouldincludeHittableInPageSource = NO;
64
+ static BOOL FBShouldIncludeHittableInPageSource = NO;
65
+ static BOOL FBShouldIncludeNativeFrameInPageSource = NO;
65
66
 
66
67
  @implementation FBConfiguration
67
68
 
@@ -643,14 +644,24 @@ static BOOL FBShouldincludeHittableInPageSource = NO;
643
644
  return NO;
644
645
  }
645
646
 
646
- + (void)setincludeHittableInPageSource:(BOOL)enabled
647
+ + (void)setIncludeHittableInPageSource:(BOOL)enabled
647
648
  {
648
- FBShouldincludeHittableInPageSource = enabled;
649
+ FBShouldIncludeHittableInPageSource = enabled;
649
650
  }
650
651
 
651
652
  + (BOOL)includeHittableInPageSource
652
653
  {
653
- return FBShouldincludeHittableInPageSource;
654
+ return FBShouldIncludeHittableInPageSource;
655
+ }
656
+
657
+ + (void)setIncludeNativeFrameInPageSource:(BOOL)enabled
658
+ {
659
+ FBShouldIncludeNativeFrameInPageSource = enabled;
660
+ }
661
+
662
+ + (BOOL)includeNativeFrameInPageSource
663
+ {
664
+ return FBShouldIncludeNativeFrameInPageSource;
654
665
  }
655
666
 
656
667
  @end
@@ -41,6 +41,7 @@ extern NSString* const FB_SETTING_USE_CLEAR_TEXT_SHORTCUT;
41
41
  extern NSString* const FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE;
42
42
  extern NSString* const FB_SETTING_AUTO_CLICK_ALERT_SELECTOR;
43
43
  extern NSString *const FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE;
44
+ extern NSString *const FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE;
44
45
 
45
46
 
46
47
  NS_ASSUME_NONNULL_END
@@ -37,3 +37,4 @@ NSString* const FB_SETTING_USE_CLEAR_TEXT_SHORTCUT = @"useClearTextShortcut";
37
37
  NSString* const FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE = @"limitXPathContextScope";
38
38
  NSString* const FB_SETTING_AUTO_CLICK_ALERT_SELECTOR = @"autoClickAlertSelector";
39
39
  NSString* const FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE = @"includeHittableInPageSource";
40
+ NSString* const FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE = @"includeNativeFrameInPageSource";
@@ -105,6 +105,14 @@
105
105
 
106
106
  @end
107
107
 
108
+ @interface FBNativeFrameAttribute : FBElementAttribute
109
+
110
+ @end
111
+
112
+ @interface FBTraitsAttribute : FBElementAttribute
113
+
114
+ @end
115
+
108
116
  #if TARGET_OS_TV
109
117
 
110
118
  @interface FBFocusedAttribute : FBElementAttribute
@@ -362,6 +370,10 @@ static NSString *const topNodeIndexPath = @"top";
362
370
  // thus we only include it when requested explicitly
363
371
  [includedAttributes removeObject:FBHittableAttribute.class];
364
372
  }
373
+ if (!FBConfiguration.includeNativeFrameInPageSource) {
374
+ // Include nativeFrame only when requested
375
+ [includedAttributes removeObject:FBNativeFrameAttribute.class];
376
+ }
365
377
  if (nil != excludedAttributes) {
366
378
  for (NSString *excludedAttributeName in excludedAttributes) {
367
379
  for (Class supportedAttribute in FBElementAttribute.supportedAttributes) {
@@ -583,6 +595,8 @@ static NSString *const FBAbstractMethodInvocationException = @"AbstractMethodInv
583
595
  FBIndexAttribute.class,
584
596
  FBHittableAttribute.class,
585
597
  FBPlaceholderValueAttribute.class,
598
+ FBTraitsAttribute.class,
599
+ FBNativeFrameAttribute.class,
586
600
  ];
587
601
  }
588
602
 
@@ -818,5 +832,31 @@ static NSString *const FBAbstractMethodInvocationException = @"AbstractMethodInv
818
832
  {
819
833
  return element.wdPlaceholderValue;
820
834
  }
835
+ @end
836
+
837
+ @implementation FBNativeFrameAttribute
838
+
839
+ + (NSString *)name
840
+ {
841
+ return @"nativeFrame";
842
+ }
843
+
844
+ + (NSString *)valueForElement:(id<FBElement>)element
845
+ {
846
+ return NSStringFromCGRect(element.wdNativeFrame);
847
+ }
848
+ @end
849
+
850
+ @implementation FBTraitsAttribute
851
+
852
+ + (NSString *)name
853
+ {
854
+ return @"traits";
855
+ }
856
+
857
+ + (NSString *)valueForElement:(id<FBElement>)element
858
+ {
859
+ return element.wdTraits;
860
+ }
821
861
 
822
862
  @end
@@ -57,7 +57,7 @@
57
57
  NSString *xmlStr = [FBXPath xmlStringWithRootElement:wrappedSnapshot
58
58
  options:nil];
59
59
  XCTAssertNotNil(xmlStr);
60
- NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\"/>\n", wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, FBBoolToString(wrappedSnapshot.wdEnabled), FBBoolToString(wrappedSnapshot.wdVisible), FBBoolToString(wrappedSnapshot.wdAccessible), [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdIndex];
60
+ NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" traits=\"%@\"/>\n", wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, FBBoolToString(wrappedSnapshot.wdEnabled), FBBoolToString(wrappedSnapshot.wdVisible), FBBoolToString(wrappedSnapshot.wdAccessible), [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdIndex, wrappedSnapshot.wdTraits];
61
61
  XCTAssertEqualObjects(xmlStr, expectedXml);
62
62
  }
63
63
 
@@ -70,7 +70,7 @@
70
70
  NSString *xmlStr = [FBXPath xmlStringWithRootElement:wrappedSnapshot
71
71
  options:options];
72
72
  XCTAssertNotNil(xmlStr);
73
- NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@>\n <%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\"/>\n</%@>\n", scope, wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, FBBoolToString(wrappedSnapshot.wdEnabled), FBBoolToString(wrappedSnapshot.wdVisible), FBBoolToString(wrappedSnapshot.wdAccessible), [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdIndex, scope];
73
+ NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@>\n <%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" traits=\"%@\"/>\n</%@>\n", scope, wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, FBBoolToString(wrappedSnapshot.wdEnabled), FBBoolToString(wrappedSnapshot.wdVisible), FBBoolToString(wrappedSnapshot.wdAccessible), [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdIndex, wrappedSnapshot.wdTraits, scope];
74
74
  XCTAssertEqualObjects(xmlStr, expectedXml);
75
75
  }
76
76
 
@@ -83,7 +83,7 @@
83
83
  NSString *xmlStr = [FBXPath xmlStringWithRootElement:wrappedSnapshot
84
84
  options:options];
85
85
  XCTAssertNotNil(xmlStr);
86
- NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\"/>\n", wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, FBBoolToString(wrappedSnapshot.wdAccessible), [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue]];
86
+ NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" traits=\"%@\"/>\n", wrappedSnapshot.wdType, wrappedSnapshot.wdType, wrappedSnapshot.wdName, wrappedSnapshot.wdLabel, FBBoolToString(wrappedSnapshot.wdAccessible), [wrappedSnapshot.wdRect[@"x"] stringValue], [wrappedSnapshot.wdRect[@"y"] stringValue], [wrappedSnapshot.wdRect[@"width"] stringValue], [wrappedSnapshot.wdRect[@"height"] stringValue], wrappedSnapshot.wdTraits];
87
87
  XCTAssertEqualObjects(xmlStr, expectedXml);
88
88
  }
89
89
 
@@ -12,4 +12,5 @@
12
12
  @interface XCElementSnapshotDouble : NSObject<XCUIElementAttributes>
13
13
  @property (readwrite, nullable) id value;
14
14
  @property (readwrite, nullable, copy) NSString *label;
15
+ @property (nonatomic, assign) UIAccessibilityTraits traits;
15
16
  @end
@@ -108,4 +108,8 @@
108
108
  return CGRectZero;
109
109
  }
110
110
 
111
+ - (UIAccessibilityTraits)traits
112
+ {
113
+ return UIAccessibilityTraitButton;
114
+ }
111
115
  @end
@@ -63,8 +63,9 @@
63
63
  NSString *resultXml = [self xmlStringWithElement:(id<FBXCElementSnapshot>)element
64
64
  xpathQuery:nil
65
65
  excludingAttributes:nil];
66
- 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\" placeholderValue=\"%@\" private_indexPath=\"top\"/>\n",
67
- element.wdType, element.wdType, element.wdValue, element.wdName, element.wdLabel, FBBoolToString(element.wdEnabled), FBBoolToString(element.wdVisible), FBBoolToString(element.wdAccessible), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex, element.wdPlaceholderValue];
66
+ NSLog(@"[DefaultXPath] Result XML:\n%@", resultXml);
67
+ 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\" placeholderValue=\"%@\" traits=\"%@\" private_indexPath=\"top\"/>\n",
68
+ element.wdType, element.wdType, element.wdValue, element.wdName, element.wdLabel, FBBoolToString(element.wdEnabled), FBBoolToString(element.wdVisible), FBBoolToString(element.wdAccessible), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex, element.wdPlaceholderValue, element.wdTraits];
68
69
  XCTAssertTrue([resultXml isEqualToString: expectedXml]);
69
70
  }
70
71
 
@@ -74,7 +75,7 @@
74
75
  id<FBElement> element = (id<FBElement>)[FBXCElementSnapshotWrapper ensureWrapped:(id)snapshot];
75
76
  NSString *resultXml = [self xmlStringWithElement:(id<FBXCElementSnapshot>)element
76
77
  xpathQuery:nil
77
- excludingAttributes:@[@"type", @"visible", @"value", @"index"]];
78
+ excludingAttributes:@[@"type", @"visible", @"value", @"index", @"traits", @"nativeFrame"]];
78
79
  NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ name=\"%@\" label=\"%@\" enabled=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" placeholderValue=\"%@\" private_indexPath=\"top\"/>\n",
79
80
  element.wdType, element.wdName, element.wdLabel, FBBoolToString(element.wdEnabled), FBBoolToString(element.wdAccessible), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdPlaceholderValue];
80
81
  XCTAssertEqualObjects(resultXml, expectedXml);
@@ -89,8 +90,8 @@
89
90
  NSString *resultXml = [self xmlStringWithElement:(id<FBXCElementSnapshot>)element
90
91
  xpathQuery:[NSString stringWithFormat:@"//%@[@*]", element.wdType]
91
92
  excludingAttributes:@[@"visible"]];
92
- 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=\"%@\" placeholderValue=\"%@\" private_indexPath=\"top\"/>\n",
93
- 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.wdPlaceholderValue];
93
+ 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=\"%@\" placeholderValue=\"%@\" traits=\"%@\" nativeFrame=\"%@\" private_indexPath=\"top\"/>\n",
94
+ 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.wdPlaceholderValue, element.wdTraits, NSStringFromCGRect(element.wdNativeFrame)];
94
95
  XCTAssertEqualObjects(expectedXml, resultXml);
95
96
  }
96
97
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium-webdriveragent",
3
- "version": "9.11.0",
3
+ "version": "9.13.0",
4
4
  "description": "Package bundling WebDriverAgent",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",