appium-webdriveragent 4.7.0 → 4.8.2
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 +3 -3
- 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.m +73 -51
- 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 +17 -15
- 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/FBPasteboard.m +91 -3
- 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/FBPasteboardTests.m +1 -5
- 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
|
@@ -36,13 +36,13 @@
|
|
|
36
36
|
return instance;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
+ (
|
|
39
|
+
+ (id<FBXCAccessibilityElement>)axElementWithPoint:(CGPoint)point
|
|
40
40
|
{
|
|
41
|
-
__block
|
|
41
|
+
__block id<FBXCAccessibilityElement> onScreenElement = nil;
|
|
42
42
|
id<XCTestManager_ManagerInterface> proxy = [FBXCTestDaemonsProxy testRunnerProxy];
|
|
43
43
|
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
|
|
44
44
|
[proxy _XCT_requestElementAtPoint:point
|
|
45
|
-
reply:^(
|
|
45
|
+
reply:^(id element, NSError *error) {
|
|
46
46
|
if (nil == error) {
|
|
47
47
|
onScreenElement = element;
|
|
48
48
|
} else {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
return onScreenElement;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
- (
|
|
57
|
+
- (id<FBXCAccessibilityElement>)axElement
|
|
58
58
|
{
|
|
59
59
|
return [self.class axElementWithPoint:self.coordinates];
|
|
60
60
|
}
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
#import "FBElementCache.h"
|
|
11
|
+
#import "FBXCElementSnapshot.h"
|
|
11
12
|
#import "XCUIApplication.h"
|
|
12
|
-
#import "XCElementSnapshot.h"
|
|
13
13
|
#import "XCSynthesizedEventRecord.h"
|
|
14
14
|
|
|
15
15
|
NS_ASSUME_NONNULL_BEGIN
|
|
@@ -62,7 +62,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
62
62
|
@param snapshot Element's snapshot instance
|
|
63
63
|
@return The fixed hit point coordinates, if there is a need to fix them, or the unchanged hit point value
|
|
64
64
|
*/
|
|
65
|
-
- (CGPoint)fixedHitPointWith:(CGPoint)hitPoint forSnapshot:(
|
|
65
|
+
- (CGPoint)fixedHitPointWith:(CGPoint)hitPoint forSnapshot:(id<FBXCElementSnapshot>)snapshot;
|
|
66
66
|
|
|
67
67
|
/**
|
|
68
68
|
Calculate absolute gesture position on the screen based on provided element and positionOffset values.
|
|
@@ -13,12 +13,11 @@
|
|
|
13
13
|
#import "FBLogger.h"
|
|
14
14
|
#import "FBMacros.h"
|
|
15
15
|
#import "FBMathUtils.h"
|
|
16
|
+
#import "FBXCElementSnapshotWrapper+Helpers.h"
|
|
16
17
|
#import "XCUIApplication+FBHelpers.h"
|
|
18
|
+
#import "XCUIElement.h"
|
|
17
19
|
#import "XCUIElement+FBIsVisible.h"
|
|
18
|
-
#import "XCElementSnapshot.h"
|
|
19
20
|
#import "XCUIElement+FBCaching.h"
|
|
20
|
-
#import "XCElementSnapshot+FBHitPoint.h"
|
|
21
|
-
#import "XCElementSnapshot+FBHelpers.h"
|
|
22
21
|
#import "XCPointerEventPath.h"
|
|
23
22
|
#import "XCSynthesizedEventRecord.h"
|
|
24
23
|
#import "XCUIElement+FBUtilities.h"
|
|
@@ -42,7 +41,7 @@
|
|
|
42
41
|
|
|
43
42
|
@implementation FBBaseGestureItem
|
|
44
43
|
|
|
45
|
-
- (CGPoint)fixedHitPointWith:(CGPoint)hitPoint forSnapshot:(
|
|
44
|
+
- (CGPoint)fixedHitPointWith:(CGPoint)hitPoint forSnapshot:(id<FBXCElementSnapshot>)snapshot
|
|
46
45
|
{
|
|
47
46
|
UIInterfaceOrientation interfaceOrientation = self.application.interfaceOrientation;
|
|
48
47
|
if (interfaceOrientation == UIInterfaceOrientationPortrait) {
|
|
@@ -54,8 +53,8 @@
|
|
|
54
53
|
// For Xcode11 it is always necessary to adjust the tap point coordinates
|
|
55
54
|
return FBInvertPointForApplication(hitPoint, appFrame.size, interfaceOrientation);
|
|
56
55
|
}
|
|
57
|
-
NSArray<
|
|
58
|
-
|
|
56
|
+
NSArray<id<FBXCElementSnapshot>> *ancestors = [FBXCElementSnapshotWrapper ensureWrapped:snapshot].fb_ancestors;
|
|
57
|
+
id<FBXCElementSnapshot> parentWindow = ancestors.count > 1 ? [ancestors objectAtIndex:ancestors.count - 2] : nil;
|
|
59
58
|
CGRect parentWindowFrame = nil == parentWindow ? snapshot.frame : parentWindow.frame;
|
|
60
59
|
if ((appFrame.size.height > appFrame.size.width && parentWindowFrame.size.height < parentWindowFrame.size.width) ||
|
|
61
60
|
(appFrame.size.height < appFrame.size.width && parentWindowFrame.size.height > parentWindowFrame.size.width)) {
|
|
@@ -86,11 +85,11 @@
|
|
|
86
85
|
} else {
|
|
87
86
|
// The offset relative to the element is defined
|
|
88
87
|
|
|
89
|
-
|
|
88
|
+
id<FBXCElementSnapshot> snapshot = element.fb_isResolvedFromCache.boolValue
|
|
90
89
|
? element.lastSnapshot
|
|
91
90
|
: element.fb_takeSnapshot;
|
|
92
91
|
if (nil == positionOffset) {
|
|
93
|
-
NSValue *hitPointValue = snapshot.fb_hitPoint;
|
|
92
|
+
NSValue *hitPointValue = [FBXCElementSnapshotWrapper ensureWrapped:snapshot].fb_hitPoint;
|
|
94
93
|
if (nil != hitPointValue) {
|
|
95
94
|
// short circuit element hitpoint
|
|
96
95
|
return hitPointValue;
|
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
#import "FBErrorBuilder.h"
|
|
12
12
|
#import "FBElementTypeTransformer.h"
|
|
13
13
|
#import "FBExceptions.h"
|
|
14
|
-
#import "FBPredicate.h"
|
|
15
14
|
#import "NSPredicate+FBFormat.h"
|
|
16
15
|
|
|
17
16
|
NS_ASSUME_NONNULL_BEGIN
|
|
@@ -559,7 +558,7 @@ static NSNumberFormatter *numberFormatter = nil;
|
|
|
559
558
|
*error = [self.class compilationErrorWithQuery:originalQuery description:description];
|
|
560
559
|
return nil;
|
|
561
560
|
}
|
|
562
|
-
NSPredicate *value = [NSPredicate
|
|
561
|
+
NSPredicate *value = [NSPredicate fb_snapshotBlockPredicateWithPredicate:[NSPredicate predicateWithFormat:token.asString]];
|
|
563
562
|
if ([token isKindOfClass:FBSelfPredicateToken.class]) {
|
|
564
563
|
[predicates addObject:[[FBSelfPredicateItem alloc] initWithValue:value]];
|
|
565
564
|
} else if ([token isKindOfClass:FBDescendantPredicateToken.class]) {
|
|
@@ -57,6 +57,8 @@ const CGFloat FBMaxCompressionQuality = 1.0f;
|
|
|
57
57
|
self.nextImage = image;
|
|
58
58
|
[self.nextImageLock unlock];
|
|
59
59
|
|
|
60
|
+
#pragma clang diagnostic push
|
|
61
|
+
#pragma clang diagnostic ignored "-Wcompletion-handler"
|
|
60
62
|
dispatch_async(self.scalingQueue, ^{
|
|
61
63
|
[self.nextImageLock lock];
|
|
62
64
|
NSData *next = self.nextImage;
|
|
@@ -77,6 +79,7 @@ const CGFloat FBMaxCompressionQuality = 1.0f;
|
|
|
77
79
|
}
|
|
78
80
|
completionHandler(scaled);
|
|
79
81
|
});
|
|
82
|
+
#pragma clang diagnostic pop
|
|
80
83
|
}
|
|
81
84
|
|
|
82
85
|
// This method is more optimized for JPEG scaling
|
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
#import "FBRunLoopSpinner.h"
|
|
18
18
|
#import "FBMacros.h"
|
|
19
19
|
#import "FBXCodeCompatibility.h"
|
|
20
|
-
#import "XCElementSnapshot.h"
|
|
21
20
|
#import "XCUIElement+FBUtilities.h"
|
|
22
21
|
#import "XCUIElement+FBIsVisible.h"
|
|
23
22
|
#import "XCTestDriver.h"
|
|
@@ -58,7 +57,7 @@
|
|
|
58
57
|
return NO;
|
|
59
58
|
}
|
|
60
59
|
|
|
61
|
-
NSPredicate *keySearchPredicate = [NSPredicate predicateWithBlock:^BOOL(
|
|
60
|
+
NSPredicate *keySearchPredicate = [NSPredicate predicateWithBlock:^BOOL(id<FBXCElementSnapshot> snapshot,
|
|
62
61
|
NSDictionary *bindings) {
|
|
63
62
|
return snapshot.label.length > 0;
|
|
64
63
|
}];
|
|
@@ -9,7 +9,16 @@
|
|
|
9
9
|
|
|
10
10
|
#import "FBPasteboard.h"
|
|
11
11
|
|
|
12
|
+
#import <mach/mach_time.h>
|
|
13
|
+
#import "FBAlert.h"
|
|
14
|
+
#import "FBApplication.h"
|
|
12
15
|
#import "FBErrorBuilder.h"
|
|
16
|
+
#import "FBMacros.h"
|
|
17
|
+
#import "XCUIApplication+FBAlert.h"
|
|
18
|
+
|
|
19
|
+
#define ALERT_TIMEOUT_SEC 30
|
|
20
|
+
// Must not be less than FB_MONTORING_INTERVAL in FBAlertsMonitor
|
|
21
|
+
#define ALERT_CHECK_INTERVAL_SEC 2
|
|
13
22
|
|
|
14
23
|
#if !TARGET_OS_TV
|
|
15
24
|
@implementation FBPasteboard
|
|
@@ -50,21 +59,100 @@
|
|
|
50
59
|
return YES;
|
|
51
60
|
}
|
|
52
61
|
|
|
62
|
+
+ (nullable id)pasteboardContentForItem:(NSString *)item
|
|
63
|
+
instance:(UIPasteboard *)pbInstance
|
|
64
|
+
timeout:(NSTimeInterval)timeout
|
|
65
|
+
error:(NSError **)error
|
|
66
|
+
{
|
|
67
|
+
SEL selector = NSSelectorFromString(item);
|
|
68
|
+
NSMethodSignature *methodSignature = [pbInstance methodSignatureForSelector:selector];
|
|
69
|
+
if (nil == methodSignature) {
|
|
70
|
+
NSString *description = [NSString stringWithFormat:@"Cannot retrieve '%@' from a UIPasteboard instance", item];
|
|
71
|
+
if (error) {
|
|
72
|
+
*error = [[FBErrorBuilder.builder withDescription:description] build];
|
|
73
|
+
}
|
|
74
|
+
return nil;
|
|
75
|
+
}
|
|
76
|
+
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
|
|
77
|
+
[invocation setSelector:selector];
|
|
78
|
+
[invocation setTarget:pbInstance];
|
|
79
|
+
if (SYSTEM_VERSION_LESS_THAN(@"16.0")) {
|
|
80
|
+
[invocation invoke];
|
|
81
|
+
id __unsafe_unretained result;
|
|
82
|
+
[invocation getReturnValue:&result];
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// https://github.com/appium/appium/issues/17392
|
|
87
|
+
__block id pasteboardContent;
|
|
88
|
+
dispatch_queue_t backgroundQueue = dispatch_queue_create("GetPasteboard", NULL);
|
|
89
|
+
__block BOOL didFinishGetPasteboard = NO;
|
|
90
|
+
dispatch_async(backgroundQueue, ^{
|
|
91
|
+
[invocation invoke];
|
|
92
|
+
id __unsafe_unretained result;
|
|
93
|
+
[invocation getReturnValue:&result];
|
|
94
|
+
pasteboardContent = result;
|
|
95
|
+
didFinishGetPasteboard = YES;
|
|
96
|
+
});
|
|
97
|
+
uint64_t timeStarted = mach_absolute_time();
|
|
98
|
+
while (!didFinishGetPasteboard) {
|
|
99
|
+
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:ALERT_CHECK_INTERVAL_SEC]];
|
|
100
|
+
if (didFinishGetPasteboard) {
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
XCUIElement *alertElement = FBApplication.fb_systemApplication.fb_alertElement;
|
|
105
|
+
if (nil != alertElement) {
|
|
106
|
+
FBAlert *alert = [FBAlert alertWithElement:alertElement];
|
|
107
|
+
[alert acceptWithError:nil];
|
|
108
|
+
}
|
|
109
|
+
uint64_t timeElapsed = mach_absolute_time() - timeStarted;
|
|
110
|
+
if (timeElapsed / NSEC_PER_SEC > timeout) {
|
|
111
|
+
NSString *description = [NSString stringWithFormat:@"Cannot handle pasteboard alert within %@s timeout", @(timeout)];
|
|
112
|
+
if (error) {
|
|
113
|
+
*error = [[FBErrorBuilder.builder withDescription:description] build];
|
|
114
|
+
}
|
|
115
|
+
return nil;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return pasteboardContent;
|
|
119
|
+
}
|
|
120
|
+
|
|
53
121
|
+ (NSData *)dataForType:(NSString *)type error:(NSError **)error
|
|
54
122
|
{
|
|
55
123
|
UIPasteboard *pb = UIPasteboard.generalPasteboard;
|
|
56
124
|
if ([type.lowercaseString isEqualToString:@"plaintext"]) {
|
|
57
125
|
if (pb.hasStrings) {
|
|
58
|
-
|
|
126
|
+
id result = [self.class pasteboardContentForItem:@"strings"
|
|
127
|
+
instance:pb
|
|
128
|
+
timeout:ALERT_TIMEOUT_SEC
|
|
129
|
+
error:error
|
|
130
|
+
];
|
|
131
|
+
return nil == result
|
|
132
|
+
? nil
|
|
133
|
+
: [[(NSArray *)result componentsJoinedByString:@"\n"] dataUsingEncoding:NSUTF8StringEncoding];
|
|
59
134
|
}
|
|
60
135
|
} else if ([type.lowercaseString isEqualToString:@"image"]) {
|
|
61
136
|
if (pb.hasImages) {
|
|
62
|
-
|
|
137
|
+
id result = [self.class pasteboardContentForItem:@"image"
|
|
138
|
+
instance:pb
|
|
139
|
+
timeout:ALERT_TIMEOUT_SEC
|
|
140
|
+
error:error
|
|
141
|
+
];
|
|
142
|
+
return nil == result ? nil : UIImagePNGRepresentation((UIImage *)result);
|
|
63
143
|
}
|
|
64
144
|
} else if ([type.lowercaseString isEqualToString:@"url"]) {
|
|
65
145
|
if (pb.hasURLs) {
|
|
146
|
+
id result = [self.class pasteboardContentForItem:@"URLs"
|
|
147
|
+
instance:pb
|
|
148
|
+
timeout:ALERT_TIMEOUT_SEC
|
|
149
|
+
error:error
|
|
150
|
+
];
|
|
151
|
+
if (nil == result) {
|
|
152
|
+
return nil;
|
|
153
|
+
}
|
|
66
154
|
NSMutableArray<NSString *> *urls = [NSMutableArray array];
|
|
67
|
-
for (NSURL *url in
|
|
155
|
+
for (NSURL *url in (NSArray *)result) {
|
|
68
156
|
if (nil != url.absoluteString) {
|
|
69
157
|
[urls addObject:(id)url.absoluteString];
|
|
70
158
|
}
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
if (self) {
|
|
60
60
|
_targetElement = targetElement;
|
|
61
61
|
CGRect frame = targetElement.fb_isResolvedFromCache.boolValue
|
|
62
|
-
? targetElement.lastSnapshot.wdFrame
|
|
62
|
+
? [FBXCElementSnapshotWrapper ensureWrapped:targetElement.lastSnapshot].wdFrame
|
|
63
63
|
: targetElement.wdFrame;
|
|
64
64
|
_targetCenter = FBRectGetCenter(frame);
|
|
65
65
|
_navigationItems = [NSMutableDictionary dictionary];
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
#import "FBW3CActionsHelpers.h"
|
|
20
20
|
#import "FBXCodeCompatibility.h"
|
|
21
21
|
#import "FBXCTestDaemonsProxy.h"
|
|
22
|
-
#import "
|
|
22
|
+
#import "FBXCElementSnapshotWrapper+Helpers.h"
|
|
23
23
|
#import "XCUIApplication+FBHelpers.h"
|
|
24
24
|
#import "XCUIDevice.h"
|
|
25
25
|
#import "XCUIElement+FBCaching.h"
|
|
@@ -163,13 +163,13 @@ static NSString *const FB_KEY_ACTIONS = @"actions";
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
// An offset relative to the element is defined
|
|
166
|
-
|
|
166
|
+
id<FBXCElementSnapshot> snapshot = element.fb_isResolvedFromCache.boolValue
|
|
167
167
|
? element.lastSnapshot
|
|
168
168
|
: element.fb_takeSnapshot;
|
|
169
169
|
CGRect frame = snapshot.frame;
|
|
170
170
|
if (CGRectIsEmpty(frame)) {
|
|
171
171
|
[FBLogger log:self.application.fb_descriptionRepresentation];
|
|
172
|
-
NSString *description = [NSString stringWithFormat:@"The element '%@' is not visible on the screen and thus is not interactable", snapshot.fb_description];
|
|
172
|
+
NSString *description = [NSString stringWithFormat:@"The element '%@' is not visible on the screen and thus is not interactable", [FBXCElementSnapshotWrapper ensureWrapped:snapshot].fb_description];
|
|
173
173
|
if (error) {
|
|
174
174
|
*error = [[FBErrorBuilder.builder withDescription:description] build];
|
|
175
175
|
}
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
#import <XCTest/XCTest.h>
|
|
11
|
-
#import "
|
|
12
|
-
|
|
11
|
+
#import "FBXCElementSnapshot.h"
|
|
12
|
+
|
|
13
|
+
@protocol FBXCAccessibilityElement;
|
|
13
14
|
|
|
14
15
|
NS_ASSUME_NONNULL_BEGIN
|
|
15
16
|
|
|
@@ -24,21 +25,21 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
24
25
|
|
|
25
26
|
- (BOOL)setAXTimeout:(NSTimeInterval)timeout error:(NSError **)error;
|
|
26
27
|
|
|
27
|
-
- (nullable
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
- (nullable id<FBXCElementSnapshot>)snapshotForElement:(id<FBXCAccessibilityElement>)element
|
|
29
|
+
attributes:(nullable NSArray<NSString *> *)attributes
|
|
30
|
+
maxDepth:(nullable NSNumber *)maxDepth
|
|
31
|
+
error:(NSError **)error;
|
|
31
32
|
|
|
32
|
-
- (NSArray<
|
|
33
|
+
- (NSArray<id<FBXCAccessibilityElement>> *)activeApplications;
|
|
33
34
|
|
|
34
|
-
- (
|
|
35
|
+
- (id<FBXCAccessibilityElement>)systemApplication;
|
|
35
36
|
|
|
36
37
|
- (NSDictionary *)defaultParameters;
|
|
37
38
|
|
|
38
39
|
- (void)notifyWhenNoAnimationsAreActiveForApplication:(XCUIApplication *)application
|
|
39
40
|
reply:(void (^)(void))reply;
|
|
40
41
|
|
|
41
|
-
- (NSDictionary *)attributesForElement:(
|
|
42
|
+
- (NSDictionary *)attributesForElement:(id<FBXCAccessibilityElement>)element
|
|
42
43
|
attributes:(NSArray *)attributes;
|
|
43
44
|
|
|
44
45
|
- (XCUIApplication *)monitoredApplicationWithProcessIdentifier:(int)pid;
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
#import <objc/runtime.h>
|
|
13
13
|
|
|
14
|
+
#import "FBXCAccessibilityElement.h"
|
|
14
15
|
#import "FBConfiguration.h"
|
|
15
16
|
#import "FBLogger.h"
|
|
16
17
|
#import "FBMacros.h"
|
|
@@ -32,6 +33,9 @@ static id FBAXClient = nil;
|
|
|
32
33
|
return FBConfiguration.snapshotRequestParameters;
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
#pragma clang diagnostic push
|
|
37
|
+
#pragma clang diagnostic ignored "-Wobjc-load-method"
|
|
38
|
+
|
|
35
39
|
+ (void)load
|
|
36
40
|
{
|
|
37
41
|
static dispatch_once_t onceToken;
|
|
@@ -42,6 +46,8 @@ static id FBAXClient = nil;
|
|
|
42
46
|
});
|
|
43
47
|
}
|
|
44
48
|
|
|
49
|
+
#pragma clang diagnostic pop
|
|
50
|
+
|
|
45
51
|
@end
|
|
46
52
|
|
|
47
53
|
@implementation FBXCAXClientProxy
|
|
@@ -62,10 +68,10 @@ static id FBAXClient = nil;
|
|
|
62
68
|
return [FBAXClient _setAXTimeout:timeout error:error];
|
|
63
69
|
}
|
|
64
70
|
|
|
65
|
-
- (
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
71
|
+
- (id<FBXCElementSnapshot>)snapshotForElement:(id<FBXCAccessibilityElement>)element
|
|
72
|
+
attributes:(NSArray<NSString *> *)attributes
|
|
73
|
+
maxDepth:(nullable NSNumber *)maxDepth
|
|
74
|
+
error:(NSError **)error
|
|
69
75
|
{
|
|
70
76
|
NSMutableDictionary *parameters = [[NSMutableDictionary alloc] init];
|
|
71
77
|
// Mimicking XCTest framework behavior (this attribute is added by default unless it is an excludingNonModalElements query)
|
|
@@ -82,16 +88,16 @@ static id FBAXClient = nil;
|
|
|
82
88
|
attributes:attributes
|
|
83
89
|
parameters:[parameters copy]
|
|
84
90
|
error:error];
|
|
85
|
-
|
|
91
|
+
id<FBXCElementSnapshot> snapshot = [result valueForKey:@"_rootElementSnapshot"];
|
|
86
92
|
return nil == snapshot ? result : snapshot;
|
|
87
93
|
}
|
|
88
94
|
|
|
89
|
-
- (NSArray<
|
|
95
|
+
- (NSArray<id<FBXCAccessibilityElement>> *)activeApplications
|
|
90
96
|
{
|
|
91
97
|
return [FBAXClient activeApplications];
|
|
92
98
|
}
|
|
93
99
|
|
|
94
|
-
- (
|
|
100
|
+
- (id<FBXCAccessibilityElement>)systemApplication
|
|
95
101
|
{
|
|
96
102
|
return [FBAXClient systemApplication];
|
|
97
103
|
}
|
|
@@ -107,7 +113,7 @@ static id FBAXClient = nil;
|
|
|
107
113
|
[FBAXClient notifyWhenNoAnimationsAreActiveForApplication:application reply:reply];
|
|
108
114
|
}
|
|
109
115
|
|
|
110
|
-
- (NSDictionary *)attributesForElement:(
|
|
116
|
+
- (NSDictionary *)attributesForElement:(id<FBXCAccessibilityElement>)element
|
|
111
117
|
attributes:(NSArray *)attributes
|
|
112
118
|
{
|
|
113
119
|
NSError *error = nil;
|
|
@@ -23,6 +23,10 @@
|
|
|
23
23
|
|
|
24
24
|
static Class FBXCTRunnerDaemonSessionClass = nil;
|
|
25
25
|
static dispatch_once_t onceTestRunnerDaemonClass;
|
|
26
|
+
|
|
27
|
+
#pragma clang diagnostic push
|
|
28
|
+
#pragma clang diagnostic ignored "-Wobjc-load-method"
|
|
29
|
+
|
|
26
30
|
+ (void)load
|
|
27
31
|
{
|
|
28
32
|
// XCTRunnerDaemonSession class is only available since Xcode 8.3
|
|
@@ -31,6 +35,8 @@ static dispatch_once_t onceTestRunnerDaemonClass;
|
|
|
31
35
|
});
|
|
32
36
|
}
|
|
33
37
|
|
|
38
|
+
#pragma clang diagnostic pop
|
|
39
|
+
|
|
34
40
|
+ (id<XCTestManager_ManagerInterface>)testRunnerProxy
|
|
35
41
|
{
|
|
36
42
|
static id<XCTestManager_ManagerInterface> proxy = nil;
|
|
@@ -28,16 +28,6 @@ NSInteger FBTestmanagerdVersion(void);
|
|
|
28
28
|
|
|
29
29
|
NS_ASSUME_NONNULL_BEGIN
|
|
30
30
|
|
|
31
|
-
/**
|
|
32
|
-
Set of categories that patches method name differences between Xcode versions,
|
|
33
|
-
so that WDA can be build with different Xcode versions.
|
|
34
|
-
*/
|
|
35
|
-
@interface XCElementSnapshot (FBCompatibility)
|
|
36
|
-
|
|
37
|
-
+ (nullable SEL)fb_attributesForElementSnapshotKeyPathsSelector;
|
|
38
|
-
|
|
39
|
-
@end
|
|
40
|
-
|
|
41
31
|
/**
|
|
42
32
|
The exception happends if one tries to call application method,
|
|
43
33
|
which is not supported in the current iOS version
|
|
@@ -19,30 +19,6 @@
|
|
|
19
19
|
|
|
20
20
|
static const NSTimeInterval APP_STATE_CHANGE_TIMEOUT = 5.0;
|
|
21
21
|
|
|
22
|
-
@implementation XCElementSnapshot (FBCompatibility)
|
|
23
|
-
|
|
24
|
-
+ (id)fb_axAttributesForElementSnapshotKeyPathsIOS:(id)arg1
|
|
25
|
-
{
|
|
26
|
-
return [self.class axAttributesForElementSnapshotKeyPaths:arg1 isMacOS:NO];
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
+ (nullable SEL)fb_attributesForElementSnapshotKeyPathsSelector
|
|
30
|
-
{
|
|
31
|
-
static SEL attributesForElementSnapshotKeyPathsSelector = nil;
|
|
32
|
-
static dispatch_once_t attributesForElementSnapshotKeyPathsSelectorToken;
|
|
33
|
-
dispatch_once(&attributesForElementSnapshotKeyPathsSelectorToken, ^{
|
|
34
|
-
if ([self.class respondsToSelector:@selector(axAttributesForElementSnapshotKeyPaths:)]) {
|
|
35
|
-
attributesForElementSnapshotKeyPathsSelector = @selector(axAttributesForElementSnapshotKeyPaths:);
|
|
36
|
-
} else if ([self.class respondsToSelector:@selector(axAttributesForElementSnapshotKeyPaths:isMacOS:)]) {
|
|
37
|
-
attributesForElementSnapshotKeyPathsSelector = @selector(fb_axAttributesForElementSnapshotKeyPathsIOS:);
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
return attributesForElementSnapshotKeyPathsSelector;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
@end
|
|
44
|
-
|
|
45
|
-
|
|
46
22
|
NSString *const FBApplicationMethodNotSupportedException = @"FBApplicationMethodNotSupportedException";
|
|
47
23
|
|
|
48
24
|
@implementation XCUIApplication (FBCompatibility)
|
|
@@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
25
25
|
If `query` argument is assigned then `excludedAttributes` argument is effectively ignored.
|
|
26
26
|
@return zero if the method has completed successfully
|
|
27
27
|
*/
|
|
28
|
-
+ (int)xmlRepresentationWithRootElement:(
|
|
28
|
+
+ (int)xmlRepresentationWithRootElement:(id<FBElement>)root
|
|
29
29
|
writer:(xmlTextWriterPtr)writer
|
|
30
30
|
elementStore:(nullable NSMutableDictionary *)elementStore
|
|
31
31
|
query:(nullable NSString*)query
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
#import <XCTest/XCTest.h>
|
|
11
11
|
#import <WebDriverAgentLib/FBElement.h>
|
|
12
|
-
#import
|
|
12
|
+
#import "FBXCElementSnapshot.h"
|
|
13
13
|
|
|
14
14
|
#ifdef __clang__
|
|
15
15
|
#pragma clang diagnostic push
|
|
@@ -41,8 +41,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
41
41
|
@return an array of descendants matching the given xpath query or an empty array if no matches were found
|
|
42
42
|
@throws NSException if there is an unexpected internal error during xml parsing
|
|
43
43
|
*/
|
|
44
|
-
+ (NSArray<
|
|
45
|
-
|
|
44
|
+
+ (NSArray<id<FBXCElementSnapshot>> *)matchesWithRootElement:(id<FBElement>)root
|
|
45
|
+
forQuery:(NSString *)xpathQuery;
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
Gets XML representation of XCElementSnapshot with all its descendants. This method generates the same
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
#import "FBExceptions.h"
|
|
14
14
|
#import "FBLogger.h"
|
|
15
15
|
#import "FBXMLGenerationOptions.h"
|
|
16
|
+
#import "FBXCElementSnapshotWrapper+Helpers.h"
|
|
16
17
|
#import "NSString+FBXMLSafeString.h"
|
|
17
|
-
#import "XCElementSnapshot+FBHelpers.h"
|
|
18
18
|
#import "XCUIElement.h"
|
|
19
19
|
#import "XCUIElement+FBCaching.h"
|
|
20
20
|
#import "XCUIElement+FBUtilities.h"
|
|
@@ -172,8 +172,8 @@ static NSString *const topNodeIndexPath = @"top";
|
|
|
172
172
|
return result;
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
+ (NSArray<
|
|
176
|
-
|
|
175
|
+
+ (NSArray<id<FBXCElementSnapshot>> *)matchesWithRootElement:(id<FBElement>)root
|
|
176
|
+
forQuery:(NSString *)xpathQuery
|
|
177
177
|
{
|
|
178
178
|
xmlDocPtr doc;
|
|
179
179
|
|
|
@@ -238,7 +238,7 @@ static NSString *const topNodeIndexPath = @"top";
|
|
|
238
238
|
[FBLogger log:@"Failed to invoke libxml2>xmlGetProp"];
|
|
239
239
|
return nil;
|
|
240
240
|
}
|
|
241
|
-
|
|
241
|
+
id<FBXCElementSnapshot> element = [elementStore objectForKey:(id)[NSString stringWithCString:(const char *)attrValue encoding:NSUTF8StringEncoding]];
|
|
242
242
|
if (element) {
|
|
243
243
|
[matchingSnapshots addObject:element];
|
|
244
244
|
}
|
|
@@ -325,7 +325,7 @@ static NSString *const topNodeIndexPath = @"top";
|
|
|
325
325
|
}
|
|
326
326
|
|
|
327
327
|
+ (int)recordElementAttributes:(xmlTextWriterPtr)writer
|
|
328
|
-
forElement:(
|
|
328
|
+
forElement:(id<FBXCElementSnapshot>)element
|
|
329
329
|
indexPath:(nullable NSString *)indexPath
|
|
330
330
|
includedAttributes:(nullable NSSet<Class> *)includedAttributes
|
|
331
331
|
{
|
|
@@ -334,7 +334,8 @@ static NSString *const topNodeIndexPath = @"top";
|
|
|
334
334
|
if (includedAttributes && ![includedAttributes containsObject:attributeCls]) {
|
|
335
335
|
continue;
|
|
336
336
|
}
|
|
337
|
-
int rc = [attributeCls recordWithWriter:writer
|
|
337
|
+
int rc = [attributeCls recordWithWriter:writer
|
|
338
|
+
forElement:[FBXCElementSnapshotWrapper ensureWrapped:element]];
|
|
338
339
|
if (rc < 0) {
|
|
339
340
|
return rc;
|
|
340
341
|
}
|
|
@@ -355,8 +356,8 @@ static NSString *const topNodeIndexPath = @"top";
|
|
|
355
356
|
{
|
|
356
357
|
NSAssert((indexPath == nil && elementStore == nil) || (indexPath != nil && elementStore != nil), @"Either both or none of indexPath and elementStore arguments should be equal to nil", nil);
|
|
357
358
|
|
|
358
|
-
|
|
359
|
-
NSArray<
|
|
359
|
+
id<FBXCElementSnapshot> currentSnapshot;
|
|
360
|
+
NSArray<id<FBXCElementSnapshot>> *children;
|
|
360
361
|
if ([root isKindOfClass:XCUIElement.class]) {
|
|
361
362
|
XCUIElement *element = (XCUIElement *)root;
|
|
362
363
|
NSMutableArray<NSString *> *snapshotAttributes = [NSMutableArray arrayWithArray:FBStandardAttributeNames()];
|
|
@@ -370,7 +371,7 @@ static NSString *const topNodeIndexPath = @"top";
|
|
|
370
371
|
maxDepth:nil];
|
|
371
372
|
children = currentSnapshot.children;
|
|
372
373
|
} else {
|
|
373
|
-
currentSnapshot = (
|
|
374
|
+
currentSnapshot = (id<FBXCElementSnapshot>)root;
|
|
374
375
|
children = currentSnapshot.children;
|
|
375
376
|
}
|
|
376
377
|
|
|
@@ -378,9 +379,10 @@ static NSString *const topNodeIndexPath = @"top";
|
|
|
378
379
|
[elementStore setObject:currentSnapshot forKey:topNodeIndexPath];
|
|
379
380
|
}
|
|
380
381
|
|
|
381
|
-
|
|
382
|
+
FBXCElementSnapshotWrapper *wrappedSnapshot = [FBXCElementSnapshotWrapper ensureWrapped:currentSnapshot];
|
|
383
|
+
int rc = xmlTextWriterStartElement(writer, (xmlChar *)[wrappedSnapshot.wdType UTF8String]);
|
|
382
384
|
if (rc < 0) {
|
|
383
|
-
[FBLogger logFmt:@"Failed to invoke libxml2>xmlTextWriterStartElement for the tag value '%@'. Error code: %d",
|
|
385
|
+
[FBLogger logFmt:@"Failed to invoke libxml2>xmlTextWriterStartElement for the tag value '%@'. Error code: %d", wrappedSnapshot.wdType, rc];
|
|
384
386
|
return rc;
|
|
385
387
|
}
|
|
386
388
|
|
|
@@ -393,12 +395,12 @@ static NSString *const topNodeIndexPath = @"top";
|
|
|
393
395
|
}
|
|
394
396
|
|
|
395
397
|
for (NSUInteger i = 0; i < [children count]; i++) {
|
|
396
|
-
|
|
398
|
+
id<FBXCElementSnapshot> childSnapshot = [children objectAtIndex:i];
|
|
397
399
|
NSString *newIndexPath = (indexPath != nil) ? [indexPath stringByAppendingFormat:@",%lu", (unsigned long)i] : nil;
|
|
398
400
|
if (elementStore != nil && newIndexPath != nil) {
|
|
399
401
|
[elementStore setObject:childSnapshot forKey:(id)newIndexPath];
|
|
400
402
|
}
|
|
401
|
-
rc = [self writeXmlWithRootElement:childSnapshot
|
|
403
|
+
rc = [self writeXmlWithRootElement:[FBXCElementSnapshotWrapper ensureWrapped:childSnapshot]
|
|
402
404
|
indexPath:newIndexPath
|
|
403
405
|
elementStore:elementStore
|
|
404
406
|
includedAttributes:includedAttributes
|
|
@@ -23,7 +23,20 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
23
23
|
@return formatted predicate
|
|
24
24
|
@throw FBUnknownPredicateKeyException in case the given property name is not declared in FBElement protocol
|
|
25
25
|
*/
|
|
26
|
-
+ (
|
|
26
|
+
+ (instancetype)fb_formatSearchPredicate:(NSPredicate *)input;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
Creates a block predicate expression, which properly evalluates the given raw predicate agains
|
|
30
|
+
xctest hierarchy. Vanilla string predicates don't work on this hierachy because "raw" snapshots
|
|
31
|
+
don't have any of the custom properties declared in FBElement protocol.
|
|
32
|
+
`fb_formatSearchPredicate` is called automtically on the original predicate before
|
|
33
|
+
making it to a block.
|
|
34
|
+
|
|
35
|
+
@param input predicate object received from user input
|
|
36
|
+
@return formatted predicate
|
|
37
|
+
@throw FBUnknownPredicateKeyException in case the given property name is not declared in FBElement protocol
|
|
38
|
+
*/
|
|
39
|
+
+ (instancetype)fb_snapshotBlockPredicateWithPredicate:(NSPredicate *)input;
|
|
27
40
|
|
|
28
41
|
@end
|
|
29
42
|
|