appium-webdriveragent 9.9.0 → 9.10.1

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,19 @@
1
+ ## [9.10.1](https://github.com/appium/WebDriverAgent/compare/v9.10.0...v9.10.1) (2025-05-30)
2
+
3
+ ### Miscellaneous Chores
4
+
5
+ * Make sure the same import style is used everywhere ([#1024](https://github.com/appium/WebDriverAgent/issues/1024)) ([1c50072](https://github.com/appium/WebDriverAgent/commit/1c50072457a8b82eec3684029386ccfa9432eccc))
6
+
7
+ ## [9.10.0](https://github.com/appium/WebDriverAgent/compare/v9.9.0...v9.10.0) (2025-05-27)
8
+
9
+ ### Features
10
+
11
+ * Add accessibility traits of the element ([#1020](https://github.com/appium/WebDriverAgent/issues/1020)) ([9465aaf](https://github.com/appium/WebDriverAgent/commit/9465aafd5e81ef57be7f78e9f2e188d3c1ba1bee))
12
+
13
+ ### Bug Fixes
14
+
15
+ * Use native snapshots if hittable attribute is requested in xPath ([#1023](https://github.com/appium/WebDriverAgent/issues/1023)) ([49d26cb](https://github.com/appium/WebDriverAgent/commit/49d26cb02a8515d1a1b52b65b7cb65512dfd749b))
16
+
1
17
  ## [9.9.0](https://github.com/appium/WebDriverAgent/compare/v9.8.0...v9.9.0) (2025-05-26)
2
18
 
3
19
  ### Features
@@ -21,12 +21,12 @@
21
21
  13DE7A4A287C4005003243C6 /* FBXCDeviceEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = 13DE7A47287C4005003243C6 /* FBXCDeviceEvent.h */; };
22
22
  13DE7A4B287C4005003243C6 /* FBXCDeviceEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DE7A48287C4005003243C6 /* FBXCDeviceEvent.m */; };
23
23
  13DE7A4C287C4005003243C6 /* FBXCDeviceEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DE7A48287C4005003243C6 /* FBXCDeviceEvent.m */; };
24
- 13DE7A4F287C46BB003243C6 /* FBXCElementSnapshot.h in Headers */ = {isa = PBXBuildFile; fileRef = 13DE7A4D287C46BB003243C6 /* FBXCElementSnapshot.h */; };
25
- 13DE7A50287C46BB003243C6 /* FBXCElementSnapshot.h in Headers */ = {isa = PBXBuildFile; fileRef = 13DE7A4D287C46BB003243C6 /* FBXCElementSnapshot.h */; };
24
+ 13DE7A4F287C46BB003243C6 /* FBXCElementSnapshot.h in Headers */ = {isa = PBXBuildFile; fileRef = 13DE7A4D287C46BB003243C6 /* FBXCElementSnapshot.h */; settings = {ATTRIBUTES = (Public, ); }; };
25
+ 13DE7A50287C46BB003243C6 /* FBXCElementSnapshot.h in Headers */ = {isa = PBXBuildFile; fileRef = 13DE7A4D287C46BB003243C6 /* FBXCElementSnapshot.h */; settings = {ATTRIBUTES = (Public, ); }; };
26
26
  13DE7A51287C46BB003243C6 /* FBXCElementSnapshot.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DE7A4E287C46BB003243C6 /* FBXCElementSnapshot.m */; };
27
27
  13DE7A52287C46BB003243C6 /* FBXCElementSnapshot.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DE7A4E287C46BB003243C6 /* FBXCElementSnapshot.m */; };
28
- 13DE7A55287CA1EC003243C6 /* FBXCElementSnapshotWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 13DE7A53287CA1EC003243C6 /* FBXCElementSnapshotWrapper.h */; };
29
- 13DE7A56287CA1EC003243C6 /* FBXCElementSnapshotWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 13DE7A53287CA1EC003243C6 /* FBXCElementSnapshotWrapper.h */; };
28
+ 13DE7A55287CA1EC003243C6 /* FBXCElementSnapshotWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 13DE7A53287CA1EC003243C6 /* FBXCElementSnapshotWrapper.h */; settings = {ATTRIBUTES = (Public, ); }; };
29
+ 13DE7A56287CA1EC003243C6 /* FBXCElementSnapshotWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 13DE7A53287CA1EC003243C6 /* FBXCElementSnapshotWrapper.h */; settings = {ATTRIBUTES = (Public, ); }; };
30
30
  13DE7A57287CA1EC003243C6 /* FBXCElementSnapshotWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DE7A54287CA1EC003243C6 /* FBXCElementSnapshotWrapper.m */; };
31
31
  13DE7A58287CA1EC003243C6 /* FBXCElementSnapshotWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 13DE7A54287CA1EC003243C6 /* FBXCElementSnapshotWrapper.m */; };
32
32
  13DE7A5B287CA444003243C6 /* FBXCElementSnapshotWrapper+Helpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 13DE7A59287CA444003243C6 /* FBXCElementSnapshotWrapper+Helpers.h */; };
@@ -539,6 +539,10 @@
539
539
  ADBC39981D07842800327304 /* XCUIElementDouble.m in Sources */ = {isa = PBXBuildFile; fileRef = ADBC39971D07842800327304 /* XCUIElementDouble.m */; };
540
540
  ADDA07241D6BB2BF001700AC /* FBScrollViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = ADDA07231D6BB2BF001700AC /* FBScrollViewController.m */; };
541
541
  ADEF63AF1D09DEBE0070A7E3 /* FBRuntimeUtilsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = ADEF63AE1D09DEBE0070A7E3 /* FBRuntimeUtilsTests.m */; };
542
+ B316351C2DDF0CF5007D9317 /* FBAccessibilityTraits.m in Sources */ = {isa = PBXBuildFile; fileRef = B316351B2DDF0CF5007D9317 /* FBAccessibilityTraits.m */; };
543
+ B316351D2DDF0CF5007D9317 /* FBAccessibilityTraits.m in Sources */ = {isa = PBXBuildFile; fileRef = B316351B2DDF0CF5007D9317 /* FBAccessibilityTraits.m */; };
544
+ B316351F2DDF0D0B007D9317 /* FBAccessibilityTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = B316351E2DDF0D0B007D9317 /* FBAccessibilityTraits.h */; };
545
+ B31635202DDF0D0B007D9317 /* FBAccessibilityTraits.h in Headers */ = {isa = PBXBuildFile; fileRef = B316351E2DDF0D0B007D9317 /* FBAccessibilityTraits.h */; };
542
546
  C845206222D5E79400EA68CB /* FBUnattachedAppLauncher.h in Headers */ = {isa = PBXBuildFile; fileRef = C8FB547722D4C1FC00B69954 /* FBUnattachedAppLauncher.h */; };
543
547
  C845206322D5E79700EA68CB /* FBUnattachedAppLauncher.m in Sources */ = {isa = PBXBuildFile; fileRef = C8FB547822D4C1FC00B69954 /* FBUnattachedAppLauncher.m */; };
544
548
  C8FB547422D3949C00B69954 /* LSApplicationWorkspace.h in Headers */ = {isa = PBXBuildFile; fileRef = C8FB547322D3949C00B69954 /* LSApplicationWorkspace.h */; };
@@ -1115,6 +1119,8 @@
1115
1119
  ADDA07221D6BB2BF001700AC /* FBScrollViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FBScrollViewController.h; sourceTree = "<group>"; };
1116
1120
  ADDA07231D6BB2BF001700AC /* FBScrollViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBScrollViewController.m; sourceTree = "<group>"; };
1117
1121
  ADEF63AE1D09DEBE0070A7E3 /* FBRuntimeUtilsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBRuntimeUtilsTests.m; sourceTree = "<group>"; };
1122
+ B316351B2DDF0CF5007D9317 /* FBAccessibilityTraits.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBAccessibilityTraits.m; sourceTree = "<group>"; };
1123
+ B316351E2DDF0D0B007D9317 /* FBAccessibilityTraits.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBAccessibilityTraits.h; sourceTree = "<group>"; };
1118
1124
  C8FB547322D3949C00B69954 /* LSApplicationWorkspace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LSApplicationWorkspace.h; sourceTree = "<group>"; };
1119
1125
  C8FB547722D4C1FC00B69954 /* FBUnattachedAppLauncher.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBUnattachedAppLauncher.h; sourceTree = "<group>"; };
1120
1126
  C8FB547822D4C1FC00B69954 /* FBUnattachedAppLauncher.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBUnattachedAppLauncher.m; sourceTree = "<group>"; };
@@ -1979,6 +1985,8 @@
1979
1985
  EE6B64FC1D0F86EF00E85F5D /* XCTestPrivateSymbols.m */,
1980
1986
  633E904A220DEE7F007CADF9 /* XCUIApplicationProcessDelay.h */,
1981
1987
  6385F4A5220A40760095BBDB /* XCUIApplicationProcessDelay.m */,
1988
+ B316351B2DDF0CF5007D9317 /* FBAccessibilityTraits.m */,
1989
+ B316351E2DDF0D0B007D9317 /* FBAccessibilityTraits.h */,
1982
1990
  );
1983
1991
  name = Utilities;
1984
1992
  path = WebDriverAgentLib/Utilities;
@@ -2292,6 +2300,8 @@
2292
2300
  641EE6392240C5CA00173FCB /* FBRouteRequest.h in Headers */,
2293
2301
  648C10AC22AAAD9C00B81B9A /* UIKeyboardImpl.h in Headers */,
2294
2302
  718226CD2587443700661B83 /* GCDAsyncSocket.h in Headers */,
2303
+ 13DE7A50287C46BB003243C6 /* FBXCElementSnapshot.h in Headers */,
2304
+ 13DE7A56287CA1EC003243C6 /* FBXCElementSnapshotWrapper.h in Headers */,
2295
2305
  71F3E7D525417FF400E0C22B /* FBSettings.h in Headers */,
2296
2306
  641EE63A2240C5CA00173FCB /* XCTest.h in Headers */,
2297
2307
  641EE63B2240C5CA00173FCB /* FBAlertsMonitor.h in Headers */,
@@ -2340,7 +2350,6 @@
2340
2350
  641EE6632240C5CA00173FCB /* FBUnknownCommands.h in Headers */,
2341
2351
  641EE7062240CDCF00173FCB /* XCUIElement+FBTVFocuse.h in Headers */,
2342
2352
  71822738258744B800661B83 /* HTTPConnection.h in Headers */,
2343
- 13DE7A56287CA1EC003243C6 /* FBXCElementSnapshotWrapper.h in Headers */,
2344
2353
  641EE6642240C5CA00173FCB /* NSPredicate+FBFormat.h in Headers */,
2345
2354
  641EE6652240C5CA00173FCB /* UILongPressGestureRecognizer-RecordingAdditions.h in Headers */,
2346
2355
  641EE6662240C5CA00173FCB /* XCTestCase.h in Headers */,
@@ -2420,6 +2429,7 @@
2420
2429
  641EE6A62240C5CA00173FCB /* FBImageProcessor.h in Headers */,
2421
2430
  641EE6A72240C5CA00173FCB /* FBSession-Private.h in Headers */,
2422
2431
  641EE6A82240C5CA00173FCB /* NSString+FBXMLSafeString.h in Headers */,
2432
+ B316351F2DDF0D0B007D9317 /* FBAccessibilityTraits.h in Headers */,
2423
2433
  64E3502F2AC0B6FE005F3ACB /* NSDictionary+FBUtf8SafeDictionary.h in Headers */,
2424
2434
  641EE6A92240C5CA00173FCB /* FBCommandStatus.h in Headers */,
2425
2435
  71822702258744A400661B83 /* HTTPResponseProxy.h in Headers */,
@@ -2501,7 +2511,6 @@
2501
2511
  641EE6E72240C5CA00173FCB /* XCUIElement+FBFind.h in Headers */,
2502
2512
  641EE6E82240C5CA00173FCB /* XCTestManager_ManagerInterface-Protocol.h in Headers */,
2503
2513
  641EE6E92240C5CA00173FCB /* FBFailureProofTestCase.h in Headers */,
2504
- 13DE7A50287C46BB003243C6 /* FBXCElementSnapshot.h in Headers */,
2505
2514
  641EE6EA2240C5CA00173FCB /* XCTTestRunSessionDelegate-Protocol.h in Headers */,
2506
2515
  641EE6EB2240C5CA00173FCB /* XCTestCaseSuite.h in Headers */,
2507
2516
  641EE6EC2240C5CA00173FCB /* _XCInternalTestRun.h in Headers */,
@@ -2572,6 +2581,7 @@
2572
2581
  EE35AD721E3B77D600A02D78 /* XCUIElementHitPointCoordinate.h in Headers */,
2573
2582
  EE35AD3F1E3B77D600A02D78 /* XCTDarwinNotificationExpectation.h in Headers */,
2574
2583
  EE35AD5F1E3B77D600A02D78 /* XCTRunnerAutomationSession.h in Headers */,
2584
+ 13DE7A4F287C46BB003243C6 /* FBXCElementSnapshot.h in Headers */,
2575
2585
  71C9EAAC25E8415A00470CD8 /* FBScreenshot.h in Headers */,
2576
2586
  EE35AD371E3B77D600A02D78 /* XCSourceCodeTreeNodeEnumerator.h in Headers */,
2577
2587
  EE158AB01CBD456F00A3E3F0 /* XCUIElement+FBIsVisible.h in Headers */,
@@ -2669,7 +2679,6 @@
2669
2679
  EE158AB81CBD456F00A3E3F0 /* FBAlertViewCommands.h in Headers */,
2670
2680
  EE35AD651E3B77D600A02D78 /* XCTWaiter.h in Headers */,
2671
2681
  EE35AD681E3B77D600A02D78 /* XCTWaiterManagement-Protocol.h in Headers */,
2672
- 13DE7A4F287C46BB003243C6 /* FBXCElementSnapshot.h in Headers */,
2673
2682
  EE35AD451E3B77D600A02D78 /* XCTestContext.h in Headers */,
2674
2683
  EE35AD661E3B77D600A02D78 /* XCTWaiterDelegate-Protocol.h in Headers */,
2675
2684
  EE35AD0E1E3B77D600A02D78 /* _XCTestExpectationImplementation.h in Headers */,
@@ -2712,6 +2721,7 @@
2712
2721
  EE35AD571E3B77D600A02D78 /* XCTestSuiteRun.h in Headers */,
2713
2722
  EE35AD701E3B77D600A02D78 /* XCUIElementAsynchronousHandlerWrapper.h in Headers */,
2714
2723
  EE35AD4C1E3B77D600A02D78 /* XCTestLog.h in Headers */,
2724
+ B31635202DDF0D0B007D9317 /* FBAccessibilityTraits.h in Headers */,
2715
2725
  71BB58E82B96328700CB9BFE /* FBScreenRecordingRequest.h in Headers */,
2716
2726
  EE35AD231E3B77D600A02D78 /* UITapGestureRecognizer-RecordingAdditions.h in Headers */,
2717
2727
  EE35AD2A1E3B77D600A02D78 /* XCDebugLogDelegate-Protocol.h in Headers */,
@@ -3173,6 +3183,7 @@
3173
3183
  641EE6082240C5CA00173FCB /* FBRuntimeUtils.m in Sources */,
3174
3184
  641EE6092240C5CA00173FCB /* XCUIElement+FBUtilities.m in Sources */,
3175
3185
  641EE60A2240C5CA00173FCB /* FBLogger.m in Sources */,
3186
+ B316351D2DDF0CF5007D9317 /* FBAccessibilityTraits.m in Sources */,
3176
3187
  641EE60B2240C5CA00173FCB /* FBCustomCommands.m in Sources */,
3177
3188
  71BB58E42B9631F100CB9BFE /* FBScreenRecordingPromise.m in Sources */,
3178
3189
  641EE60C2240C5CA00173FCB /* XCUIDevice+FBHelpers.m in Sources */,
@@ -3257,6 +3268,7 @@
3257
3268
  71AE3CFA2D38EE8E0039FC36 /* XCUIElement+FBVisibleFrame.m in Sources */,
3258
3269
  EEBBD48C1D47746D00656A81 /* XCUIElement+FBFind.m in Sources */,
3259
3270
  EE158ADD1CBD456F00A3E3F0 /* FBResponsePayload.m in Sources */,
3271
+ B316351C2DDF0CF5007D9317 /* FBAccessibilityTraits.m in Sources */,
3260
3272
  E444DCB524913C220060D7EB /* RouteRequest.m in Sources */,
3261
3273
  C8FB547A22D4C1FC00B69954 /* FBUnattachedAppLauncher.m in Sources */,
3262
3274
  EE158ADF1CBD456F00A3E3F0 /* FBRoute.m in Sources */,
@@ -48,6 +48,7 @@ static NSString* const FBExclusionAttributeAccessible = @"accessible";
48
48
  static NSString* const FBExclusionAttributeFocused = @"focused";
49
49
  static NSString* const FBExclusionAttributePlaceholderValue = @"placeholderValue";
50
50
  static NSString* const FBExclusionAttributeNativeFrame = @"nativeFrame";
51
+ static NSString* const FBExclusionAttributeTraits = @"traits";
51
52
 
52
53
  _Nullable id extractIssueProperty(id issue, NSString *propertyName) {
53
54
  SEL selector = NSSelectorFromString(propertyName);
@@ -209,6 +210,7 @@ NSDictionary<NSString *, NSString *> *customExclusionAttributesMap(void) {
209
210
  FBExclusionAttributeFrame,
210
211
  FBExclusionAttributePlaceholderValue,
211
212
  FBExclusionAttributeNativeFrame,
213
+ FBExclusionAttributeTraits,
212
214
  nil];
213
215
 
214
216
  for (NSString *key in attributeBlocks) {
@@ -265,6 +267,9 @@ NSDictionary<NSString *, NSString *> *customExclusionAttributesMap(void) {
265
267
  },
266
268
  FBExclusionAttributeFocused: ^{
267
269
  return [@([wrappedSnapshot isWDFocused]) stringValue];
270
+ },
271
+ FBExclusionAttributeTraits: ^{
272
+ return wrappedSnapshot.wdTraits;
268
273
  }
269
274
  } mutableCopy];
270
275
 
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  #import <WebDriverAgentLib/XCUIElement.h>
11
- #import "FBXCElementSnapshotWrapper.h"
11
+ #import <WebDriverAgentLib/FBXCElementSnapshotWrapper.h>
12
12
 
13
13
  NS_ASSUME_NONNULL_BEGIN
14
14
 
@@ -7,7 +7,7 @@
7
7
  * of patent rights can be found in the PATENTS file in the same directory.
8
8
  */
9
9
 
10
- #import "FBXCElementSnapshotWrapper.h"
10
+ #import <WebDriverAgentLib/FBXCElementSnapshotWrapper.h>
11
11
 
12
12
  NS_ASSUME_NONNULL_BEGIN
13
13
 
@@ -9,7 +9,7 @@
9
9
 
10
10
  #import <XCTest/XCTest.h>
11
11
  #import <WebDriverAgentLib/FBElement.h>
12
- #import "FBXCElementSnapshot.h"
12
+ #import <WebDriverAgentLib/FBXCElementSnapshot.h>
13
13
 
14
14
  NS_ASSUME_NONNULL_BEGIN
15
15
 
@@ -9,7 +9,7 @@
9
9
 
10
10
  #import <WebDriverAgentLib/FBElement.h>
11
11
  #import <WebDriverAgentLib/XCUIElement.h>
12
- #import "FBXCElementSnapshotWrapper.h"
12
+ #import <WebDriverAgentLib/FBXCElementSnapshotWrapper.h>
13
13
 
14
14
  NS_ASSUME_NONNULL_BEGIN
15
15
 
@@ -22,6 +22,7 @@
22
22
  #import "FBElementUtils.h"
23
23
  #import "XCTestPrivateSymbols.h"
24
24
  #import "XCUIHitPointResult.h"
25
+ #import "FBAccessibilityTraits.h"
25
26
 
26
27
  #define BROKEN_RECT CGRectMake(-1, -1, 0, 0)
27
28
 
@@ -159,6 +160,22 @@
159
160
  return self.frame;
160
161
  }
161
162
 
163
+ /**
164
+ Returns a comma-separated string of accessibility traits for the element.
165
+ This method converts the element's accessibility traits bitmask into human-readable strings
166
+ using FBAccessibilityTraitsToStringsArray. The traits represent various accessibility
167
+ characteristics of the element such as Button, Link, Image, etc.
168
+ You can find the list of possible traits in the Apple documentation:
169
+ https://developer.apple.com/documentation/uikit/uiaccessibilitytraits?language=objc
170
+
171
+ @return A comma-separated string of accessibility traits, or an empty string if no traits are set
172
+ */
173
+ - (NSString *)wdTraits
174
+ {
175
+ NSArray<NSString *> *traits = FBAccessibilityTraitsToStringsArray(self.snapshot.traits);
176
+ return [traits componentsJoinedByString:@", "];
177
+ }
178
+
162
179
  - (BOOL)isWDVisible
163
180
  {
164
181
  return self.fb_isVisible;
@@ -15,11 +15,11 @@
15
15
  <key>CFBundlePackageType</key>
16
16
  <string>FMWK</string>
17
17
  <key>CFBundleShortVersionString</key>
18
- <string>9.9.0</string>
18
+ <string>9.10.1</string>
19
19
  <key>CFBundleSignature</key>
20
20
  <string>????</string>
21
21
  <key>CFBundleVersion</key>
22
- <string>9.9.0</string>
22
+ <string>9.10.1</string>
23
23
  <key>NSPrincipalClass</key>
24
24
  <string/>
25
25
  </dict>
@@ -38,6 +38,9 @@ NS_ASSUME_NONNULL_BEGIN
38
38
  /*! Element's type */
39
39
  @property (nonatomic, readonly, copy) NSString *wdType;
40
40
 
41
+ /*! Element's accessibility traits as a comma-separated string */
42
+ @property (nonatomic, readonly, copy) NSString *wdTraits;
43
+
41
44
  /*! Element's value */
42
45
  @property (nonatomic, readonly, strong, nullable) NSString *wdValue;
43
46
 
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ */
9
+
10
+ #import <XCTest/XCTest.h>
11
+
12
+ NS_ASSUME_NONNULL_BEGIN
13
+
14
+ /**
15
+ Converts accessibility traits bitmask to an array of string representations
16
+ @param traits The accessibility traits bitmask
17
+ @return Array of strings representing the accessibility traits
18
+ */
19
+ NSArray<NSString *> *FBAccessibilityTraitsToStringsArray(unsigned long long traits);
20
+
21
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ */
9
+
10
+ #import "FBAccessibilityTraits.h"
11
+
12
+ NSArray<NSString *> *FBAccessibilityTraitsToStringsArray(unsigned long long traits) {
13
+ NSMutableArray<NSString *> *traitStringsArray;
14
+ NSNumber *key;
15
+
16
+ static NSDictionary<NSNumber *, NSString *> *traitsMapping;
17
+ static dispatch_once_t onceToken;
18
+
19
+ dispatch_once(&onceToken, ^{
20
+ NSMutableDictionary<NSNumber *, NSString *> *mapping = [@{
21
+ @(UIAccessibilityTraitNone): @"None",
22
+ @(UIAccessibilityTraitButton): @"Button",
23
+ @(UIAccessibilityTraitLink): @"Link",
24
+ @(UIAccessibilityTraitHeader): @"Header",
25
+ @(UIAccessibilityTraitSearchField): @"SearchField",
26
+ @(UIAccessibilityTraitImage): @"Image",
27
+ @(UIAccessibilityTraitSelected): @"Selected",
28
+ @(UIAccessibilityTraitPlaysSound): @"PlaysSound",
29
+ @(UIAccessibilityTraitKeyboardKey): @"KeyboardKey",
30
+ @(UIAccessibilityTraitStaticText): @"StaticText",
31
+ @(UIAccessibilityTraitSummaryElement): @"SummaryElement",
32
+ @(UIAccessibilityTraitNotEnabled): @"NotEnabled",
33
+ @(UIAccessibilityTraitUpdatesFrequently): @"UpdatesFrequently",
34
+ @(UIAccessibilityTraitStartsMediaSession): @"StartsMediaSession",
35
+ @(UIAccessibilityTraitAdjustable): @"Adjustable",
36
+ @(UIAccessibilityTraitAllowsDirectInteraction): @"AllowsDirectInteraction",
37
+ @(UIAccessibilityTraitCausesPageTurn): @"CausesPageTurn",
38
+ @(UIAccessibilityTraitTabBar): @"TabBar"
39
+ } mutableCopy];
40
+
41
+ #if __clang_major__ >= 16
42
+ // Add iOS 17.0 specific traits if available
43
+ if (@available(iOS 17.0, *)) {
44
+ [mapping addEntriesFromDictionary:@{
45
+ @(UIAccessibilityTraitToggleButton): @"ToggleButton",
46
+ @(UIAccessibilityTraitSupportsZoom): @"SupportsZoom"
47
+ }];
48
+ }
49
+ #endif
50
+
51
+ traitsMapping = [mapping copy];
52
+ });
53
+
54
+ traitStringsArray = [NSMutableArray array];
55
+ for (key in traitsMapping) {
56
+ if (traits & [key unsignedLongLongValue] && nil != traitsMapping[key]) {
57
+ [traitStringsArray addObject:(id)traitsMapping[key]];
58
+ }
59
+ }
60
+
61
+ return [traitStringsArray copy];
62
+ }
@@ -9,7 +9,7 @@
9
9
 
10
10
  #import <XCTest/XCTest.h>
11
11
  #import <WebDriverAgentLib/FBElement.h>
12
- #import "FBXCElementSnapshot.h"
12
+ #import <WebDriverAgentLib/FBXCElementSnapshot.h>
13
13
 
14
14
  #ifdef __clang__
15
15
  #pragma clang diagnostic push
@@ -146,7 +146,8 @@ static NSString *const topNodeIndexPath = @"top";
146
146
  }
147
147
 
148
148
  if (rc >= 0) {
149
- rc = [self xmlRepresentationWithRootElement:[self snapshotWithRoot:root]
149
+ [self waitUntilStableWithElement:root];
150
+ rc = [self xmlRepresentationWithRootElement:[self snapshotWithRoot:root useNative:NO]
150
151
  writer:writer
151
152
  elementStore:nil
152
153
  query:nil
@@ -196,17 +197,23 @@ static NSString *const topNodeIndexPath = @"top";
196
197
  int rc = xmlTextWriterStartDocument(writer, NULL, _UTF8Encoding, NULL);
197
198
  id<FBXCElementSnapshot> lookupScopeSnapshot = nil;
198
199
  id<FBXCElementSnapshot> contextRootSnapshot = nil;
200
+ BOOL useNativeSnapshot = nil == xpathQuery
201
+ ? NO
202
+ : [[self.class elementAttributesWithXPathQuery:xpathQuery] containsObject:FBHittableAttribute.class];
199
203
  if (rc < 0) {
200
204
  [FBLogger logFmt:@"Failed to invoke libxml2>xmlTextWriterStartDocument. Error code: %d", rc];
201
205
  } else {
206
+ [self waitUntilStableWithElement:root];
202
207
  if (FBConfiguration.limitXpathContextScope) {
203
- lookupScopeSnapshot = [self snapshotWithRoot:root];
208
+ lookupScopeSnapshot = [self snapshotWithRoot:root useNative:useNativeSnapshot];
204
209
  } else {
205
210
  if ([root isKindOfClass:XCUIElement.class]) {
206
- lookupScopeSnapshot = [self snapshotWithRoot:[(XCUIElement *)root application]];
211
+ lookupScopeSnapshot = [self snapshotWithRoot:[(XCUIElement *)root application]
212
+ useNative:useNativeSnapshot];
207
213
  contextRootSnapshot = [root isKindOfClass:XCUIApplication.class]
208
214
  ? nil
209
- : ([(XCUIElement *)root lastSnapshot] ?: [(XCUIElement *)root fb_customSnapshot]);
215
+ : ([(XCUIElement *)root lastSnapshot] ?: [self snapshotWithRoot:(XCUIElement *)root
216
+ useNative:useNativeSnapshot]);
210
217
  } else {
211
218
  lookupScopeSnapshot = (id<FBXCElementSnapshot>)root;
212
219
  contextRootSnapshot = nil == lookupScopeSnapshot.parent ? nil : (id<FBXCElementSnapshot>)root;
@@ -483,19 +490,29 @@ static NSString *const topNodeIndexPath = @"top";
483
490
  }
484
491
 
485
492
  + (id<FBXCElementSnapshot>)snapshotWithRoot:(id<FBElement>)root
493
+ useNative:(BOOL)useNative
486
494
  {
487
495
  if (![root isKindOfClass:XCUIElement.class]) {
488
496
  return (id<FBXCElementSnapshot>)root;
489
497
  }
490
498
 
491
- // If the app is not idle state while we retrieve the visiblity state
492
- // then the snapshot retrieval operation might freeze and time out
493
- [[(XCUIElement *)root application] fb_waitUntilStableWithTimeout:FBConfiguration.animationCoolOffTimeout];
499
+ if (useNative) {
500
+ return [(XCUIElement *)root fb_nativeSnapshot];
501
+ }
494
502
  return [root isKindOfClass:XCUIApplication.class]
495
503
  ? [(XCUIElement *)root fb_standardSnapshot]
496
504
  : [(XCUIElement *)root fb_customSnapshot];
497
505
  }
498
506
 
507
+ + (void)waitUntilStableWithElement:(id<FBElement>)root
508
+ {
509
+ if ([root isKindOfClass:XCUIElement.class]) {
510
+ // If the app is not idle state while we retrieve the visiblity state
511
+ // then the snapshot retrieval operation might freeze and time out
512
+ [[(XCUIElement *)root application] fb_waitUntilStableWithTimeout:FBConfiguration.animationCoolOffTimeout];
513
+ }
514
+ }
515
+
499
516
  @end
500
517
 
501
518
 
@@ -15,6 +15,7 @@ FOUNDATION_EXPORT double WebDriverAgentLib_VersionNumber;
15
15
  //! Project version string for WebDriverAgentLib_.
16
16
  FOUNDATION_EXPORT const unsigned char WebDriverAgentLib_VersionString[];
17
17
 
18
+ #import <WebDriverAgentLib/CDStructures.h>
18
19
  #import <WebDriverAgentLib/FBAlert.h>
19
20
  #import <WebDriverAgentLib/FBCommandHandler.h>
20
21
  #import <WebDriverAgentLib/FBCommandStatus.h>
@@ -38,9 +39,17 @@ FOUNDATION_EXPORT const unsigned char WebDriverAgentLib_VersionString[];
38
39
  #import <WebDriverAgentLib/FBRuntimeUtils.h>
39
40
  #import <WebDriverAgentLib/FBSession.h>
40
41
  #import <WebDriverAgentLib/FBWebServer.h>
42
+ #import <WebDriverAgentLib/FBXCElementSnapshot.h>
43
+ #import <WebDriverAgentLib/FBXCElementSnapshotWrapper.h>
44
+ #import <WebDriverAgentLib/FBXPath.h>
45
+ #import <WebDriverAgentLib/WebDriverAgentLib.h>
46
+ #import <WebDriverAgentLib/XCDebugLogDelegate-Protocol.h>
47
+ #import <WebDriverAgentLib/XCTestCase.h>
48
+ #import <WebDriverAgentLib/XCTIssue+FBPatcher.h>
41
49
  #import <WebDriverAgentLib/XCUIApplication+FBHelpers.h>
42
50
  #import <WebDriverAgentLib/XCUIDevice+FBHelpers.h>
43
51
  #import <WebDriverAgentLib/XCUIDevice+FBRotation.h>
52
+ #import <WebDriverAgentLib/XCUIElement.h>
44
53
  #import <WebDriverAgentLib/XCUIElement+FBAccessibility.h>
45
54
  #import <WebDriverAgentLib/XCUIElement+FBFind.h>
46
55
  #import <WebDriverAgentLib/XCUIElement+FBIsVisible.h>
@@ -96,6 +96,52 @@
96
96
  XCTAssertEqual(element2.wdIndex, 0);
97
97
  }
98
98
 
99
+ - (void)testAccessibilityTraits
100
+ {
101
+ XCUIElement *button = self.testedApplication.buttons.firstMatch;
102
+ XCTAssertTrue(button.exists);
103
+ NSArray *buttonTraits = [button.wdTraits componentsSeparatedByString:@", "];
104
+ NSArray *expectedButtonTraits = @[@"Button"];
105
+ XCTAssertEqual(buttonTraits.count, expectedButtonTraits.count, @"Button should have exactly 1 trait");
106
+ XCTAssertEqualObjects(buttonTraits, expectedButtonTraits);
107
+ XCTAssertEqualObjects(button.wdType, @"XCUIElementTypeButton");
108
+
109
+ XCUIElement *toggle = self.testedApplication.switches.firstMatch;
110
+ XCTAssertTrue(toggle.exists);
111
+
112
+ // iOS 17.0 specific traits if available
113
+ NSArray *toggleTraits = [toggle.wdTraits componentsSeparatedByString:@", "];
114
+ NSArray *expectedToggleTraits;
115
+
116
+ #if __clang_major__ >= 16
117
+ if (@available(iOS 17.0, *)) {
118
+ expectedToggleTraits = @[@"ToggleButton", @"Button"];
119
+ XCTAssertEqual(toggleTraits.count, 2, @"Toggle should have exactly 2 traits on iOS 17+");
120
+ }
121
+ #else
122
+ expectedToggleTraits = @[@"Button"];
123
+ XCTAssertEqual(toggleTraits.count, 1, @"Toggle should have exactly 1 trait on iOS < 17");
124
+ #endif
125
+ XCTAssertEqualObjects(toggleTraits, expectedToggleTraits);
126
+ XCTAssertEqualObjects(toggle.wdType, @"XCUIElementTypeSwitch");
127
+
128
+ XCUIElement *slider = self.testedApplication.sliders.firstMatch;
129
+ XCTAssertTrue(slider.exists);
130
+ NSArray *sliderTraits = [slider.wdTraits componentsSeparatedByString:@", "];
131
+ NSArray *expectedSliderTraits = @[@"Adjustable"];
132
+ XCTAssertEqual(sliderTraits.count, expectedSliderTraits.count, @"Slider should have exactly 1 trait");
133
+ XCTAssertEqualObjects(sliderTraits, expectedSliderTraits);
134
+ XCTAssertEqualObjects(slider.wdType, @"XCUIElementTypeSlider");
135
+
136
+ XCUIElement *picker = self.testedApplication.pickerWheels.firstMatch;
137
+ XCTAssertTrue(picker.exists);
138
+ NSArray *pickerTraits = [picker.wdTraits componentsSeparatedByString:@", "];
139
+ NSArray *expectedPickerTraits = @[@"Adjustable"];
140
+ XCTAssertEqual(pickerTraits.count, expectedPickerTraits.count, @"Picker should have exactly 1 trait");
141
+ XCTAssertEqualObjects(pickerTraits, expectedPickerTraits);
142
+ XCTAssertEqualObjects(picker.wdType, @"XCUIElementTypePickerWheel");
143
+ }
144
+
99
145
  - (void)testTextFieldAttributes
100
146
  {
101
147
  XCUIElement *element = self.testedApplication.textFields[@"Value"];
@@ -461,4 +461,13 @@
461
461
  XCTAssertFalse(matchingSnapshots.lastObject.fb_isVisible);
462
462
  }
463
463
 
464
+ - (void)testNonHittableDescendantWithXPathQuery
465
+ {
466
+ NSArray<XCUIElement *> *matchingSnapshots = [self.testedApplication fb_descendantsMatchingXPathQuery:@"//XCUIElementTypeStaticText[@hittable='false']"
467
+ shouldReturnAfterFirstMatch:NO];
468
+ XCTAssertGreaterThan(matchingSnapshots.count, 1);
469
+ XCTAssertEqual(matchingSnapshots.lastObject.elementType, XCUIElementTypeStaticText);
470
+ XCTAssertFalse(matchingSnapshots.lastObject.fb_isVisible);
471
+ }
472
+
464
473
  @end
@@ -28,6 +28,7 @@
28
28
  @property (nonatomic, strong, readwrite, nullable) NSString *wdValue;
29
29
  @property (nonatomic, readwrite, getter=isWDEnabled) BOOL wdEnabled;
30
30
  @property (nonatomic, readwrite, getter=isWDSelected) BOOL wdSelected;
31
+ @property (nonatomic, readwrite, assign) CGRect wdNativeFrame;
31
32
  @property (nonatomic, readwrite) NSUInteger wdIndex;
32
33
  @property (nonatomic, readwrite, getter=isWDVisible) BOOL wdVisible;
33
34
  @property (nonatomic, readwrite, getter=isWDAccessible) BOOL wdAccessible;
@@ -37,6 +38,7 @@
37
38
  @property (copy, nonnull) NSArray *children;
38
39
  @property (nonatomic, readwrite, assign) XCUIElementType elementType;
39
40
  @property (nonatomic, readwrite, getter=isWDAccessibilityContainer) BOOL wdAccessibilityContainer;
41
+ @property (nonatomic, copy, readwrite, nullable) NSString *wdTraits;
40
42
 
41
43
  - (void)resolve;
42
44
  - (id _Nonnull)fb_standardSnapshot;
@@ -19,11 +19,13 @@
19
19
  {
20
20
  self = [super init];
21
21
  if (self) {
22
- self.wdFrame = CGRectMake(0, 0, 0, 0);
22
+ self.wdFrame = CGRectZero;
23
+ self.wdNativeFrame = CGRectZero;
23
24
  self.wdName = @"testName";
24
25
  self.wdLabel = @"testLabel";
25
26
  self.wdValue = @"magicValue";
26
27
  self.wdPlaceholderValue = @"testPlaceholderValue";
28
+ self.wdTraits = @"testTraits";
27
29
  self.wdVisible = YES;
28
30
  self.wdAccessible = YES;
29
31
  self.wdEnabled = YES;
@@ -94,4 +96,9 @@
94
96
  return self.wdUID;
95
97
  }
96
98
 
99
+ - (NSString *)wdTraits
100
+ {
101
+ return self.wdTraits;
102
+ }
103
+
97
104
  @end
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium-webdriveragent",
3
- "version": "9.9.0",
3
+ "version": "9.10.1",
4
4
  "description": "Package bundling WebDriverAgent",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",