appium-webdriveragent 4.6.1 → 4.8.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/PrivateHeaders/XCTest/XCAXClient_iOS.h +2 -4
- package/PrivateHeaders/XCTest/XCActivityRecord.h +3 -3
- package/PrivateHeaders/XCTest/XCApplicationQuery.h +3 -3
- package/PrivateHeaders/XCTest/XCTElementSetTransformer-Protocol.h +2 -2
- package/PrivateHeaders/XCTest/XCTRunnerDaemonSession.h +1 -1
- package/PrivateHeaders/XCTest/XCTestManager_IDEInterface-Protocol.h +5 -5
- package/PrivateHeaders/XCTest/XCTestManager_ManagerInterface-Protocol.h +8 -8
- package/PrivateHeaders/XCTest/XCUIApplication.h +2 -2
- package/PrivateHeaders/XCTest/XCUIApplicationImpl.h +2 -2
- package/PrivateHeaders/XCTest/XCUIApplicationProcess.h +3 -5
- package/PrivateHeaders/XCTest/XCUIElement.h +4 -4
- package/PrivateHeaders/XCTest/XCUIElementQuery.h +4 -4
- package/PrivateHeaders/XCTest/XCUIRecorderNodeFinder.h +3 -3
- package/PrivateHeaders/XCTest/XCUIRecorderUtilities.h +3 -3
- package/Scripts/build.sh +3 -6
- package/WebDriverAgent.xcodeproj/project.pbxproj +66 -70
- package/WebDriverAgentLib/Categories/{XCElementSnapshot+FBHelpers.h → FBXCElementSnapshotWrapper+Helpers.h} +18 -11
- package/WebDriverAgentLib/Categories/{XCElementSnapshot+FBHelpers.m → FBXCElementSnapshotWrapper+Helpers.m} +57 -39
- package/WebDriverAgentLib/Categories/NSExpression+FBFormat.m +8 -3
- package/WebDriverAgentLib/Categories/XCUIApplication+FBAlert.m +8 -7
- package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.h +2 -2
- package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +29 -28
- package/WebDriverAgentLib/Categories/XCUIApplicationProcess+FBQuiescence.m +5 -0
- package/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.m +0 -1
- package/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m +8 -5
- package/WebDriverAgentLib/Categories/XCUIElement+FBAccessibility.h +2 -2
- package/WebDriverAgentLib/Categories/XCUIElement+FBAccessibility.m +5 -4
- package/WebDriverAgentLib/Categories/XCUIElement+FBCaching.m +3 -2
- package/WebDriverAgentLib/Categories/XCUIElement+FBFind.m +22 -18
- package/WebDriverAgentLib/Categories/XCUIElement+FBIsVisible.h +2 -3
- package/WebDriverAgentLib/Categories/XCUIElement+FBIsVisible.m +28 -26
- package/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m +2 -1
- package/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m +8 -4
- package/WebDriverAgentLib/Categories/XCUIElement+FBScrolling.h +10 -0
- package/WebDriverAgentLib/Categories/XCUIElement+FBScrolling.m +81 -50
- package/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m +11 -10
- package/WebDriverAgentLib/Categories/XCUIElement+FBUID.h +10 -5
- package/WebDriverAgentLib/Categories/XCUIElement+FBUID.m +15 -3
- package/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.h +7 -7
- package/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m +29 -20
- package/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.h +2 -2
- package/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m +17 -14
- package/WebDriverAgentLib/Categories/XCUIElementQuery+FBHelpers.h +2 -3
- package/WebDriverAgentLib/Categories/XCUIElementQuery+FBHelpers.m +3 -3
- package/WebDriverAgentLib/Commands/FBElementCommands.m +31 -16
- package/WebDriverAgentLib/Commands/FBFindElementCommands.m +5 -6
- package/WebDriverAgentLib/FBAlert.m +16 -13
- package/WebDriverAgentLib/FBApplication.m +8 -8
- package/WebDriverAgentLib/Routing/FBElementUtils.h +11 -2
- package/WebDriverAgentLib/Routing/FBElementUtils.m +15 -12
- package/WebDriverAgentLib/Routing/FBResponsePayload.m +11 -10
- package/WebDriverAgentLib/Routing/FBSession.m +1 -1
- package/{PrivateHeaders/XCTest/XCAccessibilityElement.h → WebDriverAgentLib/Routing/FBXCAccessibilityElement.h} +19 -18
- package/WebDriverAgentLib/{Categories/XCAccessibilityElement+FBComparison.m → Routing/FBXCAccessibilityElement.m} +5 -11
- package/WebDriverAgentLib/Routing/FBXCDeviceEvent.h +35 -0
- package/WebDriverAgentLib/Routing/FBXCDeviceEvent.m +43 -0
- package/{PrivateHeaders/XCTest/XCElementSnapshot.h → WebDriverAgentLib/Routing/FBXCElementSnapshot.h} +25 -44
- package/WebDriverAgentLib/Routing/FBXCElementSnapshot.m +10 -0
- package/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.h +30 -0
- package/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.m +45 -0
- package/WebDriverAgentLib/Utilities/FBActiveAppDetectionPoint.h +3 -4
- package/WebDriverAgentLib/Utilities/FBActiveAppDetectionPoint.m +4 -4
- package/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.h +2 -2
- package/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.m +7 -8
- package/WebDriverAgentLib/Utilities/FBClassChainQueryParser.m +1 -2
- package/WebDriverAgentLib/Utilities/FBConfiguration.m +0 -1
- package/WebDriverAgentLib/Utilities/FBImageIOScaler.m +3 -0
- package/WebDriverAgentLib/Utilities/FBKeyboard.m +1 -2
- package/WebDriverAgentLib/Utilities/FBTVNavigationTracker.m +1 -1
- package/WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m +3 -3
- package/WebDriverAgentLib/Utilities/FBXCAXClientProxy.h +10 -9
- package/WebDriverAgentLib/Utilities/FBXCAXClientProxy.m +14 -8
- package/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.h +0 -1
- package/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m +6 -0
- package/WebDriverAgentLib/Utilities/FBXCodeCompatibility.h +0 -10
- package/WebDriverAgentLib/Utilities/FBXCodeCompatibility.m +0 -24
- package/WebDriverAgentLib/Utilities/FBXPath-Private.h +1 -1
- package/WebDriverAgentLib/Utilities/FBXPath.h +3 -3
- package/WebDriverAgentLib/Utilities/FBXPath.m +15 -13
- package/WebDriverAgentLib/Utilities/NSPredicate+FBFormat.h +14 -1
- package/WebDriverAgentLib/Utilities/NSPredicate+FBFormat.m +18 -9
- package/WebDriverAgentLib/Utilities/XCTestPrivateSymbols.m +9 -3
- package/WebDriverAgentLib/Utilities/XCUIApplicationProcessDelay.m +7 -1
- package/WebDriverAgentLib/Vendor/CocoaAsyncSocket/GCDAsyncSocket.m +7 -1
- package/WebDriverAgentLib/WebDriverAgentLib.h +0 -1
- package/WebDriverAgentRunner-Runner.app.zip +0 -0
- package/WebDriverAgentTests/IntegrationTests/FBScrollingTests.m +10 -0
- package/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m +26 -19
- package/WebDriverAgentTests/IntegrationTests/XCElementSnapshotHelperTests.m +24 -29
- package/WebDriverAgentTests/IntegrationTests/XCElementSnapshotHitPointTests.m +2 -2
- package/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m +5 -3
- package/WebDriverAgentTests/IntegrationTests/XCUIElementHelperIntegrationTests.m +2 -1
- package/{WebDriverAgentLib/Categories/XCElementSnapshot+FBHitPoint.h → WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.h} +3 -14
- package/WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.m +99 -0
- package/WebDriverAgentTests/UnitTests/FBXPathTests.m +21 -13
- package/WebDriverAgentTests/UnitTests/NSPredicateFBFormatTests.m +4 -5
- package/package.json +1 -1
- package/WebDriverAgentLib/Categories/XCAccessibilityElement+FBComparison.h +0 -27
- package/WebDriverAgentLib/Categories/XCElementSnapshot+FBHitPoint.m +0 -29
- package/WebDriverAgentLib/Utilities/FBPredicate.h +0 -28
- package/WebDriverAgentLib/Utilities/FBPredicate.m +0 -29
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
#import "FBErrorBuilder.h"
|
|
14
14
|
#import "FBKeyboard.h"
|
|
15
15
|
#import "NSString+FBVisualLength.h"
|
|
16
|
-
#import "
|
|
16
|
+
#import "FBXCElementSnapshotWrapper.h"
|
|
17
|
+
#import "FBXCElementSnapshotWrapper+Helpers.h"
|
|
17
18
|
#import "XCUIElement+FBCaching.h"
|
|
18
19
|
#import "XCUIElement+FBTap.h"
|
|
19
20
|
#import "XCUIElement+FBUtilities.h"
|
|
@@ -39,19 +40,19 @@
|
|
|
39
40
|
@end
|
|
40
41
|
|
|
41
42
|
|
|
42
|
-
@interface
|
|
43
|
+
@interface FBXCElementSnapshotWrapper (FBKeyboardFocus)
|
|
43
44
|
|
|
44
45
|
- (BOOL)fb_hasKeyboardFocus;
|
|
45
46
|
|
|
46
47
|
@end
|
|
47
48
|
|
|
48
|
-
@implementation
|
|
49
|
+
@implementation FBXCElementSnapshotWrapper (FBKeyboardFocus)
|
|
49
50
|
|
|
50
51
|
- (BOOL)fb_hasKeyboardFocus
|
|
51
52
|
{
|
|
52
53
|
// https://developer.apple.com/documentation/xctest/xcuielement/1500968-typetext?language=objc
|
|
53
54
|
// > The element or a descendant must have keyboard focus; otherwise an error is raised.
|
|
54
|
-
return self.hasKeyboardFocus || [self descendantsByFilteringWithBlock:^BOOL(
|
|
55
|
+
return self.hasKeyboardFocus || [self descendantsByFilteringWithBlock:^BOOL(id<FBXCElementSnapshot> snapshot) {
|
|
55
56
|
return snapshot.hasKeyboardFocus;
|
|
56
57
|
}].count > 0;
|
|
57
58
|
}
|
|
@@ -61,7 +62,7 @@
|
|
|
61
62
|
|
|
62
63
|
@implementation XCUIElement (FBTyping)
|
|
63
64
|
|
|
64
|
-
- (void)fb_prepareForTextInputWithSnapshot:(
|
|
65
|
+
- (void)fb_prepareForTextInputWithSnapshot:(FBXCElementSnapshotWrapper *)snapshot
|
|
65
66
|
{
|
|
66
67
|
if (snapshot.fb_hasKeyboardFocus) {
|
|
67
68
|
return;
|
|
@@ -92,10 +93,10 @@
|
|
|
92
93
|
frequency:(NSUInteger)frequency
|
|
93
94
|
error:(NSError **)error
|
|
94
95
|
{
|
|
95
|
-
|
|
96
|
+
id<FBXCElementSnapshot> snapshot = self.fb_isResolvedFromCache.boolValue
|
|
96
97
|
? self.lastSnapshot
|
|
97
98
|
: self.fb_takeSnapshot;
|
|
98
|
-
[self fb_prepareForTextInputWithSnapshot:snapshot];
|
|
99
|
+
[self fb_prepareForTextInputWithSnapshot:[FBXCElementSnapshotWrapper ensureWrapped:snapshot]];
|
|
99
100
|
if (shouldClear && ![self fb_clearTextWithSnapshot:self.lastSnapshot
|
|
100
101
|
shouldPrepareForInput:NO
|
|
101
102
|
error:error]) {
|
|
@@ -106,15 +107,15 @@
|
|
|
106
107
|
|
|
107
108
|
- (BOOL)fb_clearTextWithError:(NSError **)error
|
|
108
109
|
{
|
|
109
|
-
|
|
110
|
+
id<FBXCElementSnapshot> snapshot = self.fb_isResolvedFromCache.boolValue
|
|
110
111
|
? self.lastSnapshot
|
|
111
112
|
: self.fb_takeSnapshot;
|
|
112
|
-
return [self fb_clearTextWithSnapshot:snapshot
|
|
113
|
+
return [self fb_clearTextWithSnapshot:[FBXCElementSnapshotWrapper ensureWrapped:snapshot]
|
|
113
114
|
shouldPrepareForInput:YES
|
|
114
115
|
error:error];
|
|
115
116
|
}
|
|
116
117
|
|
|
117
|
-
- (BOOL)fb_clearTextWithSnapshot:(
|
|
118
|
+
- (BOOL)fb_clearTextWithSnapshot:(FBXCElementSnapshotWrapper *)snapshot
|
|
118
119
|
shouldPrepareForInput:(BOOL)shouldPrepareForInput
|
|
119
120
|
error:(NSError **)error
|
|
120
121
|
{
|
|
@@ -7,24 +7,29 @@
|
|
|
7
7
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
#import
|
|
11
|
-
#import <WebDriverAgentLib/XCUIElement.h>
|
|
10
|
+
#import "FBXCElementSnapshotWrapper.h"
|
|
12
11
|
|
|
13
12
|
NS_ASSUME_NONNULL_BEGIN
|
|
14
13
|
|
|
15
14
|
@interface XCUIElement (FBUID)
|
|
16
15
|
|
|
17
|
-
/*! Represents unique internal element identifier, which is the same for an element and its snapshot */
|
|
16
|
+
/*! Represents unique internal element identifier, which is the same for an element and its snapshot as UUIDv4 */
|
|
18
17
|
@property (nonatomic, nullable, readonly, copy) NSString *fb_uid;
|
|
19
18
|
|
|
19
|
+
/*! Represents unique internal element identifier, which is the same for an element and its snapshot */
|
|
20
|
+
@property (nonatomic, readonly) unsigned long long fb_accessibiltyId;
|
|
21
|
+
|
|
20
22
|
@end
|
|
21
23
|
|
|
22
24
|
|
|
23
|
-
@interface
|
|
25
|
+
@interface FBXCElementSnapshotWrapper (FBUID)
|
|
24
26
|
|
|
25
|
-
/*! Represents unique internal element identifier, which is the same for an element and its snapshot */
|
|
27
|
+
/*! Represents unique internal element identifier, which is the same for an element and its snapshot as UUIDv4 */
|
|
26
28
|
@property (nonatomic, nullable, readonly, copy) NSString *fb_uid;
|
|
27
29
|
|
|
30
|
+
/*! Represents unique internal element identifier, which is the same for an element and its snapshot */
|
|
31
|
+
@property (nonatomic, readonly) unsigned long long fb_accessibiltyId;
|
|
32
|
+
|
|
28
33
|
@end
|
|
29
34
|
|
|
30
35
|
NS_ASSUME_NONNULL_END
|
|
@@ -15,20 +15,32 @@
|
|
|
15
15
|
|
|
16
16
|
@implementation XCUIElement (FBUID)
|
|
17
17
|
|
|
18
|
+
- (unsigned long long)fb_accessibiltyId
|
|
19
|
+
{
|
|
20
|
+
return [FBElementUtils idWithAccessibilityElement:([self isKindOfClass:XCUIApplication.class]
|
|
21
|
+
? [(XCUIApplication *)self accessibilityElement]
|
|
22
|
+
: [self fb_takeSnapshot].accessibilityElement)];
|
|
23
|
+
}
|
|
24
|
+
|
|
18
25
|
- (NSString *)fb_uid
|
|
19
26
|
{
|
|
20
27
|
return [self isKindOfClass:XCUIApplication.class]
|
|
21
28
|
? [FBElementUtils uidWithAccessibilityElement:[(XCUIApplication *)self accessibilityElement]]
|
|
22
|
-
: [self fb_takeSnapshot].fb_uid;
|
|
29
|
+
: [FBXCElementSnapshotWrapper ensureWrapped:[self fb_takeSnapshot]].fb_uid;
|
|
23
30
|
}
|
|
24
31
|
|
|
25
32
|
@end
|
|
26
33
|
|
|
27
|
-
@implementation
|
|
34
|
+
@implementation FBXCElementSnapshotWrapper (FBUID)
|
|
35
|
+
|
|
36
|
+
- (unsigned long long)fb_accessibiltyId
|
|
37
|
+
{
|
|
38
|
+
return [FBElementUtils idWithAccessibilityElement:self.accessibilityElement];
|
|
39
|
+
}
|
|
28
40
|
|
|
29
41
|
- (NSString *)fb_uid
|
|
30
42
|
{
|
|
31
|
-
return [FBElementUtils uidWithAccessibilityElement:self
|
|
43
|
+
return [FBElementUtils uidWithAccessibilityElement:[self accessibilityElement]];
|
|
32
44
|
}
|
|
33
45
|
|
|
34
46
|
@end
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
#import <XCTest/XCTest.h>
|
|
11
|
-
#import <WebDriverAgentLib/XCElementSnapshot.h>
|
|
12
11
|
#import <WebDriverAgentLib/FBElement.h>
|
|
12
|
+
#import "FBXCElementSnapshot.h"
|
|
13
13
|
|
|
14
14
|
NS_ASSUME_NONNULL_BEGIN
|
|
15
15
|
|
|
@@ -24,7 +24,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
24
24
|
@return The recent snapshot of the element
|
|
25
25
|
@throws FBStaleElementException if the element is not present in DOM and thus no snapshot could be made
|
|
26
26
|
*/
|
|
27
|
-
- (
|
|
27
|
+
- (id<FBXCElementSnapshot>)fb_takeSnapshot;
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
Extracts the cached element snapshot from its query.
|
|
@@ -34,7 +34,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
34
34
|
|
|
35
35
|
@return Either the cached snapshot or nil
|
|
36
36
|
*/
|
|
37
|
-
- (nullable
|
|
37
|
+
- (nullable id<FBXCElementSnapshot>)fb_cachedSnapshot;
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
40
|
Gets the most recent snapshot of the current element and already resolves the accessibility attributes
|
|
@@ -50,7 +50,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
50
50
|
attributes resolved if there was a failure while resolving additional attributes
|
|
51
51
|
@throws FBStaleElementException if the element is not present in DOM and thus no snapshot could be made
|
|
52
52
|
*/
|
|
53
|
-
- (nullable
|
|
53
|
+
- (nullable id<FBXCElementSnapshot>)fb_snapshotWithAllAttributesAndMaxDepth:(nullable NSNumber *)maxDepth;
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
56
|
Gets the most recent snapshot of the current element with given attributes resolved.
|
|
@@ -67,8 +67,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
67
67
|
attributes resolved if there was a failure while resolving additional attributes
|
|
68
68
|
@throws FBStaleElementException if the element is not present in DOM and thus no snapshot could be made
|
|
69
69
|
*/
|
|
70
|
-
- (nullable
|
|
71
|
-
|
|
70
|
+
- (nullable id<FBXCElementSnapshot>)fb_snapshotWithAttributes:(nullable NSArray<NSString *> *)attributeNames
|
|
71
|
+
maxDepth:(nullable NSNumber *)maxDepth;
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
74
|
Filters elements by matching them to snapshots from the corresponding array
|
|
@@ -80,7 +80,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
80
80
|
|
|
81
81
|
@return Array of filtered elements, which have matches in snapshots array
|
|
82
82
|
*/
|
|
83
|
-
- (NSArray<XCUIElement *> *)fb_filterDescendantsWithSnapshots:(NSArray<
|
|
83
|
+
- (NSArray<XCUIElement *> *)fb_filterDescendantsWithSnapshots:(NSArray<id<FBXCElementSnapshot>> *)snapshots
|
|
84
84
|
selfUID:(nullable NSString *)selfUID
|
|
85
85
|
onlyChildren:(BOOL)onlyChildren;
|
|
86
86
|
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
#import "FBScreenshot.h"
|
|
23
23
|
#import "FBXCAXClientProxy.h"
|
|
24
24
|
#import "FBXCodeCompatibility.h"
|
|
25
|
+
#import "FBXCElementSnapshot.h"
|
|
26
|
+
#import "FBXCElementSnapshotWrapper+Helpers.h"
|
|
25
27
|
#import "XCUIApplication.h"
|
|
26
28
|
#import "XCUIApplication+FBQuiescence.h"
|
|
27
29
|
#import "XCUIApplicationImpl.h"
|
|
@@ -41,7 +43,7 @@
|
|
|
41
43
|
|
|
42
44
|
@implementation XCUIElement (FBUtilities)
|
|
43
45
|
|
|
44
|
-
- (
|
|
46
|
+
- (id<FBXCElementSnapshot>)fb_takeSnapshot
|
|
45
47
|
{
|
|
46
48
|
NSError *error = nil;
|
|
47
49
|
self.fb_isResolvedFromCache = @(NO);
|
|
@@ -61,12 +63,12 @@
|
|
|
61
63
|
return self.lastSnapshot;
|
|
62
64
|
}
|
|
63
65
|
|
|
64
|
-
- (
|
|
66
|
+
- (id<FBXCElementSnapshot>)fb_cachedSnapshot
|
|
65
67
|
{
|
|
66
68
|
return [self.query fb_cachedSnapshot];
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
- (nullable
|
|
71
|
+
- (nullable id<FBXCElementSnapshot>)fb_snapshotWithAllAttributesAndMaxDepth:(NSNumber *)maxDepth
|
|
70
72
|
{
|
|
71
73
|
NSMutableArray *allNames = [NSMutableArray arrayWithArray:FBStandardAttributeNames()];
|
|
72
74
|
[allNames addObjectsFromArray:FBCustomAttributeNames()];
|
|
@@ -74,11 +76,11 @@
|
|
|
74
76
|
maxDepth:maxDepth];
|
|
75
77
|
}
|
|
76
78
|
|
|
77
|
-
- (nullable
|
|
78
|
-
|
|
79
|
+
- (nullable id<FBXCElementSnapshot>)fb_snapshotWithAttributes:(NSArray<NSString *> *)attributeNames
|
|
80
|
+
maxDepth:(NSNumber *)maxDepth
|
|
79
81
|
{
|
|
80
82
|
NSSet<NSString *> *standardAttributes = [NSSet setWithArray:FBStandardAttributeNames()];
|
|
81
|
-
|
|
83
|
+
id<FBXCElementSnapshot> snapshot = self.fb_takeSnapshot;
|
|
82
84
|
NSTimeInterval axTimeout = FBConfiguration.customSnapshotTimeout;
|
|
83
85
|
if (nil == attributeNames
|
|
84
86
|
|| [[NSSet setWithArray:attributeNames] isSubsetOfSet:standardAttributes]
|
|
@@ -87,7 +89,7 @@
|
|
|
87
89
|
return snapshot;
|
|
88
90
|
}
|
|
89
91
|
|
|
90
|
-
|
|
92
|
+
id<FBXCAccessibilityElement> axElement = snapshot.accessibilityElement;
|
|
91
93
|
if (nil == axElement) {
|
|
92
94
|
return nil;
|
|
93
95
|
}
|
|
@@ -101,16 +103,17 @@
|
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
NSError *error;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
id<FBXCElementSnapshot> snapshotWithAttributes = [FBXCAXClientProxy.sharedClient snapshotForElement:axElement
|
|
107
|
+
attributes:attributeNames
|
|
108
|
+
maxDepth:maxDepth
|
|
109
|
+
error:&error];
|
|
108
110
|
if (nil == snapshotWithAttributes) {
|
|
111
|
+
NSString *description = [FBXCElementSnapshotWrapper ensureWrapped:snapshot].fb_description;
|
|
109
112
|
[FBLogger logFmt:@"Cannot take a snapshot with attribute(s) %@ of '%@' after %.2f seconds",
|
|
110
|
-
attributeNames,
|
|
113
|
+
attributeNames, description, axTimeout];
|
|
111
114
|
[FBLogger logFmt:@"This timeout could be customized via '%@' setting", FB_SETTING_CUSTOM_SNAPSHOT_TIMEOUT];
|
|
112
115
|
[FBLogger logFmt:@"Internal error: %@", error.localizedDescription];
|
|
113
|
-
[FBLogger logFmt:@"Falling back to the default snapshotting mechanism for the element '%@' (some attribute values, like visibility or accessibility might not be precise though)",
|
|
116
|
+
[FBLogger logFmt:@"Falling back to the default snapshotting mechanism for the element '%@' (some attribute values, like visibility or accessibility might not be precise though)", description];
|
|
114
117
|
snapshotWithAttributes = self.lastSnapshot;
|
|
115
118
|
} else {
|
|
116
119
|
self.lastSnapshot = snapshotWithAttributes;
|
|
@@ -122,19 +125,22 @@
|
|
|
122
125
|
return snapshotWithAttributes;
|
|
123
126
|
}
|
|
124
127
|
|
|
125
|
-
- (NSArray<XCUIElement *> *)fb_filterDescendantsWithSnapshots:(NSArray<
|
|
128
|
+
- (NSArray<XCUIElement *> *)fb_filterDescendantsWithSnapshots:(NSArray<id<FBXCElementSnapshot>> *)snapshots
|
|
126
129
|
selfUID:(NSString *)selfUID
|
|
127
130
|
onlyChildren:(BOOL)onlyChildren
|
|
128
131
|
{
|
|
129
132
|
if (0 == snapshots.count) {
|
|
130
133
|
return @[];
|
|
131
134
|
}
|
|
132
|
-
|
|
135
|
+
NSMutableArray<NSString *> *sortedIds = [NSMutableArray new];
|
|
136
|
+
for (id<FBXCElementSnapshot> snapshot in snapshots) {
|
|
137
|
+
[sortedIds addObject:(NSString *)[FBXCElementSnapshotWrapper ensureWrapped:snapshot].fb_uid];
|
|
138
|
+
}
|
|
133
139
|
NSMutableArray<XCUIElement *> *matchedElements = [NSMutableArray array];
|
|
134
140
|
NSString *uid = selfUID;
|
|
135
141
|
if (nil == uid) {
|
|
136
142
|
uid = self.fb_isResolvedFromCache.boolValue
|
|
137
|
-
? self.lastSnapshot.fb_uid
|
|
143
|
+
? [FBXCElementSnapshotWrapper ensureWrapped:self.lastSnapshot].fb_uid
|
|
138
144
|
: self.fb_uid;
|
|
139
145
|
}
|
|
140
146
|
if ([sortedIds containsObject:uid]) {
|
|
@@ -151,7 +157,10 @@
|
|
|
151
157
|
XCUIElementQuery *query = onlyChildren
|
|
152
158
|
? [self.fb_query childrenMatchingType:type]
|
|
153
159
|
: [self.fb_query descendantsMatchingType:type];
|
|
154
|
-
|
|
160
|
+
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id<FBXCElementSnapshot> snapshot, NSDictionary *bindings) {
|
|
161
|
+
return [sortedIds containsObject:(NSString *)[FBXCElementSnapshotWrapper ensureWrapped:snapshot].fb_uid];
|
|
162
|
+
}];
|
|
163
|
+
query = [query matchingPredicate:predicate];
|
|
155
164
|
if (1 == snapshots.count) {
|
|
156
165
|
XCUIElement *result = query.fb_firstMatch;
|
|
157
166
|
result.fb_isResolvedNatively = @NO;
|
|
@@ -206,7 +215,7 @@
|
|
|
206
215
|
|
|
207
216
|
- (NSData *)fb_screenshotWithError:(NSError **)error
|
|
208
217
|
{
|
|
209
|
-
|
|
218
|
+
id<FBXCElementSnapshot> selfSnapshot = self.fb_isResolvedFromCache.boolValue
|
|
210
219
|
? self.lastSnapshot
|
|
211
220
|
: self.fb_takeSnapshot;
|
|
212
221
|
if (CGRectIsEmpty(selfSnapshot.frame)) {
|
|
@@ -221,8 +230,8 @@
|
|
|
221
230
|
UIInterfaceOrientation orientation = self.application.interfaceOrientation;
|
|
222
231
|
if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) {
|
|
223
232
|
// Workaround XCTest bug when element frame is returned as in portrait mode even if the screenshot is rotated
|
|
224
|
-
NSArray<
|
|
225
|
-
|
|
233
|
+
NSArray<id<FBXCElementSnapshot>> *ancestors = [FBXCElementSnapshotWrapper ensureWrapped:selfSnapshot].fb_ancestors;
|
|
234
|
+
id<FBXCElementSnapshot> parentWindow = nil;
|
|
226
235
|
if (1 == ancestors.count) {
|
|
227
236
|
parentWindow = selfSnapshot;
|
|
228
237
|
} else if (ancestors.count > 1) {
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
#import <WebDriverAgentLib/FBElement.h>
|
|
11
|
-
#import <WebDriverAgentLib/XCElementSnapshot.h>
|
|
12
11
|
#import <WebDriverAgentLib/XCUIElement.h>
|
|
12
|
+
#import "FBXCElementSnapshotWrapper.h"
|
|
13
13
|
|
|
14
14
|
NS_ASSUME_NONNULL_BEGIN
|
|
15
15
|
|
|
@@ -18,7 +18,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
18
18
|
@end
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
@interface
|
|
21
|
+
@interface FBXCElementSnapshotWrapper (WebDriverAttributes) <FBElement>
|
|
22
22
|
|
|
23
23
|
@end
|
|
24
24
|
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
#import "FBElementTypeTransformer.h"
|
|
15
15
|
#import "FBLogger.h"
|
|
16
16
|
#import "FBMacros.h"
|
|
17
|
+
#import "FBXCElementSnapshotWrapper.h"
|
|
17
18
|
#import "XCUIElement+FBAccessibility.h"
|
|
18
19
|
#import "XCUIElement+FBIsVisible.h"
|
|
19
20
|
#import "XCUIElement+FBUID.h"
|
|
@@ -26,9 +27,9 @@
|
|
|
26
27
|
|
|
27
28
|
@implementation XCUIElement (WebDriverAttributesForwarding)
|
|
28
29
|
|
|
29
|
-
- (
|
|
30
|
+
- (id<FBXCElementSnapshot>)fb_snapshotForAttributeName:(NSString *)name
|
|
30
31
|
{
|
|
31
|
-
// These
|
|
32
|
+
// These attributes are special, because we can only retrieve them from
|
|
32
33
|
// the snapshot if we explicitly ask XCTest to include them into the query while taking it.
|
|
33
34
|
// That is why fb_snapshotWithAllAttributes method must be used instead of the default snapshot
|
|
34
35
|
// call
|
|
@@ -51,8 +52,8 @@
|
|
|
51
52
|
- (id)fb_valueForWDAttributeName:(NSString *)name
|
|
52
53
|
{
|
|
53
54
|
NSString *wdAttributeName = [FBElementUtils wdAttributeNameForAttributeName:name];
|
|
54
|
-
|
|
55
|
-
return [snapshot fb_valueForWDAttributeName:name];
|
|
55
|
+
id<FBXCElementSnapshot> snapshot = [self fb_snapshotForAttributeName:wdAttributeName];
|
|
56
|
+
return [[FBXCElementSnapshotWrapper ensureWrapped:snapshot] fb_valueForWDAttributeName:name];
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
- (id)forwardingTargetForSelector:(SEL)aSelector
|
|
@@ -61,13 +62,13 @@
|
|
|
61
62
|
SEL webDriverAttributesSelector = descr.name;
|
|
62
63
|
return nil == webDriverAttributesSelector
|
|
63
64
|
? nil
|
|
64
|
-
: [self fb_snapshotForAttributeName:NSStringFromSelector(webDriverAttributesSelector)];
|
|
65
|
+
: [FBXCElementSnapshotWrapper ensureWrapped:[self fb_snapshotForAttributeName:NSStringFromSelector(webDriverAttributesSelector)]];
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
@end
|
|
68
69
|
|
|
69
70
|
|
|
70
|
-
@implementation
|
|
71
|
+
@implementation FBXCElementSnapshotWrapper (WebDriverAttributes)
|
|
71
72
|
|
|
72
73
|
- (id)fb_valueForWDAttributeName:(NSString *)name
|
|
73
74
|
{
|
|
@@ -161,8 +162,8 @@
|
|
|
161
162
|
// Text fields: actual accessible element isn't text field itself, but nested element
|
|
162
163
|
if (elementType == XCUIElementTypeCell) {
|
|
163
164
|
if (!self.fb_isAccessibilityElement) {
|
|
164
|
-
|
|
165
|
-
if (!containerView.fb_isAccessibilityElement) {
|
|
165
|
+
id<FBXCElementSnapshot> containerView = [[self children] firstObject];
|
|
166
|
+
if (![FBXCElementSnapshotWrapper ensureWrapped:containerView].fb_isAccessibilityElement) {
|
|
166
167
|
return NO;
|
|
167
168
|
}
|
|
168
169
|
}
|
|
@@ -171,12 +172,13 @@
|
|
|
171
172
|
return NO;
|
|
172
173
|
}
|
|
173
174
|
}
|
|
174
|
-
|
|
175
|
+
id<FBXCElementSnapshot> parentSnapshot = self.parent;
|
|
175
176
|
while (parentSnapshot) {
|
|
176
177
|
// In the scenario when table provides Search results controller, table could be marked as accessible element, even though it isn't
|
|
177
178
|
// As it is highly unlikely that table view should ever be an accessibility element itself,
|
|
178
179
|
// for now we work around that by skipping Table View in container checks
|
|
179
|
-
if (parentSnapshot.fb_isAccessibilityElement
|
|
180
|
+
if ([FBXCElementSnapshotWrapper ensureWrapped:parentSnapshot].fb_isAccessibilityElement
|
|
181
|
+
&& parentSnapshot.elementType != XCUIElementTypeTable) {
|
|
180
182
|
return NO;
|
|
181
183
|
}
|
|
182
184
|
parentSnapshot = parentSnapshot.parent;
|
|
@@ -186,9 +188,10 @@
|
|
|
186
188
|
|
|
187
189
|
- (BOOL)isWDAccessibilityContainer
|
|
188
190
|
{
|
|
189
|
-
NSArray<
|
|
190
|
-
for (
|
|
191
|
-
|
|
191
|
+
NSArray<id<FBXCElementSnapshot>> *children = self.children;
|
|
192
|
+
for (id<FBXCElementSnapshot> child in children) {
|
|
193
|
+
FBXCElementSnapshotWrapper *wrappedChild = [FBXCElementSnapshotWrapper ensureWrapped:child];
|
|
194
|
+
if (wrappedChild.isWDAccessibilityContainer || wrappedChild.fb_isAccessibilityElement) {
|
|
192
195
|
return YES;
|
|
193
196
|
}
|
|
194
197
|
}
|
|
@@ -209,7 +212,7 @@
|
|
|
209
212
|
{
|
|
210
213
|
if (nil != self.parent) {
|
|
211
214
|
for (NSUInteger index = 0; index < self.parent.children.count; ++index) {
|
|
212
|
-
if ([self.parent.children objectAtIndex:index] == self) {
|
|
215
|
+
if ([self.parent.children objectAtIndex:index] == self.snapshot) {
|
|
213
216
|
return index;
|
|
214
217
|
}
|
|
215
218
|
}
|
|
@@ -8,8 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
#import <XCTest/XCTest.h>
|
|
11
|
-
|
|
12
|
-
@class XCElementSnapshot;
|
|
11
|
+
#import "FBXCElementSnapshot.h"
|
|
13
12
|
|
|
14
13
|
NS_ASSUME_NONNULL_BEGIN
|
|
15
14
|
|
|
@@ -23,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
23
22
|
|
|
24
23
|
@return Either the cached snapshot or nil
|
|
25
24
|
*/
|
|
26
|
-
- (nullable
|
|
25
|
+
- (nullable id<FBXCElementSnapshot>)fb_cachedSnapshot;
|
|
27
26
|
|
|
28
27
|
@end
|
|
29
28
|
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
|
|
12
12
|
#import "FBXCodeCompatibility.h"
|
|
13
13
|
#import "XCUIElementQuery.h"
|
|
14
|
-
|
|
14
|
+
#import "FBXCElementSnapshot.h"
|
|
15
15
|
|
|
16
16
|
@implementation XCUIElementQuery (FBHelpers)
|
|
17
17
|
|
|
18
|
-
- (nullable
|
|
18
|
+
- (nullable id<FBXCElementSnapshot>)fb_cachedSnapshot
|
|
19
19
|
{
|
|
20
|
-
|
|
20
|
+
id<FBXCElementSnapshot> rootElementSnapshot = self.rootElementSnapshot;
|
|
21
21
|
if (nil == rootElementSnapshot) {
|
|
22
22
|
return nil;
|
|
23
23
|
}
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
#import "FBApplication.h"
|
|
13
13
|
#import "FBConfiguration.h"
|
|
14
14
|
#import "FBKeyboard.h"
|
|
15
|
-
#import "FBPredicate.h"
|
|
16
15
|
#import "FBRoute.h"
|
|
17
16
|
#import "FBRouteRequest.h"
|
|
18
17
|
#import "FBRunLoopSpinner.h"
|
|
@@ -84,6 +83,7 @@
|
|
|
84
83
|
[[FBRoute POST:@"/wda/element/:uuid/tapWithNumberOfTaps"] respondWithTarget:self action:@selector(handleTapWithNumberOfTaps:)],
|
|
85
84
|
[[FBRoute POST:@"/wda/element/:uuid/touchAndHold"] respondWithTarget:self action:@selector(handleTouchAndHold:)],
|
|
86
85
|
[[FBRoute POST:@"/wda/element/:uuid/scroll"] respondWithTarget:self action:@selector(handleScroll:)],
|
|
86
|
+
[[FBRoute POST:@"/wda/element/:uuid/scrollTo"] respondWithTarget:self action:@selector(handleScrollTo:)],
|
|
87
87
|
[[FBRoute POST:@"/wda/element/:uuid/dragfromtoforduration"] respondWithTarget:self action:@selector(handleDrag:)],
|
|
88
88
|
[[FBRoute POST:@"/wda/element/:uuid/forceTouch"] respondWithTarget:self action:@selector(handleForceTouch:)],
|
|
89
89
|
[[FBRoute POST:@"/wda/dragfromtoforduration"] respondWithTarget:self action:@selector(handleDragCoordinate:)],
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
{
|
|
105
105
|
FBElementCache *elementCache = request.session.elementCache;
|
|
106
106
|
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
|
|
107
|
-
BOOL isEnabled = element.lastSnapshot.isWDEnabled;
|
|
107
|
+
BOOL isEnabled = [FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot].isWDEnabled;
|
|
108
108
|
return FBResponseWithObject(isEnabled ? @YES : @NO);
|
|
109
109
|
}
|
|
110
110
|
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
{
|
|
113
113
|
FBElementCache *elementCache = request.session.elementCache;
|
|
114
114
|
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
|
|
115
|
-
return FBResponseWithObject(element.lastSnapshot.wdRect);
|
|
115
|
+
return FBResponseWithObject([FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot].wdRect);
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
+ (id<FBResponsePayload>)handleGetAttribute:(FBRouteRequest *)request
|
|
@@ -134,7 +134,8 @@
|
|
|
134
134
|
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]
|
|
135
135
|
resolveForAdditionalAttributes:additionalAttributes
|
|
136
136
|
andMaxDepth:maxDepth];
|
|
137
|
-
|
|
137
|
+
FBXCElementSnapshotWrapper *wrappedSnapshot = [FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot];
|
|
138
|
+
id attributeValue = [wrappedSnapshot fb_valueForWDAttributeName:attributeName];
|
|
138
139
|
return FBResponseWithObject(attributeValue ?: [NSNull null]);
|
|
139
140
|
}
|
|
140
141
|
|
|
@@ -142,7 +143,8 @@
|
|
|
142
143
|
{
|
|
143
144
|
FBElementCache *elementCache = request.session.elementCache;
|
|
144
145
|
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
|
|
145
|
-
|
|
146
|
+
FBXCElementSnapshotWrapper *wrappedSnapshot = [FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot];
|
|
147
|
+
id text = FBFirstNonEmptyValue(wrappedSnapshot.wdValue, wrappedSnapshot.wdLabel);
|
|
146
148
|
return FBResponseWithObject(text ?: @"");
|
|
147
149
|
}
|
|
148
150
|
|
|
@@ -152,7 +154,7 @@
|
|
|
152
154
|
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]
|
|
153
155
|
resolveForAdditionalAttributes:@[FB_XCAXAIsVisibleAttributeName]
|
|
154
156
|
andMaxDepth:@1];
|
|
155
|
-
return FBResponseWithObject(@(element.lastSnapshot.isWDVisible));
|
|
157
|
+
return FBResponseWithObject(@([FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot].isWDVisible));
|
|
156
158
|
}
|
|
157
159
|
|
|
158
160
|
+ (id<FBResponsePayload>)handleGetAccessible:(FBRouteRequest *)request
|
|
@@ -161,7 +163,7 @@
|
|
|
161
163
|
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]
|
|
162
164
|
resolveForAdditionalAttributes:@[FB_XCAXAIsElementAttributeName]
|
|
163
165
|
andMaxDepth:@1];
|
|
164
|
-
return FBResponseWithObject(@(element.lastSnapshot.isWDAccessible));
|
|
166
|
+
return FBResponseWithObject(@([FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot].isWDAccessible));
|
|
165
167
|
}
|
|
166
168
|
|
|
167
169
|
+ (id<FBResponsePayload>)handleGetIsAccessibilityContainer:(FBRouteRequest *)request
|
|
@@ -170,21 +172,21 @@
|
|
|
170
172
|
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]
|
|
171
173
|
resolveForAdditionalAttributes:@[FB_XCAXAIsElementAttributeName]
|
|
172
174
|
andMaxDepth:nil];
|
|
173
|
-
return FBResponseWithObject(@(element.lastSnapshot.isWDAccessibilityContainer));
|
|
175
|
+
return FBResponseWithObject(@([FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot].isWDAccessibilityContainer));
|
|
174
176
|
}
|
|
175
177
|
|
|
176
178
|
+ (id<FBResponsePayload>)handleGetName:(FBRouteRequest *)request
|
|
177
179
|
{
|
|
178
180
|
FBElementCache *elementCache = request.session.elementCache;
|
|
179
181
|
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
|
|
180
|
-
return FBResponseWithObject(element.lastSnapshot.wdType);
|
|
182
|
+
return FBResponseWithObject([FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot].wdType);
|
|
181
183
|
}
|
|
182
184
|
|
|
183
185
|
+ (id<FBResponsePayload>)handleGetSelected:(FBRouteRequest *)request
|
|
184
186
|
{
|
|
185
187
|
FBElementCache *elementCache = request.session.elementCache;
|
|
186
188
|
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
|
|
187
|
-
return FBResponseWithObject(@(element.lastSnapshot.wdSelected));
|
|
189
|
+
return FBResponseWithObject(@([FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot].wdSelected));
|
|
188
190
|
}
|
|
189
191
|
|
|
190
192
|
+ (id<FBResponsePayload>)handleSetValue:(FBRouteRequest *)request
|
|
@@ -198,7 +200,7 @@
|
|
|
198
200
|
NSString *textToType = [value isKindOfClass:NSArray.class]
|
|
199
201
|
? [value componentsJoinedByString:@""]
|
|
200
202
|
: value;
|
|
201
|
-
XCUIElementType elementType = element.lastSnapshot
|
|
203
|
+
XCUIElementType elementType = [(id<FBXCElementSnapshot>)element.lastSnapshot elementType];
|
|
202
204
|
#if !TARGET_OS_TV
|
|
203
205
|
if (elementType == XCUIElementTypePickerWheel) {
|
|
204
206
|
[element adjustToPickerWheelValue:textToType];
|
|
@@ -369,7 +371,8 @@
|
|
|
369
371
|
|
|
370
372
|
NSString *const predicateString = request.arguments[@"predicateString"];
|
|
371
373
|
if (predicateString) {
|
|
372
|
-
NSPredicate *formattedPredicate = [NSPredicate
|
|
374
|
+
NSPredicate *formattedPredicate = [NSPredicate fb_snapshotBlockPredicateWithPredicate:[NSPredicate
|
|
375
|
+
predicateWithFormat:predicateString]];
|
|
373
376
|
XCUIElement *childElement = [[[[element.fb_query descendantsMatchingType:XCUIElementTypeAny] matchingPredicate:formattedPredicate] allElementsBoundByAccessibilityElement] lastObject];
|
|
374
377
|
if (!childElement) {
|
|
375
378
|
return FBResponseWithStatus([FBCommandStatus noSuchElementErrorWithMessage:[NSString stringWithFormat:@"'%@' predicate didn't match any elements", predicateString] traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]);
|
|
@@ -383,6 +386,17 @@
|
|
|
383
386
|
return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:@"Unsupported scroll type" traceback:nil]);
|
|
384
387
|
}
|
|
385
388
|
|
|
389
|
+
+ (id<FBResponsePayload>)handleScrollTo:(FBRouteRequest *)request
|
|
390
|
+
{
|
|
391
|
+
FBElementCache *elementCache = request.session.elementCache;
|
|
392
|
+
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
|
|
393
|
+
NSError *error;
|
|
394
|
+
return [element fb_nativeScrollToVisibleWithError:&error]
|
|
395
|
+
? FBResponseWithOK()
|
|
396
|
+
: FBResponseWithStatus([FBCommandStatus invalidElementStateErrorWithMessage:error.description
|
|
397
|
+
traceback:nil]);
|
|
398
|
+
}
|
|
399
|
+
|
|
386
400
|
+ (id<FBResponsePayload>)handleDragCoordinate:(FBRouteRequest *)request
|
|
387
401
|
{
|
|
388
402
|
FBSession *session = request.session;
|
|
@@ -402,7 +416,7 @@
|
|
|
402
416
|
FBSession *session = request.session;
|
|
403
417
|
FBElementCache *elementCache = session.elementCache;
|
|
404
418
|
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
|
|
405
|
-
CGRect frame = element.lastSnapshot
|
|
419
|
+
CGRect frame = [(id<FBXCElementSnapshot>)element.lastSnapshot frame];
|
|
406
420
|
CGPoint startPoint = CGPointMake((CGFloat)(frame.origin.x + [request.arguments[@"fromX"] doubleValue]), (CGFloat)(frame.origin.y + [request.arguments[@"fromY"] doubleValue]));
|
|
407
421
|
CGPoint endPoint = CGPointMake((CGFloat)(frame.origin.x + [request.arguments[@"toX"] doubleValue]), (CGFloat)(frame.origin.y + [request.arguments[@"toY"] doubleValue]));
|
|
408
422
|
NSTimeInterval duration = [request.arguments[@"duration"] doubleValue];
|
|
@@ -537,7 +551,8 @@
|
|
|
537
551
|
NSError *error;
|
|
538
552
|
NSData *screenshotData = [element fb_screenshotWithError:&error];
|
|
539
553
|
if (nil == screenshotData) {
|
|
540
|
-
return FBResponseWithStatus([FBCommandStatus unableToCaptureScreenErrorWithMessage:error.description
|
|
554
|
+
return FBResponseWithStatus([FBCommandStatus unableToCaptureScreenErrorWithMessage:error.description
|
|
555
|
+
traceback:nil]);
|
|
541
556
|
}
|
|
542
557
|
NSString *screenshot = [screenshotData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
|
|
543
558
|
return FBResponseWithObject(screenshot);
|
|
@@ -551,7 +566,7 @@ static const CGFloat DEFAULT_OFFSET = (CGFloat)0.2;
|
|
|
551
566
|
{
|
|
552
567
|
FBElementCache *elementCache = request.session.elementCache;
|
|
553
568
|
XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
|
|
554
|
-
if (element.lastSnapshot
|
|
569
|
+
if ([element.lastSnapshot elementType] != XCUIElementTypePickerWheel) {
|
|
555
570
|
return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:[NSString stringWithFormat:@"The element is expected to be a valid Picker Wheel control. '%@' was given instead", element.wdType] traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]);
|
|
556
571
|
}
|
|
557
572
|
NSString* order = [request.arguments[@"order"] lowercaseString];
|
|
@@ -621,7 +636,7 @@ static const CGFloat DEFAULT_OFFSET = (CGFloat)0.2;
|
|
|
621
636
|
XCUIElement *window = application.windows.fb_firstMatch;
|
|
622
637
|
if (window) {
|
|
623
638
|
element = window;
|
|
624
|
-
|
|
639
|
+
id<FBXCElementSnapshot> snapshot = element.fb_cachedSnapshot ?: element.fb_takeSnapshot;
|
|
625
640
|
point.x -= snapshot.frame.origin.x;
|
|
626
641
|
point.y -= snapshot.frame.origin.y;
|
|
627
642
|
}
|