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.
Files changed (101) hide show
  1. package/PrivateHeaders/XCTest/XCAXClient_iOS.h +2 -4
  2. package/PrivateHeaders/XCTest/XCActivityRecord.h +3 -3
  3. package/PrivateHeaders/XCTest/XCApplicationQuery.h +3 -3
  4. package/PrivateHeaders/XCTest/XCTElementSetTransformer-Protocol.h +2 -2
  5. package/PrivateHeaders/XCTest/XCTRunnerDaemonSession.h +1 -1
  6. package/PrivateHeaders/XCTest/XCTestManager_IDEInterface-Protocol.h +5 -5
  7. package/PrivateHeaders/XCTest/XCTestManager_ManagerInterface-Protocol.h +8 -8
  8. package/PrivateHeaders/XCTest/XCUIApplication.h +2 -2
  9. package/PrivateHeaders/XCTest/XCUIApplicationImpl.h +2 -2
  10. package/PrivateHeaders/XCTest/XCUIApplicationProcess.h +3 -5
  11. package/PrivateHeaders/XCTest/XCUIElement.h +3 -3
  12. package/PrivateHeaders/XCTest/XCUIElementQuery.h +4 -4
  13. package/PrivateHeaders/XCTest/XCUIRecorderNodeFinder.h +3 -3
  14. package/PrivateHeaders/XCTest/XCUIRecorderUtilities.h +3 -3
  15. package/Scripts/build.sh +3 -6
  16. package/WebDriverAgent.xcodeproj/project.pbxproj +66 -70
  17. package/WebDriverAgentLib/Categories/{XCElementSnapshot+FBHelpers.h → FBXCElementSnapshotWrapper+Helpers.h} +18 -11
  18. package/WebDriverAgentLib/Categories/{XCElementSnapshot+FBHelpers.m → FBXCElementSnapshotWrapper+Helpers.m} +57 -39
  19. package/WebDriverAgentLib/Categories/NSExpression+FBFormat.m +8 -3
  20. package/WebDriverAgentLib/Categories/XCUIApplication+FBAlert.m +8 -7
  21. package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.h +2 -2
  22. package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +29 -28
  23. package/WebDriverAgentLib/Categories/XCUIApplicationProcess+FBQuiescence.m +5 -0
  24. package/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.m +0 -1
  25. package/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m +8 -5
  26. package/WebDriverAgentLib/Categories/XCUIElement+FBAccessibility.h +2 -2
  27. package/WebDriverAgentLib/Categories/XCUIElement+FBAccessibility.m +5 -4
  28. package/WebDriverAgentLib/Categories/XCUIElement+FBCaching.m +3 -2
  29. package/WebDriverAgentLib/Categories/XCUIElement+FBFind.m +22 -18
  30. package/WebDriverAgentLib/Categories/XCUIElement+FBIsVisible.h +2 -3
  31. package/WebDriverAgentLib/Categories/XCUIElement+FBIsVisible.m +28 -26
  32. package/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m +2 -1
  33. package/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m +8 -4
  34. package/WebDriverAgentLib/Categories/XCUIElement+FBScrolling.m +73 -51
  35. package/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m +11 -10
  36. package/WebDriverAgentLib/Categories/XCUIElement+FBUID.h +10 -5
  37. package/WebDriverAgentLib/Categories/XCUIElement+FBUID.m +15 -3
  38. package/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.h +7 -7
  39. package/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m +29 -20
  40. package/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.h +2 -2
  41. package/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m +17 -14
  42. package/WebDriverAgentLib/Categories/XCUIElementQuery+FBHelpers.h +2 -3
  43. package/WebDriverAgentLib/Categories/XCUIElementQuery+FBHelpers.m +3 -3
  44. package/WebDriverAgentLib/Commands/FBElementCommands.m +17 -15
  45. package/WebDriverAgentLib/Commands/FBFindElementCommands.m +5 -6
  46. package/WebDriverAgentLib/FBAlert.m +16 -13
  47. package/WebDriverAgentLib/FBApplication.m +8 -8
  48. package/WebDriverAgentLib/Routing/FBElementUtils.h +11 -2
  49. package/WebDriverAgentLib/Routing/FBElementUtils.m +15 -12
  50. package/WebDriverAgentLib/Routing/FBResponsePayload.m +11 -10
  51. package/WebDriverAgentLib/Routing/FBSession.m +1 -1
  52. package/{PrivateHeaders/XCTest/XCAccessibilityElement.h → WebDriverAgentLib/Routing/FBXCAccessibilityElement.h} +19 -18
  53. package/WebDriverAgentLib/{Categories/XCAccessibilityElement+FBComparison.m → Routing/FBXCAccessibilityElement.m} +5 -11
  54. package/WebDriverAgentLib/Routing/FBXCDeviceEvent.h +35 -0
  55. package/WebDriverAgentLib/Routing/FBXCDeviceEvent.m +43 -0
  56. package/{PrivateHeaders/XCTest/XCElementSnapshot.h → WebDriverAgentLib/Routing/FBXCElementSnapshot.h} +25 -44
  57. package/WebDriverAgentLib/Routing/FBXCElementSnapshot.m +10 -0
  58. package/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.h +30 -0
  59. package/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.m +45 -0
  60. package/WebDriverAgentLib/Utilities/FBActiveAppDetectionPoint.h +3 -4
  61. package/WebDriverAgentLib/Utilities/FBActiveAppDetectionPoint.m +4 -4
  62. package/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.h +2 -2
  63. package/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.m +7 -8
  64. package/WebDriverAgentLib/Utilities/FBClassChainQueryParser.m +1 -2
  65. package/WebDriverAgentLib/Utilities/FBConfiguration.m +0 -1
  66. package/WebDriverAgentLib/Utilities/FBImageIOScaler.m +3 -0
  67. package/WebDriverAgentLib/Utilities/FBKeyboard.m +1 -2
  68. package/WebDriverAgentLib/Utilities/FBPasteboard.m +91 -3
  69. package/WebDriverAgentLib/Utilities/FBTVNavigationTracker.m +1 -1
  70. package/WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m +3 -3
  71. package/WebDriverAgentLib/Utilities/FBXCAXClientProxy.h +10 -9
  72. package/WebDriverAgentLib/Utilities/FBXCAXClientProxy.m +14 -8
  73. package/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.h +0 -1
  74. package/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m +6 -0
  75. package/WebDriverAgentLib/Utilities/FBXCodeCompatibility.h +0 -10
  76. package/WebDriverAgentLib/Utilities/FBXCodeCompatibility.m +0 -24
  77. package/WebDriverAgentLib/Utilities/FBXPath-Private.h +1 -1
  78. package/WebDriverAgentLib/Utilities/FBXPath.h +3 -3
  79. package/WebDriverAgentLib/Utilities/FBXPath.m +15 -13
  80. package/WebDriverAgentLib/Utilities/NSPredicate+FBFormat.h +14 -1
  81. package/WebDriverAgentLib/Utilities/NSPredicate+FBFormat.m +18 -9
  82. package/WebDriverAgentLib/Utilities/XCTestPrivateSymbols.m +9 -3
  83. package/WebDriverAgentLib/Utilities/XCUIApplicationProcessDelay.m +7 -1
  84. package/WebDriverAgentLib/Vendor/CocoaAsyncSocket/GCDAsyncSocket.m +7 -1
  85. package/WebDriverAgentLib/WebDriverAgentLib.h +0 -1
  86. package/WebDriverAgentRunner-Runner.app.zip +0 -0
  87. package/WebDriverAgentTests/IntegrationTests/FBPasteboardTests.m +1 -5
  88. package/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m +26 -19
  89. package/WebDriverAgentTests/IntegrationTests/XCElementSnapshotHelperTests.m +24 -29
  90. package/WebDriverAgentTests/IntegrationTests/XCElementSnapshotHitPointTests.m +2 -2
  91. package/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m +5 -3
  92. package/WebDriverAgentTests/IntegrationTests/XCUIElementHelperIntegrationTests.m +2 -1
  93. package/{WebDriverAgentLib/Categories/XCElementSnapshot+FBHitPoint.h → WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.h} +3 -14
  94. package/WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.m +99 -0
  95. package/WebDriverAgentTests/UnitTests/FBXPathTests.m +21 -13
  96. package/WebDriverAgentTests/UnitTests/NSPredicateFBFormatTests.m +4 -5
  97. package/package.json +1 -1
  98. package/WebDriverAgentLib/Categories/XCAccessibilityElement+FBComparison.h +0 -27
  99. package/WebDriverAgentLib/Categories/XCElementSnapshot+FBHitPoint.m +0 -29
  100. package/WebDriverAgentLib/Utilities/FBPredicate.h +0 -28
  101. package/WebDriverAgentLib/Utilities/FBPredicate.m +0 -29
@@ -36,13 +36,13 @@
36
36
  return instance;
37
37
  }
38
38
 
39
- + (XCAccessibilityElement *)axElementWithPoint:(CGPoint)point
39
+ + (id<FBXCAccessibilityElement>)axElementWithPoint:(CGPoint)point
40
40
  {
41
- __block XCAccessibilityElement *onScreenElement = nil;
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:^(XCAccessibilityElement *element, NSError *error) {
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
- - (XCAccessibilityElement *)axElement
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:(XCElementSnapshot *)snapshot;
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:(XCElementSnapshot *)snapshot
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<XCElementSnapshot *> *ancestors = snapshot.fb_ancestors;
58
- XCElementSnapshot *parentWindow = ancestors.count > 1 ? [ancestors objectAtIndex:ancestors.count - 2] : nil;
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
- XCElementSnapshot *snapshot = element.fb_isResolvedFromCache.boolValue
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 fb_formatSearchPredicate:[FBPredicate predicateWithFormat:token.asString]];
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]) {
@@ -15,7 +15,6 @@
15
15
  #include "TargetConditionals.h"
16
16
  #import "FBXCodeCompatibility.h"
17
17
  #import "XCTestPrivateSymbols.h"
18
- #import "XCElementSnapshot.h"
19
18
  #import "XCTestConfiguration.h"
20
19
  #import "XCUIApplication+FBUIInterruptions.h"
21
20
 
@@ -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(XCElementSnapshot *snapshot,
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
- return [[pb.strings componentsJoinedByString:@"\n"] dataUsingEncoding:NSUTF8StringEncoding];
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
- return UIImagePNGRepresentation((UIImage *)pb.image);
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 pb.URLs) {
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 "XCElementSnapshot+FBHelpers.h"
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
- XCElementSnapshot *snapshot = element.fb_isResolvedFromCache.boolValue
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 "XCElementSnapshot.h"
12
- #import "XCAccessibilityElement.h"
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 XCElementSnapshot *)snapshotForElement:(XCAccessibilityElement *)element
28
- attributes:(nullable NSArray<NSString *> *)attributes
29
- maxDepth:(nullable NSNumber *)maxDepth
30
- error:(NSError **)error;
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<XCAccessibilityElement *> *)activeApplications;
33
+ - (NSArray<id<FBXCAccessibilityElement>> *)activeApplications;
33
34
 
34
- - (XCAccessibilityElement *)systemApplication;
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:(XCAccessibilityElement *)element
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
- - (XCElementSnapshot *)snapshotForElement:(XCAccessibilityElement *)element
66
- attributes:(NSArray<NSString *> *)attributes
67
- maxDepth:(nullable NSNumber *)maxDepth
68
- error:(NSError **)error
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
- XCElementSnapshot *snapshot = [result valueForKey:@"_rootElementSnapshot"];
91
+ id<FBXCElementSnapshot> snapshot = [result valueForKey:@"_rootElementSnapshot"];
86
92
  return nil == snapshot ? result : snapshot;
87
93
  }
88
94
 
89
- - (NSArray<XCAccessibilityElement *> *)activeApplications
95
+ - (NSArray<id<FBXCAccessibilityElement>> *)activeApplications
90
96
  {
91
97
  return [FBAXClient activeApplications];
92
98
  }
93
99
 
94
- - (XCAccessibilityElement *)systemApplication
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:(XCAccessibilityElement *)element
116
+ - (NSDictionary *)attributesForElement:(id<FBXCAccessibilityElement>)element
111
117
  attributes:(NSArray *)attributes
112
118
  {
113
119
  NSError *error = nil;
@@ -9,7 +9,6 @@
9
9
 
10
10
  #import <XCTest/XCTest.h>
11
11
  #import "XCSynthesizedEventRecord.h"
12
- #import "XCElementSnapshot.h"
13
12
 
14
13
  NS_ASSUME_NONNULL_BEGIN
15
14
 
@@ -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:(XCElementSnapshot *)root
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 <WebDriverAgentLib/XCElementSnapshot.h>
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<XCElementSnapshot *> *)matchesWithRootElement:(id<FBElement>)root
45
- forQuery:(NSString *)xpathQuery;
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<XCElementSnapshot *> *)matchesWithRootElement:(id<FBElement>)root
176
- forQuery:(NSString *)xpathQuery
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
- XCElementSnapshot *element = [elementStore objectForKey:(id)[NSString stringWithCString:(const char *)attrValue encoding:NSUTF8StringEncoding]];
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:(XCElementSnapshot *)element
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 forElement:element];
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
- XCElementSnapshot *currentSnapshot;
359
- NSArray<XCElementSnapshot *> *children;
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 = (XCElementSnapshot *)root;
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
- int rc = xmlTextWriterStartElement(writer, (xmlChar *)[currentSnapshot.wdType UTF8String]);
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", currentSnapshot.wdType, rc];
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
- XCElementSnapshot *childSnapshot = [children objectAtIndex:i];
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
- + (NSPredicate *)fb_formatSearchPredicate:(NSPredicate *)input;
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