appium-webdriveragent 3.11.1 → 3.12.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.
@@ -466,6 +466,10 @@
466
466
  71D04DC925356C43008A052C /* XCUIElement+FBCaching.h in Headers */ = {isa = PBXBuildFile; fileRef = 71D04DC625356C43008A052C /* XCUIElement+FBCaching.h */; settings = {ATTRIBUTES = (Public, ); }; };
467
467
  71D04DCA25356C43008A052C /* XCUIElement+FBCaching.m in Sources */ = {isa = PBXBuildFile; fileRef = 71D04DC725356C43008A052C /* XCUIElement+FBCaching.m */; };
468
468
  71D04DCB25356C43008A052C /* XCUIElement+FBCaching.m in Sources */ = {isa = PBXBuildFile; fileRef = 71D04DC725356C43008A052C /* XCUIElement+FBCaching.m */; };
469
+ 71D3B3D5267FC7260076473D /* XCUIElement+FBResolve.h in Headers */ = {isa = PBXBuildFile; fileRef = 71D3B3D3267FC7260076473D /* XCUIElement+FBResolve.h */; };
470
+ 71D3B3D6267FC7260076473D /* XCUIElement+FBResolve.h in Headers */ = {isa = PBXBuildFile; fileRef = 71D3B3D3267FC7260076473D /* XCUIElement+FBResolve.h */; };
471
+ 71D3B3D7267FC7260076473D /* XCUIElement+FBResolve.m in Sources */ = {isa = PBXBuildFile; fileRef = 71D3B3D4267FC7260076473D /* XCUIElement+FBResolve.m */; };
472
+ 71D3B3D8267FC7260076473D /* XCUIElement+FBResolve.m in Sources */ = {isa = PBXBuildFile; fileRef = 71D3B3D4267FC7260076473D /* XCUIElement+FBResolve.m */; };
469
473
  71D475C22538F5A8008D9401 /* XCUIApplicationProcess+FBQuiescence.h in Headers */ = {isa = PBXBuildFile; fileRef = 71D475C02538F5A8008D9401 /* XCUIApplicationProcess+FBQuiescence.h */; };
470
474
  71D475C32538F5A8008D9401 /* XCUIApplicationProcess+FBQuiescence.h in Headers */ = {isa = PBXBuildFile; fileRef = 71D475C02538F5A8008D9401 /* XCUIApplicationProcess+FBQuiescence.h */; };
471
475
  71D475C42538F5A8008D9401 /* XCUIApplicationProcess+FBQuiescence.m in Sources */ = {isa = PBXBuildFile; fileRef = 71D475C12538F5A8008D9401 /* XCUIApplicationProcess+FBQuiescence.m */; };
@@ -1033,6 +1037,8 @@
1033
1037
  71C9EAAB25E8415A00470CD8 /* FBScreenshot.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBScreenshot.m; sourceTree = "<group>"; };
1034
1038
  71D04DC625356C43008A052C /* XCUIElement+FBCaching.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XCUIElement+FBCaching.h"; sourceTree = "<group>"; };
1035
1039
  71D04DC725356C43008A052C /* XCUIElement+FBCaching.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "XCUIElement+FBCaching.m"; sourceTree = "<group>"; };
1040
+ 71D3B3D3267FC7260076473D /* XCUIElement+FBResolve.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XCUIElement+FBResolve.h"; sourceTree = "<group>"; };
1041
+ 71D3B3D4267FC7260076473D /* XCUIElement+FBResolve.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "XCUIElement+FBResolve.m"; sourceTree = "<group>"; };
1036
1042
  71D475C02538F5A8008D9401 /* XCUIApplicationProcess+FBQuiescence.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XCUIApplicationProcess+FBQuiescence.h"; sourceTree = "<group>"; };
1037
1043
  71D475C12538F5A8008D9401 /* XCUIApplicationProcess+FBQuiescence.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "XCUIApplicationProcess+FBQuiescence.m"; sourceTree = "<group>"; };
1038
1044
  71E504941DF59BAD0020C32A /* XCUIElementAttributesTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XCUIElementAttributesTests.m; sourceTree = "<group>"; };
@@ -1745,6 +1751,8 @@
1745
1751
  EE9AB7481CAEDF0C008C271F /* XCUIElement+FBIsVisible.m */,
1746
1752
  7136A4771E8918E60024FC3D /* XCUIElement+FBPickerWheel.h */,
1747
1753
  7136A4781E8918E60024FC3D /* XCUIElement+FBPickerWheel.m */,
1754
+ 71D3B3D3267FC7260076473D /* XCUIElement+FBResolve.h */,
1755
+ 71D3B3D4267FC7260076473D /* XCUIElement+FBResolve.m */,
1748
1756
  EE9AB7491CAEDF0C008C271F /* XCUIElement+FBScrolling.h */,
1749
1757
  EE9AB74A1CAEDF0C008C271F /* XCUIElement+FBScrolling.m */,
1750
1758
  71F5BE21252E576C00EE9EBA /* XCUIElement+FBSwiping.h */,
@@ -2399,6 +2407,7 @@
2399
2407
  641EE6C12240C5CA00173FCB /* _XCTestObservationCenterImplementation.h in Headers */,
2400
2408
  714EAA0E2673FDFE005C5B47 /* FBCapabilities.h in Headers */,
2401
2409
  641EE6C22240C5CA00173FCB /* XCUIDevice+FBHelpers.h in Headers */,
2410
+ 71D3B3D6267FC7260076473D /* XCUIElement+FBResolve.h in Headers */,
2402
2411
  641EE6C32240C5CA00173FCB /* FBClassChainQueryParser.h in Headers */,
2403
2412
  641EE6C42240C5CA00173FCB /* FBMacros.h in Headers */,
2404
2413
  641EE6C52240C5CA00173FCB /* XCTestExpectationDelegate-Protocol.h in Headers */,
@@ -2531,6 +2540,7 @@
2531
2540
  EE35AD6B1E3B77D600A02D78 /* XCUIApplicationImpl.h in Headers */,
2532
2541
  EE35AD201E3B77D600A02D78 /* UIPanGestureRecognizer-RecordingAdditions.h in Headers */,
2533
2542
  71555A3D1DEC460A007D4A8B /* NSExpression+FBFormat.h in Headers */,
2543
+ 71D3B3D5267FC7260076473D /* XCUIElement+FBResolve.h in Headers */,
2534
2544
  EE35AD0C1E3B77D600A02D78 /* _XCTestCaseImplementation.h in Headers */,
2535
2545
  EE35AD211E3B77D600A02D78 /* UIPinchGestureRecognizer-RecordingAdditions.h in Headers */,
2536
2546
  EE35AD4F1E3B77D600A02D78 /* XCTestManager_TestsInterface-Protocol.h in Headers */,
@@ -3045,6 +3055,7 @@
3045
3055
  files = (
3046
3056
  718226CF2587443700661B83 /* GCDAsyncSocket.m in Sources */,
3047
3057
  E444DCBC24917A5E0060D7EB /* HTTPResponseProxy.m in Sources */,
3058
+ 71D3B3D8267FC7260076473D /* XCUIElement+FBResolve.m in Sources */,
3048
3059
  E444DCBE24917A5E0060D7EB /* Route.m in Sources */,
3049
3060
  E444DCC024917A5E0060D7EB /* RouteRequest.m in Sources */,
3050
3061
  E444DCC224917A5E0060D7EB /* RouteResponse.m in Sources */,
@@ -3273,6 +3284,7 @@
3273
3284
  EE158AE91CBD456F00A3E3F0 /* FBElementTypeTransformer.m in Sources */,
3274
3285
  E444DC9D249131D40060D7EB /* HTTPMessage.m in Sources */,
3275
3286
  E444DCB024913C220060D7EB /* RouteResponse.m in Sources */,
3287
+ 71D3B3D7267FC7260076473D /* XCUIElement+FBResolve.m in Sources */,
3276
3288
  EE158AF61CBD456F00A3E3F0 /* FBApplication.m in Sources */,
3277
3289
  715AFAC21FFA29180053896D /* FBScreen.m in Sources */,
3278
3290
  71B155DC230711E900646AFB /* FBCommandStatus.m in Sources */,
@@ -31,5 +31,21 @@
31
31
  endingLineNumber = "264">
32
32
  </BreakpointContent>
33
33
  </BreakpointProxy>
34
+ <BreakpointProxy
35
+ BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
36
+ <BreakpointContent
37
+ uuid = "54216FE6-E240-47F1-88D3-D450CF0AF44E"
38
+ shouldBeEnabled = "Yes"
39
+ ignoreCount = "0"
40
+ continueAfterRunningActions = "No"
41
+ filePath = "WebDriverAgentLib/Categories/XCUIElement+FBResolve.m"
42
+ startingColumnNumber = "9223372036854775807"
43
+ endingColumnNumber = "9223372036854775807"
44
+ startingLineNumber = "37"
45
+ endingLineNumber = "37"
46
+ landmarkName = "-fb_stableInstance"
47
+ landmarkType = "7">
48
+ </BreakpointContent>
49
+ </BreakpointProxy>
34
50
  </Breakpoints>
35
51
  </Bucket>
@@ -0,0 +1,37 @@
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
+ @interface XCUIElement (FBResolve)
15
+
16
+ /*! This property is always true unless the element gets resolved by its internal UUID (e.g. results of an xpath query) */
17
+ @property (nullable, nonatomic) NSNumber *fb_isResolvedNatively;
18
+
19
+ /**
20
+ Returns element instance based on query by element's UUID rather than any other attributes, which
21
+ might be a subject of change during the application life cycle. The UUID is calculated based on the PID
22
+ of the application to which this particular element belongs and the identifier of the underlying AXElement
23
+ instance. That usually guarantees the same element is always going to be matched in scope of the parent
24
+ application independently of its current attribute values.
25
+ Example: We have an element X with value Y. Our locator looks like 'value == Y'. Normally, if the element's
26
+ value is changed to Z and we try to reuse this cached instance of it then a StaleElement error is thrown.
27
+ Although, if the cached element instance is the one returned by this API call then the same element
28
+ is going to be matched and no staleness exception will be thrown.
29
+
30
+ @return Either the same element instance if `fb_isResolvedNatively` was set to NO (usually the cache for elements
31
+ matched by xpath locators) or the stable instance of the self element based on the query by element's UUID.
32
+ */
33
+ - (XCUIElement *)fb_stableInstance;
34
+
35
+ @end
36
+
37
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,51 @@
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 "XCUIElement+FBResolve.h"
11
+
12
+ #import <objc/runtime.h>
13
+
14
+ #import "XCUIElement.h"
15
+ #import "FBXCodeCompatibility.h"
16
+ #import "XCUIElement+FBUID.h"
17
+
18
+ @implementation XCUIElement (FBResolve)
19
+
20
+ static char XCUIELEMENT_IS_RESOLVED_NATIVELY_KEY;
21
+
22
+ @dynamic fb_isResolvedNatively;
23
+
24
+ - (void)setFb_isResolvedNatively:(NSNumber *)isResolvedNatively
25
+ {
26
+ objc_setAssociatedObject(self, &XCUIELEMENT_IS_RESOLVED_NATIVELY_KEY, isResolvedNatively, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
27
+ }
28
+
29
+ - (NSNumber *)fb_isResolvedNatively
30
+ {
31
+ NSNumber *result = objc_getAssociatedObject(self, &XCUIELEMENT_IS_RESOLVED_NATIVELY_KEY);
32
+ return nil == result ? @YES : result;
33
+ }
34
+
35
+ - (XCUIElement *)fb_stableInstance
36
+ {
37
+ if (![self.fb_isResolvedNatively boolValue]) {
38
+ return self;
39
+ }
40
+
41
+ XCUIElementQuery *query = [self isKindOfClass:XCUIApplication.class]
42
+ ? self.application.fb_query
43
+ : [self.application.fb_query descendantsMatchingType:XCUIElementTypeAny];
44
+ XCElementSnapshot *cachedSnapshot = self.fb_cachedSnapshot;
45
+ NSString *uid = nil == cachedSnapshot ? self.fb_uid : cachedSnapshot.fb_uid;
46
+ return nil == uid
47
+ ? self
48
+ : [query matchingPredicate:[NSPredicate predicateWithFormat:@"%K = %@", FBStringify(XCUIElement, wdUID), uid]].fb_firstMatch;
49
+ }
50
+
51
+ @end
@@ -35,6 +35,7 @@
35
35
  #import "XCUIElementQuery+FBHelpers.h"
36
36
  #import "XCUIElement+FBUID.h"
37
37
  #import "XCUIScreen.h"
38
+ #import "XCUIElement+FBResolve.h"
38
39
 
39
40
  #define DEFAULT_AX_TIMEOUT 60.
40
41
 
@@ -113,7 +114,7 @@
113
114
  if (nil == snapshotWithAttributes) {
114
115
  [FBLogger logFmt:@"Cannot take a snapshot with attribute(s) %@ of '%@' after %.2f seconds",
115
116
  attributeNames, snapshot.fb_description, axTimeout];
116
- [FBLogger logFmt:@"This timeout could be customized via '%@' setting", CUSTOM_SNAPSHOT_TIMEOUT];
117
+ [FBLogger logFmt:@"This timeout could be customized via '%@' setting", FB_SETTING_CUSTOM_SNAPSHOT_TIMEOUT];
117
118
  [FBLogger logFmt:@"Internal error: %@", error.localizedDescription];
118
119
  [FBLogger logFmt:@"Falling back to the default snapshotting mechanism for the element '%@' (some attribute values, like visibility or accessibility might not be precise though)", snapshot.fb_description];
119
120
  snapshotWithAttributes = self.lastSnapshot;
@@ -159,6 +160,7 @@
159
160
  query = [query matchingPredicate:[NSPredicate predicateWithFormat:@"%K IN %@", FBStringify(XCUIElement, wdUID), sortedIds]];
160
161
  if (1 == snapshots.count) {
161
162
  XCUIElement *result = query.fb_firstMatch;
163
+ result.fb_isResolvedNatively = @NO;
162
164
  return result ? @[result] : @[];
163
165
  }
164
166
  // Rely here on the fact, that XPath always returns query results in the same
@@ -176,7 +178,11 @@
176
178
  // }
177
179
  // return NSOrderedSame;
178
180
  // }];
179
- return query.fb_allMatches;
181
+ NSArray<XCUIElement *> *result = query.fb_allMatches;
182
+ for (XCUIElement *el in result) {
183
+ el.fb_isResolvedNatively = @NO;
184
+ }
185
+ return result;
180
186
  }
181
187
 
182
188
  - (void)fb_waitUntilStable
@@ -38,6 +38,7 @@
38
38
  #import "XCUIElement+FBUtilities.h"
39
39
  #import "XCUIElement+FBWebDriverAttributes.h"
40
40
  #import "XCUIElement+FBTVFocuse.h"
41
+ #import "XCUIElement+FBResolve.h"
41
42
  #import "FBElementTypeTransformer.h"
42
43
  #import "XCUIElement.h"
43
44
  #import "XCUIElementQuery.h"
@@ -258,7 +259,8 @@
258
259
  XCUIElement *focusedElement = request.session.activeApplication.fb_focusedElement;
259
260
  if (focusedElement != nil) {
260
261
  FBElementCache *elementCache = request.session.elementCache;
261
- NSString *focusedUUID = [elementCache storeElement:focusedElement];
262
+ BOOL useNativeCachingStrategy = request.session.useNativeCachingStrategy;
263
+ NSString *focusedUUID = [elementCache storeElement:(useNativeCachingStrategy ? focusedElement : focusedElement.fb_stableInstance)];
262
264
  if (focusedUUID && [focusedUUID isEqualToString:(id)request.parameters[@"uuid"]]) {
263
265
  isFocused = YES;
264
266
  }
@@ -40,9 +40,13 @@ const struct FBWDOrientationValues FBWDOrientationValues = {
40
40
  return
41
41
  @[
42
42
  [[FBRoute GET:@"/orientation"] respondWithTarget:self action:@selector(handleGetOrientation:)],
43
+ [[FBRoute GET:@"/orientation"].withoutSession respondWithTarget:self action:@selector(handleGetOrientation:)],
43
44
  [[FBRoute POST:@"/orientation"] respondWithTarget:self action:@selector(handleSetOrientation:)],
45
+ [[FBRoute POST:@"/orientation"].withoutSession respondWithTarget:self action:@selector(handleSetOrientation:)],
44
46
  [[FBRoute GET:@"/rotation"] respondWithTarget:self action:@selector(handleGetRotation:)],
47
+ [[FBRoute GET:@"/rotation"].withoutSession respondWithTarget:self action:@selector(handleGetRotation:)],
45
48
  [[FBRoute POST:@"/rotation"] respondWithTarget:self action:@selector(handleSetRotation:)],
49
+ [[FBRoute POST:@"/rotation"].withoutSession respondWithTarget:self action:@selector(handleSetRotation:)],
46
50
  ];
47
51
  }
48
52
 
@@ -51,15 +55,15 @@ const struct FBWDOrientationValues FBWDOrientationValues = {
51
55
 
52
56
  + (id<FBResponsePayload>)handleGetOrientation:(FBRouteRequest *)request
53
57
  {
54
- FBSession *session = request.session;
55
- NSString *orientation = [self.class interfaceOrientationForApplication:session.activeApplication];
58
+ FBApplication *application = request.session.activeApplication ?: FBApplication.fb_activeApplication;
59
+ NSString *orientation = [self.class interfaceOrientationForApplication:application];
56
60
  return FBResponseWithObject([[self _wdOrientationsMapping] objectForKey:orientation]);
57
61
  }
58
62
 
59
63
  + (id<FBResponsePayload>)handleSetOrientation:(FBRouteRequest *)request
60
64
  {
61
- FBSession *session = request.session;
62
- if ([self.class setDeviceOrientation:request.arguments[@"orientation"] forApplication:session.activeApplication]) {
65
+ FBApplication *application = request.session.activeApplication ?: FBApplication.fb_activeApplication;
66
+ if ([self.class setDeviceOrientation:request.arguments[@"orientation"] forApplication:application]) {
63
67
  return FBResponseWithOK();
64
68
  }
65
69
 
@@ -69,7 +73,8 @@ const struct FBWDOrientationValues FBWDOrientationValues = {
69
73
  + (id<FBResponsePayload>)handleGetRotation:(FBRouteRequest *)request
70
74
  {
71
75
  XCUIDevice *device = [XCUIDevice sharedDevice];
72
- UIInterfaceOrientation orientation = request.session.activeApplication.interfaceOrientation;
76
+ FBApplication *application = request.session.activeApplication ?: FBApplication.fb_activeApplication;
77
+ UIInterfaceOrientation orientation = application.interfaceOrientation;
73
78
  return FBResponseWithObject(device.fb_rotationMapping[@(orientation)]);
74
79
  }
75
80
 
@@ -88,14 +93,20 @@ const struct FBWDOrientationValues FBWDOrientationValues = {
88
93
  };
89
94
  NSArray<NSDictionary *> *supportedRotations = XCUIDevice.sharedDevice.fb_rotationMapping.allValues;
90
95
  if (![supportedRotations containsObject:rotation]) {
91
- NSString *errMessage = [NSString stringWithFormat:@"%@ rotation is not supported. Only the following values are supported: %@", rotation, supportedRotations];
96
+ NSString *errMessage = [
97
+ NSString stringWithFormat:@"%@ rotation is not supported. Only the following values are supported: %@",
98
+ rotation, supportedRotations
99
+ ];
92
100
  return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:errMessage
93
101
  traceback:nil]);
94
102
  }
95
103
 
96
- FBApplication *app = request.session.activeApplication;
97
- if (![self.class setDeviceRotation:request.arguments forApplication:app]) {
98
- NSString *errMessage = [NSString stringWithFormat:@"The current rotation cannot be set to %@. Make sure the %@ application supports it", rotation, app.bundleID];
104
+ FBApplication *application = request.session.activeApplication ?: FBApplication.fb_activeApplication;
105
+ if (![self.class setDeviceRotation:request.arguments forApplication:application]) {
106
+ NSString *errMessage = [
107
+ NSString stringWithFormat:@"The current rotation cannot be set to %@. Make sure the %@ application supports it",
108
+ rotation, application.bundleID
109
+ ];
99
110
  return FBResponseWithStatus([FBCommandStatus invalidElementStateErrorWithMessage:errMessage
100
111
  traceback:nil]);
101
112
  }
@@ -89,10 +89,10 @@
89
89
  return FBResponseWithStatus([FBCommandStatus sessionNotCreatedError:error.description traceback:nil]);
90
90
  }
91
91
  [FBConfiguration setShouldUseTestManagerForVisibilityDetection:[capabilities[FB_CAP_USE_TEST_MANAGER_FOR_VISIBLITY_DETECTION] boolValue]];
92
- if (capabilities[USE_COMPACT_RESPONSES]) {
93
- [FBConfiguration setShouldUseCompactResponses:[capabilities[USE_COMPACT_RESPONSES] boolValue]];
92
+ if (capabilities[FB_SETTING_USE_COMPACT_RESPONSES]) {
93
+ [FBConfiguration setShouldUseCompactResponses:[capabilities[FB_SETTING_USE_COMPACT_RESPONSES] boolValue]];
94
94
  }
95
- NSString *elementResponseAttributes = capabilities[ELEMENT_RESPONSE_ATTRIBUTES];
95
+ NSString *elementResponseAttributes = capabilities[FB_SETTING_ELEMENT_RESPONSE_ATTRIBUTES];
96
96
  if (elementResponseAttributes) {
97
97
  [FBConfiguration setElementResponseAttributes:elementResponseAttributes];
98
98
  }
@@ -119,8 +119,8 @@
119
119
  [XCUIApplicationProcessDelay disableEventLoopDelay];
120
120
  }
121
121
 
122
- if (nil != capabilities[WAIT_FOR_IDLE_TIMEOUT]) {
123
- FBConfiguration.waitForIdleTimeout = [capabilities[WAIT_FOR_IDLE_TIMEOUT] doubleValue];
122
+ if (nil != capabilities[FB_SETTING_WAIT_FOR_IDLE_TIMEOUT]) {
123
+ FBConfiguration.waitForIdleTimeout = [capabilities[FB_SETTING_WAIT_FOR_IDLE_TIMEOUT] doubleValue];
124
124
  }
125
125
 
126
126
  NSString *bundleID = capabilities[FB_CAP_BUNDLE_ID];
@@ -149,13 +149,17 @@
149
149
  }
150
150
  }
151
151
 
152
- if (capabilities[DEFAULT_ALERT_ACTION]) {
152
+ if (capabilities[FB_SETTING_DEFAULT_ALERT_ACTION]) {
153
153
  [FBSession initWithApplication:app
154
- defaultAlertAction:(id)capabilities[DEFAULT_ALERT_ACTION]];
154
+ defaultAlertAction:(id)capabilities[FB_SETTING_DEFAULT_ALERT_ACTION]];
155
155
  } else {
156
156
  [FBSession initWithApplication:app];
157
157
  }
158
158
 
159
+ if (nil != capabilities[FB_CAP_USE_NATIVE_CACHING_STRATEGY]) {
160
+ FBSession.activeSession.useNativeCachingStrategy = [capabilities[FB_CAP_USE_NATIVE_CACHING_STRATEGY] boolValue];
161
+ }
162
+
159
163
  return FBResponseWithObject(FBSessionCommands.sessionInformation);
160
164
  }
161
165
 
@@ -256,29 +260,29 @@
256
260
  {
257
261
  return FBResponseWithObject(
258
262
  @{
259
- USE_COMPACT_RESPONSES: @([FBConfiguration shouldUseCompactResponses]),
260
- ELEMENT_RESPONSE_ATTRIBUTES: [FBConfiguration elementResponseAttributes],
261
- MJPEG_SERVER_SCREENSHOT_QUALITY: @([FBConfiguration mjpegServerScreenshotQuality]),
262
- MJPEG_SERVER_FRAMERATE: @([FBConfiguration mjpegServerFramerate]),
263
- MJPEG_SCALING_FACTOR: @([FBConfiguration mjpegScalingFactor]),
264
- SCREENSHOT_QUALITY: @([FBConfiguration screenshotQuality]),
265
- KEYBOARD_AUTOCORRECTION: @([FBConfiguration keyboardAutocorrection]),
266
- KEYBOARD_PREDICTION: @([FBConfiguration keyboardPrediction]),
267
- CUSTOM_SNAPSHOT_TIMEOUT: @([FBConfiguration customSnapshotTimeout]),
268
- SNAPSHOT_MAX_DEPTH: @([FBConfiguration snapshotMaxDepth]),
269
- USE_FIRST_MATCH: @([FBConfiguration useFirstMatch]),
270
- WAIT_FOR_IDLE_TIMEOUT: @([FBConfiguration waitForIdleTimeout]),
271
- ANIMATION_COOL_OFF_TIMEOUT: @([FBConfiguration animationCoolOffTimeout]),
272
- BOUND_ELEMENTS_BY_INDEX: @([FBConfiguration boundElementsByIndex]),
273
- REDUCE_MOTION: @([FBConfiguration reduceMotionEnabled]),
274
- DEFAULT_ACTIVE_APPLICATION: request.session.defaultActiveApplication,
275
- ACTIVE_APP_DETECTION_POINT: FBActiveAppDetectionPoint.sharedInstance.stringCoordinates,
276
- INCLUDE_NON_MODAL_ELEMENTS: @([FBConfiguration includeNonModalElements]),
277
- ACCEPT_ALERT_BUTTON_SELECTOR: FBConfiguration.acceptAlertButtonSelector,
278
- DISMISS_ALERT_BUTTON_SELECTOR: FBConfiguration.dismissAlertButtonSelector,
279
- DEFAULT_ALERT_ACTION: request.session.defaultAlertAction ?: @"",
263
+ FB_SETTING_USE_COMPACT_RESPONSES: @([FBConfiguration shouldUseCompactResponses]),
264
+ FB_SETTING_ELEMENT_RESPONSE_ATTRIBUTES: [FBConfiguration elementResponseAttributes],
265
+ FB_SETTING_MJPEG_SERVER_SCREENSHOT_QUALITY: @([FBConfiguration mjpegServerScreenshotQuality]),
266
+ FB_SETTING_MJPEG_SERVER_FRAMERATE: @([FBConfiguration mjpegServerFramerate]),
267
+ FB_SETTING_MJPEG_SCALING_FACTOR: @([FBConfiguration mjpegScalingFactor]),
268
+ FB_SETTING_SCREENSHOT_QUALITY: @([FBConfiguration screenshotQuality]),
269
+ FB_SETTING_KEYBOARD_AUTOCORRECTION: @([FBConfiguration keyboardAutocorrection]),
270
+ FB_SETTING_KEYBOARD_PREDICTION: @([FBConfiguration keyboardPrediction]),
271
+ FB_SETTING_CUSTOM_SNAPSHOT_TIMEOUT: @([FBConfiguration customSnapshotTimeout]),
272
+ FB_SETTING_SNAPSHOT_MAX_DEPTH: @([FBConfiguration snapshotMaxDepth]),
273
+ FB_SETTING_USE_FIRST_MATCH: @([FBConfiguration useFirstMatch]),
274
+ FB_SETTING_WAIT_FOR_IDLE_TIMEOUT: @([FBConfiguration waitForIdleTimeout]),
275
+ FB_SETTING_ANIMATION_COOL_OFF_TIMEOUT: @([FBConfiguration animationCoolOffTimeout]),
276
+ FB_SETTING_BOUND_ELEMENTS_BY_INDEX: @([FBConfiguration boundElementsByIndex]),
277
+ FB_SETTING_REDUCE_MOTION: @([FBConfiguration reduceMotionEnabled]),
278
+ FB_SETTING_DEFAULT_ACTIVE_APPLICATION: request.session.defaultActiveApplication,
279
+ FB_SETTING_ACTIVE_APP_DETECTION_POINT: FBActiveAppDetectionPoint.sharedInstance.stringCoordinates,
280
+ FB_SETTING_INCLUDE_NON_MODAL_ELEMENTS: @([FBConfiguration includeNonModalElements]),
281
+ FB_SETTING_ACCEPT_ALERT_BUTTON_SELECTOR: FBConfiguration.acceptAlertButtonSelector,
282
+ FB_SETTING_DISMISS_ALERT_BUTTON_SELECTOR: FBConfiguration.dismissAlertButtonSelector,
283
+ FB_SETTING_DEFAULT_ALERT_ACTION: request.session.defaultAlertAction ?: @"",
280
284
  #if !TARGET_OS_TV
281
- SCREENSHOT_ORIENTATION: [FBConfiguration humanReadableScreenshotOrientation],
285
+ FB_SETTING_SCREENSHOT_ORIENTATION: [FBConfiguration humanReadableScreenshotOrientation],
282
286
  #endif
283
287
  }
284
288
  );
@@ -290,86 +294,86 @@
290
294
  {
291
295
  NSDictionary* settings = request.arguments[@"settings"];
292
296
 
293
- if (nil != [settings objectForKey:USE_COMPACT_RESPONSES]) {
294
- [FBConfiguration setShouldUseCompactResponses:[[settings objectForKey:USE_COMPACT_RESPONSES] boolValue]];
297
+ if (nil != [settings objectForKey:FB_SETTING_USE_COMPACT_RESPONSES]) {
298
+ [FBConfiguration setShouldUseCompactResponses:[[settings objectForKey:FB_SETTING_USE_COMPACT_RESPONSES] boolValue]];
295
299
  }
296
- if (nil != [settings objectForKey:ELEMENT_RESPONSE_ATTRIBUTES]) {
297
- [FBConfiguration setElementResponseAttributes:(NSString *)[settings objectForKey:ELEMENT_RESPONSE_ATTRIBUTES]];
300
+ if (nil != [settings objectForKey:FB_SETTING_ELEMENT_RESPONSE_ATTRIBUTES]) {
301
+ [FBConfiguration setElementResponseAttributes:(NSString *)[settings objectForKey:FB_SETTING_ELEMENT_RESPONSE_ATTRIBUTES]];
298
302
  }
299
- if (nil != [settings objectForKey:MJPEG_SERVER_SCREENSHOT_QUALITY]) {
300
- [FBConfiguration setMjpegServerScreenshotQuality:[[settings objectForKey:MJPEG_SERVER_SCREENSHOT_QUALITY] unsignedIntegerValue]];
303
+ if (nil != [settings objectForKey:FB_SETTING_MJPEG_SERVER_SCREENSHOT_QUALITY]) {
304
+ [FBConfiguration setMjpegServerScreenshotQuality:[[settings objectForKey:FB_SETTING_MJPEG_SERVER_SCREENSHOT_QUALITY] unsignedIntegerValue]];
301
305
  }
302
- if (nil != [settings objectForKey:MJPEG_SERVER_FRAMERATE]) {
303
- [FBConfiguration setMjpegServerFramerate:[[settings objectForKey:MJPEG_SERVER_FRAMERATE] unsignedIntegerValue]];
306
+ if (nil != [settings objectForKey:FB_SETTING_MJPEG_SERVER_FRAMERATE]) {
307
+ [FBConfiguration setMjpegServerFramerate:[[settings objectForKey:FB_SETTING_MJPEG_SERVER_FRAMERATE] unsignedIntegerValue]];
304
308
  }
305
- if (nil != [settings objectForKey:SCREENSHOT_QUALITY]) {
306
- [FBConfiguration setScreenshotQuality:[[settings objectForKey:SCREENSHOT_QUALITY] unsignedIntegerValue]];
309
+ if (nil != [settings objectForKey:FB_SETTING_SCREENSHOT_QUALITY]) {
310
+ [FBConfiguration setScreenshotQuality:[[settings objectForKey:FB_SETTING_SCREENSHOT_QUALITY] unsignedIntegerValue]];
307
311
  }
308
- if (nil != [settings objectForKey:MJPEG_SCALING_FACTOR]) {
309
- [FBConfiguration setMjpegScalingFactor:[[settings objectForKey:MJPEG_SCALING_FACTOR] unsignedIntegerValue]];
312
+ if (nil != [settings objectForKey:FB_SETTING_MJPEG_SCALING_FACTOR]) {
313
+ [FBConfiguration setMjpegScalingFactor:[[settings objectForKey:FB_SETTING_MJPEG_SCALING_FACTOR] unsignedIntegerValue]];
310
314
  }
311
- if (nil != [settings objectForKey:KEYBOARD_AUTOCORRECTION]) {
312
- [FBConfiguration setKeyboardAutocorrection:[[settings objectForKey:KEYBOARD_AUTOCORRECTION] boolValue]];
315
+ if (nil != [settings objectForKey:FB_SETTING_KEYBOARD_AUTOCORRECTION]) {
316
+ [FBConfiguration setKeyboardAutocorrection:[[settings objectForKey:FB_SETTING_KEYBOARD_AUTOCORRECTION] boolValue]];
313
317
  }
314
- if (nil != [settings objectForKey:KEYBOARD_PREDICTION]) {
315
- [FBConfiguration setKeyboardPrediction:[[settings objectForKey:KEYBOARD_PREDICTION] boolValue]];
318
+ if (nil != [settings objectForKey:FB_SETTING_KEYBOARD_PREDICTION]) {
319
+ [FBConfiguration setKeyboardPrediction:[[settings objectForKey:FB_SETTING_KEYBOARD_PREDICTION] boolValue]];
316
320
  }
317
321
  // SNAPSHOT_TIMEOUT setting is deprecated. Please use CUSTOM_SNAPSHOT_TIMEOUT instead
318
- if (nil != [settings objectForKey:SNAPSHOT_TIMEOUT]) {
319
- [FBConfiguration setCustomSnapshotTimeout:[[settings objectForKey:SNAPSHOT_TIMEOUT] doubleValue]];
322
+ if (nil != [settings objectForKey:FB_SETTING_SNAPSHOT_TIMEOUT]) {
323
+ [FBConfiguration setCustomSnapshotTimeout:[[settings objectForKey:FB_SETTING_SNAPSHOT_TIMEOUT] doubleValue]];
320
324
  }
321
- if (nil != [settings objectForKey:CUSTOM_SNAPSHOT_TIMEOUT]) {
322
- [FBConfiguration setCustomSnapshotTimeout:[[settings objectForKey:CUSTOM_SNAPSHOT_TIMEOUT] doubleValue]];
325
+ if (nil != [settings objectForKey:FB_SETTING_CUSTOM_SNAPSHOT_TIMEOUT]) {
326
+ [FBConfiguration setCustomSnapshotTimeout:[[settings objectForKey:FB_SETTING_CUSTOM_SNAPSHOT_TIMEOUT] doubleValue]];
323
327
  }
324
- if (nil != [settings objectForKey:SNAPSHOT_MAX_DEPTH]) {
325
- [FBConfiguration setSnapshotMaxDepth:[[settings objectForKey:SNAPSHOT_MAX_DEPTH] intValue]];
328
+ if (nil != [settings objectForKey:FB_SETTING_SNAPSHOT_MAX_DEPTH]) {
329
+ [FBConfiguration setSnapshotMaxDepth:[[settings objectForKey:FB_SETTING_SNAPSHOT_MAX_DEPTH] intValue]];
326
330
  }
327
- if (nil != [settings objectForKey:USE_FIRST_MATCH]) {
328
- [FBConfiguration setUseFirstMatch:[[settings objectForKey:USE_FIRST_MATCH] boolValue]];
331
+ if (nil != [settings objectForKey:FB_SETTING_USE_FIRST_MATCH]) {
332
+ [FBConfiguration setUseFirstMatch:[[settings objectForKey:FB_SETTING_USE_FIRST_MATCH] boolValue]];
329
333
  }
330
- if (nil != [settings objectForKey:BOUND_ELEMENTS_BY_INDEX]) {
331
- [FBConfiguration setBoundElementsByIndex:[[settings objectForKey:BOUND_ELEMENTS_BY_INDEX] boolValue]];
334
+ if (nil != [settings objectForKey:FB_SETTING_BOUND_ELEMENTS_BY_INDEX]) {
335
+ [FBConfiguration setBoundElementsByIndex:[[settings objectForKey:FB_SETTING_BOUND_ELEMENTS_BY_INDEX] boolValue]];
332
336
  }
333
- if (nil != [settings objectForKey:REDUCE_MOTION]) {
334
- [FBConfiguration setReduceMotionEnabled:[[settings objectForKey:REDUCE_MOTION] boolValue]];
337
+ if (nil != [settings objectForKey:FB_SETTING_REDUCE_MOTION]) {
338
+ [FBConfiguration setReduceMotionEnabled:[[settings objectForKey:FB_SETTING_REDUCE_MOTION] boolValue]];
335
339
  }
336
- if (nil != [settings objectForKey:DEFAULT_ACTIVE_APPLICATION]) {
337
- request.session.defaultActiveApplication = (NSString *)[settings objectForKey:DEFAULT_ACTIVE_APPLICATION];
340
+ if (nil != [settings objectForKey:FB_SETTING_DEFAULT_ACTIVE_APPLICATION]) {
341
+ request.session.defaultActiveApplication = (NSString *)[settings objectForKey:FB_SETTING_DEFAULT_ACTIVE_APPLICATION];
338
342
  }
339
- if (nil != [settings objectForKey:ACTIVE_APP_DETECTION_POINT]) {
343
+ if (nil != [settings objectForKey:FB_SETTING_ACTIVE_APP_DETECTION_POINT]) {
340
344
  NSError *error;
341
- if (![FBActiveAppDetectionPoint.sharedInstance setCoordinatesWithString:(NSString *)[settings objectForKey:ACTIVE_APP_DETECTION_POINT]
345
+ if (![FBActiveAppDetectionPoint.sharedInstance setCoordinatesWithString:(NSString *)[settings objectForKey:FB_SETTING_ACTIVE_APP_DETECTION_POINT]
342
346
  error:&error]) {
343
347
  return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:error.description traceback:nil]);
344
348
  }
345
349
  }
346
- if (nil != [settings objectForKey:INCLUDE_NON_MODAL_ELEMENTS]) {
350
+ if (nil != [settings objectForKey:FB_SETTING_INCLUDE_NON_MODAL_ELEMENTS]) {
347
351
  if ([XCUIElement fb_supportsNonModalElementsInclusion]) {
348
- [FBConfiguration setIncludeNonModalElements:[[settings objectForKey:INCLUDE_NON_MODAL_ELEMENTS] boolValue]];
352
+ [FBConfiguration setIncludeNonModalElements:[[settings objectForKey:FB_SETTING_INCLUDE_NON_MODAL_ELEMENTS] boolValue]];
349
353
  } else {
350
- [FBLogger logFmt:@"'%@' settings value cannot be assigned, because non modal elements inclusion is not supported by the current iOS SDK", INCLUDE_NON_MODAL_ELEMENTS];
354
+ [FBLogger logFmt:@"'%@' settings value cannot be assigned, because non modal elements inclusion is not supported by the current iOS SDK", FB_SETTING_INCLUDE_NON_MODAL_ELEMENTS];
351
355
  }
352
356
  }
353
- if (nil != [settings objectForKey:ACCEPT_ALERT_BUTTON_SELECTOR]) {
354
- [FBConfiguration setAcceptAlertButtonSelector:(NSString *)[settings objectForKey:ACCEPT_ALERT_BUTTON_SELECTOR]];
357
+ if (nil != [settings objectForKey:FB_SETTING_ACCEPT_ALERT_BUTTON_SELECTOR]) {
358
+ [FBConfiguration setAcceptAlertButtonSelector:(NSString *)[settings objectForKey:FB_SETTING_ACCEPT_ALERT_BUTTON_SELECTOR]];
355
359
  }
356
- if (nil != [settings objectForKey:DISMISS_ALERT_BUTTON_SELECTOR]) {
357
- [FBConfiguration setDismissAlertButtonSelector:(NSString *)[settings objectForKey:DISMISS_ALERT_BUTTON_SELECTOR]];
360
+ if (nil != [settings objectForKey:FB_SETTING_DISMISS_ALERT_BUTTON_SELECTOR]) {
361
+ [FBConfiguration setDismissAlertButtonSelector:(NSString *)[settings objectForKey:FB_SETTING_DISMISS_ALERT_BUTTON_SELECTOR]];
358
362
  }
359
- if (nil != [settings objectForKey:WAIT_FOR_IDLE_TIMEOUT]) {
360
- [FBConfiguration setWaitForIdleTimeout:[[settings objectForKey:WAIT_FOR_IDLE_TIMEOUT] doubleValue]];
363
+ if (nil != [settings objectForKey:FB_SETTING_WAIT_FOR_IDLE_TIMEOUT]) {
364
+ [FBConfiguration setWaitForIdleTimeout:[[settings objectForKey:FB_SETTING_WAIT_FOR_IDLE_TIMEOUT] doubleValue]];
361
365
  }
362
- if (nil != [settings objectForKey:ANIMATION_COOL_OFF_TIMEOUT]) {
363
- [FBConfiguration setAnimationCoolOffTimeout:[[settings objectForKey:ANIMATION_COOL_OFF_TIMEOUT] doubleValue]];
366
+ if (nil != [settings objectForKey:FB_SETTING_ANIMATION_COOL_OFF_TIMEOUT]) {
367
+ [FBConfiguration setAnimationCoolOffTimeout:[[settings objectForKey:FB_SETTING_ANIMATION_COOL_OFF_TIMEOUT] doubleValue]];
364
368
  }
365
- if ([[settings objectForKey:DEFAULT_ALERT_ACTION] isKindOfClass:NSString.class]) {
366
- request.session.defaultAlertAction = [settings[DEFAULT_ALERT_ACTION] lowercaseString];
369
+ if ([[settings objectForKey:FB_SETTING_DEFAULT_ALERT_ACTION] isKindOfClass:NSString.class]) {
370
+ request.session.defaultAlertAction = [settings[FB_SETTING_DEFAULT_ALERT_ACTION] lowercaseString];
367
371
  }
368
372
 
369
373
  #if !TARGET_OS_TV
370
- if (nil != [settings objectForKey:SCREENSHOT_ORIENTATION]) {
374
+ if (nil != [settings objectForKey:FB_SETTING_SCREENSHOT_ORIENTATION]) {
371
375
  NSError *error;
372
- if (![FBConfiguration setScreenshotOrientation:(NSString *)[settings objectForKey:SCREENSHOT_ORIENTATION]
376
+ if (![FBConfiguration setScreenshotOrientation:(NSString *)[settings objectForKey:FB_SETTING_SCREENSHOT_ORIENTATION]
373
377
  error:&error]) {
374
378
  return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:error.description traceback:nil]);
375
379
  }
@@ -19,6 +19,7 @@
19
19
  #import "XCUIElement+FBUtilities.h"
20
20
  #import "XCUIElement+FBWebDriverAttributes.h"
21
21
  #import "XCUIElement+FBUID.h"
22
+ #import "XCUIElement+FBResolve.h"
22
23
  #import "XCUIElementQuery.h"
23
24
 
24
25
  const int ELEMENT_CACHE_SIZE = 1024;
@@ -16,8 +16,8 @@
16
16
  #import "FBConfiguration.h"
17
17
  #import "FBMacros.h"
18
18
  #import "FBProtocolHelpers.h"
19
-
20
19
  #import "XCUIElementQuery.h"
20
+ #import "XCUIElement+FBResolve.h"
21
21
  #import "XCUIElement+FBUtilities.h"
22
22
  #import "XCUIElement+FBWebDriverAttributes.h"
23
23
 
@@ -35,15 +35,21 @@ id<FBResponsePayload> FBResponseWithObject(id object)
35
35
 
36
36
  id<FBResponsePayload> FBResponseWithCachedElement(XCUIElement *element, FBElementCache *elementCache, BOOL compact)
37
37
  {
38
- [elementCache storeElement:element];
38
+ BOOL useNativeCachingStrategy = nil == FBSession.activeSession
39
+ ? YES
40
+ : FBSession.activeSession.useNativeCachingStrategy;
41
+ [elementCache storeElement:(useNativeCachingStrategy ? element : element.fb_stableInstance)];
39
42
  return FBResponseWithStatus([FBCommandStatus okWithValue: FBDictionaryResponseWithElement(element, compact)]);
40
43
  }
41
44
 
42
45
  id<FBResponsePayload> FBResponseWithCachedElements(NSArray<XCUIElement *> *elements, FBElementCache *elementCache, BOOL compact)
43
46
  {
44
47
  NSMutableArray *elementsResponse = [NSMutableArray array];
48
+ BOOL useNativeCachingStrategy = nil == FBSession.activeSession
49
+ ? YES
50
+ : FBSession.activeSession.useNativeCachingStrategy;
45
51
  for (XCUIElement *element in elements) {
46
- [elementCache storeElement:element];
52
+ [elementCache storeElement:(useNativeCachingStrategy ? element : element.fb_stableInstance)];
47
53
  [elementsResponse addObject:FBDictionaryResponseWithElement(element, compact)];
48
54
  }
49
55
  return FBResponseWithStatus([FBCommandStatus okWithValue:elementsResponse]);
@@ -34,6 +34,9 @@ NS_ASSUME_NONNULL_BEGIN
34
34
  /*! The action to apply to unexpected alerts. Either "accept"/"dismiss" or nil/empty string (by default) to do nothing */
35
35
  @property (nonatomic, nullable) NSString *defaultAlertAction;
36
36
 
37
+ /*! Whether to use the native caching strategy for elements or the custom one: https://discuss.appium.io/t/elements-state-coming-from-xpath-vs-ios-predicate-string/34016 */
38
+ @property (nonatomic) BOOL useNativeCachingStrategy;
39
+
37
40
  /*! Keeps cached visibility values for the current snapshots tree */
38
41
  @property (nonatomic, readonly) NSMutableDictionary<NSNumber *, NSMutableDictionary<NSString *, NSNumber *> *> *elementsVisibilityCache;
39
42
 
@@ -99,6 +99,7 @@ static FBSession *_activeSession = nil;
99
99
  + (instancetype)initWithApplication:(FBApplication *)application
100
100
  {
101
101
  FBSession *session = [FBSession new];
102
+ session.useNativeCachingStrategy = YES;
102
103
  session.alertsMonitor = nil;
103
104
  session.defaultAlertAction = nil;
104
105
  session.elementsVisibilityCache = [NSMutableDictionary dictionary];
@@ -20,3 +20,4 @@ extern NSString* const FB_CAP_FORCE_APP_LAUNCH;
20
20
  extern NSString* const FB_CAP_SHOULD_WAIT_FOR_QUIESCENCE;
21
21
  extern NSString* const FB_CAP_ARGUMENTS;
22
22
  extern NSString* const FB_CAP_ENVIRNOMENT;
23
+ extern NSString* const FB_CAP_USE_NATIVE_CACHING_STRATEGY;
@@ -20,3 +20,4 @@ NSString* const FB_CAP_FORCE_APP_LAUNCH = @"forceAppLaunch";
20
20
  NSString* const FB_CAP_SHOULD_WAIT_FOR_QUIESCENCE = @"shouldWaitForQuiescence";
21
21
  NSString* const FB_CAP_ARGUMENTS = @"arguments";
22
22
  NSString* const FB_CAP_ENVIRNOMENT = @"environment";
23
+ NSString* const FB_CAP_USE_NATIVE_CACHING_STRATEGY = @"useNativeCachingStrategy";
@@ -13,30 +13,30 @@ NS_ASSUME_NONNULL_BEGIN
13
13
 
14
14
  // See FBConfiguration.h for more details on the meaning of each setting
15
15
 
16
- extern NSString* const USE_COMPACT_RESPONSES;
17
- extern NSString* const ELEMENT_RESPONSE_ATTRIBUTES;
18
- extern NSString* const MJPEG_SERVER_SCREENSHOT_QUALITY;
19
- extern NSString* const MJPEG_SERVER_FRAMERATE;
20
- extern NSString* const MJPEG_SCALING_FACTOR;
21
- extern NSString* const SCREENSHOT_QUALITY;
22
- extern NSString* const KEYBOARD_AUTOCORRECTION;
23
- extern NSString* const KEYBOARD_PREDICTION;
16
+ extern NSString* const FB_SETTING_USE_COMPACT_RESPONSES;
17
+ extern NSString* const FB_SETTING_ELEMENT_RESPONSE_ATTRIBUTES;
18
+ extern NSString* const FB_SETTING_MJPEG_SERVER_SCREENSHOT_QUALITY;
19
+ extern NSString* const FB_SETTING_MJPEG_SERVER_FRAMERATE;
20
+ extern NSString* const FB_SETTING_MJPEG_SCALING_FACTOR;
21
+ extern NSString* const FB_SETTING_SCREENSHOT_QUALITY;
22
+ extern NSString* const FB_SETTING_KEYBOARD_AUTOCORRECTION;
23
+ extern NSString* const FB_SETTING_KEYBOARD_PREDICTION;
24
24
  // This setting is deprecated. Please use CUSTOM_SNAPSHOT_TIMEOUT instead
25
- extern NSString* const SNAPSHOT_TIMEOUT;
26
- extern NSString* const CUSTOM_SNAPSHOT_TIMEOUT;
27
- extern NSString* const SNAPSHOT_MAX_DEPTH;
28
- extern NSString* const USE_FIRST_MATCH;
29
- extern NSString* const BOUND_ELEMENTS_BY_INDEX;
30
- extern NSString* const REDUCE_MOTION;
31
- extern NSString* const DEFAULT_ACTIVE_APPLICATION;
32
- extern NSString* const ACTIVE_APP_DETECTION_POINT;
33
- extern NSString* const INCLUDE_NON_MODAL_ELEMENTS;
34
- extern NSString* const DEFAULT_ALERT_ACTION;
35
- extern NSString* const ACCEPT_ALERT_BUTTON_SELECTOR;
36
- extern NSString* const DISMISS_ALERT_BUTTON_SELECTOR;
37
- extern NSString* const SCREENSHOT_ORIENTATION;
38
- extern NSString* const WAIT_FOR_IDLE_TIMEOUT;
39
- extern NSString* const ANIMATION_COOL_OFF_TIMEOUT;
25
+ extern NSString* const FB_SETTING_SNAPSHOT_TIMEOUT;
26
+ extern NSString* const FB_SETTING_CUSTOM_SNAPSHOT_TIMEOUT;
27
+ extern NSString* const FB_SETTING_SNAPSHOT_MAX_DEPTH;
28
+ extern NSString* const FB_SETTING_USE_FIRST_MATCH;
29
+ extern NSString* const FB_SETTING_BOUND_ELEMENTS_BY_INDEX;
30
+ extern NSString* const FB_SETTING_REDUCE_MOTION;
31
+ extern NSString* const FB_SETTING_DEFAULT_ACTIVE_APPLICATION;
32
+ extern NSString* const FB_SETTING_ACTIVE_APP_DETECTION_POINT;
33
+ extern NSString* const FB_SETTING_INCLUDE_NON_MODAL_ELEMENTS;
34
+ extern NSString* const FB_SETTING_DEFAULT_ALERT_ACTION;
35
+ extern NSString* const FB_SETTING_ACCEPT_ALERT_BUTTON_SELECTOR;
36
+ extern NSString* const FB_SETTING_DISMISS_ALERT_BUTTON_SELECTOR;
37
+ extern NSString* const FB_SETTING_SCREENSHOT_ORIENTATION;
38
+ extern NSString* const FB_SETTING_WAIT_FOR_IDLE_TIMEOUT;
39
+ extern NSString* const FB_SETTING_ANIMATION_COOL_OFF_TIMEOUT;
40
40
 
41
41
 
42
42
  NS_ASSUME_NONNULL_END
@@ -9,26 +9,26 @@
9
9
 
10
10
  #import "FBSettings.h"
11
11
 
12
- NSString* const USE_COMPACT_RESPONSES = @"shouldUseCompactResponses";
13
- NSString* const ELEMENT_RESPONSE_ATTRIBUTES = @"elementResponseAttributes";
14
- NSString* const MJPEG_SERVER_SCREENSHOT_QUALITY = @"mjpegServerScreenshotQuality";
15
- NSString* const MJPEG_SERVER_FRAMERATE = @"mjpegServerFramerate";
16
- NSString* const MJPEG_SCALING_FACTOR = @"mjpegScalingFactor";
17
- NSString* const SCREENSHOT_QUALITY = @"screenshotQuality";
18
- NSString* const KEYBOARD_AUTOCORRECTION = @"keyboardAutocorrection";
19
- NSString* const KEYBOARD_PREDICTION = @"keyboardPrediction";
20
- NSString* const SNAPSHOT_TIMEOUT = @"snapshotTimeout";
21
- NSString* const CUSTOM_SNAPSHOT_TIMEOUT = @"customSnapshotTimeout";
22
- NSString* const SNAPSHOT_MAX_DEPTH = @"snapshotMaxDepth";
23
- NSString* const USE_FIRST_MATCH = @"useFirstMatch";
24
- NSString* const BOUND_ELEMENTS_BY_INDEX = @"boundElementsByIndex";
25
- NSString* const REDUCE_MOTION = @"reduceMotion";
26
- NSString* const DEFAULT_ACTIVE_APPLICATION = @"defaultActiveApplication";
27
- NSString* const ACTIVE_APP_DETECTION_POINT = @"activeAppDetectionPoint";
28
- NSString* const INCLUDE_NON_MODAL_ELEMENTS = @"includeNonModalElements";
29
- NSString* const DEFAULT_ALERT_ACTION = @"defaultAlertAction";
30
- NSString* const ACCEPT_ALERT_BUTTON_SELECTOR = @"acceptAlertButtonSelector";
31
- NSString* const DISMISS_ALERT_BUTTON_SELECTOR = @"dismissAlertButtonSelector";
32
- NSString* const SCREENSHOT_ORIENTATION = @"screenshotOrientation";
33
- NSString* const WAIT_FOR_IDLE_TIMEOUT = @"waitForIdleTimeout";
34
- NSString* const ANIMATION_COOL_OFF_TIMEOUT = @"animationCoolOffTimeout";
12
+ NSString* const FB_SETTING_USE_COMPACT_RESPONSES = @"shouldUseCompactResponses";
13
+ NSString* const FB_SETTING_ELEMENT_RESPONSE_ATTRIBUTES = @"elementResponseAttributes";
14
+ NSString* const FB_SETTING_MJPEG_SERVER_SCREENSHOT_QUALITY = @"mjpegServerScreenshotQuality";
15
+ NSString* const FB_SETTING_MJPEG_SERVER_FRAMERATE = @"mjpegServerFramerate";
16
+ NSString* const FB_SETTING_MJPEG_SCALING_FACTOR = @"mjpegScalingFactor";
17
+ NSString* const FB_SETTING_SCREENSHOT_QUALITY = @"screenshotQuality";
18
+ NSString* const FB_SETTING_KEYBOARD_AUTOCORRECTION = @"keyboardAutocorrection";
19
+ NSString* const FB_SETTING_KEYBOARD_PREDICTION = @"keyboardPrediction";
20
+ NSString* const FB_SETTING_SNAPSHOT_TIMEOUT = @"snapshotTimeout";
21
+ NSString* const FB_SETTING_CUSTOM_SNAPSHOT_TIMEOUT = @"customSnapshotTimeout";
22
+ NSString* const FB_SETTING_SNAPSHOT_MAX_DEPTH = @"snapshotMaxDepth";
23
+ NSString* const FB_SETTING_USE_FIRST_MATCH = @"useFirstMatch";
24
+ NSString* const FB_SETTING_BOUND_ELEMENTS_BY_INDEX = @"boundElementsByIndex";
25
+ NSString* const FB_SETTING_REDUCE_MOTION = @"reduceMotion";
26
+ NSString* const FB_SETTING_DEFAULT_ACTIVE_APPLICATION = @"defaultActiveApplication";
27
+ NSString* const FB_SETTING_ACTIVE_APP_DETECTION_POINT = @"activeAppDetectionPoint";
28
+ NSString* const FB_SETTING_INCLUDE_NON_MODAL_ELEMENTS = @"includeNonModalElements";
29
+ NSString* const FB_SETTING_DEFAULT_ALERT_ACTION = @"defaultAlertAction";
30
+ NSString* const FB_SETTING_ACCEPT_ALERT_BUTTON_SELECTOR = @"acceptAlertButtonSelector";
31
+ NSString* const FB_SETTING_DISMISS_ALERT_BUTTON_SELECTOR = @"dismissAlertButtonSelector";
32
+ NSString* const FB_SETTING_SCREENSHOT_ORIENTATION = @"screenshotOrientation";
33
+ NSString* const FB_SETTING_WAIT_FOR_IDLE_TIMEOUT = @"waitForIdleTimeout";
34
+ NSString* const FB_SETTING_ANIMATION_COOL_OFF_TIMEOUT = @"animationCoolOffTimeout";
Binary file
@@ -18,6 +18,7 @@
18
18
  #import "XCElementSnapshot+FBHelpers.h"
19
19
  #import "XCUIElement+FBIsVisible.h"
20
20
  #import "XCUIElement+FBClassChain.h"
21
+ #import "XCUIElement+FBResolve.h"
21
22
  #import "FBXPath.h"
22
23
  #import "FBXCodeCompatibility.h"
23
24
 
@@ -86,6 +87,16 @@
86
87
  XCTAssertEqualObjects(matchingSnapshots.lastObject.label, @"Alerts");
87
88
  }
88
89
 
90
+ - (void)testStableInstance
91
+ {
92
+ NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"Alerts" shouldReturnAfterFirstMatch:YES];
93
+ XCTAssertEqual(matchingSnapshots.count, 1);
94
+ for (XCUIElement *el in @[matchingSnapshots.lastObject, matchingSnapshots.lastObject.fb_stableInstance]) {
95
+ XCTAssertEqual(el.elementType, XCUIElementTypeButton);
96
+ XCTAssertEqualObjects(el.label, @"Alerts");
97
+ }
98
+ }
99
+
89
100
  - (void)testSingleDescendantWithMissingIdentifier
90
101
  {
91
102
  NSArray<XCUIElement *> *matchingSnapshots = [self.testedView fb_descendantsMatchingIdentifier:@"blabla" shouldReturnAfterFirstMatch:YES];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium-webdriveragent",
3
- "version": "3.11.1",
3
+ "version": "3.12.0",
4
4
  "description": "Package bundling WebDriverAgent",
5
5
  "main": "build/index.js",
6
6
  "scripts": {