appium-webdriveragent 3.9.2 → 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.
Files changed (65) hide show
  1. package/PrivateHeaders/.DS_Store +0 -0
  2. package/PrivateHeaders/XCTest/XCTestManager_ManagerInterface-Protocol.h +3 -0
  3. package/README.md +0 -1
  4. package/WebDriverAgent.xcodeproj/project.pbxproj +56 -56
  5. package/WebDriverAgent.xcodeproj/project.xcworkspace/xcuserdata/elf.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  6. package/WebDriverAgent.xcodeproj/xcuserdata/elf.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +51 -0
  7. package/WebDriverAgent.xcodeproj/xcuserdata/{kazuaki.xcuserdatad → elf.xcuserdatad}/xcschemes/xcschememanagement.plist +23 -8
  8. package/WebDriverAgentLib/.DS_Store +0 -0
  9. package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.h +0 -17
  10. package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +0 -16
  11. package/WebDriverAgentLib/Categories/XCUIElement+FBIsVisible.m +28 -14
  12. package/WebDriverAgentLib/Categories/XCUIElement+FBResolve.h +37 -0
  13. package/WebDriverAgentLib/Categories/XCUIElement+FBResolve.m +51 -0
  14. package/WebDriverAgentLib/Categories/XCUIElement+FBUtilities.m +8 -2
  15. package/WebDriverAgentLib/Commands/FBElementCommands.m +3 -1
  16. package/WebDriverAgentLib/Commands/FBOrientationCommands.m +20 -9
  17. package/WebDriverAgentLib/Commands/FBSessionCommands.m +119 -99
  18. package/WebDriverAgentLib/FBApplication.m +1 -1
  19. package/WebDriverAgentLib/Routing/FBElementCache.m +42 -11
  20. package/WebDriverAgentLib/Routing/FBResponsePayload.m +9 -3
  21. package/WebDriverAgentLib/Routing/FBSession.h +6 -0
  22. package/WebDriverAgentLib/Routing/FBSession.m +45 -55
  23. package/WebDriverAgentLib/Utilities/FBAlertsMonitor.h +1 -3
  24. package/WebDriverAgentLib/Utilities/FBAlertsMonitor.m +6 -13
  25. package/WebDriverAgentLib/Utilities/FBCapabilities.h +23 -0
  26. package/WebDriverAgentLib/Utilities/FBCapabilities.m +23 -0
  27. package/WebDriverAgentLib/Utilities/FBConfiguration.m +6 -1
  28. package/WebDriverAgentLib/Utilities/FBScreenshot.m +125 -14
  29. package/WebDriverAgentLib/Utilities/FBSettings.h +23 -23
  30. package/WebDriverAgentLib/Utilities/FBSettings.m +23 -23
  31. package/WebDriverAgentLib/Utilities/FBXCodeCompatibility.h +16 -0
  32. package/WebDriverAgentLib/Utilities/FBXCodeCompatibility.m +16 -0
  33. package/WebDriverAgentLib/Utilities/FBXPath.m +15 -44
  34. package/WebDriverAgentLib/Utilities/LRUCache/.DS_Store +0 -0
  35. package/WebDriverAgentLib/Utilities/LRUCache/LRUCache.h +59 -0
  36. package/WebDriverAgentLib/Utilities/LRUCache/LRUCache.m +104 -0
  37. package/WebDriverAgentLib/Utilities/LRUCache/LRUCacheNode.h +43 -0
  38. package/WebDriverAgentLib/Utilities/LRUCache/LRUCacheNode.m +59 -0
  39. package/WebDriverAgentLib/Vendor/.DS_Store +0 -0
  40. package/WebDriverAgentRunner/.DS_Store +0 -0
  41. package/WebDriverAgentRunner-Runner.app.zip +0 -0
  42. package/WebDriverAgentTests/IntegrationApp/Resources/.DS_Store +0 -0
  43. package/WebDriverAgentTests/IntegrationTests/FBSessionIntegrationTests.m +20 -16
  44. package/WebDriverAgentTests/IntegrationTests/XCUIApplicationHelperTests.m +2 -1
  45. package/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m +11 -0
  46. package/WebDriverAgentTests/UnitTests/Doubles/FBApplicationDouble.h +3 -0
  47. package/WebDriverAgentTests/UnitTests/Doubles/FBApplicationDouble.m +15 -0
  48. package/WebDriverAgentTests/UnitTests/Doubles/XCUIElementDouble.h +1 -0
  49. package/WebDriverAgentTests/UnitTests/Doubles/XCUIElementDouble.m +1 -0
  50. package/WebDriverAgentTests/UnitTests/FBSessionTests.m +11 -1
  51. package/WebDriverAgentTests/UnitTests/FBXPathTests.m +3 -1
  52. package/WebDriverAgentTests/UnitTests_tvOS/Doubles/XCUIElementDouble.h +1 -0
  53. package/WebDriverAgentTests/UnitTests_tvOS/Doubles/XCUIElementDouble.m +1 -0
  54. package/package.json +3 -3
  55. package/WebDriverAgent.xcodeproj/project.xcworkspace/xcuserdata/kazuaki.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  56. package/WebDriverAgent.xcodeproj/project.xcworkspace/xcuserdata/kazuaki.xcuserdatad/WorkspaceSettings.xcsettings +0 -20
  57. package/WebDriverAgent.xcodeproj/xcuserdata/kazuaki.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +0 -906
  58. package/WebDriverAgentLib/Vendor/YYCache/YYCache.h +0 -206
  59. package/WebDriverAgentLib/Vendor/YYCache/YYCache.m +0 -140
  60. package/WebDriverAgentLib/Vendor/YYCache/YYDiskCache.h +0 -412
  61. package/WebDriverAgentLib/Vendor/YYCache/YYDiskCache.m +0 -462
  62. package/WebDriverAgentLib/Vendor/YYCache/YYKVStorage.h +0 -325
  63. package/WebDriverAgentLib/Vendor/YYCache/YYKVStorage.m +0 -1068
  64. package/WebDriverAgentLib/Vendor/YYCache/YYMemoryCache.h +0 -213
  65. package/WebDriverAgentLib/Vendor/YYCache/YYMemoryCache.m +0 -508
@@ -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";
@@ -10,6 +10,22 @@
10
10
  #import <WebDriverAgentLib/WebDriverAgentLib.h>
11
11
  #import "XCPointerEvent.h"
12
12
 
13
+ /**
14
+ The version of testmanagerd process which is running on the device.
15
+
16
+ Potentially, we can handle processes based on this version instead of iOS versions,
17
+ iOS 10.1 -> 6
18
+ iOS 11.0.1 -> 18
19
+ iOS 11.4 -> 22
20
+ iOS 12.1, 12.4 -> 26
21
+ iOS 13.0, 13.4.1 -> 28
22
+
23
+ tvOS 13.3 -> 28
24
+
25
+ @return The version of testmanagerd
26
+ */
27
+ NSInteger FBTestmanagerdVersion(void);
28
+
13
29
  NS_ASSUME_NONNULL_BEGIN
14
30
 
15
31
  /**
@@ -193,3 +193,19 @@ static dispatch_once_t onceAppWithPIDToken;
193
193
  }
194
194
 
195
195
  @end
196
+
197
+ NSInteger FBTestmanagerdVersion(void)
198
+ {
199
+ static dispatch_once_t getTestmanagerdVersion;
200
+ static NSInteger testmanagerdVersion;
201
+ dispatch_once(&getTestmanagerdVersion, ^{
202
+ id<XCTestManager_ManagerInterface> proxy = [FBXCTestDaemonsProxy testRunnerProxy];
203
+ dispatch_semaphore_t sem = dispatch_semaphore_create(0);
204
+ [proxy _XCT_exchangeProtocolVersion:testmanagerdVersion reply:^(unsigned long long code) {
205
+ testmanagerdVersion = (NSInteger) code;
206
+ dispatch_semaphore_signal(sem);
207
+ }];
208
+ dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)));
209
+ });
210
+ return testmanagerdVersion;
211
+ }
@@ -136,7 +136,9 @@ static NSString *const topNodeIndexPath = @"top";
136
136
  xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1);
137
137
  xmlFreeTextWriter(writer);
138
138
  xmlFreeDoc(doc);
139
- return [NSString stringWithCString:(const char *)xmlbuff encoding:NSUTF8StringEncoding];
139
+ NSString *result = [NSString stringWithCString:(const char *)xmlbuff encoding:NSUTF8StringEncoding];
140
+ xmlFree(xmlbuff);
141
+ return result;
140
142
  }
141
143
 
142
144
  + (NSArray<XCElementSnapshot *> *)matchesWithRootElement:(id<FBElement>)root forQuery:(NSString *)xpathQuery
@@ -183,7 +185,7 @@ static NSString *const topNodeIndexPath = @"top";
183
185
  return @[];
184
186
  }
185
187
  NSMutableArray *matchingSnapshots = [NSMutableArray array];
186
- const xmlChar *indexPathKeyName = [self xmlCharPtrForInput:[kXMLIndexPathKey cStringUsingEncoding:NSUTF8StringEncoding]];
188
+ const xmlChar *indexPathKeyName = (xmlChar *)[kXMLIndexPathKey UTF8String];
187
189
  for (NSInteger i = 0; i < nodeSet->nodeNr; i++) {
188
190
  xmlNodePtr currentNode = nodeSet->nodeTab[i];
189
191
  xmlChar *attrValue = xmlGetProp(currentNode, indexPathKeyName);
@@ -195,6 +197,7 @@ static NSString *const topNodeIndexPath = @"top";
195
197
  if (element) {
196
198
  [matchingSnapshots addObject:element];
197
199
  }
200
+ xmlFree(attrValue);
198
201
  }
199
202
  return matchingSnapshots.copy;
200
203
  }
@@ -263,37 +266,6 @@ static NSString *const topNodeIndexPath = @"top";
263
266
  return 0;
264
267
  }
265
268
 
266
- + (xmlChar *)xmlCharPtrForInput:(const char *)input
267
- {
268
- if (0 == input) {
269
- return NULL;
270
- }
271
-
272
- xmlCharEncodingHandlerPtr handler = xmlFindCharEncodingHandler(_UTF8Encoding);
273
- if (!handler) {
274
- [FBLogger log:@"Failed to invoke libxml2>xmlFindCharEncodingHandler"];
275
- return NULL;
276
- }
277
-
278
- int size = (int) strlen(input) + 1;
279
- int outputSize = size * 2 - 1;
280
- xmlChar *output = (unsigned char *) xmlMalloc((size_t) outputSize);
281
-
282
- if (0 != output) {
283
- int temp = size - 1;
284
- int ret = handler->input(output, &outputSize, (const xmlChar *) input, &temp);
285
- if ((ret < 0) || (temp - size + 1)) {
286
- xmlFree(output);
287
- output = 0;
288
- } else {
289
- output = (unsigned char *) xmlRealloc(output, outputSize + 1);
290
- output[outputSize] = 0;
291
- }
292
- }
293
-
294
- return output;
295
- }
296
-
297
269
  + (xmlXPathObjectPtr)evaluate:(NSString *)xpathQuery document:(xmlDocPtr)doc
298
270
  {
299
271
  xmlXPathContextPtr xpathCtx = xmlXPathNewContext(doc);
@@ -303,7 +275,7 @@ static NSString *const topNodeIndexPath = @"top";
303
275
  }
304
276
  xpathCtx->node = doc->children;
305
277
 
306
- xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression([self xmlCharPtrForInput:[xpathQuery cStringUsingEncoding:NSUTF8StringEncoding]], xpathCtx);
278
+ xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression((const xmlChar *)[xpathQuery UTF8String], xpathCtx);
307
279
  if (NULL == xpathObj) {
308
280
  xmlXPathFreeContext(xpathCtx);
309
281
  [FBLogger logFmt:@"Failed to invoke libxml2>xmlXPathEvalExpression for XPath query \"%@\"", xpathQuery];
@@ -313,14 +285,9 @@ static NSString *const topNodeIndexPath = @"top";
313
285
  return xpathObj;
314
286
  }
315
287
 
316
- + (xmlChar *)safeXmlStringWithString:(NSString *)str
288
+ + (nullable NSString *)safeXmlStringWithString:(NSString *)str
317
289
  {
318
- if (nil == str) {
319
- return NULL;
320
- }
321
-
322
- NSString *safeString = [str fb_xmlSafeStringWithReplacement:@""];
323
- return [self.class xmlCharPtrForInput:[safeString cStringUsingEncoding:NSUTF8StringEncoding]];
290
+ return [str fb_xmlSafeStringWithReplacement:@""];
324
291
  }
325
292
 
326
293
  + (int)recordElementAttributes:(xmlTextWriterPtr)writer forElement:(XCElementSnapshot *)element indexPath:(nullable NSString *)indexPath includedAttributes:(nullable NSSet<Class> *)includedAttributes
@@ -374,7 +341,7 @@ static NSString *const topNodeIndexPath = @"top";
374
341
  [elementStore setObject:currentSnapshot forKey:topNodeIndexPath];
375
342
  }
376
343
 
377
- int rc = xmlTextWriterStartElement(writer, [self xmlCharPtrForInput:[currentSnapshot.wdType cStringUsingEncoding:NSUTF8StringEncoding]]);
344
+ int rc = xmlTextWriterStartElement(writer, (xmlChar *)[currentSnapshot.wdType UTF8String]);
378
345
  if (rc < 0) {
379
346
  [FBLogger logFmt:@"Failed to invoke libxml2>xmlTextWriterStartElement for the tag value '%@'. Error code: %d", currentSnapshot.wdType, rc];
380
347
  return rc;
@@ -447,7 +414,9 @@ static NSString *const FBAbstractMethodInvocationException = @"AbstractMethodInv
447
414
  // Skip the attribute if the value equals to nil
448
415
  return 0;
449
416
  }
450
- int rc = xmlTextWriterWriteAttribute(writer, [FBXPath safeXmlStringWithString:[self name]], [FBXPath safeXmlStringWithString:value]);
417
+ int rc = xmlTextWriterWriteAttribute(writer,
418
+ (xmlChar *)[[FBXPath safeXmlStringWithString:[self name]] UTF8String],
419
+ (xmlChar *)[[FBXPath safeXmlStringWithString:value] UTF8String]);
451
420
  if (rc < 0) {
452
421
  [FBLogger logFmt:@"Failed to invoke libxml2>xmlTextWriterWriteAttribute(%@='%@'). Error code: %d", [self name], value, rc];
453
422
  }
@@ -672,7 +641,9 @@ static NSString *const FBAbstractMethodInvocationException = @"AbstractMethodInv
672
641
  // Skip the attribute if the value equals to nil
673
642
  return 0;
674
643
  }
675
- int rc = xmlTextWriterWriteAttribute(writer, [FBXPath safeXmlStringWithString:[self name]], [FBXPath safeXmlStringWithString:value]);
644
+ int rc = xmlTextWriterWriteAttribute(writer,
645
+ (xmlChar *)[[FBXPath safeXmlStringWithString:[self name]] UTF8String],
646
+ (xmlChar *)[[FBXPath safeXmlStringWithString:value] UTF8String]);
676
647
  if (rc < 0) {
677
648
  [FBLogger logFmt:@"Failed to invoke libxml2>xmlTextWriterWriteAttribute(%@='%@'). Error code: %d", [self name], value, rc];
678
649
  }
@@ -0,0 +1,59 @@
1
+ /*
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * See the NOTICE file distributed with this work for additional
5
+ * information regarding copyright ownership.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #import <Foundation/Foundation.h>
18
+
19
+ NS_ASSUME_NONNULL_BEGIN
20
+
21
+ @interface LRUCache : NSObject
22
+
23
+ /*! Maximum cache capacity. Could only be set in the constructor */
24
+ @property (nonatomic, readonly) NSUInteger capacity;
25
+
26
+ /**
27
+ Constructs a new LRU cache instance with the given capacity
28
+
29
+ @param capacity Maximum cache capacity
30
+ */
31
+ - (instancetype)initWithCapacity:(NSUInteger)capacity;
32
+
33
+ /**
34
+ Puts a new object into the cache. nil cannot be stored in the cache.
35
+
36
+ @param object Object to put
37
+ @param key Object's key
38
+ */
39
+ - (void)setObject:(id)object forKey:(id<NSCopying>)key;
40
+
41
+ /**
42
+ Retrieves an object from the cache. Every time this method is called the matched
43
+ object is bumped in the cache (if exists)
44
+
45
+ @param key Object's key
46
+ @returns Either the stored instance or nil if the object does not exist or has expired
47
+ */
48
+ - (nullable id)objectForKey:(id<NSCopying>)key;
49
+
50
+ /**
51
+ Retrieves all values from the cache. No bump is performed
52
+
53
+ @return Array of all cache values
54
+ */
55
+ - (NSArray *)allObjects;
56
+
57
+ @end
58
+
59
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,104 @@
1
+ /*
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * See the NOTICE file distributed with this work for additional
5
+ * information regarding copyright ownership.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #import "LRUCache.h"
18
+ #import "LRUCacheNode.h"
19
+
20
+ @interface LRUCache ()
21
+ @property (nonatomic) NSMutableDictionary *store;
22
+ @property (nonatomic, nullable) LRUCacheNode *headNode;
23
+ @property (nonatomic, nullable) LRUCacheNode *tailNode;
24
+ @property (nonatomic) NSUInteger size;
25
+ @end
26
+
27
+ @implementation LRUCache
28
+
29
+ - (instancetype)initWithCapacity:(NSUInteger)capacity
30
+ {
31
+ if ((self = [super init])) {
32
+ _store = [NSMutableDictionary dictionary];
33
+ _capacity = capacity;
34
+ }
35
+ return self;
36
+ }
37
+
38
+ - (void)setObject:(id)object forKey:(id<NSCopying>)key
39
+ {
40
+ NSAssert(nil != object, @"LRUCache cannot store nil objects");
41
+
42
+ LRUCacheNode *previousNode = self.store[key];
43
+ LRUCacheNode *newNode = [LRUCacheNode nodeWithValue:object key:key];
44
+ self.store[key] = newNode;
45
+ if (nil == previousNode) {
46
+ ++self.size;
47
+ }
48
+ if (previousNode == self.tailNode) {
49
+ self.tailNode = newNode;
50
+ }
51
+ if (previousNode == self.headNode) {
52
+ self.headNode = newNode;
53
+ }
54
+
55
+ [self bumpNode:newNode];
56
+ [self alignSize];
57
+ }
58
+
59
+ - (id)objectForKey:(id<NSCopying>)key
60
+ {
61
+ LRUCacheNode *node = self.store[key];
62
+ if (nil != node) {
63
+ [self bumpNode:node];
64
+ }
65
+
66
+ return node.value;
67
+ }
68
+
69
+ - (NSArray *)allObjects
70
+ {
71
+ return (NSArray *)[self.store.allValues valueForKeyPath:@"value"];
72
+ }
73
+
74
+ - (void)bumpNode:(LRUCacheNode *)node
75
+ {
76
+ if (node == self.headNode) {
77
+ return;
78
+ }
79
+
80
+ if (node == self.tailNode) {
81
+ self.tailNode = self.tailNode.prev;
82
+ }
83
+
84
+ self.headNode.prev.next = node.next;
85
+
86
+ LRUCacheNode *prevHead = self.headNode;
87
+ self.headNode = node;
88
+ self.headNode.next = prevHead;
89
+ }
90
+
91
+ - (void)alignSize
92
+ {
93
+ if (self.size <= self.capacity) {
94
+ return;
95
+ }
96
+
97
+ LRUCacheNode *nextTail = self.tailNode.prev;
98
+ [self.store removeObjectForKey:(id)self.tailNode.key];
99
+ self.tailNode = nextTail;
100
+ self.tailNode.next = nil;
101
+ --self.size;
102
+ }
103
+
104
+ @end
@@ -0,0 +1,43 @@
1
+ /*
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * See the NOTICE file distributed with this work for additional
5
+ * information regarding copyright ownership.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #import <Foundation/Foundation.h>
18
+
19
+ NS_ASSUME_NONNULL_BEGIN
20
+
21
+ @interface LRUCacheNode : NSObject
22
+
23
+ /*! Node value */
24
+ @property (nonatomic, readonly) id value;
25
+ /*! Node key */
26
+ @property (nonatomic, readonly) id<NSCopying> key;
27
+ /*! Pointer to the next node */
28
+ @property (nonatomic, nullable) LRUCacheNode *next;
29
+ /*! Pointer to the previous node */
30
+ @property (nonatomic, nullable) LRUCacheNode *prev;
31
+
32
+ /**
33
+ Factory method to create a new cache node with the given value and key
34
+
35
+ @param value Node value
36
+ @param key Node key
37
+ @returns Cache node instance
38
+ */
39
+ + (instancetype)nodeWithValue:(id)value key:(id<NSCopying>)key;
40
+
41
+ @end
42
+
43
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,59 @@
1
+ /*
2
+ * Licensed under the Apache License, Version 2.0 (the "License");
3
+ * you may not use this file except in compliance with the License.
4
+ * See the NOTICE file distributed with this work for additional
5
+ * information regarding copyright ownership.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #import "LRUCacheNode.h"
18
+
19
+ @interface LRUCacheNode ()
20
+ @property (nonatomic, readwrite) id value;
21
+ @property (nonatomic, readwrite) id<NSCopying> key;
22
+
23
+ - (instancetype)initWithValue:(id)value key:(id<NSCopying>)key;
24
+ @end
25
+
26
+ @implementation LRUCacheNode
27
+
28
+ - (instancetype)initWithValue:(id)value key:(id<NSCopying>)key
29
+ {
30
+ if (nil == value) {
31
+ return nil;
32
+ }
33
+
34
+ if ((self = [super init])) {
35
+ _value = value;
36
+ _key = key;
37
+ }
38
+ return self;
39
+ }
40
+
41
+ + (instancetype)nodeWithValue:(id)value key:(id<NSCopying>)key
42
+ {
43
+ return [[LRUCacheNode alloc] initWithValue:value key:key];
44
+ }
45
+
46
+ - (NSString *)description
47
+ {
48
+ return [NSString stringWithFormat:@"%@ %@", self.value, self.next];
49
+ }
50
+
51
+ - (void)setNext:(LRUCacheNode *)next
52
+ {
53
+ if (_next != next) {
54
+ _next = next;
55
+ next.prev = self;
56
+ }
57
+ }
58
+
59
+ @end
Binary file
Binary file
@@ -19,8 +19,6 @@
19
19
 
20
20
  @interface FBSession (Tests)
21
21
 
22
- @property (nonatomic) NSDictionary<NSString *, FBApplication *> *applications;
23
-
24
22
  @end
25
23
 
26
24
  @interface FBSessionIntegrationTests : FBIntegrationTestCase
@@ -36,7 +34,14 @@ static NSString *const SETTINGS_BUNDLE_ID = @"com.apple.Preferences";
36
34
  {
37
35
  [super setUp];
38
36
  [self launchApplication];
39
- self.session = [FBSession initWithApplication:FBApplication.fb_activeApplication];
37
+ FBApplication *app = [[FBApplication alloc] initWithBundleIdentifier:self.testedApplication.bundleID];
38
+ self.session = [FBSession initWithApplication:app];
39
+ }
40
+
41
+ - (void)tearDown
42
+ {
43
+ [self.session kill];
44
+ [super tearDown];
40
45
  }
41
46
 
42
47
  - (void)testSettingsAppCanBeOpenedInScopeOfTheCurrentSession
@@ -46,28 +51,28 @@ static NSString *const SETTINGS_BUNDLE_ID = @"com.apple.Preferences";
46
51
  shouldWaitForQuiescence:nil
47
52
  arguments:nil
48
53
  environment:nil];
49
- XCTAssertEqualObjects(SETTINGS_BUNDLE_ID, self.session.activeApplication.bundleID);
54
+ FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:SETTINGS_BUNDLE_ID]);
50
55
  XCTAssertEqual([self.session applicationStateWithBundleId:SETTINGS_BUNDLE_ID], 4);
51
56
  [self.session activateApplicationWithBundleId:testedApp.bundleID];
52
- XCTAssertEqualObjects(testedApp.bundleID, self.session.activeApplication.bundleID);
57
+ FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString: testedApp.bundleID]);
53
58
  XCTAssertEqual([self.session applicationStateWithBundleId:testedApp.bundleID], 4);
54
59
  }
55
60
 
56
61
  - (void)testSettingsAppCanBeReopenedInScopeOfTheCurrentSession
57
62
  {
58
- FBApplication *systemApp = FBApplication.fb_systemApplication;
63
+ FBApplication *systemApp = self.springboard;
59
64
  [self.session launchApplicationWithBundleId:SETTINGS_BUNDLE_ID
60
65
  shouldWaitForQuiescence:nil
61
66
  arguments:nil
62
67
  environment:nil];
63
- FBAssertWaitTillBecomesTrue([SETTINGS_BUNDLE_ID isEqualToString:self.session.activeApplication.bundleID]);
68
+ FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:SETTINGS_BUNDLE_ID]);
64
69
  XCTAssertTrue([self.session terminateApplicationWithBundleId:SETTINGS_BUNDLE_ID]);
65
70
  FBAssertWaitTillBecomesTrue([systemApp.bundleID isEqualToString:self.session.activeApplication.bundleID]);
66
71
  [self.session launchApplicationWithBundleId:SETTINGS_BUNDLE_ID
67
72
  shouldWaitForQuiescence:nil
68
73
  arguments:nil
69
74
  environment:nil];
70
- XCTAssertEqualObjects(SETTINGS_BUNDLE_ID, self.session.activeApplication.bundleID);
75
+ FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:SETTINGS_BUNDLE_ID]);
71
76
  }
72
77
 
73
78
  - (void)testMainAppCanBeReactivatedInScopeOfTheCurrentSession
@@ -77,28 +82,27 @@ static NSString *const SETTINGS_BUNDLE_ID = @"com.apple.Preferences";
77
82
  shouldWaitForQuiescence:nil
78
83
  arguments:nil
79
84
  environment:nil];
80
- XCTAssertEqualObjects(SETTINGS_BUNDLE_ID, self.session.activeApplication.bundleID);
85
+ FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:SETTINGS_BUNDLE_ID]);
81
86
  [self.session activateApplicationWithBundleId:testedApp.bundleID];
82
- XCTAssertEqualObjects(testedApp.bundleID, self.session.activeApplication.bundleID);
87
+ FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:testedApp.bundleID]);
83
88
  }
84
89
 
85
90
  - (void)testMainAppCanBeRestartedInScopeOfTheCurrentSession
86
91
  {
87
- FBApplication *systemApp = FBApplication.fb_systemApplication;
88
- FBApplication *testedApp = FBApplication.fb_activeApplication;
89
- XCTAssertTrue([self.session terminateApplicationWithBundleId:testedApp.bundleID]);
90
- XCTAssertEqualObjects(systemApp.bundleID, self.session.activeApplication.bundleID);
92
+ FBApplication *systemApp = self.springboard;
93
+ FBApplication *testedApp = [[FBApplication alloc] initWithBundleIdentifier:self.testedApplication.bundleID];
94
+ [self.session terminateApplicationWithBundleId:testedApp.bundleID];
95
+ FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:systemApp.bundleID]);
91
96
  [self.session launchApplicationWithBundleId:testedApp.bundleID
92
97
  shouldWaitForQuiescence:nil
93
98
  arguments:nil
94
99
  environment:nil];
95
- XCTAssertEqualObjects(testedApp.bundleID, self.session.activeApplication.bundleID);
100
+ FBAssertWaitTillBecomesTrue([self.session.activeApplication.bundleID isEqualToString:testedApp.bundleID]);
96
101
  }
97
102
 
98
103
  - (void)testLaunchUnattachedApp
99
104
  {
100
105
  [FBUnattachedAppLauncher launchAppWithBundleId:SETTINGS_BUNDLE_ID];
101
- XCTAssertNil(self.session.applications[SETTINGS_BUNDLE_ID]);
102
106
  [self.session kill];
103
107
  XCTAssertEqualObjects(SETTINGS_BUNDLE_ID, FBApplication.fb_activeApplication.bundleID);
104
108
  }
@@ -17,6 +17,7 @@
17
17
  #import "FBTestMacros.h"
18
18
  #import "XCUIApplication+FBHelpers.h"
19
19
  #import "XCUIElement+FBIsVisible.h"
20
+ #import "FBXCodeCompatibility.h"
20
21
 
21
22
  @interface XCUIApplicationHelperTests : FBIntegrationTestCase
22
23
  @end
@@ -90,7 +91,7 @@
90
91
 
91
92
  - (void)testTestmanagerdVersion
92
93
  {
93
- XCTAssertGreaterThan([XCUIApplication fb_testmanagerdVersion], 0);
94
+ XCTAssertGreaterThan(FBTestmanagerdVersion(), 0);
94
95
  }
95
96
 
96
97
  @end