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.
- package/Scripts/build-webdriveragent.js +1 -1
- package/Scripts/fetch-prebuilt-wda.js +1 -1
- package/WebDriverAgent.xcodeproj/project.pbxproj +38 -2
- package/WebDriverAgent.xcodeproj/project.xcworkspace/xcuserdata/elf.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/WebDriverAgent.xcodeproj/xcuserdata/elf.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +91 -0
- package/WebDriverAgent.xcodeproj/xcuserdata/{kazuaki.xcuserdatad → elf.xcuserdatad}/xcschemes/xcschememanagement.plist +12 -35
- package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.h +9 -6
- package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +4 -6
- package/WebDriverAgentLib/Categories/XCUIApplication+FBUIInterruptions.h +23 -0
- package/WebDriverAgentLib/Categories/XCUIApplication+FBUIInterruptions.m +32 -0
- package/WebDriverAgentLib/Commands/FBAlertViewCommands.m +6 -6
- package/WebDriverAgentLib/Commands/FBDebugCommands.m +6 -3
- package/WebDriverAgentLib/FBAlert.m +1 -0
- package/WebDriverAgentLib/Utilities/FBConfiguration.h +5 -0
- package/WebDriverAgentLib/Utilities/FBConfiguration.m +6 -0
- package/WebDriverAgentLib/Utilities/FBReflectionUtils.h +24 -0
- package/WebDriverAgentLib/Utilities/FBReflectionUtils.m +32 -0
- package/WebDriverAgentLib/Utilities/FBScreen.m +3 -1
- package/WebDriverAgentLib/Utilities/FBXCAXClientProxy.m +5 -23
- package/WebDriverAgentLib/Utilities/FBXMLGenerationOptions.h +46 -0
- package/WebDriverAgentLib/Utilities/FBXMLGenerationOptions.m +26 -0
- package/WebDriverAgentLib/Utilities/FBXPath.h +4 -3
- package/WebDriverAgentLib/Utilities/FBXPath.m +65 -28
- package/WebDriverAgentRunner/UITestingUITests.m +1 -0
- package/WebDriverAgentRunner-Runner.app.zip +0 -0
- package/WebDriverAgentTests/IntegrationTests/FBAlertTests.m +6 -0
- package/WebDriverAgentTests/IntegrationTests/FBAppiumMultiTouchActionsIntegrationTests.m +7 -0
- package/WebDriverAgentTests/IntegrationTests/FBAppiumTouchActionsIntegrationTests.m +19 -0
- package/WebDriverAgentTests/IntegrationTests/FBElementScreenshotTests.m +4 -0
- package/WebDriverAgentTests/IntegrationTests/FBElementSwipingTests.m +71 -6
- package/WebDriverAgentTests/IntegrationTests/FBElementVisibilityTests.m +3 -1
- package/WebDriverAgentTests/IntegrationTests/FBForceTouchTests.m +6 -0
- package/WebDriverAgentTests/IntegrationTests/FBIntegrationTestCase.m +2 -1
- package/WebDriverAgentTests/IntegrationTests/FBKeyboardTests.m +19 -0
- package/WebDriverAgentTests/IntegrationTests/FBW3CTouchActionsIntegrationTests.m +15 -0
- package/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m +16 -2
- package/WebDriverAgentTests/IntegrationTests/XCUIApplicationHelperTests.m +1 -1
- package/WebDriverAgentTests/IntegrationTests/XCUIElementFBFindTests.m +1 -1
- package/WebDriverAgentTests/UnitTests/FBXPathTests.m +28 -15
- package/build/lib/check-dependencies.js +3 -3
- package/build/lib/logger.js +3 -3
- package/build/lib/no-session-proxy.js +3 -3
- package/build/lib/utils.js +17 -17
- package/build/lib/webdriveragent.js +16 -16
- package/build/lib/xcodebuild.js +5 -5
- package/lib/check-dependencies.js +1 -1
- package/lib/logger.js +1 -1
- package/lib/no-session-proxy.js +1 -1
- package/lib/utils.js +3 -2
- package/lib/webdriveragent.js +2 -2
- package/lib/xcodebuild.js +1 -1
- package/package.json +10 -11
- package/WebDriverAgent.xcodeproj/project.xcworkspace/xcuserdata/kazuaki.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/WebDriverAgent.xcodeproj/project.xcworkspace/xcuserdata/kazuaki.xcuserdatad/WorkspaceSettings.xcsettings +0 -20
- package/WebDriverAgent.xcodeproj/xcuserdata/kazuaki.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +0 -1979
- 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
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
121
|
+
options:(nullable FBXMLGenerationOptions *)options
|
|
121
122
|
{
|
|
122
123
|
xmlDocPtr doc;
|
|
123
124
|
xmlTextWriterPtr writer = xmlNewTextWriterDoc(&doc, 0);
|
|
124
|
-
int rc =
|
|
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
|
|
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 =
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
|
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
|
|
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 =
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
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",
|