appium-webdriveragent 9.7.1 → 9.9.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.9.0](https://github.com/appium/WebDriverAgent/compare/v9.8.0...v9.9.0) (2025-05-26)
2
+
3
+ ### Features
4
+
5
+ * Use another snapshotting mechanism for the hittable attribute calculation ([#1022](https://github.com/appium/WebDriverAgent/issues/1022)) ([13c9f45](https://github.com/appium/WebDriverAgent/commit/13c9f453d890ad9b78fa7c47728ebae33880966a))
6
+
7
+ ## [9.8.0](https://github.com/appium/WebDriverAgent/compare/v9.7.1...v9.8.0) (2025-05-21)
8
+
9
+ ### Features
10
+
11
+ * Add a native frame property of the element ([#1017](https://github.com/appium/WebDriverAgent/issues/1017)) ([09214c4](https://github.com/appium/WebDriverAgent/commit/09214c4228ed5a49c02adead452cb0bb8dd83b6d))
12
+
1
13
  ## [9.7.1](https://github.com/appium/WebDriverAgent/compare/v9.7.0...v9.7.1) (2025-05-21)
2
14
 
3
15
  ### Miscellaneous Chores
@@ -47,7 +47,7 @@ static NSString* const FBExclusionAttributeVisible = @"visible";
47
47
  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
51
 
52
52
  _Nullable id extractIssueProperty(id issue, NSString *propertyName) {
53
53
  SEL selector = NSSelectorFromString(propertyName);
@@ -205,8 +205,11 @@ NSDictionary<NSString *, NSString *> *customExclusionAttributesMap(void) {
205
205
 
206
206
  NSDictionary<NSString *, NSString *(^)(void)> *attributeBlocks = [self fb_attributeBlockMapForWrappedSnapshot:wrappedSnapshot];
207
207
 
208
- NSSet *nonPrefixedKeys = [NSSet setWithObjects:FBExclusionAttributeFrame,
209
- FBExclusionAttributePlaceholderValue, nil];
208
+ NSSet *nonPrefixedKeys = [NSSet setWithObjects:
209
+ FBExclusionAttributeFrame,
210
+ FBExclusionAttributePlaceholderValue,
211
+ FBExclusionAttributeNativeFrame,
212
+ nil];
210
213
 
211
214
  for (NSString *key in attributeBlocks) {
212
215
  if (excludedAttributes == nil || ![excludedAttributes containsObject:key]) {
@@ -247,6 +250,9 @@ NSDictionary<NSString *, NSString *> *customExclusionAttributesMap(void) {
247
250
  [@{
248
251
  FBExclusionAttributeFrame: ^{
249
252
  return NSStringFromCGRect(wrappedSnapshot.wdFrame);
253
+ },
254
+ FBExclusionAttributeNativeFrame: ^{
255
+ return NSStringFromCGRect(wrappedSnapshot.wdNativeFrame);
250
256
  },
251
257
  FBExclusionAttributeEnabled: ^{
252
258
  return [@([wrappedSnapshot isWDEnabled]) stringValue];
@@ -36,7 +36,7 @@ NS_ASSUME_NONNULL_BEGIN
36
36
  /**
37
37
  Gets the most recent snapshot of the current element. The element will be
38
38
  automatically resolved if the snapshot is not available yet.
39
- Calls to this method mutate the `lastSnapshot` instance property..
39
+ Calls to this method mutate the `lastSnapshot` instance property.
40
40
  The maximum snapshot tree depth is set by `FBConfiguration.snapshotMaxDepth`
41
41
 
42
42
  Snapshot specifics:
@@ -49,6 +49,21 @@ NS_ASSUME_NONNULL_BEGIN
49
49
  */
50
50
  - (id<FBXCElementSnapshot>)fb_customSnapshot;
51
51
 
52
+ /**
53
+ Gets the most recent snapshot of the current element. The element will be
54
+ automatically resolved if the snapshot is not available yet.
55
+ Calls to this method mutate the `lastSnapshot` instance property.
56
+ The maximum snapshot tree depth is set by `FBConfiguration.snapshotMaxDepth`
57
+
58
+ Snapshot specifics:
59
+ - Less performant in comparison to the standard one
60
+ - The `hittable` property calculation is aligned with the native calculation logic
61
+
62
+ @return The recent snapshot of the element
63
+ @throws FBStaleElementException if the element is not present in DOM and thus no snapshot could be made
64
+ */
65
+ - (id<FBXCElementSnapshot>)fb_nativeSnapshot;
66
+
52
67
  /**
53
68
  Extracts the cached element snapshot from its query.
54
69
  No requests to the accessiblity framework is made.
@@ -53,16 +53,7 @@
53
53
  ? [self.fb_query fb_uniqueSnapshotWithError:&error]
54
54
  : (id<FBXCElementSnapshot>)[self snapshotWithError:&error];
55
55
  if (nil == snapshot) {
56
- NSString *hintText = @"Make sure the application UI has the expected state";
57
- if (nil != error && [error.localizedDescription containsString:@"Identity Binding"]) {
58
- hintText = [NSString stringWithFormat:@"%@. You could also try to switch the binding strategy using the 'boundElementsByIndex' setting for the element lookup", hintText];
59
- }
60
- NSString *reason = [NSString stringWithFormat:@"The previously found element \"%@\" is not present in the current view anymore. %@",
61
- self.description, hintText];
62
- if (nil != error) {
63
- reason = [NSString stringWithFormat:@"%@. Original error: %@", reason, error.localizedDescription];
64
- }
65
- @throw [NSException exceptionWithName:FBStaleElementException reason:reason userInfo:@{}];
56
+ [self fb_raiseStaleElementExceptionWithError:error];
66
57
  }
67
58
  }
68
59
  self.lastSnapshot = snapshot;
@@ -79,6 +70,16 @@
79
70
  return [self fb_takeSnapshot:YES];
80
71
  }
81
72
 
73
+ - (id<FBXCElementSnapshot>)fb_nativeSnapshot
74
+ {
75
+ NSError *error = nil;
76
+ BOOL isSuccessful = [self resolveOrRaiseTestFailure:NO error:&error];
77
+ if (nil == self.lastSnapshot || !isSuccessful) {
78
+ [self fb_raiseStaleElementExceptionWithError:error];
79
+ }
80
+ return self.lastSnapshot;
81
+ }
82
+
82
83
  - (id<FBXCElementSnapshot>)fb_cachedSnapshot
83
84
  {
84
85
  return [self.query fb_cachedSnapshot];
@@ -153,4 +154,18 @@
153
154
  FBConfiguration.waitForIdleTimeout = previousTimeout;
154
155
  }
155
156
 
157
+ - (void)fb_raiseStaleElementExceptionWithError:(NSError *)error __attribute__((noreturn))
158
+ {
159
+ NSString *hintText = @"Make sure the application UI has the expected state";
160
+ if (nil != error && [error.localizedDescription containsString:@"Identity Binding"]) {
161
+ hintText = [NSString stringWithFormat:@"%@. You could also try to switch the binding strategy using the 'boundElementsByIndex' setting for the element lookup", hintText];
162
+ }
163
+ NSString *reason = [NSString stringWithFormat:@"The previously found element \"%@\" is not present in the current view anymore. %@",
164
+ self.description, hintText];
165
+ if (nil != error) {
166
+ reason = [NSString stringWithFormat:@"%@. Original error: %@", reason, error.localizedDescription];
167
+ }
168
+ @throw [NSException exceptionWithName:FBStaleElementException reason:reason userInfo:@{}];
169
+ }
170
+
156
171
  @end
@@ -29,6 +29,10 @@
29
29
 
30
30
  - (id<FBXCElementSnapshot>)fb_snapshotForAttributeName:(NSString *)name
31
31
  {
32
+ // https://github.com/appium/appium-xcuitest-driver/pull/2565
33
+ if ([name isEqualToString:FBStringify(XCUIElement, isWDHittable)]) {
34
+ return [self fb_nativeSnapshot];
35
+ }
32
36
  // https://github.com/appium/appium-xcuitest-driver/issues/2552
33
37
  BOOL isValueRequest = [name isEqualToString:FBStringify(XCUIElement, wdValue)];
34
38
  if ([self isKindOfClass:XCUIApplication.class] && !isValueRequest) {
@@ -147,6 +151,14 @@
147
151
  : CGRectIntegral(frame);
148
152
  }
149
153
 
154
+ - (CGRect)wdNativeFrame
155
+ {
156
+ // To avoid confusion regarding the frame returned by `wdFrame`,
157
+ // the current property is provided to represent the element's
158
+ // actual rendered frame.
159
+ return self.frame;
160
+ }
161
+
150
162
  - (BOOL)isWDVisible
151
163
  {
152
164
  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.7.1</string>
18
+ <string>9.9.0</string>
19
19
  <key>CFBundleSignature</key>
20
20
  <string>????</string>
21
21
  <key>CFBundleVersion</key>
22
- <string>9.7.1</string>
22
+ <string>9.9.0</string>
23
23
  <key>NSPrincipalClass</key>
24
24
  <string/>
25
25
  </dict>
@@ -20,6 +20,9 @@ NS_ASSUME_NONNULL_BEGIN
20
20
  /*! Element's frame in normalized (rounded dimensions without Infinity values) CGRect format */
21
21
  @property (nonatomic, readonly, assign) CGRect wdFrame;
22
22
 
23
+ /*! Represents the element's frame as a CGRect, preserving the actual values. */
24
+ @property (nonatomic, readonly, assign) CGRect wdNativeFrame;
25
+
23
26
  /*! Element's wsFrame in NSDictionary format */
24
27
  @property (nonatomic, readonly, copy) NSDictionary *wdRect;
25
28
 
@@ -16,7 +16,6 @@
16
16
  #import "XCUIElement+FBAccessibility.h"
17
17
  #import "XCUIElement+FBIsVisible.h"
18
18
  #import "XCUIElement+FBWebDriverAttributes.h"
19
- #import "FBXCodeCompatibility.h"
20
19
 
21
20
  @interface FBElementAttributeTests : FBIntegrationTestCase
22
21
  @end
@@ -157,7 +156,7 @@
157
156
  XCTAssertNil(element.wdPlaceholderValue);
158
157
  XCTAssertEqualObjects(element.wdValue, @"1");
159
158
  XCTAssertFalse(element.wdSelected);
160
- XCTAssertTrue(element.wdHittable);
159
+ XCTAssertEqual(element.wdHittable, element.hittable);
161
160
  [element tap];
162
161
  XCTAssertEqualObjects(element.wdValue, @"0");
163
162
  XCTAssertFalse(element.wdSelected);
@@ -15,7 +15,6 @@
15
15
  #import "FBMacros.h"
16
16
  #import "XCUIElement+FBIsVisible.h"
17
17
  #import "XCUIElement+FBScrolling.h"
18
-
19
18
  #import "XCUIElement+FBClassChain.h"
20
19
  #import "FBXCodeCompatibility.h"
21
20
 
@@ -43,8 +42,12 @@
43
42
  {
44
43
  FBAssertVisibleCell(@"0");
45
44
  FBAssertVisibleCell(@"10");
45
+ XCUIElement *cell10 = FBCellElementWithLabel(@"10");
46
+ XCTAssertEqual([cell10 isWDHittable], [cell10 isHittable]);
46
47
  FBAssertInvisibleCell(@"30");
47
48
  FBAssertInvisibleCell(@"50");
49
+ XCUIElement *cell50 = FBCellElementWithLabel(@"50");
50
+ XCTAssertEqual([cell50 isWDHittable], [cell50 isHittable]);
48
51
  }
49
52
 
50
53
  - (void)testSimpleScroll
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium-webdriveragent",
3
- "version": "9.7.1",
3
+ "version": "9.9.0",
4
4
  "description": "Package bundling WebDriverAgent",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",