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