appium-webdriveragent 9.0.0 → 9.0.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 +6 -0
- package/WebDriverAgentLib/Categories/XCUIElement+FBFind.m +0 -1
- package/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m +2 -1
- package/WebDriverAgentLib/Categories/XCUIElement+FBResolve.h +2 -1
- package/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m +9 -13
- package/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.h +0 -3
- package/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m +4 -7
- package/WebDriverAgentLib/Commands/FBElementCommands.m +4 -1
- package/WebDriverAgentLib/Commands/FBFindElementCommands.m +0 -1
- package/WebDriverAgentLib/Info.plist +2 -2
- package/WebDriverAgentLib/Routing/FBResponsePayload.m +18 -6
- package/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m +1 -3
- package/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m +5 -1
- package/WebDriverAgentTests/IntegrationTests/XCUIElementHelperIntegrationTests.m +0 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [9.0.1](https://github.com/appium/WebDriverAgent/compare/v9.0.0...v9.0.1) (2025-01-17)
|
|
2
|
+
|
|
3
|
+
### Miscellaneous Chores
|
|
4
|
+
|
|
5
|
+
* Optimize stable instance retrieval ([#973](https://github.com/appium/WebDriverAgent/issues/973)) ([f2c752d](https://github.com/appium/WebDriverAgent/commit/f2c752db4707b3864efb62b95b64abb487d28e4b))
|
|
6
|
+
|
|
1
7
|
## [9.0.0](https://github.com/appium/WebDriverAgent/compare/v8.12.2...v9.0.0) (2025-01-16)
|
|
2
8
|
|
|
3
9
|
### ⚠ BREAKING CHANGES
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
#import "FBRunLoopSpinner.h"
|
|
13
13
|
#import "FBXCElementSnapshot.h"
|
|
14
14
|
#import "FBXCodeCompatibility.h"
|
|
15
|
+
#import "XCUIElement+FBUID.h"
|
|
15
16
|
#import "XCUICoordinate.h"
|
|
16
17
|
#import "XCUIElement+FBCaching.h"
|
|
17
18
|
#import "XCUIElement+FBResolve.h"
|
|
@@ -33,7 +34,7 @@ static const NSTimeInterval VALUE_CHANGE_TIMEOUT = 2;
|
|
|
33
34
|
// Fetching stable instance of an element allows it to be bounded to the
|
|
34
35
|
// unique element identifier (UID), so it could be found next time even if its
|
|
35
36
|
// id is different from the initial one. See https://github.com/appium/appium/issues/17569
|
|
36
|
-
XCUIElement *stableInstance = self
|
|
37
|
+
XCUIElement *stableInstance = [self fb_stableInstanceWithUid:[FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot]];
|
|
37
38
|
[endCoord tap];
|
|
38
39
|
return [[[[FBRunLoopSpinner new]
|
|
39
40
|
timeout:VALUE_CHANGE_TIMEOUT]
|
|
@@ -27,10 +27,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
27
27
|
Although, if the cached element instance is the one returned by this API call then the same element
|
|
28
28
|
is going to be matched and no staleness exception will be thrown.
|
|
29
29
|
|
|
30
|
+
@param uid Element UUID
|
|
30
31
|
@return Either the same element instance if `fb_isResolvedNatively` was set to NO (usually the cache for elements
|
|
31
32
|
matched by xpath locators) or the stable instance of the self element based on the query by element's UUID.
|
|
32
33
|
*/
|
|
33
|
-
- (XCUIElement *)
|
|
34
|
+
- (XCUIElement *)fb_stableInstanceWithUid:(NSString *)uid;
|
|
34
35
|
|
|
35
36
|
@end
|
|
36
37
|
|
|
@@ -32,23 +32,19 @@ static char XCUIELEMENT_IS_RESOLVED_NATIVELY_KEY;
|
|
|
32
32
|
return nil == result ? @YES : result;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
- (XCUIElement *)
|
|
35
|
+
- (XCUIElement *)fb_stableInstanceWithUid:(NSString *)uid
|
|
36
36
|
{
|
|
37
|
-
if (![self.fb_isResolvedNatively boolValue]) {
|
|
37
|
+
if (nil == uid || ![self.fb_isResolvedNatively boolValue] || [self isKindOfClass:XCUIApplication.class]) {
|
|
38
38
|
return self;
|
|
39
39
|
}
|
|
40
|
-
|
|
41
|
-
XCUIElementQuery *query = [self
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
: [FBXCElementSnapshotWrapper wdUIDWithSnapshot:(id)self.fb_cachedSnapshot];
|
|
47
|
-
if (nil == uid) {
|
|
48
|
-
return self;
|
|
40
|
+
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K = %@", FBStringify(FBXCElementSnapshotWrapper, fb_uid), uid];
|
|
41
|
+
XCUIElementQuery *query = [self.application.fb_query descendantsMatchingType:XCUIElementTypeAny];
|
|
42
|
+
XCUIElement *result = [query matchingPredicate:predicate].allElementsBoundByIndex.firstObject;
|
|
43
|
+
if (nil != result) {
|
|
44
|
+
result.fb_isResolvedNatively = @NO;
|
|
45
|
+
return result;
|
|
49
46
|
}
|
|
50
|
-
|
|
51
|
-
return [query matchingPredicate:predicate].allElementsBoundByIndex.firstObject ?: self;
|
|
47
|
+
return self;
|
|
52
48
|
}
|
|
53
49
|
|
|
54
50
|
@end
|
|
@@ -41,14 +41,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
41
41
|
Filters elements by matching them to snapshots from the corresponding array
|
|
42
42
|
|
|
43
43
|
@param snapshots Array of snapshots to be matched with
|
|
44
|
-
@param selfUID Optionally the unique identifier of the current element.
|
|
45
|
-
Providing it as an argument improves the performance of the method.
|
|
46
44
|
@param onlyChildren Whether to only look for direct element children
|
|
47
45
|
|
|
48
46
|
@return Array of filtered elements, which have matches in snapshots array
|
|
49
47
|
*/
|
|
50
48
|
- (NSArray<XCUIElement *> *)fb_filterDescendantsWithSnapshots:(NSArray<id<FBXCElementSnapshot>> *)snapshots
|
|
51
|
-
selfUID:(nullable NSString *)selfUID
|
|
52
49
|
onlyChildren:(BOOL)onlyChildren;
|
|
53
50
|
|
|
54
51
|
/**
|
|
@@ -71,7 +71,6 @@
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
- (NSArray<XCUIElement *> *)fb_filterDescendantsWithSnapshots:(NSArray<id<FBXCElementSnapshot>> *)snapshots
|
|
74
|
-
selfUID:(NSString *)selfUID
|
|
75
74
|
onlyChildren:(BOOL)onlyChildren
|
|
76
75
|
{
|
|
77
76
|
if (0 == snapshots.count) {
|
|
@@ -85,13 +84,11 @@
|
|
|
85
84
|
}
|
|
86
85
|
}
|
|
87
86
|
NSMutableArray<XCUIElement *> *matchedElements = [NSMutableArray array];
|
|
88
|
-
NSString *uid =
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
87
|
+
NSString *uid = nil == self.lastSnapshot
|
|
88
|
+
? self.fb_uid
|
|
89
|
+
: [FBXCElementSnapshotWrapper wdUIDWithSnapshot:self.lastSnapshot];
|
|
92
90
|
if (nil != uid && [matchedIds containsObject:uid]) {
|
|
93
|
-
XCUIElement *stableSelf = self
|
|
94
|
-
stableSelf.fb_isResolvedNatively = @NO;
|
|
91
|
+
XCUIElement *stableSelf = [self fb_stableInstanceWithUid:uid];
|
|
95
92
|
if (1 == snapshots.count) {
|
|
96
93
|
return @[stableSelf];
|
|
97
94
|
}
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
#import "XCUIElement+FBWebDriverAttributes.h"
|
|
36
36
|
#import "XCUIElement+FBTVFocuse.h"
|
|
37
37
|
#import "XCUIElement+FBResolve.h"
|
|
38
|
+
#import "XCUIElement+FBUID.h"
|
|
38
39
|
#import "FBElementTypeTransformer.h"
|
|
39
40
|
#import "XCUIElement.h"
|
|
40
41
|
#import "XCUIElementQuery.h"
|
|
@@ -264,7 +265,9 @@
|
|
|
264
265
|
if (focusedElement != nil) {
|
|
265
266
|
FBElementCache *elementCache = request.session.elementCache;
|
|
266
267
|
BOOL useNativeCachingStrategy = request.session.useNativeCachingStrategy;
|
|
267
|
-
NSString *focusedUUID = [elementCache storeElement:(useNativeCachingStrategy
|
|
268
|
+
NSString *focusedUUID = [elementCache storeElement:(useNativeCachingStrategy
|
|
269
|
+
? focusedElement
|
|
270
|
+
: [focusedElement fb_stableInstanceWithUid:focusedElement.fb_uid])];
|
|
268
271
|
if (focusedUUID && [focusedUUID isEqualToString:(id)request.parameters[@"uuid"]]) {
|
|
269
272
|
isFocused = YES;
|
|
270
273
|
}
|
|
@@ -87,7 +87,6 @@ static id<FBResponsePayload> FBNoSuchElementErrorResponseForRequest(FBRouteReque
|
|
|
87
87
|
&& [FBXCElementSnapshotWrapper ensureWrapped:shot].wdVisible;
|
|
88
88
|
}];
|
|
89
89
|
NSArray *cells = [element fb_filterDescendantsWithSnapshots:visibleCellSnapshots
|
|
90
|
-
selfUID:[FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot]
|
|
91
90
|
onlyChildren:NO];
|
|
92
91
|
return FBResponseWithCachedElements(cells, request.session.elementCache, FBConfiguration.shouldUseCompactResponses);
|
|
93
92
|
}
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
<key>CFBundlePackageType</key>
|
|
16
16
|
<string>FMWK</string>
|
|
17
17
|
<key>CFBundleShortVersionString</key>
|
|
18
|
-
<string>9.0.
|
|
18
|
+
<string>9.0.1</string>
|
|
19
19
|
<key>CFBundleSignature</key>
|
|
20
20
|
<string>????</string>
|
|
21
21
|
<key>CFBundleVersion</key>
|
|
22
|
-
<string>9.0.
|
|
22
|
+
<string>9.0.1</string>
|
|
23
23
|
<key>NSPrincipalClass</key>
|
|
24
24
|
<string/>
|
|
25
25
|
</dict>
|
|
@@ -34,23 +34,35 @@ id<FBResponsePayload> FBResponseWithObject(id object)
|
|
|
34
34
|
return FBResponseWithStatus([FBCommandStatus okWithValue:object]);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
XCUIElement *maybeStable(XCUIElement *element)
|
|
38
38
|
{
|
|
39
39
|
BOOL useNativeCachingStrategy = nil == FBSession.activeSession
|
|
40
40
|
? YES
|
|
41
41
|
: FBSession.activeSession.useNativeCachingStrategy;
|
|
42
|
-
|
|
42
|
+
if (useNativeCachingStrategy) {
|
|
43
|
+
return element;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
XCUIElement *result = element;
|
|
47
|
+
id<FBXCElementSnapshot> snapshot = element.lastSnapshot ?: [element fb_cachedSnapshot] ?: [element fb_takeSnapshot:NO];
|
|
48
|
+
NSString *uid = [FBXCElementSnapshotWrapper wdUIDWithSnapshot:snapshot];
|
|
49
|
+
if (nil != uid) {
|
|
50
|
+
result = [element fb_stableInstanceWithUid:uid];
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
id<FBResponsePayload> FBResponseWithCachedElement(XCUIElement *element, FBElementCache *elementCache, BOOL compact)
|
|
56
|
+
{
|
|
57
|
+
[elementCache storeElement:maybeStable(element)];
|
|
43
58
|
return FBResponseWithStatus([FBCommandStatus okWithValue:FBDictionaryResponseWithElement(element, compact)]);
|
|
44
59
|
}
|
|
45
60
|
|
|
46
61
|
id<FBResponsePayload> FBResponseWithCachedElements(NSArray<XCUIElement *> *elements, FBElementCache *elementCache, BOOL compact)
|
|
47
62
|
{
|
|
48
63
|
NSMutableArray *elementsResponse = [NSMutableArray array];
|
|
49
|
-
BOOL useNativeCachingStrategy = nil == FBSession.activeSession
|
|
50
|
-
? YES
|
|
51
|
-
: FBSession.activeSession.useNativeCachingStrategy;
|
|
52
64
|
for (XCUIElement *element in elements) {
|
|
53
|
-
[elementCache storeElement:(
|
|
65
|
+
[elementCache storeElement:maybeStable(element)];
|
|
54
66
|
[elementsResponse addObject:FBDictionaryResponseWithElement(element, compact)];
|
|
55
67
|
}
|
|
56
68
|
return FBResponseWithStatus([FBCommandStatus okWithValue:elementsResponse]);
|
|
@@ -43,9 +43,7 @@
|
|
|
43
43
|
- (id<FBXCElementSnapshot>)destinationSnapshot
|
|
44
44
|
{
|
|
45
45
|
XCUIElement *matchingElement = self.testedView.buttons.allElementsBoundByIndex.firstObject;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
id<FBXCElementSnapshot> snapshot = matchingElement.lastSnapshot;
|
|
46
|
+
id<FBXCElementSnapshot> snapshot = [matchingElement fb_takeSnapshot:YES];
|
|
49
47
|
// Over iOS13, snapshot returns a child.
|
|
50
48
|
// The purpose of here is return a single element to replace children with an empty array for testing.
|
|
51
49
|
snapshot.children = @[];
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
#import "FBTestMacros.h"
|
|
16
16
|
#import "XCUIElement.h"
|
|
17
17
|
#import "XCUIElement+FBFind.h"
|
|
18
|
+
#import "XCUIElement+FBUID.h"
|
|
18
19
|
#import "FBXCElementSnapshotWrapper+Helpers.h"
|
|
19
20
|
#import "XCUIElement+FBIsVisible.h"
|
|
20
21
|
#import "XCUIElement+FBClassChain.h"
|
|
@@ -93,7 +94,10 @@
|
|
|
93
94
|
NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"Alerts"
|
|
94
95
|
shouldReturnAfterFirstMatch:YES];
|
|
95
96
|
XCTAssertEqual(matchingSnapshots.count, 1);
|
|
96
|
-
for (XCUIElement *el in @[
|
|
97
|
+
for (XCUIElement *el in @[
|
|
98
|
+
matchingSnapshots.lastObject,
|
|
99
|
+
[matchingSnapshots.lastObject fb_stableInstanceWithUid:[matchingSnapshots.lastObject fb_uid]]
|
|
100
|
+
]) {
|
|
97
101
|
XCTAssertEqual(el.elementType, XCUIElementTypeButton);
|
|
98
102
|
XCTAssertEqualObjects(el.label, @"Alerts");
|
|
99
103
|
}
|
|
@@ -44,7 +44,6 @@
|
|
|
44
44
|
[buttonSnapshots addObject:[buttons.firstObject fb_takeSnapshot:YES]];
|
|
45
45
|
|
|
46
46
|
NSArray<XCUIElement *> *result = [self.testedApplication fb_filterDescendantsWithSnapshots:buttonSnapshots
|
|
47
|
-
selfUID:nil
|
|
48
47
|
onlyChildren:NO];
|
|
49
48
|
XCTAssertEqual(1, result.count);
|
|
50
49
|
XCTAssertEqual([result.firstObject elementType], XCUIElementTypeButton);
|