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
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (c) 2015-present, Facebook, Inc.
2
+ * Copyright (c) 2018-present, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
@@ -7,11 +7,11 @@
7
7
  * of patent rights can be found in the PATENTS file in the same directory.
8
8
  */
9
9
 
10
- #import <WebDriverAgentLib/XCElementSnapshot.h>
10
+ #import "FBXCElementSnapshotWrapper.h"
11
11
 
12
12
  NS_ASSUME_NONNULL_BEGIN
13
13
 
14
- @interface XCElementSnapshot (FBHelpers)
14
+ @interface FBXCElementSnapshotWrapper (Helpers)
15
15
 
16
16
  /**
17
17
  Returns an array of descendants matching given type
@@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
19
19
  @param type requested descendant type
20
20
  @return an array of descendants matching given type
21
21
  */
22
- - (NSArray<XCElementSnapshot *> *)fb_descendantsMatchingType:(XCUIElementType)type;
22
+ - (NSArray<id<FBXCElementSnapshot>> *)fb_descendantsMatchingType:(XCUIElementType)type;
23
23
 
24
24
  /**
25
25
  Returns first (going up element tree) parent that matches given type. If non found returns nil.
@@ -27,7 +27,7 @@ NS_ASSUME_NONNULL_BEGIN
27
27
  @param type requested parent type
28
28
  @return parent element matching given type
29
29
  */
30
- - (nullable XCElementSnapshot *)fb_parentMatchingType:(XCUIElementType)type;
30
+ - (nullable id<FBXCElementSnapshot>)fb_parentMatchingType:(XCUIElementType)type;
31
31
 
32
32
  /**
33
33
  Returns first (going up element tree) parent that matches one of given types. If non found returns nil.
@@ -35,7 +35,7 @@ NS_ASSUME_NONNULL_BEGIN
35
35
  @param types possible parent types
36
36
  @return parent element matching one of given types
37
37
  */
38
- - (nullable XCElementSnapshot *)fb_parentMatchingOneOfTypes:(NSArray<NSNumber *> *)types;
38
+ - (nullable id<FBXCElementSnapshot>)fb_parentMatchingOneOfTypes:(NSArray<NSNumber *> *)types;
39
39
 
40
40
  /**
41
41
  Returns first (going up element tree) visible parent that matches one of given types and has more than one child. If non found returns nil.
@@ -44,14 +44,14 @@ NS_ASSUME_NONNULL_BEGIN
44
44
  @param filter will filter results even further after matching one of given types
45
45
  @return parent element matching one of given types and satisfying filter condition
46
46
  */
47
- - (nullable XCElementSnapshot *)fb_parentMatchingOneOfTypes:(NSArray<NSNumber *> *)types filter:(BOOL(^)(XCElementSnapshot *snapshot))filter;
47
+ - (nullable id<FBXCElementSnapshot>)fb_parentMatchingOneOfTypes:(NSArray<NSNumber *> *)types filter:(BOOL(^)(id<FBXCElementSnapshot> snapshot))filter;
48
48
 
49
49
  /**
50
50
  Retrieves the list of all element ancestors in the snapshot hierarchy.
51
51
 
52
52
  @return the list of element ancestors or an empty list if the snapshot has no parent.
53
53
  */
54
- - (NSArray<XCElementSnapshot *> *)fb_ancestors;
54
+ - (NSArray<id<FBXCElementSnapshot>> *)fb_ancestors;
55
55
 
56
56
  /**
57
57
  Returns value for given accessibility property identifier.
@@ -68,21 +68,21 @@ NS_ASSUME_NONNULL_BEGIN
68
68
  @param snapshot element's snapshot to compare against
69
69
  @return YES, if they match otherwise NO
70
70
  */
71
- - (BOOL)fb_framelessFuzzyMatchesElement:(XCElementSnapshot *)snapshot;
71
+ - (BOOL)fb_framelessFuzzyMatchesElement:(id<FBXCElementSnapshot>)snapshot;
72
72
 
73
73
  /**
74
74
  Returns an array of descendants cell snapshots
75
75
 
76
76
  @return an array of descendants cell snapshots
77
77
  */
78
- - (NSArray<XCElementSnapshot *> *)fb_descendantsCellSnapshots;
78
+ - (NSArray<id<FBXCElementSnapshot>> *)fb_descendantsCellSnapshots;
79
79
 
80
80
  /**
81
81
  Returns itself if it is either XCUIElementTypeIcon or XCUIElementTypeCell. Otherwise, returns first (going up element tree) parent that matches cell (XCUIElementTypeCell or XCUIElementTypeIcon). If non found returns nil.
82
82
 
83
83
  @return parent element matching either XCUIElementTypeIcon or XCUIElementTypeCell.
84
84
  */
85
- - (nullable XCElementSnapshot *)fb_parentCellSnapshot;
85
+ - (nullable id<FBXCElementSnapshot>)fb_parentCellSnapshot;
86
86
 
87
87
  /**! Human-readable snapshot description */
88
88
  - (NSString *)fb_description;
@@ -94,6 +94,13 @@ NS_ASSUME_NONNULL_BEGIN
94
94
  */
95
95
  - (CGRect)fb_visibleFrameWithFallback;
96
96
 
97
+ /**
98
+ Wrapper for Apple's hitpoint, thats resolves few known issues
99
+
100
+ @return Element's hitpoint if exists nil otherwise
101
+ */
102
+ - (nullable NSValue *)fb_hitPoint;
103
+
97
104
  @end
98
105
 
99
106
  NS_ASSUME_NONNULL_END
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright (c) 2015-present, Facebook, Inc.
2
+ * Copyright (c) 2018-present, Facebook, Inc.
3
3
  * All rights reserved.
4
4
  *
5
5
  * This source code is licensed under the BSD-style license found in the
@@ -7,20 +7,23 @@
7
7
  * of patent rights can be found in the PATENTS file in the same directory.
8
8
  */
9
9
 
10
- #import "XCElementSnapshot+FBHelpers.h"
10
+ #import "FBXCElementSnapshotWrapper+Helpers.h"
11
11
 
12
12
  #import "FBFindElementCommands.h"
13
13
  #import "FBRunLoopSpinner.h"
14
14
  #import "FBLogger.h"
15
+ #import "FBXCElementSnapshot.h"
15
16
  #import "FBXCAXClientProxy.h"
16
17
  #import "XCTestDriver.h"
17
18
  #import "XCTestPrivateSymbols.h"
18
19
  #import "XCUIElement.h"
19
20
  #import "XCUIElement+FBWebDriverAttributes.h"
21
+ #import "XCUIHitPointResult.h"
20
22
 
21
- inline static BOOL isSnapshotTypeAmongstGivenTypes(XCElementSnapshot* snapshot, NSArray<NSNumber *> *types);
23
+ inline static BOOL isSnapshotTypeAmongstGivenTypes(id<FBXCElementSnapshot> snapshot,
24
+ NSArray<NSNumber *> *types);
22
25
 
23
- @implementation XCElementSnapshot (FBHelpers)
26
+ @implementation FBXCElementSnapshotWrapper (Helpers)
24
27
 
25
28
  - (NSString *)fb_description
26
29
  {
@@ -31,29 +34,30 @@ inline static BOOL isSnapshotTypeAmongstGivenTypes(XCElementSnapshot* snapshot,
31
34
  return result;
32
35
  }
33
36
 
34
- - (NSArray<XCElementSnapshot *> *)fb_descendantsMatchingType:(XCUIElementType)type
37
+ - (NSArray<id<FBXCElementSnapshot>> *)fb_descendantsMatchingType:(XCUIElementType)type
35
38
  {
36
- return [self descendantsByFilteringWithBlock:^BOOL(XCElementSnapshot *snapshot) {
39
+ return [self descendantsByFilteringWithBlock:^BOOL(id<FBXCElementSnapshot> snapshot) {
37
40
  return snapshot.elementType == type;
38
41
  }];
39
42
  }
40
43
 
41
- - (XCElementSnapshot *)fb_parentMatchingType:(XCUIElementType)type
44
+ - (id<FBXCElementSnapshot>)fb_parentMatchingType:(XCUIElementType)type
42
45
  {
43
46
  NSArray *acceptedParents = @[@(type)];
44
47
  return [self fb_parentMatchingOneOfTypes:acceptedParents];
45
48
  }
46
49
 
47
- - (XCElementSnapshot *)fb_parentMatchingOneOfTypes:(NSArray<NSNumber *> *)types
50
+ - (id<FBXCElementSnapshot>)fb_parentMatchingOneOfTypes:(NSArray<NSNumber *> *)types
48
51
  {
49
- return [self fb_parentMatchingOneOfTypes:types filter:^(XCElementSnapshot *snapshot) {
52
+ return [self fb_parentMatchingOneOfTypes:types filter:^(id<FBXCElementSnapshot> snapshot) {
50
53
  return YES;
51
54
  }];
52
55
  }
53
56
 
54
- - (XCElementSnapshot *)fb_parentMatchingOneOfTypes:(NSArray<NSNumber *> *)types filter:(BOOL(^)(XCElementSnapshot *snapshot))filter
57
+ - (id<FBXCElementSnapshot>)fb_parentMatchingOneOfTypes:(NSArray<NSNumber *> *)types
58
+ filter:(BOOL(^)(id<FBXCElementSnapshot> snapshot))filter
55
59
  {
56
- XCElementSnapshot *snapshot = self.parent;
60
+ id<FBXCElementSnapshot> snapshot = self.parent;
57
61
  while (snapshot && !(isSnapshotTypeAmongstGivenTypes(snapshot, types) && filter(snapshot))) {
58
62
  snapshot = snapshot.parent;
59
63
  }
@@ -73,12 +77,15 @@ inline static BOOL areValuesEqualOrBlank(id value1, id value2);
73
77
 
74
78
  inline static BOOL isNilOrEmpty(id value);
75
79
 
76
- - (BOOL)fb_framelessFuzzyMatchesElement:(XCElementSnapshot *)snapshot
80
+ - (BOOL)fb_framelessFuzzyMatchesElement:(id<FBXCElementSnapshot>)snapshot
77
81
  {
78
82
  // Pure payload-based comparison sometimes yield false negatives, therefore relying on it only if all of the identifying properties are blank
79
- if (isNilOrEmpty(self.identifier) && isNilOrEmpty(self.title) && isNilOrEmpty(self.label) &&
80
- isNilOrEmpty(self.value) && isNilOrEmpty(self.placeholderValue)) {
81
- return [self.wdUID isEqualToString:(snapshot.wdUID ?: @"")];
83
+ if (isNilOrEmpty(self.identifier)
84
+ && isNilOrEmpty(self.title)
85
+ && isNilOrEmpty(self.label)
86
+ && isNilOrEmpty(self.value)
87
+ && isNilOrEmpty(self.placeholderValue)) {
88
+ return [self.wdUID isEqualToString:([FBXCElementSnapshotWrapper ensureWrapped:snapshot].wdUID ?: @"")];
82
89
  }
83
90
 
84
91
  // Sometimes value and placeholderValue of a correct match from different snapshots are not the same (one is nil and one is a blank string)
@@ -91,27 +98,27 @@ inline static BOOL isNilOrEmpty(id value);
91
98
  areValuesEqualOrBlank(self.placeholderValue, snapshot.placeholderValue);
92
99
  }
93
100
 
94
- - (NSArray<XCElementSnapshot *> *)fb_descendantsCellSnapshots
101
+ - (NSArray<id<FBXCElementSnapshot>> *)fb_descendantsCellSnapshots
95
102
  {
96
- NSArray<XCElementSnapshot *> *cellSnapshots = [self fb_descendantsMatchingType:XCUIElementTypeCell];
97
-
103
+ NSArray<id<FBXCElementSnapshot>> *cellSnapshots = [self fb_descendantsMatchingType:XCUIElementTypeCell];
104
+
98
105
  if (cellSnapshots.count == 0) {
99
- // For the home screen, cells are actually of type XCUIElementTypeIcon
100
- cellSnapshots = [self fb_descendantsMatchingType:XCUIElementTypeIcon];
106
+ // For the home screen, cells are actually of type XCUIElementTypeIcon
107
+ cellSnapshots = [self fb_descendantsMatchingType:XCUIElementTypeIcon];
101
108
  }
102
-
109
+
103
110
  if (cellSnapshots.count == 0) {
104
- // In some cases XCTest will not report Cell Views. In that case grab all descendants and try to figure out scroll directon from them.
105
- cellSnapshots = self._allDescendants;
111
+ // In some cases XCTest will not report Cell Views. In that case grab all descendants and try to figure out scroll directon from them.
112
+ cellSnapshots = self._allDescendants;
106
113
  }
107
114
 
108
- return cellSnapshots;
115
+ return cellSnapshots;
109
116
  }
110
117
 
111
- - (NSArray<XCElementSnapshot *> *)fb_ancestors
118
+ - (NSArray<id<FBXCElementSnapshot>> *)fb_ancestors
112
119
  {
113
- NSMutableArray<XCElementSnapshot *> *ancestors = [NSMutableArray array];
114
- XCElementSnapshot *parent = self.parent;
120
+ NSMutableArray<id<FBXCElementSnapshot>> *ancestors = [NSMutableArray array];
121
+ id<FBXCElementSnapshot> parent = self.parent;
115
122
  while (parent) {
116
123
  [ancestors addObject:parent];
117
124
  parent = parent.parent;
@@ -119,18 +126,18 @@ inline static BOOL isNilOrEmpty(id value);
119
126
  return ancestors.copy;
120
127
  }
121
128
 
122
- - (XCElementSnapshot *)fb_parentCellSnapshot
129
+ - (id<FBXCElementSnapshot>)fb_parentCellSnapshot
123
130
  {
124
- XCElementSnapshot *targetCellSnapshot = self;
125
- // XCUIElementTypeIcon is the cell type for homescreen icons
126
- NSArray<NSNumber *> *acceptableElementTypes = @[
127
- @(XCUIElementTypeCell),
128
- @(XCUIElementTypeIcon),
129
- ];
130
- if (self.elementType != XCUIElementTypeCell && self.elementType != XCUIElementTypeIcon) {
131
- targetCellSnapshot = [self fb_parentMatchingOneOfTypes:acceptableElementTypes];
132
- }
133
- return targetCellSnapshot;
131
+ id<FBXCElementSnapshot> targetCellSnapshot = self.snapshot;
132
+ // XCUIElementTypeIcon is the cell type for homescreen icons
133
+ NSArray<NSNumber *> *acceptableElementTypes = @[
134
+ @(XCUIElementTypeCell),
135
+ @(XCUIElementTypeIcon),
136
+ ];
137
+ if (self.elementType != XCUIElementTypeCell && self.elementType != XCUIElementTypeIcon) {
138
+ targetCellSnapshot = [self fb_parentMatchingOneOfTypes:acceptableElementTypes];
139
+ }
140
+ return targetCellSnapshot;
134
141
  }
135
142
 
136
143
  - (CGRect)fb_visibleFrameWithFallback
@@ -156,9 +163,20 @@ inline static BOOL isNilOrEmpty(id value);
156
163
  return thisVisibleFrame;
157
164
  }
158
165
 
166
+ - (NSValue *)fb_hitPoint
167
+ {
168
+ NSError *error;
169
+ XCUIHitPointResult *result = [self hitPoint:&error];
170
+ if (nil != error) {
171
+ [FBLogger logFmt:@"Failed to fetch hit point for %@ - %@", self.fb_description, error.localizedDescription];
172
+ return nil;
173
+ }
174
+ return [NSValue valueWithCGPoint:result.hitPoint];
175
+ }
176
+
159
177
  @end
160
178
 
161
- inline static BOOL isSnapshotTypeAmongstGivenTypes(XCElementSnapshot* snapshot, NSArray<NSNumber *> *types)
179
+ inline static BOOL isSnapshotTypeAmongstGivenTypes(id<FBXCElementSnapshot> snapshot, NSArray<NSNumber *> *types)
162
180
  {
163
181
  for (NSUInteger i = 0; i < types.count; i++) {
164
182
  if([@(snapshot.elementType) isEqual: types[i]] || [types[i] isEqual: @(XCUIElementTypeAny)]){
@@ -8,6 +8,7 @@
8
8
  */
9
9
 
10
10
  #import "NSExpression+FBFormat.h"
11
+
11
12
  #import "FBElementUtils.h"
12
13
 
13
14
  @implementation NSExpression (FBFormat)
@@ -17,14 +18,18 @@
17
18
  if ([input expressionType] != NSKeyPathExpressionType) {
18
19
  return input;
19
20
  }
21
+
20
22
  NSString *propName = [input keyPath];
21
23
  NSUInteger dotPos = [propName rangeOfString:@"."].location;
22
- if (NSNotFound != dotPos) {
24
+ NSString *wdPropName;
25
+ if (NSNotFound == dotPos) {
26
+ wdPropName = [FBElementUtils wdAttributeNameForAttributeName:propName];
27
+ } else {
23
28
  NSString *actualPropName = [propName substringToIndex:dotPos];
24
29
  NSString *suffix = [propName substringFromIndex:(dotPos + 1)];
25
- return [NSExpression expressionForKeyPath:[NSString stringWithFormat:@"%@.%@", [FBElementUtils wdAttributeNameForAttributeName:actualPropName], suffix]];
30
+ wdPropName = [NSString stringWithFormat:@"%@.%@", [FBElementUtils wdAttributeNameForAttributeName:actualPropName], suffix];
26
31
  }
27
- return [NSExpression expressionForKeyPath:[FBElementUtils wdAttributeNameForAttributeName:propName]];
32
+ return [NSExpression expressionForKeyPath:wdPropName];
28
33
  }
29
34
 
30
35
  @end
@@ -10,6 +10,7 @@
10
10
  #import "XCUIApplication+FBAlert.h"
11
11
 
12
12
  #import "FBMacros.h"
13
+ #import "FBXCElementSnapshotWrapper+Helpers.h"
13
14
  #import "FBXCodeCompatibility.h"
14
15
  #import "XCUIElement+FBUtilities.h"
15
16
 
@@ -21,10 +22,10 @@ NSString *const FB_SAFARI_APP_NAME = @"Safari";
21
22
  @implementation XCUIApplication (FBAlert)
22
23
 
23
24
  - (nullable XCUIElement *)fb_alertElementFromSafariWithScrollView:(XCUIElement *)scrollView
24
- viewSnapshot:(XCElementSnapshot *)viewSnapshot
25
+ viewSnapshot:(id<FBXCElementSnapshot>)viewSnapshot
25
26
  {
26
27
  CGRect appFrame = viewSnapshot.frame;
27
- NSPredicate *dstViewMatchPredicate = [NSPredicate predicateWithBlock:^BOOL(XCElementSnapshot *snapshot, NSDictionary *bindings) {
28
+ NSPredicate *dstViewMatchPredicate = [NSPredicate predicateWithBlock:^BOOL(id<FBXCElementSnapshot> snapshot, NSDictionary *bindings) {
28
29
  CGRect curFrame = snapshot.frame;
29
30
  if (!CGRectEqualToRect(appFrame, curFrame)
30
31
  && curFrame.origin.x > 0 && curFrame.size.width < appFrame.size.width) {
@@ -62,8 +63,8 @@ NSString *const FB_SAFARI_APP_NAME = @"Safari";
62
63
  // and conatins at least one text view
63
64
  __block NSUInteger buttonsCount = 0;
64
65
  __block NSUInteger textViewsCount = 0;
65
- XCElementSnapshot *snapshot = candidate.fb_cachedSnapshot ?: candidate.fb_takeSnapshot;
66
- [snapshot enumerateDescendantsUsingBlock:^(XCElementSnapshot *descendant) {
66
+ id<FBXCElementSnapshot> snapshot = candidate.fb_cachedSnapshot ?: candidate.fb_takeSnapshot;
67
+ [snapshot enumerateDescendantsUsingBlock:^(id<FBXCElementSnapshot> descendant) {
67
68
  XCUIElementType curType = descendant.elementType;
68
69
  if (curType == XCUIElementTypeButton) {
69
70
  buttonsCount++;
@@ -83,7 +84,7 @@ NSString *const FB_SAFARI_APP_NAME = @"Safari";
83
84
  if (nil == alert) {
84
85
  return nil;
85
86
  }
86
- XCElementSnapshot *alertSnapshot = alert.fb_cachedSnapshot ?: alert.fb_takeSnapshot;
87
+ id<FBXCElementSnapshot> alertSnapshot = alert.fb_cachedSnapshot ?: alert.fb_takeSnapshot;
87
88
 
88
89
  if (alertSnapshot.elementType == XCUIElementTypeAlert) {
89
90
  return alert;
@@ -96,7 +97,7 @@ NSString *const FB_SAFARI_APP_NAME = @"Safari";
96
97
 
97
98
  // In case of iPad we want to check if sheet isn't contained by popover.
98
99
  // In that case we ignore it.
99
- XCElementSnapshot *ancestor = alertSnapshot.parent;
100
+ id<FBXCElementSnapshot> ancestor = alertSnapshot.parent;
100
101
  while (nil != ancestor) {
101
102
  if (nil != ancestor.identifier && [ancestor.identifier isEqualToString:@"PopoverDismissRegion"]) {
102
103
  return nil;
@@ -107,7 +108,7 @@ NSString *const FB_SAFARI_APP_NAME = @"Safari";
107
108
  }
108
109
 
109
110
  if (alertSnapshot.elementType == XCUIElementTypeScrollView) {
110
- XCElementSnapshot *app = [alertSnapshot fb_parentMatchingType:XCUIElementTypeApplication];
111
+ id<FBXCElementSnapshot> app = [[FBXCElementSnapshotWrapper ensureWrapped:alertSnapshot] fb_parentMatchingType:XCUIElementTypeApplication];
111
112
  if (nil != app && [app.label isEqualToString:FB_SAFARI_APP_NAME]) {
112
113
  // Check alert presence in Safari web view
113
114
  return [self fb_alertElementFromSafariWithScrollView:alert viewSnapshot:alertSnapshot];
@@ -10,7 +10,7 @@
10
10
  #import <XCTest/XCTest.h>
11
11
 
12
12
  @class XCElementSnapshot;
13
- @class XCAccessibilityElement;
13
+ @protocol FBXCAccessibilityElement;
14
14
  @class FBXMLGenerationOptions;
15
15
 
16
16
  NS_ASSUME_NONNULL_BEGIN
@@ -83,7 +83,7 @@ NS_ASSUME_NONNULL_BEGIN
83
83
  @param axElements the list of accessibility elements
84
84
  @returns The list of dictionaries. Each dictionary contains `bundleId` and `pid` items
85
85
  */
86
- + (NSArray<NSDictionary<NSString *, id> *> *)fb_appsInfoWithAxElements:(NSArray<XCAccessibilityElement *> *)axElements;
86
+ + (NSArray<NSDictionary<NSString *, id> *> *)fb_appsInfoWithAxElements:(NSArray<id<FBXCAccessibilityElement>> *)axElements;
87
87
 
88
88
  /**
89
89
  Retrieves the information about the currently active apps
@@ -9,7 +9,6 @@
9
9
 
10
10
  #import "XCUIApplication+FBHelpers.h"
11
11
 
12
- #import "XCElementSnapshot.h"
13
12
  #import "FBElementTypeTransformer.h"
14
13
  #import "FBKeyboard.h"
15
14
  #import "FBLogger.h"
@@ -18,11 +17,11 @@
18
17
  #import "FBActiveAppDetectionPoint.h"
19
18
  #import "FBXCodeCompatibility.h"
20
19
  #import "FBXPath.h"
20
+ #import "FBXCAccessibilityElement.h"
21
21
  #import "FBXCTestDaemonsProxy.h"
22
+ #import "FBXCElementSnapshotWrapper+Helpers.h"
22
23
  #import "FBXCAXClientProxy.h"
23
24
  #import "FBXMLGenerationOptions.h"
24
- #import "XCAccessibilityElement.h"
25
- #import "XCElementSnapshot+FBHelpers.h"
26
25
  #import "XCUIDevice+FBHelpers.h"
27
26
  #import "XCUIElement+FBCaching.h"
28
27
  #import "XCUIElement+FBIsVisible.h"
@@ -41,11 +40,11 @@ static NSString* const FBUnknownBundleId = @"unknown";
41
40
  - (BOOL)fb_waitForAppElement:(NSTimeInterval)timeout
42
41
  {
43
42
  __block BOOL canDetectAxElement = YES;
44
- int currentProcessIdentifier = self.accessibilityElement.processIdentifier;
43
+ int currentProcessIdentifier = [self.accessibilityElement processIdentifier];
45
44
  BOOL result = [[[FBRunLoopSpinner new]
46
45
  timeout:timeout]
47
46
  spinUntilTrue:^BOOL{
48
- XCAccessibilityElement *currentAppElement = FBActiveAppDetectionPoint.sharedInstance.axElement;
47
+ id<FBXCAccessibilityElement> currentAppElement = FBActiveAppDetectionPoint.sharedInstance.axElement;
49
48
  canDetectAxElement = nil != currentAppElement;
50
49
  if (!canDetectAxElement) {
51
50
  return YES;
@@ -57,11 +56,11 @@ static NSString* const FBUnknownBundleId = @"unknown";
57
56
  : [self waitForExistenceWithTimeout:timeout];
58
57
  }
59
58
 
60
- + (NSArray<NSDictionary<NSString *, id> *> *)fb_appsInfoWithAxElements:(NSArray<XCAccessibilityElement *> *)axElements
59
+ + (NSArray<NSDictionary<NSString *, id> *> *)fb_appsInfoWithAxElements:(NSArray<id<FBXCAccessibilityElement>> *)axElements
61
60
  {
62
61
  NSMutableArray<NSDictionary<NSString *, id> *> *result = [NSMutableArray array];
63
62
  id<XCTestManager_ManagerInterface> proxy = [FBXCTestDaemonsProxy testRunnerProxy];
64
- for (XCAccessibilityElement *axElement in axElements) {
63
+ for (id<FBXCAccessibilityElement> axElement in axElements) {
65
64
  NSMutableDictionary<NSString *, id> *appInfo = [NSMutableDictionary dictionary];
66
65
  pid_t pid = axElement.processIdentifier;
67
66
  appInfo[@"pid"] = @(pid);
@@ -100,7 +99,7 @@ static NSString* const FBUnknownBundleId = @"unknown";
100
99
 
101
100
  - (NSDictionary *)fb_tree
102
101
  {
103
- XCElementSnapshot *snapshot = self.fb_isResolvedFromCache.boolValue
102
+ id<FBXCElementSnapshot> snapshot = self.fb_isResolvedFromCache.boolValue
104
103
  ? self.lastSnapshot
105
104
  : [self fb_snapshotWithAllAttributesAndMaxDepth:nil];
106
105
  return [self.class dictionaryForElement:snapshot recursive:YES];
@@ -108,27 +107,28 @@ static NSString* const FBUnknownBundleId = @"unknown";
108
107
 
109
108
  - (NSDictionary *)fb_accessibilityTree
110
109
  {
111
- XCElementSnapshot *snapshot = self.fb_isResolvedFromCache.boolValue
110
+ id<FBXCElementSnapshot> snapshot = self.fb_isResolvedFromCache.boolValue
112
111
  ? self.lastSnapshot
113
112
  : [self fb_snapshotWithAllAttributesAndMaxDepth:nil];
114
113
  return [self.class accessibilityInfoForElement:snapshot];
115
114
  }
116
115
 
117
- + (NSDictionary *)dictionaryForElement:(XCElementSnapshot *)snapshot recursive:(BOOL)recursive
116
+ + (NSDictionary *)dictionaryForElement:(id<FBXCElementSnapshot>)snapshot recursive:(BOOL)recursive
118
117
  {
119
118
  NSMutableDictionary *info = [[NSMutableDictionary alloc] init];
120
119
  info[@"type"] = [FBElementTypeTransformer shortStringWithElementType:snapshot.elementType];
121
120
  info[@"rawIdentifier"] = FBValueOrNull([snapshot.identifier isEqual:@""] ? nil : snapshot.identifier);
122
- info[@"name"] = FBValueOrNull(snapshot.wdName);
123
- info[@"value"] = FBValueOrNull(snapshot.wdValue);
124
- info[@"label"] = FBValueOrNull(snapshot.wdLabel);
125
- info[@"rect"] = snapshot.wdRect;
126
- info[@"frame"] = NSStringFromCGRect(snapshot.wdFrame);
127
- info[@"isEnabled"] = [@([snapshot isWDEnabled]) stringValue];
128
- info[@"isVisible"] = [@([snapshot isWDVisible]) stringValue];
129
- info[@"isAccessible"] = [@([snapshot isWDAccessible]) stringValue];
121
+ FBXCElementSnapshotWrapper *wrappedSnapshot = [FBXCElementSnapshotWrapper ensureWrapped:snapshot];
122
+ info[@"name"] = FBValueOrNull(wrappedSnapshot.wdName);
123
+ info[@"value"] = FBValueOrNull(wrappedSnapshot.wdValue);
124
+ info[@"label"] = FBValueOrNull(wrappedSnapshot.wdLabel);
125
+ info[@"rect"] = wrappedSnapshot.wdRect;
126
+ info[@"frame"] = NSStringFromCGRect(wrappedSnapshot.wdFrame);
127
+ info[@"isEnabled"] = [@([wrappedSnapshot isWDEnabled]) stringValue];
128
+ info[@"isVisible"] = [@([wrappedSnapshot isWDVisible]) stringValue];
129
+ info[@"isAccessible"] = [@([wrappedSnapshot isWDAccessible]) stringValue];
130
130
  #if TARGET_OS_TV
131
- info[@"isFocused"] = [@([snapshot isWDFocused]) stringValue];
131
+ info[@"isFocused"] = [@([wrappedSnapshot isWDFocused]) stringValue];
132
132
  #endif
133
133
 
134
134
  if (!recursive) {
@@ -138,28 +138,29 @@ static NSString* const FBUnknownBundleId = @"unknown";
138
138
  NSArray *childElements = snapshot.children;
139
139
  if ([childElements count]) {
140
140
  info[@"children"] = [[NSMutableArray alloc] init];
141
- for (XCElementSnapshot *childSnapshot in childElements) {
141
+ for (id<FBXCElementSnapshot> childSnapshot in childElements) {
142
142
  [info[@"children"] addObject:[self dictionaryForElement:childSnapshot recursive:YES]];
143
143
  }
144
144
  }
145
145
  return info;
146
146
  }
147
147
 
148
- + (NSDictionary *)accessibilityInfoForElement:(XCElementSnapshot *)snapshot
148
+ + (NSDictionary *)accessibilityInfoForElement:(id<FBXCElementSnapshot>)snapshot
149
149
  {
150
- BOOL isAccessible = [snapshot isWDAccessible];
151
- BOOL isVisible = [snapshot isWDVisible];
150
+ FBXCElementSnapshotWrapper *wrappedSnapshot = [FBXCElementSnapshotWrapper ensureWrapped:snapshot];
151
+ BOOL isAccessible = [wrappedSnapshot isWDAccessible];
152
+ BOOL isVisible = [wrappedSnapshot isWDVisible];
152
153
 
153
154
  NSMutableDictionary *info = [[NSMutableDictionary alloc] init];
154
155
 
155
156
  if (isAccessible) {
156
157
  if (isVisible) {
157
- info[@"value"] = FBValueOrNull(snapshot.wdValue);
158
- info[@"label"] = FBValueOrNull(snapshot.wdLabel);
158
+ info[@"value"] = FBValueOrNull(wrappedSnapshot.wdValue);
159
+ info[@"label"] = FBValueOrNull(wrappedSnapshot.wdLabel);
159
160
  }
160
161
  } else {
161
162
  NSMutableArray *children = [[NSMutableArray alloc] init];
162
- for (XCElementSnapshot *childSnapshot in snapshot.children) {
163
+ for (id<FBXCElementSnapshot> childSnapshot in snapshot.children) {
163
164
  NSDictionary *childInfo = [self accessibilityInfoForElement:childSnapshot];
164
165
  if ([childInfo count]) {
165
166
  [children addObject: childInfo];
@@ -172,7 +173,7 @@ static NSString* const FBUnknownBundleId = @"unknown";
172
173
  if ([info count]) {
173
174
  info[@"type"] = [FBElementTypeTransformer shortStringWithElementType:snapshot.elementType];
174
175
  info[@"rawIdentifier"] = FBValueOrNull([snapshot.identifier isEqual:@""] ? nil : snapshot.identifier);
175
- info[@"name"] = FBValueOrNull(snapshot.wdName);
176
+ info[@"name"] = FBValueOrNull(wrappedSnapshot.wdName);
176
177
  } else {
177
178
  return nil;
178
179
  }
@@ -243,7 +244,7 @@ static NSString* const FBUnknownBundleId = @"unknown";
243
244
  };
244
245
 
245
246
  if (nil != keyNames && keyNames.count > 0) {
246
- NSPredicate *searchPredicate = [NSPredicate predicateWithBlock:^BOOL(XCElementSnapshot *snapshot, NSDictionary *bindings) {
247
+ NSPredicate *searchPredicate = [NSPredicate predicateWithBlock:^BOOL(id<FBXCElementSnapshot> snapshot, NSDictionary *bindings) {
247
248
  if (snapshot.elementType != XCUIElementTypeKey && snapshot.elementType != XCUIElementTypeButton) {
248
249
  return NO;
249
250
  }
@@ -40,6 +40,9 @@ static void swizzledWaitForQuiescenceIncludingAnimationsIdle(id self, SEL _cmd,
40
40
 
41
41
  @implementation XCUIApplicationProcess (FBQuiescence)
42
42
 
43
+ #pragma clang diagnostic push
44
+ #pragma clang diagnostic ignored "-Wobjc-load-method"
45
+
43
46
  + (void)load
44
47
  {
45
48
  Method waitForQuiescenceIncludingAnimationsIdleMethod = class_getInstanceMethod(self.class, @selector(waitForQuiescenceIncludingAnimationsIdle:));
@@ -51,6 +54,8 @@ static void swizzledWaitForQuiescenceIncludingAnimationsIdle(id self, SEL _cmd,
51
54
  }
52
55
  }
53
56
 
57
+ #pragma clang diagnostic pop
58
+
54
59
  static char XCUIAPPLICATIONPROCESS_SHOULD_WAIT_FOR_QUIESCENCE;
55
60
 
56
61
  @dynamic fb_shouldWaitForQuiescence;
@@ -11,7 +11,6 @@
11
11
 
12
12
  #import "XCUICoordinate.h"
13
13
  #import "XCUIElement+FBUtilities.h"
14
- #import "XCElementSnapshot+FBHitPoint.h"
15
14
 
16
15
  # if !TARGET_OS_TV
17
16
  @implementation XCUICoordinate (FBFix)
@@ -19,9 +19,9 @@
19
19
  #import "FBMacros.h"
20
20
  #import "FBMathUtils.h"
21
21
  #import "FBScreenshot.h"
22
+ #import "FBXCDeviceEvent.h"
22
23
  #import "FBXCodeCompatibility.h"
23
24
  #import "XCUIDevice.h"
24
- #import "XCDeviceEvent.h"
25
25
 
26
26
  static const NSTimeInterval FBHomeButtonCoolOffTime = 1.;
27
27
  static const NSTimeInterval FBScreenLockTimeout = 5.;
@@ -30,11 +30,16 @@ static const NSTimeInterval FBScreenLockTimeout = 5.;
30
30
 
31
31
  static bool fb_isLocked;
32
32
 
33
+ #pragma clang diagnostic push
34
+ #pragma clang diagnostic ignored "-Wobjc-load-method"
35
+
33
36
  + (void)load
34
37
  {
35
38
  [self fb_registerAppforDetectLockState];
36
39
  }
37
40
 
41
+ #pragma clang diagnostic pop
42
+
38
43
  + (void)fb_registerAppforDetectLockState
39
44
  {
40
45
  int notify_token;
@@ -303,10 +308,8 @@ static bool fb_isLocked;
303
308
  duration:(NSTimeInterval)duration
304
309
  error:(NSError **)error
305
310
  {
306
- XCDeviceEvent *event = [XCDeviceEvent deviceEventWithPage:page
307
- usage:usage
308
- duration:duration];
309
- return [self performDeviceEvent:event error:error];
311
+ id<FBXCDeviceEvent> event = FBCreateXCDeviceEvent(page, usage, duration, error);
312
+ return nil == event ? NO : [self performDeviceEvent:event error:error];
310
313
  }
311
314
 
312
315
  - (BOOL)fb_setAppearance:(FBUIInterfaceAppearance)appearance error:(NSError **)error
@@ -7,8 +7,8 @@
7
7
  * of patent rights can be found in the PATENTS file in the same directory.
8
8
  */
9
9
 
10
- #import <WebDriverAgentLib/XCElementSnapshot.h>
11
10
  #import <WebDriverAgentLib/XCUIElement.h>
11
+ #import "FBXCElementSnapshotWrapper.h"
12
12
 
13
13
  NS_ASSUME_NONNULL_BEGIN
14
14
 
@@ -20,7 +20,7 @@ NS_ASSUME_NONNULL_BEGIN
20
20
  @end
21
21
 
22
22
 
23
- @interface XCElementSnapshot (FBAccessibility)
23
+ @interface FBXCElementSnapshotWrapper (FBAccessibility)
24
24
 
25
25
  /*! Whether or not the element in snapshot is accessible */
26
26
  @property (atomic, readonly) BOOL fb_isAccessibilityElement;
@@ -10,21 +10,22 @@
10
10
  #import "XCUIElement+FBAccessibility.h"
11
11
 
12
12
  #import "FBConfiguration.h"
13
- #import "XCElementSnapshot+FBHelpers.h"
14
13
  #import "XCTestPrivateSymbols.h"
15
14
  #import "XCUIElement+FBUtilities.h"
15
+ #import "FBXCElementSnapshotWrapper+Helpers.h"
16
16
 
17
17
  @implementation XCUIElement (FBAccessibility)
18
18
 
19
19
  - (BOOL)fb_isAccessibilityElement
20
20
  {
21
- return [self fb_snapshotWithAttributes:@[FB_XCAXAIsElementAttributeName]
22
- maxDepth:@1].fb_isAccessibilityElement;
21
+ id<FBXCElementSnapshot> snapshot = [self fb_snapshotWithAttributes:@[FB_XCAXAIsElementAttributeName]
22
+ maxDepth:@1];
23
+ return [FBXCElementSnapshotWrapper ensureWrapped:snapshot].fb_isAccessibilityElement;
23
24
  }
24
25
 
25
26
  @end
26
27
 
27
- @implementation XCElementSnapshot (FBAccessibility)
28
+ @implementation FBXCElementSnapshotWrapper (FBAccessibility)
28
29
 
29
30
  - (BOOL)fb_isAccessibilityElement
30
31
  {