appium-webdriveragent 4.7.0 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) 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/WebDriverAgent.xcodeproj/project.xcworkspace/xcuserdata/elf.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  18. package/WebDriverAgent.xcodeproj/xcuserdata/elf.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +91 -0
  19. package/WebDriverAgent.xcodeproj/xcuserdata/elf.xcuserdatad/xcschemes/xcschememanagement.plist +59 -0
  20. package/WebDriverAgentLib/Categories/{XCElementSnapshot+FBHelpers.h → FBXCElementSnapshotWrapper+Helpers.h} +18 -11
  21. package/WebDriverAgentLib/Categories/{XCElementSnapshot+FBHelpers.m → FBXCElementSnapshotWrapper+Helpers.m} +57 -39
  22. package/WebDriverAgentLib/Categories/NSExpression+FBFormat.m +8 -3
  23. package/WebDriverAgentLib/Categories/XCUIApplication+FBAlert.m +8 -7
  24. package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.h +2 -2
  25. package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +29 -28
  26. package/WebDriverAgentLib/Categories/XCUIApplicationProcess+FBQuiescence.m +5 -0
  27. package/WebDriverAgentLib/Categories/XCUICoordinate+FBFix.m +0 -1
  28. package/WebDriverAgentLib/Categories/XCUIDevice+FBHelpers.m +8 -5
  29. package/WebDriverAgentLib/Categories/XCUIElement+FBAccessibility.h +2 -2
  30. package/WebDriverAgentLib/Categories/XCUIElement+FBAccessibility.m +5 -4
  31. package/WebDriverAgentLib/Categories/XCUIElement+FBCaching.m +3 -2
  32. package/WebDriverAgentLib/Categories/XCUIElement+FBFind.m +22 -18
  33. package/WebDriverAgentLib/Categories/XCUIElement+FBIsVisible.h +2 -3
  34. package/WebDriverAgentLib/Categories/XCUIElement+FBIsVisible.m +28 -26
  35. package/WebDriverAgentLib/Categories/XCUIElement+FBPickerWheel.m +2 -1
  36. package/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m +8 -4
  37. package/WebDriverAgentLib/Categories/XCUIElement+FBScrolling.m +73 -51
  38. package/WebDriverAgentLib/Categories/XCUIElement+FBTyping.m +11 -10
  39. package/WebDriverAgentLib/Categories/XCUIElement+FBUID.h +10 -5
  40. package/WebDriverAgentLib/Categories/XCUIElement+FBUID.m +15 -3
  41. package/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.h +7 -7
  42. package/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m +29 -20
  43. package/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.h +2 -2
  44. package/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m +16 -13
  45. package/WebDriverAgentLib/Categories/XCUIElementQuery+FBHelpers.h +2 -3
  46. package/WebDriverAgentLib/Categories/XCUIElementQuery+FBHelpers.m +3 -3
  47. package/WebDriverAgentLib/Commands/FBElementCommands.m +15 -14
  48. package/WebDriverAgentLib/Commands/FBFindElementCommands.m +5 -6
  49. package/WebDriverAgentLib/FBAlert.m +16 -13
  50. package/WebDriverAgentLib/FBApplication.m +8 -8
  51. package/WebDriverAgentLib/Routing/FBElementUtils.h +11 -2
  52. package/WebDriverAgentLib/Routing/FBElementUtils.m +15 -12
  53. package/WebDriverAgentLib/Routing/FBResponsePayload.m +11 -10
  54. package/WebDriverAgentLib/Routing/FBSession.m +1 -1
  55. package/{PrivateHeaders/XCTest/XCAccessibilityElement.h → WebDriverAgentLib/Routing/FBXCAccessibilityElement.h} +19 -18
  56. package/WebDriverAgentLib/{Categories/XCAccessibilityElement+FBComparison.m → Routing/FBXCAccessibilityElement.m} +5 -11
  57. package/WebDriverAgentLib/Routing/FBXCDeviceEvent.h +35 -0
  58. package/WebDriverAgentLib/Routing/FBXCDeviceEvent.m +43 -0
  59. package/{PrivateHeaders/XCTest/XCElementSnapshot.h → WebDriverAgentLib/Routing/FBXCElementSnapshot.h} +25 -44
  60. package/WebDriverAgentLib/Routing/FBXCElementSnapshot.m +10 -0
  61. package/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.h +30 -0
  62. package/WebDriverAgentLib/Routing/FBXCElementSnapshotWrapper.m +45 -0
  63. package/WebDriverAgentLib/Utilities/FBActiveAppDetectionPoint.h +3 -4
  64. package/WebDriverAgentLib/Utilities/FBActiveAppDetectionPoint.m +4 -4
  65. package/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.h +2 -2
  66. package/WebDriverAgentLib/Utilities/FBBaseActionsSynthesizer.m +7 -8
  67. package/WebDriverAgentLib/Utilities/FBClassChainQueryParser.m +1 -2
  68. package/WebDriverAgentLib/Utilities/FBConfiguration.m +0 -1
  69. package/WebDriverAgentLib/Utilities/FBImageIOScaler.m +3 -0
  70. package/WebDriverAgentLib/Utilities/FBKeyboard.m +1 -2
  71. package/WebDriverAgentLib/Utilities/FBTVNavigationTracker.m +1 -1
  72. package/WebDriverAgentLib/Utilities/FBW3CActionsSynthesizer.m +3 -3
  73. package/WebDriverAgentLib/Utilities/FBXCAXClientProxy.h +10 -9
  74. package/WebDriverAgentLib/Utilities/FBXCAXClientProxy.m +14 -8
  75. package/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.h +0 -1
  76. package/WebDriverAgentLib/Utilities/FBXCTestDaemonsProxy.m +6 -0
  77. package/WebDriverAgentLib/Utilities/FBXCodeCompatibility.h +0 -10
  78. package/WebDriverAgentLib/Utilities/FBXCodeCompatibility.m +0 -24
  79. package/WebDriverAgentLib/Utilities/FBXPath-Private.h +1 -1
  80. package/WebDriverAgentLib/Utilities/FBXPath.h +3 -3
  81. package/WebDriverAgentLib/Utilities/FBXPath.m +15 -13
  82. package/WebDriverAgentLib/Utilities/NSPredicate+FBFormat.h +14 -1
  83. package/WebDriverAgentLib/Utilities/NSPredicate+FBFormat.m +18 -9
  84. package/WebDriverAgentLib/Utilities/XCTestPrivateSymbols.m +9 -3
  85. package/WebDriverAgentLib/Utilities/XCUIApplicationProcessDelay.m +7 -1
  86. package/WebDriverAgentLib/Vendor/CocoaAsyncSocket/GCDAsyncSocket.m +7 -1
  87. package/WebDriverAgentLib/WebDriverAgentLib.h +0 -1
  88. package/WebDriverAgentRunner-Runner.app.zip +0 -0
  89. package/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m +26 -19
  90. package/WebDriverAgentTests/IntegrationTests/XCElementSnapshotHelperTests.m +24 -29
  91. package/WebDriverAgentTests/IntegrationTests/XCElementSnapshotHitPointTests.m +2 -2
  92. package/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m +5 -3
  93. package/WebDriverAgentTests/IntegrationTests/XCUIElementHelperIntegrationTests.m +2 -1
  94. package/{WebDriverAgentLib/Categories/XCElementSnapshot+FBHitPoint.h → WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.h} +3 -14
  95. package/WebDriverAgentTests/UnitTests/Doubles/XCElementSnapshotDouble.m +99 -0
  96. package/WebDriverAgentTests/UnitTests/FBXPathTests.m +21 -13
  97. package/WebDriverAgentTests/UnitTests/NSPredicateFBFormatTests.m +4 -5
  98. package/package.json +1 -1
  99. package/WebDriverAgentLib/Categories/XCAccessibilityElement+FBComparison.h +0 -27
  100. package/WebDriverAgentLib/Categories/XCElementSnapshot+FBHitPoint.m +0 -29
  101. package/WebDriverAgentLib/Utilities/FBPredicate.h +0 -28
  102. package/WebDriverAgentLib/Utilities/FBPredicate.m +0 -29
@@ -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,7 +27,7 @@
26
27
 
27
28
  @implementation XCUIElement (WebDriverAttributesForwarding)
28
29
 
29
- - (XCElementSnapshot *)fb_snapshotForAttributeName:(NSString *)name
30
+ - (id<FBXCElementSnapshot>)fb_snapshotForAttributeName:(NSString *)name
30
31
  {
31
32
  // These attrbiutes 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.
@@ -51,8 +52,8 @@
51
52
  - (id)fb_valueForWDAttributeName:(NSString *)name
52
53
  {
53
54
  NSString *wdAttributeName = [FBElementUtils wdAttributeNameForAttributeName:name];
54
- XCElementSnapshot *snapshot = [self fb_snapshotForAttributeName:wdAttributeName];
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 XCElementSnapshot (WebDriverAttributes)
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
- XCElementSnapshot *containerView = [[self children] firstObject];
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
- XCElementSnapshot *parentSnapshot = self.parent;
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 && parentSnapshot.elementType != XCUIElementTypeTable) {
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<XCElementSnapshot *> *children = self.children;
190
- for (XCElementSnapshot *child in children) {
191
- if (child.isWDAccessibilityContainer || child.fb_isAccessibilityElement) {
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 XCElementSnapshot *)fb_cachedSnapshot;
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 XCElementSnapshot *)fb_cachedSnapshot
18
+ - (nullable id<FBXCElementSnapshot>)fb_cachedSnapshot
19
19
  {
20
- XCElementSnapshot *rootElementSnapshot = self.rootElementSnapshot;
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"
@@ -105,7 +104,7 @@
105
104
  {
106
105
  FBElementCache *elementCache = request.session.elementCache;
107
106
  XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
108
- BOOL isEnabled = element.lastSnapshot.isWDEnabled;
107
+ BOOL isEnabled = [FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot].isWDEnabled;
109
108
  return FBResponseWithObject(isEnabled ? @YES : @NO);
110
109
  }
111
110
 
@@ -113,7 +112,7 @@
113
112
  {
114
113
  FBElementCache *elementCache = request.session.elementCache;
115
114
  XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
116
- return FBResponseWithObject(element.lastSnapshot.wdRect);
115
+ return FBResponseWithObject([FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot].wdRect);
117
116
  }
118
117
 
119
118
  + (id<FBResponsePayload>)handleGetAttribute:(FBRouteRequest *)request
@@ -143,7 +142,8 @@
143
142
  {
144
143
  FBElementCache *elementCache = request.session.elementCache;
145
144
  XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
146
- id text = FBFirstNonEmptyValue(element.lastSnapshot.wdValue, element.lastSnapshot.wdLabel);
145
+ FBXCElementSnapshotWrapper *wrappedSnapshot = [FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot];
146
+ id text = FBFirstNonEmptyValue(wrappedSnapshot.wdValue, wrappedSnapshot.wdLabel);
147
147
  return FBResponseWithObject(text ?: @"");
148
148
  }
149
149
 
@@ -153,7 +153,7 @@
153
153
  XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]
154
154
  resolveForAdditionalAttributes:@[FB_XCAXAIsVisibleAttributeName]
155
155
  andMaxDepth:@1];
156
- return FBResponseWithObject(@(element.lastSnapshot.isWDVisible));
156
+ return FBResponseWithObject(@([FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot].isWDVisible));
157
157
  }
158
158
 
159
159
  + (id<FBResponsePayload>)handleGetAccessible:(FBRouteRequest *)request
@@ -162,7 +162,7 @@
162
162
  XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]
163
163
  resolveForAdditionalAttributes:@[FB_XCAXAIsElementAttributeName]
164
164
  andMaxDepth:@1];
165
- return FBResponseWithObject(@(element.lastSnapshot.isWDAccessible));
165
+ return FBResponseWithObject(@([FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot].isWDAccessible));
166
166
  }
167
167
 
168
168
  + (id<FBResponsePayload>)handleGetIsAccessibilityContainer:(FBRouteRequest *)request
@@ -171,21 +171,21 @@
171
171
  XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]
172
172
  resolveForAdditionalAttributes:@[FB_XCAXAIsElementAttributeName]
173
173
  andMaxDepth:nil];
174
- return FBResponseWithObject(@(element.lastSnapshot.isWDAccessibilityContainer));
174
+ return FBResponseWithObject(@([FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot].isWDAccessibilityContainer));
175
175
  }
176
176
 
177
177
  + (id<FBResponsePayload>)handleGetName:(FBRouteRequest *)request
178
178
  {
179
179
  FBElementCache *elementCache = request.session.elementCache;
180
180
  XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
181
- return FBResponseWithObject(element.lastSnapshot.wdType);
181
+ return FBResponseWithObject([FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot].wdType);
182
182
  }
183
183
 
184
184
  + (id<FBResponsePayload>)handleGetSelected:(FBRouteRequest *)request
185
185
  {
186
186
  FBElementCache *elementCache = request.session.elementCache;
187
187
  XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
188
- return FBResponseWithObject(@(element.lastSnapshot.wdSelected));
188
+ return FBResponseWithObject(@([FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot].wdSelected));
189
189
  }
190
190
 
191
191
  + (id<FBResponsePayload>)handleSetValue:(FBRouteRequest *)request
@@ -199,7 +199,7 @@
199
199
  NSString *textToType = [value isKindOfClass:NSArray.class]
200
200
  ? [value componentsJoinedByString:@""]
201
201
  : value;
202
- XCUIElementType elementType = element.lastSnapshot.elementType;
202
+ XCUIElementType elementType = [(id<FBXCElementSnapshot>)element.lastSnapshot elementType];
203
203
  #if !TARGET_OS_TV
204
204
  if (elementType == XCUIElementTypePickerWheel) {
205
205
  [element adjustToPickerWheelValue:textToType];
@@ -370,7 +370,8 @@
370
370
 
371
371
  NSString *const predicateString = request.arguments[@"predicateString"];
372
372
  if (predicateString) {
373
- NSPredicate *formattedPredicate = [NSPredicate fb_formatSearchPredicate:[FBPredicate predicateWithFormat:predicateString]];
373
+ NSPredicate *formattedPredicate = [NSPredicate fb_snapshotBlockPredicateWithPredicate:[NSPredicate
374
+ predicateWithFormat:predicateString]];
374
375
  XCUIElement *childElement = [[[[element.fb_query descendantsMatchingType:XCUIElementTypeAny] matchingPredicate:formattedPredicate] allElementsBoundByAccessibilityElement] lastObject];
375
376
  if (!childElement) {
376
377
  return FBResponseWithStatus([FBCommandStatus noSuchElementErrorWithMessage:[NSString stringWithFormat:@"'%@' predicate didn't match any elements", predicateString] traceback:[NSString stringWithFormat:@"%@", NSThread.callStackSymbols]]);
@@ -414,7 +415,7 @@
414
415
  FBSession *session = request.session;
415
416
  FBElementCache *elementCache = session.elementCache;
416
417
  XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
417
- CGRect frame = element.lastSnapshot.frame;
418
+ CGRect frame = [(id<FBXCElementSnapshot>)element.lastSnapshot frame];
418
419
  CGPoint startPoint = CGPointMake((CGFloat)(frame.origin.x + [request.arguments[@"fromX"] doubleValue]), (CGFloat)(frame.origin.y + [request.arguments[@"fromY"] doubleValue]));
419
420
  CGPoint endPoint = CGPointMake((CGFloat)(frame.origin.x + [request.arguments[@"toX"] doubleValue]), (CGFloat)(frame.origin.y + [request.arguments[@"toY"] doubleValue]));
420
421
  NSTimeInterval duration = [request.arguments[@"duration"] doubleValue];
@@ -564,7 +565,7 @@ static const CGFloat DEFAULT_OFFSET = (CGFloat)0.2;
564
565
  {
565
566
  FBElementCache *elementCache = request.session.elementCache;
566
567
  XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]];
567
- if (element.lastSnapshot.elementType != XCUIElementTypePickerWheel) {
568
+ if ([element.lastSnapshot elementType] != XCUIElementTypePickerWheel) {
568
569
  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]]);
569
570
  }
570
571
  NSString* order = [request.arguments[@"order"] lowercaseString];
@@ -634,7 +635,7 @@ static const CGFloat DEFAULT_OFFSET = (CGFloat)0.2;
634
635
  XCUIElement *window = application.windows.fb_firstMatch;
635
636
  if (window) {
636
637
  element = window;
637
- XCElementSnapshot *snapshot = element.fb_cachedSnapshot ?: element.fb_takeSnapshot;
638
+ id<FBXCElementSnapshot> snapshot = element.fb_cachedSnapshot ?: element.fb_takeSnapshot;
638
639
  point.x -= snapshot.frame.origin.x;
639
640
  point.y -= snapshot.frame.origin.y;
640
641
  }
@@ -15,7 +15,6 @@
15
15
  #import "FBElementCache.h"
16
16
  #import "FBExceptions.h"
17
17
  #import "FBMacros.h"
18
- #import "FBPredicate.h"
19
18
  #import "FBRouteRequest.h"
20
19
  #import "FBSession.h"
21
20
  #import "XCTestPrivateSymbols.h"
@@ -84,11 +83,12 @@ static id<FBResponsePayload> FBNoSuchElementErrorResponseForRequest(FBRouteReque
84
83
  XCUIElement *element = [elementCache elementForUUID:(NSString *)request.parameters[@"uuid"]
85
84
  resolveForAdditionalAttributes:@[FB_XCAXAIsVisibleAttributeName]
86
85
  andMaxDepth:nil];
87
- NSArray<XCElementSnapshot *> *visibleCellSnapshots = [element.lastSnapshot descendantsByFilteringWithBlock:^BOOL(XCElementSnapshot *snapshot) {
88
- return snapshot.elementType == XCUIElementTypeCell && snapshot.wdVisible;
86
+ NSArray<id<FBXCElementSnapshot>> *visibleCellSnapshots = [element.lastSnapshot descendantsByFilteringWithBlock:^BOOL(id<FBXCElementSnapshot> snapshot) {
87
+ return snapshot.elementType == XCUIElementTypeCell
88
+ && [FBXCElementSnapshotWrapper ensureWrapped:snapshot].wdVisible;
89
89
  }];
90
90
  NSArray *cells = [element fb_filterDescendantsWithSnapshots:visibleCellSnapshots
91
- selfUID:element.lastSnapshot.wdUID
91
+ selfUID:[FBXCElementSnapshotWrapper ensureWrapped:element.lastSnapshot].wdUID
92
92
  onlyChildren:NO];
93
93
  return FBResponseWithCachedElements(cells, request.session.elementCache, FBConfiguration.shouldUseCompactResponses);
94
94
  }
@@ -169,8 +169,7 @@ shouldReturnAfterFirstMatch:(BOOL)shouldReturnAfterFirstMatch
169
169
  return [element fb_descendantsMatchingXPathQuery:value
170
170
  shouldReturnAfterFirstMatch:shouldReturnAfterFirstMatch];
171
171
  } else if ([usingText isEqualToString:@"predicate string"]) {
172
- NSPredicate *predicate = [FBPredicate predicateWithFormat:value];
173
- return [element fb_descendantsMatchingPredicate:predicate
172
+ return [element fb_descendantsMatchingPredicate:[NSPredicate predicateWithFormat:value]
174
173
  shouldReturnAfterFirstMatch:shouldReturnAfterFirstMatch];
175
174
  } else if ([usingText isEqualToString:@"name"]
176
175
  || [usingText isEqualToString:@"id"]
@@ -13,8 +13,8 @@
13
13
  #import "FBConfiguration.h"
14
14
  #import "FBErrorBuilder.h"
15
15
  #import "FBLogger.h"
16
+ #import "FBXCElementSnapshotWrapper+Helpers.h"
16
17
  #import "FBXCodeCompatibility.h"
17
- #import "XCElementSnapshot+FBHelpers.h"
18
18
  #import "XCUIApplication+FBAlert.h"
19
19
  #import "XCUIElement+FBClassChain.h"
20
20
  #import "XCUIElement+FBTap.h"
@@ -65,13 +65,14 @@
65
65
  buildError:error];
66
66
  }
67
67
 
68
- + (BOOL)isSafariWebAlertWithSnapshot:(XCElementSnapshot *)snapshot
68
+ + (BOOL)isSafariWebAlertWithSnapshot:(id<FBXCElementSnapshot>)snapshot
69
69
  {
70
70
  if (snapshot.elementType != XCUIElementTypeOther) {
71
71
  return NO;
72
72
  }
73
73
 
74
- XCElementSnapshot *application = [snapshot fb_parentMatchingType:XCUIElementTypeApplication];
74
+ FBXCElementSnapshotWrapper *snapshotWrapper = [FBXCElementSnapshotWrapper ensureWrapped:snapshot];
75
+ id<FBXCElementSnapshot> application = [snapshotWrapper fb_parentMatchingType:XCUIElementTypeApplication];
75
76
  return nil != application && [application.label isEqualToString:FB_SAFARI_APP_NAME];
76
77
  }
77
78
 
@@ -82,22 +83,24 @@
82
83
  }
83
84
 
84
85
  NSMutableArray<NSString *> *resultText = [NSMutableArray array];
85
- XCElementSnapshot *snapshot = self.alertElement.lastSnapshot;
86
+ id<FBXCElementSnapshot> snapshot = self.alertElement.lastSnapshot;
86
87
  BOOL isSafariAlert = [self.class isSafariWebAlertWithSnapshot:snapshot];
87
- [snapshot enumerateDescendantsUsingBlock:^(XCElementSnapshot *descendant) {
88
+ [snapshot enumerateDescendantsUsingBlock:^(id<FBXCElementSnapshot> descendant) {
88
89
  XCUIElementType elementType = descendant.elementType;
89
90
  if (!(elementType == XCUIElementTypeTextView || elementType == XCUIElementTypeStaticText)) {
90
91
  return;
91
92
  }
92
-
93
+
94
+ FBXCElementSnapshotWrapper *descendantWrapper = [FBXCElementSnapshotWrapper ensureWrapped:descendant];
93
95
  if (elementType == XCUIElementTypeStaticText
94
- && nil != [descendant fb_parentMatchingType:XCUIElementTypeButton]) {
96
+ && nil != [descendantWrapper fb_parentMatchingType:XCUIElementTypeButton]) {
95
97
  return;
96
98
  }
97
99
 
98
- NSString *text = descendant.wdLabel ?: descendant.wdValue;
100
+ NSString *text = descendantWrapper.wdLabel ?: descendantWrapper.wdValue;
99
101
  if (isSafariAlert && nil != descendant.parent) {
100
- NSString *parentText = descendant.parent.wdLabel ?: descendant.parent.wdValue;
102
+ FBXCElementSnapshotWrapper *descendantParentWrapper = [FBXCElementSnapshotWrapper ensureWrapped:descendant.parent];
103
+ NSString *parentText = descendantParentWrapper.wdLabel ?: descendantParentWrapper.wdValue;
101
104
  if ([parentText isEqualToString:text]) {
102
105
  // Avoid duplicated texts on Safari alerts
103
106
  return;
@@ -143,11 +146,11 @@
143
146
  }
144
147
 
145
148
  NSMutableArray<NSString *> *labels = [NSMutableArray array];
146
- [self.alertElement.lastSnapshot enumerateDescendantsUsingBlock:^(XCElementSnapshot *descendant) {
149
+ [self.alertElement.lastSnapshot enumerateDescendantsUsingBlock:^(id<FBXCElementSnapshot> descendant) {
147
150
  if (descendant.elementType != XCUIElementTypeButton) {
148
151
  return;
149
152
  }
150
- NSString *label = descendant.wdLabel;
153
+ NSString *label = [FBXCElementSnapshotWrapper ensureWrapped:descendant].wdLabel;
151
154
  if (nil != label) {
152
155
  [labels addObject:[NSString stringWithFormat:@"%@", label]];
153
156
  }
@@ -161,7 +164,7 @@
161
164
  return [self notPresentWithError:error];
162
165
  }
163
166
 
164
- XCElementSnapshot *alertSnapshot = self.alertElement.lastSnapshot;
167
+ id<FBXCElementSnapshot> alertSnapshot = self.alertElement.lastSnapshot;
165
168
  XCUIElement *acceptButton = nil;
166
169
  if (FBConfiguration.acceptAlertButtonSelector.length) {
167
170
  NSString *errorReason = nil;
@@ -200,7 +203,7 @@
200
203
  return [self notPresentWithError:error];
201
204
  }
202
205
 
203
- XCElementSnapshot *alertSnapshot = self.alertElement.lastSnapshot;
206
+ id<FBXCElementSnapshot> alertSnapshot = self.alertElement.lastSnapshot;
204
207
  XCUIElement *dismissButton = nil;
205
208
  if (FBConfiguration.dismissAlertButtonSelector.length) {
206
209
  NSString *errorReason = nil;
@@ -9,13 +9,13 @@
9
9
 
10
10
  #import "FBApplication.h"
11
11
 
12
+ #import "FBXCAccessibilityElement.h"
12
13
  #import "FBLogger.h"
13
14
  #import "FBRunLoopSpinner.h"
14
15
  #import "FBMacros.h"
15
16
  #import "FBActiveAppDetectionPoint.h"
16
17
  #import "FBXCodeCompatibility.h"
17
18
  #import "FBXCTestDaemonsProxy.h"
18
- #import "XCAccessibilityElement.h"
19
19
  #import "XCUIApplication.h"
20
20
  #import "XCUIApplication+FBHelpers.h"
21
21
  #import "XCUIApplicationImpl.h"
@@ -39,10 +39,10 @@ static const NSTimeInterval APP_STATE_CHANGE_TIMEOUT = 5.0;
39
39
 
40
40
  + (NSArray<FBApplication *> *)fb_activeApplications
41
41
  {
42
- NSArray<XCAccessibilityElement *> *activeApplicationElements = [FBXCAXClientProxy.sharedClient activeApplications];
42
+ NSArray<id<FBXCAccessibilityElement>> *activeApplicationElements = [FBXCAXClientProxy.sharedClient activeApplications];
43
43
  NSMutableArray<FBApplication *> *result = [NSMutableArray array];
44
44
  if (activeApplicationElements.count > 0) {
45
- for (XCAccessibilityElement *applicationElement in activeApplicationElements) {
45
+ for (id<FBXCAccessibilityElement> applicationElement in activeApplicationElements) {
46
46
  FBApplication *app = [FBApplication fb_applicationWithPID:applicationElement.processIdentifier];
47
47
  if (nil != app) {
48
48
  [result addObject:app];
@@ -54,9 +54,9 @@ static const NSTimeInterval APP_STATE_CHANGE_TIMEOUT = 5.0;
54
54
 
55
55
  + (instancetype)fb_activeApplicationWithDefaultBundleId:(nullable NSString *)bundleId
56
56
  {
57
- NSArray<XCAccessibilityElement *> *activeApplicationElements = [FBXCAXClientProxy.sharedClient activeApplications];
58
- XCAccessibilityElement *activeApplicationElement = nil;
59
- XCAccessibilityElement *currentElement = nil;
57
+ NSArray<id<FBXCAccessibilityElement>> *activeApplicationElements = [FBXCAXClientProxy.sharedClient activeApplications];
58
+ id<FBXCAccessibilityElement> activeApplicationElement = nil;
59
+ id<FBXCAccessibilityElement> currentElement = nil;
60
60
  if (nil != bundleId) {
61
61
  currentElement = FBActiveAppDetectionPoint.sharedInstance.axElement;
62
62
  if (nil != currentElement) {
@@ -95,7 +95,7 @@ static const NSTimeInterval APP_STATE_CHANGE_TIMEOUT = 5.0;
95
95
  [FBLogger log:@"Consider changing the 'defaultActiveApplication' setting to the bundle identifier of the desired application under test"];
96
96
  }
97
97
  } else {
98
- for (XCAccessibilityElement *appElement in activeApplicationElements) {
98
+ for (id<FBXCAccessibilityElement> appElement in activeApplicationElements) {
99
99
  if (appElement.processIdentifier == currentElement.processIdentifier) {
100
100
  activeApplicationElement = appElement;
101
101
  break;
@@ -115,7 +115,7 @@ static const NSTimeInterval APP_STATE_CHANGE_TIMEOUT = 5.0;
115
115
 
116
116
  if (activeApplicationElements.count > 0) {
117
117
  [FBLogger logFmt:@"Getting the most recent active application (out of %@ total items)", @(activeApplicationElements.count)];
118
- for (XCAccessibilityElement *appElement in activeApplicationElements) {
118
+ for (id<FBXCAccessibilityElement> appElement in activeApplicationElements) {
119
119
  FBApplication *application = [FBApplication fb_applicationWithPID:appElement.processIdentifier];
120
120
  if (nil != application) {
121
121
  return application;
@@ -9,7 +9,8 @@
9
9
 
10
10
  #import <Foundation/Foundation.h>
11
11
  #import <WebDriverAgentLib/FBElement.h>
12
- #import "XCAccessibilityElement.h"
12
+
13
+ @protocol FBXCAccessibilityElement;
13
14
 
14
15
  NS_ASSUME_NONNULL_BEGIN
15
16
 
@@ -47,13 +48,21 @@ extern NSString *const FBUnknownAttributeException;
47
48
  */
48
49
  + (NSDictionary<NSString *, NSString *> *)wdAttributeNamesMapping;
49
50
 
51
+ /**
52
+ Gets the unique identifier of the particular XCAccessibilityElement instance in form of UUIDv4.
53
+
54
+ @param element accessiblity element instance
55
+ @return the unique element identifier or nil if it cannot be retrieved
56
+ */
57
+ + (nullable NSString *)uidWithAccessibilityElement:(id<FBXCAccessibilityElement>)element;
58
+
50
59
  /**
51
60
  Gets the unique identifier of the particular XCAccessibilityElement instance.
52
61
 
53
62
  @param element accessiblity element instance
54
63
  @return the unique element identifier or nil if it cannot be retrieved
55
64
  */
56
- + (nullable NSString *)uidWithAccessibilityElement:(XCAccessibilityElement *)element;
65
+ + (unsigned long long)idWithAccessibilityElement:(id<FBXCAccessibilityElement>)element;
57
66
 
58
67
  @end
59
68
 
@@ -9,6 +9,7 @@
9
9
 
10
10
  #import <objc/runtime.h>
11
11
 
12
+ #import "FBXCAccessibilityElement.h"
12
13
  #import "FBElementUtils.h"
13
14
  #import "FBElementTypeTransformer.h"
14
15
 
@@ -109,19 +110,9 @@ static NSString *const OBJC_PROP_ATTRIBS_SEPARATOR = @",";
109
110
  return attributeNamesMapping.copy;
110
111
  }
111
112
 
112
- static BOOL FBShouldUsePayloadForUIDExtraction = YES;
113
- static dispatch_once_t oncePayloadToken;
114
- + (NSString *)uidWithAccessibilityElement:(XCAccessibilityElement *)element
113
+ + (NSString *)uidWithAccessibilityElement:(id<FBXCAccessibilityElement>)element
115
114
  {
116
- dispatch_once(&oncePayloadToken, ^{
117
- FBShouldUsePayloadForUIDExtraction = [element respondsToSelector:@selector(payload)];
118
- });
119
- unsigned long long elementId;
120
- if (FBShouldUsePayloadForUIDExtraction) {
121
- elementId = [[element.payload objectForKey:@"uid.elementID"] longLongValue];
122
- } else {
123
- elementId = [[element valueForKey:@"_elementID"] longLongValue];
124
- }
115
+ unsigned long long elementId = [self.class idWithAccessibilityElement:element];
125
116
  int processId = element.processIdentifier;
126
117
  if (elementId < 1 || processId < 1) {
127
118
  return nil;
@@ -133,4 +124,16 @@ static dispatch_once_t oncePayloadToken;
133
124
  return uuidValue.UUIDString;
134
125
  }
135
126
 
127
+ static BOOL FBShouldUsePayloadForUIDExtraction = YES;
128
+ static dispatch_once_t oncePayloadToken;
129
+ + (unsigned long long)idWithAccessibilityElement:(id<FBXCAccessibilityElement>)element
130
+ {
131
+ dispatch_once(&oncePayloadToken, ^{
132
+ FBShouldUsePayloadForUIDExtraction = [(NSObject *)element respondsToSelector:@selector(payload)];
133
+ });
134
+ return FBShouldUsePayloadForUIDExtraction
135
+ ? [[element.payload objectForKey:@"uid.elementID"] longLongValue]
136
+ : [[(NSObject *)element valueForKey:@"_elementID"] longLongValue];
137
+ }
138
+
136
139
  @end
@@ -90,35 +90,36 @@ id<FBResponsePayload> FBResponseWithStatus(FBCommandStatus *status)
90
90
 
91
91
  inline NSDictionary *FBDictionaryResponseWithElement(XCUIElement *element, BOOL compact)
92
92
  {
93
- XCElementSnapshot *snapshot = nil;
93
+ id<FBXCElementSnapshot> snapshot = nil;
94
94
  if (nil != element.query.rootElementSnapshot) {
95
95
  snapshot = element.fb_cachedSnapshot;
96
96
  }
97
97
  if (nil == snapshot) {
98
98
  snapshot = element.lastSnapshot ?: element.fb_takeSnapshot;
99
99
  }
100
- NSMutableDictionary *dictionary = FBInsertElement(@{}, (NSString *)snapshot.wdUID).mutableCopy;
100
+ FBXCElementSnapshotWrapper *wrappedSnapshot = [FBXCElementSnapshotWrapper ensureWrapped:snapshot];
101
+ NSMutableDictionary *dictionary = FBInsertElement(@{}, (NSString *)wrappedSnapshot.wdUID).mutableCopy;
101
102
  if (!compact) {
102
103
  NSArray *fields = [FBConfiguration.elementResponseAttributes componentsSeparatedByString:@","];
103
104
  for (NSString *field in fields) {
104
105
  // 'name' here is the w3c-approved identifier for what we mean by 'type'
105
106
  if ([field isEqualToString:@"name"] || [field isEqualToString:@"type"]) {
106
- dictionary[field] = snapshot.wdType;
107
+ dictionary[field] = wrappedSnapshot.wdType;
107
108
  } else if ([field isEqualToString:@"text"]) {
108
- dictionary[field] = FBFirstNonEmptyValue(snapshot.wdValue, snapshot.wdLabel) ?: [NSNull null];
109
+ dictionary[field] = FBFirstNonEmptyValue(wrappedSnapshot.wdValue, wrappedSnapshot.wdLabel) ?: [NSNull null];
109
110
  } else if ([field isEqualToString:@"rect"]) {
110
- dictionary[field] = snapshot.wdRect;
111
+ dictionary[field] = wrappedSnapshot.wdRect;
111
112
  } else if ([field isEqualToString:@"enabled"]) {
112
- dictionary[field] = @(snapshot.wdEnabled);
113
+ dictionary[field] = @(wrappedSnapshot.wdEnabled);
113
114
  } else if ([field isEqualToString:@"displayed"]) {
114
- dictionary[field] = @(snapshot.wdVisible);
115
+ dictionary[field] = @(wrappedSnapshot.wdVisible);
115
116
  } else if ([field isEqualToString:@"selected"]) {
116
- dictionary[field] = @(snapshot.wdSelected);
117
+ dictionary[field] = @(wrappedSnapshot.wdSelected);
117
118
  } else if ([field isEqualToString:@"label"]) {
118
- dictionary[field] = snapshot.wdLabel ?: [NSNull null];
119
+ dictionary[field] = wrappedSnapshot.wdLabel ?: [NSNull null];
119
120
  } else if ([field hasPrefix:arbitraryAttrPrefix]) {
120
121
  NSString *attributeName = [field substringFromIndex:[arbitraryAttrPrefix length]];
121
- dictionary[field] = [snapshot fb_valueForWDAttributeName:attributeName] ?: [NSNull null];
122
+ dictionary[field] = [wrappedSnapshot fb_valueForWDAttributeName:attributeName] ?: [NSNull null];
122
123
  }
123
124
  }
124
125
  }
@@ -12,6 +12,7 @@
12
12
 
13
13
  #import <objc/runtime.h>
14
14
 
15
+ #import "FBXCAccessibilityElement.h"
15
16
  #import "FBAlertsMonitor.h"
16
17
  #import "FBApplication.h"
17
18
  #import "FBConfiguration.h"
@@ -19,7 +20,6 @@
19
20
  #import "FBExceptions.h"
20
21
  #import "FBMacros.h"
21
22
  #import "FBXCodeCompatibility.h"
22
- #import "XCAccessibilityElement.h"
23
23
  #import "XCUIApplication+FBQuiescence.h"
24
24
  #import "XCUIElement.h"
25
25
 
@@ -1,21 +1,18 @@
1
- //
2
- // Generated by class-dump 3.5 (64 bit).
3
- //
4
- // class-dump is Copyright (C) 1997-1998, 2000-2001, 2004-2013 by Steve Nygard.
5
- //
6
-
7
- // FIXME: Probably we can remove here. instead, probably we should follow only XCElementSnapshot
8
-
9
- @class NSString;
10
-
11
- @interface XCAccessibilityElement : NSObject <NSCopying, NSSecureCoding>
12
- {
13
- NSString *_context;
14
- id _payload;
15
- int _processIdentifier;
16
- struct __AXUIElement *_axElement;
17
- unsigned long long _elementType;
18
- }
1
+ /**
2
+ * Copyright (c) 2015-present, Facebook, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * This source code is licensed under the BSD-style license found in the
6
+ * LICENSE file in the root directory of this source tree. An additional grant
7
+ * of patent rights can be found in the PATENTS file in the same directory.
8
+ */
9
+
10
+ #import <XCTest/XCTest.h>
11
+
12
+ NS_ASSUME_NONNULL_BEGIN
13
+
14
+ @protocol FBXCAccessibilityElement <NSObject>
15
+
19
16
  @property(readonly) id payload; // @synthesize payload=_payload;
20
17
  @property(readonly) int processIdentifier; // @synthesize processIdentifier=_processIdentifier;
21
18
  @property(readonly) const struct __AXUIElement *AXUIElement; // @synthesize AXUIElement=_axElement;
@@ -32,3 +29,7 @@
32
29
  - (id)init;
33
30
 
34
31
  @end
32
+
33
+ BOOL FBIsAXElementEqualToOther(id<FBXCAccessibilityElement> first, id<FBXCAccessibilityElement> second);
34
+
35
+ NS_ASSUME_NONNULL_END
@@ -7,18 +7,12 @@
7
7
  * of patent rights can be found in the PATENTS file in the same directory.
8
8
  */
9
9
 
10
- #import "XCAccessibilityElement+FBComparison.h"
11
- #import "FBElementUtils.h"
10
+ #import "FBXCAccessibilityElement.h"
12
11
 
13
- @implementation XCAccessibilityElement (FBComparison)
12
+ #import "FBElementUtils.h"
14
13
 
15
- - (BOOL)fb_isEqualToElement:(XCAccessibilityElement *)other
14
+ BOOL FBIsAXElementEqualToOther(id<FBXCAccessibilityElement> first, id<FBXCAccessibilityElement> second)
16
15
  {
17
- if (nil == other) {
18
- return NO;
19
- }
20
- return [[FBElementUtils uidWithAccessibilityElement:self]
21
- isEqualToString:([FBElementUtils uidWithAccessibilityElement:other] ?: @"")];
16
+ return nil != second && [[FBElementUtils uidWithAccessibilityElement:first]
17
+ isEqualToString:([FBElementUtils uidWithAccessibilityElement:second] ?: @"")];
22
18
  }
23
-
24
- @end