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 +12 -0
- package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +9 -3
- package/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.h +16 -1
- package/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m +25 -10
- package/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m +12 -0
- package/WebDriverAgentLib/Info.plist +2 -2
- package/WebDriverAgentLib/Routing/FBElement.h +3 -0
- package/WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m +1 -2
- package/WebDriverAgentTests/IntegrationTests/FBScrollingTests.m +4 -1
- package/package.json +1 -1
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:
|
|
209
|
-
|
|
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
|
-
|
|
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.
|
|
18
|
+
<string>9.9.0</string>
|
|
19
19
|
<key>CFBundleSignature</key>
|
|
20
20
|
<string>????</string>
|
|
21
21
|
<key>CFBundleVersion</key>
|
|
22
|
-
<string>9.
|
|
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
|
-
|
|
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
|