appium-webdriveragent 3.14.0 → 4.0.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 (56) hide show
  1. package/Scripts/build-webdriveragent.js +1 -1
  2. package/Scripts/fetch-prebuilt-wda.js +1 -1
  3. package/WebDriverAgent.xcodeproj/project.pbxproj +38 -2
  4. package/WebDriverAgent.xcodeproj/project.xcworkspace/xcuserdata/elf.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  5. package/WebDriverAgent.xcodeproj/xcuserdata/elf.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +91 -0
  6. package/WebDriverAgent.xcodeproj/xcuserdata/{kazuaki.xcuserdatad → elf.xcuserdatad}/xcschemes/xcschememanagement.plist +12 -35
  7. package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.h +9 -6
  8. package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +4 -6
  9. package/WebDriverAgentLib/Categories/XCUIApplication+FBUIInterruptions.h +23 -0
  10. package/WebDriverAgentLib/Categories/XCUIApplication+FBUIInterruptions.m +32 -0
  11. package/WebDriverAgentLib/Commands/FBAlertViewCommands.m +6 -6
  12. package/WebDriverAgentLib/Commands/FBDebugCommands.m +6 -3
  13. package/WebDriverAgentLib/FBAlert.m +1 -0
  14. package/WebDriverAgentLib/Utilities/FBConfiguration.h +5 -0
  15. package/WebDriverAgentLib/Utilities/FBConfiguration.m +6 -0
  16. package/WebDriverAgentLib/Utilities/FBReflectionUtils.h +24 -0
  17. package/WebDriverAgentLib/Utilities/FBReflectionUtils.m +32 -0
  18. package/WebDriverAgentLib/Utilities/FBScreen.m +3 -1
  19. package/WebDriverAgentLib/Utilities/FBXCAXClientProxy.m +5 -23
  20. package/WebDriverAgentLib/Utilities/FBXMLGenerationOptions.h +46 -0
  21. package/WebDriverAgentLib/Utilities/FBXMLGenerationOptions.m +26 -0
  22. package/WebDriverAgentLib/Utilities/FBXPath.h +4 -3
  23. package/WebDriverAgentLib/Utilities/FBXPath.m +65 -28
  24. package/WebDriverAgentRunner/UITestingUITests.m +1 -0
  25. package/WebDriverAgentRunner-Runner.app.zip +0 -0
  26. package/WebDriverAgentTests/IntegrationTests/FBAlertTests.m +6 -0
  27. package/WebDriverAgentTests/IntegrationTests/FBAppiumMultiTouchActionsIntegrationTests.m +7 -0
  28. package/WebDriverAgentTests/IntegrationTests/FBAppiumTouchActionsIntegrationTests.m +19 -0
  29. package/WebDriverAgentTests/IntegrationTests/FBElementScreenshotTests.m +4 -0
  30. package/WebDriverAgentTests/IntegrationTests/FBElementSwipingTests.m +71 -6
  31. package/WebDriverAgentTests/IntegrationTests/FBElementVisibilityTests.m +3 -1
  32. package/WebDriverAgentTests/IntegrationTests/FBForceTouchTests.m +6 -0
  33. package/WebDriverAgentTests/IntegrationTests/FBIntegrationTestCase.m +2 -1
  34. package/WebDriverAgentTests/IntegrationTests/FBKeyboardTests.m +19 -0
  35. package/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m +15 -0
  36. package/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m +16 -2
  37. package/WebDriverAgentTests/IntegrationTests/XCUIApplicationHelperTests.m +1 -1
  38. package/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m +1 -1
  39. package/WebDriverAgentTests/UnitTests/FBXPathTests.m +28 -15
  40. package/build/lib/check-dependencies.js +3 -3
  41. package/build/lib/logger.js +3 -3
  42. package/build/lib/no-session-proxy.js +3 -3
  43. package/build/lib/utils.js +17 -17
  44. package/build/lib/webdriveragent.js +16 -16
  45. package/build/lib/xcodebuild.js +5 -5
  46. package/lib/check-dependencies.js +1 -1
  47. package/lib/logger.js +1 -1
  48. package/lib/no-session-proxy.js +1 -1
  49. package/lib/utils.js +3 -2
  50. package/lib/webdriveragent.js +2 -2
  51. package/lib/xcodebuild.js +1 -1
  52. package/package.json +10 -11
  53. package/WebDriverAgent.xcodeproj/project.xcworkspace/xcuserdata/kazuaki.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  54. package/WebDriverAgent.xcodeproj/project.xcworkspace/xcuserdata/kazuaki.xcuserdatad/WorkspaceSettings.xcsettings +0 -20
  55. package/WebDriverAgent.xcodeproj/xcuserdata/kazuaki.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +0 -1979
  56. package/WebDriverAgentLib/.DS_Store +0 -0
@@ -0,0 +1,32 @@
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 "FBReflectionUtils.h"
11
+
12
+ #import <objc/runtime.h>
13
+
14
+ void FBReplaceMethod(Class class, SEL originalSelector, SEL swizzledSelector) {
15
+ Method originalMethod = class_getInstanceMethod(class, originalSelector);
16
+ Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
17
+
18
+ BOOL didAddMethod =
19
+ class_addMethod(class,
20
+ originalSelector,
21
+ method_getImplementation(swizzledMethod),
22
+ method_getTypeEncoding(swizzledMethod));
23
+
24
+ if (didAddMethod) {
25
+ class_replaceMethod(class,
26
+ swizzledSelector,
27
+ method_getImplementation(originalMethod),
28
+ method_getTypeEncoding(originalMethod));
29
+ } else {
30
+ method_exchangeImplementations(originalMethod, swizzledMethod);
31
+ }
32
+ }
@@ -35,7 +35,9 @@
35
35
  if (!mainStatusBar || (expectVisibleBar && !mainStatusBar.fb_isVisible)) {
36
36
  return CGSizeZero;
37
37
  }
38
- return mainStatusBar.frame.size;
38
+ CGSize result = mainStatusBar.frame.size;
39
+ // Workaround for https://github.com/appium/appium/issues/15961
40
+ return CGSizeMake(MAX(result.width, result.height), MIN(result.width, result.height));
39
41
  }
40
42
 
41
43
  @end
@@ -13,9 +13,10 @@
13
13
 
14
14
  #import "FBConfiguration.h"
15
15
  #import "FBLogger.h"
16
+ #import "FBMacros.h"
17
+ #import "FBReflectionUtils.h"
16
18
  #import "XCAXClient_iOS.h"
17
19
  #import "XCUIDevice.h"
18
- #import "FBMacros.h"
19
20
 
20
21
  static id FBAXClient = nil;
21
22
 
@@ -35,28 +36,9 @@ static id FBAXClient = nil;
35
36
  {
36
37
  static dispatch_once_t onceToken;
37
38
  dispatch_once(&onceToken, ^{
38
- Class class = [self class];
39
-
40
- SEL originalSelector = @selector(defaultParameters);
41
- SEL swizzledSelector = @selector(fb_getParametersForElementSnapshot);
42
-
43
- Method originalMethod = class_getInstanceMethod(class, originalSelector);
44
- Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
45
-
46
- BOOL didAddMethod =
47
- class_addMethod(class,
48
- originalSelector,
49
- method_getImplementation(swizzledMethod),
50
- method_getTypeEncoding(swizzledMethod));
51
-
52
- if (didAddMethod) {
53
- class_replaceMethod(class,
54
- swizzledSelector,
55
- method_getImplementation(originalMethod),
56
- method_getTypeEncoding(originalMethod));
57
- } else {
58
- method_exchangeImplementations(originalMethod, swizzledMethod);
59
- }
39
+ SEL originalParametersSelector = @selector(defaultParameters);
40
+ SEL swizzledParametersSelector = @selector(fb_getParametersForElementSnapshot);
41
+ FBReplaceMethod([self class], originalParametersSelector, swizzledParametersSelector);
60
42
  });
61
43
  }
62
44
 
@@ -0,0 +1,46 @@
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 <Foundation/Foundation.h>
11
+
12
+ NS_ASSUME_NONNULL_BEGIN
13
+
14
+ @interface FBXMLGenerationOptions : NSObject
15
+
16
+ /**
17
+ XML buidling scope. Passing nil means the XML should be built in the default scope,
18
+ i.e no changes to the original tree structore. If the scope is provided then the resulting
19
+ XML tree will be put under the root, which name is equal to the given scope value.
20
+ */
21
+ @property (nonatomic, nullable) NSString *scope;
22
+ /**
23
+ The list of attribute names to exclude from the resulting document.
24
+ Passing nil means all the available attributes should be included
25
+ */
26
+ @property (nonatomic, nullable) NSArray<NSString *> *excludedAttributes;
27
+
28
+ /**
29
+ Allows to provide XML scope.
30
+
31
+ @param scope See the property description above
32
+ @return self instance for chaining
33
+ */
34
+ - (FBXMLGenerationOptions *)withScope:(nullable NSString *)scope;
35
+
36
+ /**
37
+ Allows to provide a list of excluded XML attributes.
38
+
39
+ @param excludedAttributes See the property description above
40
+ @return self instance for chaining
41
+ */
42
+ - (FBXMLGenerationOptions *)withExcludedAttributes:(nullable NSArray<NSString *> *)excludedAttributes;
43
+
44
+ @end
45
+
46
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,26 @@
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 "FBXMLGenerationOptions.h"
11
+
12
+ @implementation FBXMLGenerationOptions
13
+
14
+ - (FBXMLGenerationOptions *)withScope:(NSString *)scope
15
+ {
16
+ self.scope = scope;
17
+ return self;
18
+ }
19
+
20
+ - (FBXMLGenerationOptions *)withExcludedAttributes:(NSArray<NSString *> *)excludedAttributes
21
+ {
22
+ self.excludedAttributes = excludedAttributes;
23
+ return self;
24
+ }
25
+
26
+ @end
@@ -27,6 +27,8 @@
27
27
  #pragma clang diagnostic pop
28
28
  #endif
29
29
 
30
+ @class FBXMLGenerationOptions;
31
+
30
32
  NS_ASSUME_NONNULL_BEGIN
31
33
 
32
34
  @interface FBXPath : NSObject
@@ -47,12 +49,11 @@ NS_ASSUME_NONNULL_BEGIN
47
49
  representation, which is used for XPath search
48
50
 
49
51
  @param root the root element
50
- @param excludedAttributes the list of attribute names to exclude from the resulting document.
51
- Passing nil means all the available attributes should be included
52
+ @param options Optional values that affect the resulting XML creation process
52
53
  @return valid XML document as string or nil in case of failure
53
54
  */
54
55
  + (nullable NSString *)xmlStringWithRootElement:(id<FBElement>)root
55
- excludingAttributes:(nullable NSArray<NSString *> *)excludedAttributes;
56
+ options:(nullable FBXMLGenerationOptions *)options;
56
57
 
57
58
  @end
58
59
 
@@ -12,6 +12,7 @@
12
12
  #import "FBConfiguration.h"
13
13
  #import "FBExceptions.h"
14
14
  #import "FBLogger.h"
15
+ #import "FBXMLGenerationOptions.h"
15
16
  #import "NSString+FBXMLSafeString.h"
16
17
  #import "XCElementSnapshot+FBHelpers.h"
17
18
  #import "XCUIElement.h"
@@ -117,15 +118,45 @@ static NSString *const topNodeIndexPath = @"top";
117
118
  }
118
119
 
119
120
  + (nullable NSString *)xmlStringWithRootElement:(id<FBElement>)root
120
- excludingAttributes:(nullable NSArray<NSString *> *)excludedAttributes
121
+ options:(nullable FBXMLGenerationOptions *)options
121
122
  {
122
123
  xmlDocPtr doc;
123
124
  xmlTextWriterPtr writer = xmlNewTextWriterDoc(&doc, 0);
124
- int rc = [self xmlRepresentationWithRootElement:root
125
+ int rc = xmlTextWriterStartDocument(writer, NULL, _UTF8Encoding, NULL);
126
+ if (rc < 0) {
127
+ [FBLogger logFmt:@"Failed to invoke libxml2>xmlTextWriterStartDocument. Error code: %d", rc];
128
+ } else {
129
+ BOOL hasScope = nil != options.scope && [options.scope length] > 0;
130
+ if (hasScope) {
131
+ rc = xmlTextWriterStartElement(writer,
132
+ (xmlChar *)[[self safeXmlStringWithString:options.scope] UTF8String]);
133
+ if (rc < 0) {
134
+ [FBLogger logFmt:@"Failed to invoke libxml2>xmlTextWriterStartElement for the tag value '%@'. Error code: %d", options.scope, rc];
135
+ }
136
+ }
137
+
138
+ if (rc >= 0) {
139
+ rc = [self xmlRepresentationWithRootElement:root
125
140
  writer:writer
126
141
  elementStore:nil
127
142
  query:nil
128
- excludingAttributes:excludedAttributes];
143
+ excludingAttributes:options.excludedAttributes];
144
+ }
145
+
146
+ if (rc >= 0 && hasScope) {
147
+ rc = xmlTextWriterEndElement(writer);
148
+ if (rc < 0) {
149
+ [FBLogger logFmt:@"Failed to invoke libxml2>xmlTextWriterEndElement. Error code: %d", rc];
150
+ }
151
+ }
152
+
153
+ if (rc >= 0) {
154
+ rc = xmlTextWriterEndDocument(writer);
155
+ if (rc < 0) {
156
+ [FBLogger logFmt:@"Failed to invoke libxml2>xmlXPathNewContext. Error code: %d", rc];
157
+ }
158
+ }
159
+ }
129
160
  if (rc < 0) {
130
161
  xmlFreeTextWriter(writer);
131
162
  xmlFreeDoc(doc);
@@ -141,7 +172,8 @@ static NSString *const topNodeIndexPath = @"top";
141
172
  return result;
142
173
  }
143
174
 
144
- + (NSArray<XCElementSnapshot *> *)matchesWithRootElement:(id<FBElement>)root forQuery:(NSString *)xpathQuery
175
+ + (NSArray<XCElementSnapshot *> *)matchesWithRootElement:(id<FBElement>)root
176
+ forQuery:(NSString *)xpathQuery
145
177
  {
146
178
  xmlDocPtr doc;
147
179
 
@@ -151,11 +183,22 @@ static NSString *const topNodeIndexPath = @"top";
151
183
  return [self throwException:FBXPathQueryEvaluationException forQuery:xpathQuery];
152
184
  }
153
185
  NSMutableDictionary *elementStore = [NSMutableDictionary dictionary];
154
- int rc = [self xmlRepresentationWithRootElement:root
155
- writer:writer
156
- elementStore:elementStore
157
- query:xpathQuery
158
- excludingAttributes:nil];
186
+ int rc = xmlTextWriterStartDocument(writer, NULL, _UTF8Encoding, NULL);
187
+ if (rc < 0) {
188
+ [FBLogger logFmt:@"Failed to invoke libxml2>xmlTextWriterStartDocument. Error code: %d", rc];
189
+ } else {
190
+ rc = [self xmlRepresentationWithRootElement:root
191
+ writer:writer
192
+ elementStore:elementStore
193
+ query:xpathQuery
194
+ excludingAttributes:nil];
195
+ if (rc >= 0) {
196
+ rc = xmlTextWriterEndDocument(writer);
197
+ if (rc < 0) {
198
+ [FBLogger logFmt:@"Failed to invoke libxml2>xmlTextWriterEndDocument. Error code: %d", rc];
199
+ }
200
+ }
201
+ }
159
202
  if (rc < 0) {
160
203
  xmlFreeTextWriter(writer);
161
204
  xmlFreeDoc(doc);
@@ -169,7 +212,8 @@ static NSString *const topNodeIndexPath = @"top";
169
212
  return [self throwException:FBInvalidXPathException forQuery:xpathQuery];
170
213
  }
171
214
 
172
- NSArray *matchingSnapshots = [self collectMatchingSnapshots:queryResult->nodesetval elementStore:elementStore];
215
+ NSArray *matchingSnapshots = [self collectMatchingSnapshots:queryResult->nodesetval
216
+ elementStore:elementStore];
173
217
  xmlXPathFreeObject(queryResult);
174
218
  xmlFreeTextWriter(writer);
175
219
  xmlFreeDoc(doc);
@@ -179,7 +223,8 @@ static NSString *const topNodeIndexPath = @"top";
179
223
  return matchingSnapshots;
180
224
  }
181
225
 
182
- + (NSArray *)collectMatchingSnapshots:(xmlNodeSetPtr)nodeSet elementStore:(NSMutableDictionary *)elementStore
226
+ + (NSArray *)collectMatchingSnapshots:(xmlNodeSetPtr)nodeSet
227
+ elementStore:(NSMutableDictionary *)elementStore
183
228
  {
184
229
  if (xmlXPathNodeSetIsEmpty(nodeSet)) {
185
230
  return @[];
@@ -243,26 +288,15 @@ static NSString *const topNodeIndexPath = @"top";
243
288
  }
244
289
  [FBLogger logFmt:@"The following attributes were requested to be included into the XML: %@", includedAttributes];
245
290
 
246
- int rc = xmlTextWriterStartDocument(writer, NULL, _UTF8Encoding, NULL);
247
- if (rc < 0) {
248
- [FBLogger logFmt:@"Failed to invoke libxml2>xmlTextWriterStartDocument. Error code: %d", rc];
249
- return rc;
250
- }
251
-
252
- rc = [self writeXmlWithRootElement:root
253
- indexPath:(elementStore != nil ? topNodeIndexPath : nil)
254
- elementStore:elementStore
255
- includedAttributes:includedAttributes.copy
256
- writer:writer];
291
+ int rc = [self writeXmlWithRootElement:root
292
+ indexPath:(elementStore != nil ? topNodeIndexPath : nil)
293
+ elementStore:elementStore
294
+ includedAttributes:includedAttributes.copy
295
+ writer:writer];
257
296
  if (rc < 0) {
258
297
  [FBLogger log:@"Failed to generate XML presentation of a screen element"];
259
298
  return rc;
260
299
  }
261
- rc = xmlTextWriterEndDocument(writer);
262
- if (rc < 0) {
263
- [FBLogger logFmt:@"Failed to invoke libxml2>xmlXPathNewContext. Error code: %d", rc];
264
- return rc;
265
- }
266
300
  return 0;
267
301
  }
268
302
 
@@ -290,7 +324,10 @@ static NSString *const topNodeIndexPath = @"top";
290
324
  return [str fb_xmlSafeStringWithReplacement:@""];
291
325
  }
292
326
 
293
- + (int)recordElementAttributes:(xmlTextWriterPtr)writer forElement:(XCElementSnapshot *)element indexPath:(nullable NSString *)indexPath includedAttributes:(nullable NSSet<Class> *)includedAttributes
327
+ + (int)recordElementAttributes:(xmlTextWriterPtr)writer
328
+ forElement:(XCElementSnapshot *)element
329
+ indexPath:(nullable NSString *)indexPath
330
+ includedAttributes:(nullable NSSet<Class> *)includedAttributes
294
331
  {
295
332
  for (Class attributeCls in FBElementAttribute.supportedAttributes) {
296
333
  // include all supported attributes by default unless enumerated explicitly
@@ -25,6 +25,7 @@
25
25
  [FBDebugLogDelegateDecorator decorateXCTestLogger];
26
26
  [FBConfiguration disableRemoteQueryEvaluation];
27
27
  [FBConfiguration configureDefaultKeyboardPreferences];
28
+ [FBConfiguration disableApplicationUIInterruptionsHandling];
28
29
  if (NSProcessInfo.processInfo.environment[@"ENABLE_AUTOMATIC_SCREENSHOTS"]) {
29
30
  [FBConfiguration enableScreenshots];
30
31
  } else {
Binary file
@@ -29,6 +29,7 @@
29
29
  dispatch_once(&onceToken, ^{
30
30
  [self launchApplication];
31
31
  [self goToAlertsPage];
32
+ [FBConfiguration disableApplicationUIInterruptionsHandling];
32
33
  });
33
34
  [self clearAlert];
34
35
  }
@@ -163,6 +164,11 @@
163
164
  FBAssertWaitTillBecomesTrue(alert.isPresent);
164
165
 
165
166
  XCTAssertTrue([alert.text containsString:@"Would Like to Access Your Photos"]);
167
+ // iOS 15 has different UI flow
168
+ if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
169
+ [[FBAlert alertWithApplication:self.testedApplication] dismissWithError:nil];
170
+ [self.testedApplication.buttons[@"Cancel"] tap];
171
+ }
166
172
  }
167
173
 
168
174
  - (void)testGPSAccessAlert
@@ -11,6 +11,7 @@
11
11
 
12
12
  #import "FBIntegrationTestCase.h"
13
13
 
14
+ #import "FBMacros.h"
14
15
  #import "XCUIElement.h"
15
16
  #import "XCUIApplication+FBTouchAction.h"
16
17
  #import "FBTestMacros.h"
@@ -132,6 +133,12 @@
132
133
 
133
134
  - (void)testMultiTouchWithMultiTaps
134
135
  {
136
+ if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
137
+ // Does not work on iOS 15.
138
+ // It tapped two times, but one was touch count was one. Not two finguer taps.
139
+ return;
140
+ }
141
+
135
142
  XCUIElement *touchableView = self.testedApplication.otherElements[@"touchableView"];
136
143
  XCTAssertNotNil(touchableView);
137
144
  NSArray<NSArray<NSDictionary<NSString *, id> *>*> *gesture =
@@ -194,6 +194,14 @@
194
194
 
195
195
  - (void)testDoubleTap
196
196
  {
197
+ if ([UIDevice.currentDevice userInterfaceIdiom] == UIUserInterfaceIdiomPad &&
198
+ SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
199
+ // "tap the element" does not work on iPadOS simulator after change the rotation in iOS 15
200
+ // while selecting the element worked. (I confirmed with getting an element screenshot that
201
+ // the FBShowAlertButtonName was actually selected after changing the orientation.)
202
+ return;
203
+ }
204
+
197
205
  NSArray<NSDictionary<NSString *, id> *> *gesture =
198
206
  @[@{
199
207
  @"action": @"tap",
@@ -208,6 +216,13 @@
208
216
 
209
217
  - (void)testPress
210
218
  {
219
+ if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
220
+ // Does not work on iOS 15.0.
221
+ // The same action tap the FBShowAlertButtonName after rotating the screen
222
+ // worked with W3C actions. `.click` action did not work.
223
+ return;
224
+ }
225
+
211
226
  NSArray<NSDictionary<NSString *, id> *> *gesture =
212
227
  @[@{
213
228
  @"action": @"press",
@@ -271,6 +286,10 @@
271
286
 
272
287
  - (void)testForcePress
273
288
  {
289
+ if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
290
+ // Does not work on iOS 15.
291
+ return;
292
+ }
274
293
  NSArray<NSDictionary<NSString *, id> *> *gesture =
275
294
  @[@{
276
295
  @"action": @"press",
@@ -51,6 +51,10 @@
51
51
  XCTAssertTrue(image.size.width > image.size.height);
52
52
 
53
53
  XCUIScreen *mainScreen = XCUIScreen.mainScreen;
54
+ // Note about iPadOS 15.0 environment.
55
+ // The 'button.screenshot.image' (by XCTest) had a white image while 'image' had
56
+ // expected FBShowAlertButtonName area image by WebDriverAgent.
57
+ // It seems the native XCTest element screenshot has an issue on iPadOS.
54
58
  UIImage *buttonScreenshot = button.screenshot.image;
55
59
  XCTAssertEqualWithAccuracy(buttonScreenshot.size.height * mainScreen.scale,
56
60
  image.size.height,
@@ -17,19 +17,38 @@
17
17
 
18
18
  @interface FBElementSwipingTests : FBIntegrationTestCase
19
19
  @property (nonatomic, strong) XCUIElement *scrollView;
20
+ - (void)openScrollView;
20
21
  @end
21
22
 
22
23
  @implementation FBElementSwipingTests
23
24
 
25
+ - (void)openScrollView
26
+ {
27
+ [self launchApplication];
28
+ [self goToScrollPageWithCells:YES];
29
+ self.scrollView = [[self.testedApplication.query descendantsMatchingType:XCUIElementTypeAny] matchingIdentifier:@"scrollView"].element;
30
+ }
31
+
24
32
  - (void)setUp
25
33
  {
26
34
  [super setUp];
27
- static dispatch_once_t onceToken;
28
- dispatch_once(&onceToken, ^{
29
- [self launchApplication];
30
- [self goToScrollPageWithCells:YES];
31
- self.scrollView = [[self.testedApplication.query descendantsMatchingType:XCUIElementTypeAny] matchingIdentifier:@"scrollView"].element;
32
- });
35
+ if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
36
+ [self openScrollView];
37
+ } else {
38
+ static dispatch_once_t onceToken;
39
+ dispatch_once(&onceToken, ^{
40
+ [self openScrollView];
41
+ });
42
+ }
43
+ }
44
+
45
+ - (void)tearDown
46
+ {
47
+ if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
48
+ // Move to top page once to reset the scroll place
49
+ // since iOS 15 seems cannot handle cell visibility well when the view keps the view
50
+ [self.testedApplication terminate];
51
+ }
33
52
  }
34
53
 
35
54
  - (void)testSwipeUp
@@ -55,3 +74,49 @@
55
74
  }
56
75
 
57
76
  @end
77
+
78
+ @interface FBElementSwipingApplicationTests : FBIntegrationTestCase
79
+ @property (nonatomic, strong) XCUIElement *scrollView;
80
+ - (void)openScrollView;
81
+ @end
82
+
83
+ @implementation FBElementSwipingApplicationTests
84
+
85
+ - (void)openScrollView
86
+ {
87
+ [self launchApplication];
88
+ [self goToScrollPageWithCells:YES];
89
+ }
90
+
91
+ - (void)setUp
92
+ {
93
+ [super setUp];
94
+ static dispatch_once_t onceToken;
95
+ dispatch_once(&onceToken, ^{
96
+ [self openScrollView];
97
+ });
98
+ }
99
+
100
+ - (void)testSwipeUp
101
+ {
102
+ [self.testedApplication fb_swipeWithDirection:@"up" velocity:nil];
103
+ FBAssertInvisibleCell(@"0");
104
+ }
105
+
106
+ - (void)testSwipeDown
107
+ {
108
+ [self.testedApplication fb_swipeWithDirection:@"up" velocity:nil];
109
+ FBAssertInvisibleCell(@"0");
110
+ [self.testedApplication fb_swipeWithDirection:@"down" velocity:nil];
111
+ FBAssertVisibleCell(@"0");
112
+ }
113
+
114
+ - (void)testSwipeDownWithVelocity
115
+ {
116
+ [self.testedApplication fb_swipeWithDirection:@"up" velocity:@2500];
117
+ FBAssertInvisibleCell(@"0");
118
+ [self.testedApplication fb_swipeWithDirection:@"down" velocity:@2500];
119
+ FBAssertVisibleCell(@"0");
120
+ }
121
+
122
+ @end
@@ -30,7 +30,9 @@
30
30
  [self goToSpringBoardFirstPage];
31
31
 
32
32
  // Check Icons on first screen
33
- XCTAssertTrue(self.springboard.icons[@"Calendar"].fb_isVisible);
33
+ // Note: Calender app exits 2 (an app icon + a widget) exist on the home screen
34
+ // on iOS 15+. The firstMatch is for it.
35
+ XCTAssertTrue(self.springboard.icons[@"Calendar"].firstMatch.fb_isVisible);
34
36
  XCTAssertTrue(self.springboard.icons[@"Reminders"].fb_isVisible);
35
37
 
36
38
  // Check Icons on second screen screen
@@ -11,6 +11,7 @@
11
11
 
12
12
  #import "FBIntegrationTestCase.h"
13
13
 
14
+ #import "FBMacros.h"
14
15
  #import "FBElementCache.h"
15
16
  #import "FBTestMacros.h"
16
17
  #import "XCUIDevice+FBRotation.h"
@@ -53,6 +54,11 @@
53
54
 
54
55
  - (void)testForceTap
55
56
  {
57
+ if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
58
+ // Does not work on iOS 15.
59
+ return;
60
+ }
61
+
56
62
  [self verifyForceTapWithOrientation:UIDeviceOrientationPortrait];
57
63
  }
58
64
 
@@ -43,6 +43,7 @@ NSString *const FBTapsCountLabelIdentifier = @"numberOfTapsLabel";
43
43
  [FBConfiguration disableRemoteQueryEvaluation];
44
44
  [FBConfiguration disableAttributeKeyPathAnalysis];
45
45
  [FBConfiguration configureDefaultKeyboardPreferences];
46
+ [FBConfiguration disableApplicationUIInterruptionsHandling];
46
47
  [FBConfiguration disableScreenshots];
47
48
  self.continueAfterFailure = NO;
48
49
  self.springboard = FBApplication.fb_systemApplication;
@@ -93,7 +94,7 @@ NSString *const FBTapsCountLabelIdentifier = @"numberOfTapsLabel";
93
94
  FBAssertWaitTillBecomesTrue(FBApplication.fb_systemApplication.icons[@"Safari"].exists);
94
95
  [[XCUIDevice sharedDevice] pressButton:XCUIDeviceButtonHome];
95
96
  [self.testedApplication fb_waitUntilStable];
96
- FBAssertWaitTillBecomesTrue(FBApplication.fb_systemApplication.icons[@"Calendar"].fb_isVisible);
97
+ FBAssertWaitTillBecomesTrue(FBApplication.fb_systemApplication.icons[@"Calendar"].firstMatch.fb_isVisible);
97
98
  }
98
99
 
99
100
  - (void)goToSpringBoardExtras
@@ -9,6 +9,7 @@
9
9
 
10
10
  #import <XCTest/XCTest.h>
11
11
 
12
+ #import "FBMacros.h"
12
13
  #import "FBIntegrationTestCase.h"
13
14
  #import "FBKeyboard.h"
14
15
  #import "FBRunLoopSpinner.h"
@@ -31,6 +32,15 @@
31
32
  NSString *text = @"Happy typing";
32
33
  XCUIElement *textField = self.testedApplication.textFields[@"aIdentifier"];
33
34
  [textField tap];
35
+
36
+ if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
37
+ // A workaround until find out to clear tutorial on iOS 15
38
+ XCUIElement *textField = self.testedApplication.staticTexts[@"Continue"];
39
+ if (textField.hittable) {
40
+ [textField tap];
41
+ }
42
+ }
43
+
34
44
  NSError *error;
35
45
  XCTAssertTrue([FBKeyboard waitUntilVisibleForApplication:self.testedApplication timeout:1 error:&error]);
36
46
  XCTAssertNil(error);
@@ -43,6 +53,15 @@
43
53
  {
44
54
  XCUIElement *textField = self.testedApplication.textFields[@"aIdentifier"];
45
55
  [textField tap];
56
+
57
+ if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
58
+ // A workaround until find out to clear tutorial on iOS 15
59
+ XCUIElement *textField = self.testedApplication.staticTexts[@"Continue"];
60
+ if (textField.hittable) {
61
+ [textField tap];
62
+ }
63
+ }
64
+
46
65
  NSError *error;
47
66
  XCTAssertTrue([FBKeyboard waitUntilVisibleForApplication:self.testedApplication timeout:1 error:&error]);
48
67
  XCTAssertNil(error);
@@ -295,6 +295,14 @@
295
295
 
296
296
  - (void)testDoubleTap
297
297
  {
298
+ if ([UIDevice.currentDevice userInterfaceIdiom] == UIUserInterfaceIdiomPad &&
299
+ SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
300
+ // "tap the element" does not work on iPadOS simulator after change the rotation in iOS 15
301
+ // while selecting the element worked. (I confirmed with getting an element screenshot that
302
+ // the FBShowAlertButtonName was actually selected after changing the orientation.)
303
+ return;
304
+ }
305
+
298
306
  NSArray<NSDictionary<NSString *, id> *> *gesture =
299
307
  @[@{
300
308
  @"type": @"pointer",
@@ -317,6 +325,13 @@
317
325
 
318
326
  - (void)testLongPressWithCombinedPause
319
327
  {
328
+ if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"15.0")) {
329
+ // Xcode 13 x iOS 14 also does not work while Xcode 12.5 x iOS 14 worked.
330
+ // Skip this test for iOS 15 since iOS 15 works with Xcode 13 at least.
331
+ return;
332
+ }
333
+
334
+
320
335
  NSArray<NSDictionary<NSString *, id> *> *gesture =
321
336
  @[@{
322
337
  @"type": @"pointer",