appium-webdriveragent 3.15.0 → 3.17.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 (29) hide show
  1. package/PrivateHeaders/XCTest/XCTestManager_ManagerInterface-Protocol.h +4 -2
  2. package/PrivateHeaders/XCTest/XCUIScreen.h +4 -3
  3. package/WebDriverAgent.xcodeproj/project.pbxproj +36 -0
  4. package/WebDriverAgent.xcodeproj/project.xcworkspace/xcuserdata/kazuaki.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  5. package/WebDriverAgent.xcodeproj/xcuserdata/kazuaki.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +1369 -500
  6. package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.h +9 -6
  7. package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +4 -6
  8. package/WebDriverAgentLib/Categories/XCUIApplication+FBUIInterruptions.h +23 -0
  9. package/WebDriverAgentLib/Categories/XCUIApplication+FBUIInterruptions.m +32 -0
  10. package/WebDriverAgentLib/Commands/FBDebugCommands.m +6 -3
  11. package/WebDriverAgentLib/Utilities/FBConfiguration.h +5 -0
  12. package/WebDriverAgentLib/Utilities/FBConfiguration.m +6 -0
  13. package/WebDriverAgentLib/Utilities/FBMjpegServer.m +1 -1
  14. package/WebDriverAgentLib/Utilities/FBReflectionUtils.h +24 -0
  15. package/WebDriverAgentLib/Utilities/FBReflectionUtils.m +32 -0
  16. package/WebDriverAgentLib/Utilities/FBScreenshot.h +1 -1
  17. package/WebDriverAgentLib/Utilities/FBScreenshot.m +3 -3
  18. package/WebDriverAgentLib/Utilities/FBXCAXClientProxy.m +5 -23
  19. package/WebDriverAgentLib/Utilities/FBXMLGenerationOptions.h +46 -0
  20. package/WebDriverAgentLib/Utilities/FBXMLGenerationOptions.m +26 -0
  21. package/WebDriverAgentLib/Utilities/FBXPath.h +4 -3
  22. package/WebDriverAgentLib/Utilities/FBXPath.m +65 -28
  23. package/WebDriverAgentRunner/UITestingUITests.m +1 -0
  24. package/WebDriverAgentRunner-Runner.app.zip +0 -0
  25. package/WebDriverAgentTests/IntegrationTests/FBAlertTests.m +1 -0
  26. package/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m +16 -2
  27. package/WebDriverAgentTests/UnitTests/FBXPathTests.m +28 -15
  28. package/package.json +2 -2
  29. package/WebDriverAgentLib/.DS_Store +0 -0
@@ -11,6 +11,7 @@
11
11
 
12
12
  @class XCElementSnapshot;
13
13
  @class XCAccessibilityElement;
14
+ @class FBXMLGenerationOptions;
14
15
 
15
16
  NS_ASSUME_NONNULL_BEGIN
16
17
 
@@ -45,18 +46,20 @@ NS_ASSUME_NONNULL_BEGIN
45
46
  - (NSDictionary *)fb_accessibilityTree;
46
47
 
47
48
  /**
48
- Return application elements tree in form of xml string
49
+ Return application elements tree in a form of xml string
50
+ with default options.
51
+
52
+ @return nil if there was a failure while retriveing the page source.
49
53
  */
50
54
  - (nullable NSString *)fb_xmlRepresentation;
51
55
 
52
56
  /**
53
- Return application elements tree in form of xml string exluding the given attribute names.
57
+ Return application elements tree in a form of xml string
54
58
 
55
- @param excludedAttributes the list of XML attribute names to be excluded from the resulting document.
56
- Invalid attribute names are silently skipped
57
- @returns The XML representation of the current element as a string
59
+ @param options Optional values that affect the resulting XML generation process.
60
+ @return nil if there was a failure while retriveing the page source.
58
61
  */
59
- - (NSString *)fb_xmlRepresentationWithoutAttributes:(NSArray<NSString *> *)excludedAttributes;
62
+ - (nullable NSString *)fb_xmlRepresentationWithOptions:(nullable FBXMLGenerationOptions *)options;
60
63
 
61
64
  /**
62
65
  Return application elements tree in form of internal XCTest debugDescription string
@@ -20,6 +20,7 @@
20
20
  #import "FBXPath.h"
21
21
  #import "FBXCTestDaemonsProxy.h"
22
22
  #import "FBXCAXClientProxy.h"
23
+ #import "FBXMLGenerationOptions.h"
23
24
  #import "XCAccessibilityElement.h"
24
25
  #import "XCElementSnapshot+FBHelpers.h"
25
26
  #import "XCUIDevice+FBHelpers.h"
@@ -180,15 +181,12 @@ static NSString* const FBUnknownBundleId = @"unknown";
180
181
 
181
182
  - (NSString *)fb_xmlRepresentation
182
183
  {
183
- return [FBXPath xmlStringWithRootElement:self excludingAttributes:nil];
184
+ return [self fb_xmlRepresentationWithOptions:nil];
184
185
  }
185
186
 
186
- - (NSString *)fb_xmlRepresentationWithoutAttributes:(NSArray<NSString *> *)excludedAttributes
187
+ - (NSString *)fb_xmlRepresentationWithOptions:(FBXMLGenerationOptions *)options
187
188
  {
188
- #pragma clang diagnostic push
189
- #pragma clang diagnostic ignored "-Wnullable-to-nonnull-conversion"
190
- return [FBXPath xmlStringWithRootElement:self excludingAttributes:excludedAttributes];
191
- #pragma clang diagnostic pop
189
+ return [FBXPath xmlStringWithRootElement:self options:options];
192
190
  }
193
191
 
194
192
  - (NSString *)fb_descriptionRepresentation
@@ -0,0 +1,23 @@
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 XCUIApplication (FBUIInterruptions)
15
+
16
+ /**
17
+ * Disables automatic UI interruptions handling for all applications.
18
+ */
19
+ + (void)fb_disableUIInterruptionsHandling;
20
+
21
+ @end
22
+
23
+ NS_ASSUME_NONNULL_END
@@ -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 "XCUIApplication+FBUIInterruptions.h"
11
+
12
+ #import "FBReflectionUtils.h"
13
+ #import "XCUIApplication.h"
14
+
15
+ @implementation XCUIApplication (FBUIInterruptions)
16
+
17
+ - (BOOL)fb_doesNotHandleUIInterruptions
18
+ {
19
+ return YES;
20
+ }
21
+
22
+ + (void)fb_disableUIInterruptionsHandling
23
+ {
24
+ static dispatch_once_t onceToken;
25
+ dispatch_once(&onceToken, ^{
26
+ FBReplaceMethod([self class],
27
+ @selector(doesNotHandleUIInterruptions),
28
+ @selector(fb_doesNotHandleUIInterruptions));
29
+ });
30
+ }
31
+
32
+ @end
@@ -12,6 +12,7 @@
12
12
  #import "FBApplication.h"
13
13
  #import "FBRouteRequest.h"
14
14
  #import "FBSession.h"
15
+ #import "FBXMLGenerationOptions.h"
15
16
  #import "XCUIApplication+FBHelpers.h"
16
17
  #import "XCUIElement+FBUtilities.h"
17
18
  #import "FBXPath.h"
@@ -43,14 +44,16 @@ static NSString *const SOURCE_FORMAT_DESCRIPTION = @"description";
43
44
  // This method might be called without session
44
45
  FBApplication *application = request.session.activeApplication ?: FBApplication.fb_activeApplication;
45
46
  NSString *sourceType = request.parameters[@"format"] ?: SOURCE_FORMAT_XML;
47
+ NSString *sourceScope = request.parameters[@"scope"];
46
48
  id result;
47
49
  if ([sourceType caseInsensitiveCompare:SOURCE_FORMAT_XML] == NSOrderedSame) {
48
50
  NSArray<NSString *> *excludedAttributes = nil == request.parameters[@"excluded_attributes"]
49
51
  ? nil
50
52
  : [request.parameters[@"excluded_attributes"] componentsSeparatedByString:@","];
51
- result = nil == excludedAttributes
52
- ? application.fb_xmlRepresentation
53
- : [application fb_xmlRepresentationWithoutAttributes:(NSArray<NSString *> *)excludedAttributes];
53
+ result = [application fb_xmlRepresentationWithOptions:
54
+ [[[FBXMLGenerationOptions new]
55
+ withExcludedAttributes:excludedAttributes]
56
+ withScope:sourceScope]];
54
57
  } else if ([sourceType caseInsensitiveCompare:SOURCE_FORMAT_JSON] == NSOrderedSame) {
55
58
  result = application.fb_tree;
56
59
  } else if ([sourceType caseInsensitiveCompare:SOURCE_FORMAT_DESCRIPTION] == NSOrderedSame) {
@@ -118,6 +118,11 @@ extern NSString *const FBSnapshotMaxDepthKey;
118
118
  */
119
119
  + (BOOL)verboseLoggingEnabled;
120
120
 
121
+ /**
122
+ Disables automatic handling of XCTest UI interruptions.
123
+ */
124
+ + (void)disableApplicationUIInterruptionsHandling;
125
+
121
126
  /**
122
127
  * Configure keyboards preference to make test running stable
123
128
  */
@@ -17,6 +17,7 @@
17
17
  #import "XCTestPrivateSymbols.h"
18
18
  #import "XCElementSnapshot.h"
19
19
  #import "XCTestConfiguration.h"
20
+ #import "XCUIApplication+FBUIInterruptions.h"
20
21
 
21
22
  static NSUInteger const DefaultStartingPort = 8100;
22
23
  static NSUInteger const DefaultMjpegServerPort = 9100;
@@ -74,6 +75,11 @@ static UIInterfaceOrientation FBScreenshotOrientation = UIInterfaceOrientationUn
74
75
  [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"XCTDisableRemoteQueryEvaluation"];
75
76
  }
76
77
 
78
+ + (void)disableApplicationUIInterruptionsHandling
79
+ {
80
+ [XCUIApplication fb_disableUIInterruptionsHandling];
81
+ }
82
+
77
83
  + (void)enableXcTestDebugLogs
78
84
  {
79
85
  ((XCTestConfiguration *)XCTestConfiguration.activeTestConfiguration).emitOSLogs = YES;
@@ -33,7 +33,7 @@ static const char *QUEUE_NAME = "JPEG Screenshots Provider Queue";
33
33
  @property (nonatomic, readonly) NSMutableArray<GCDAsyncSocket *> *listeningClients;
34
34
  @property (nonatomic, readonly) mach_timebase_info_data_t timebaseInfo;
35
35
  @property (nonatomic, readonly) FBImageIOScaler *imageScaler;
36
- @property (nonatomic, readonly) unsigned int mainScreenID;
36
+ @property (nonatomic, readonly) long long mainScreenID;
37
37
 
38
38
  @end
39
39
 
@@ -0,0 +1,24 @@
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
+ /**
15
+ * Swizzles the implemntation of originalSelector with the swizzledSelector for the given class.
16
+ * Both methods must belong to this class.
17
+ *
18
+ * @param cls The class where to swizzle
19
+ * @param originalSelector original method selector
20
+ * @paramswizzledSelector swizzled method selector
21
+ */
22
+ void FBReplaceMethod(Class cls, SEL originalSelector, SEL swizzledSelector);
23
+
24
+ NS_ASSUME_NONNULL_END
@@ -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
+ }
@@ -51,7 +51,7 @@ NS_ASSUME_NONNULL_BEGIN
51
51
  @param error If there is an error, upon return contains an NSError object that describes the problem.
52
52
  @return Device screenshot as PNG- or JPG-encoded data or nil in case of failure
53
53
  */
54
- + (nullable NSData *)takeInOriginalResolutionWithScreenID:(unsigned int)screenID
54
+ + (nullable NSData *)takeInOriginalResolutionWithScreenID:(long long)screenID
55
55
  compressionQuality:(CGFloat)compressionQuality
56
56
  uti:(NSString *)uti
57
57
  timeout:(NSTimeInterval)timeout
@@ -123,7 +123,7 @@ NSString *formatTimeInterval(NSTimeInterval interval) {
123
123
  return screenshotData;
124
124
  }
125
125
 
126
- + (NSData *)takeWithScreenID:(unsigned int)screenID
126
+ + (NSData *)takeWithScreenID:(long long)screenID
127
127
  scale:(CGFloat)scale
128
128
  compressionQuality:(CGFloat)compressionQuality
129
129
  rect:(CGRect)rect
@@ -146,7 +146,7 @@ NSString *formatTimeInterval(NSTimeInterval interval) {
146
146
  error:error];
147
147
  }
148
148
 
149
- + (NSData *)takeInOriginalResolutionWithScreenID:(unsigned int)screenID
149
+ + (NSData *)takeInOriginalResolutionWithScreenID:(long long)screenID
150
150
  compressionQuality:(CGFloat)compressionQuality
151
151
  uti:(NSString *)uti
152
152
  timeout:(NSTimeInterval)timeout
@@ -254,7 +254,7 @@ NSString *formatTimeInterval(NSTimeInterval interval) {
254
254
  return imageEncoding;
255
255
  }
256
256
 
257
- + (nullable id)screenshotRequestWithScreenID:(unsigned int)screenID
257
+ + (nullable id)screenshotRequestWithScreenID:(long long)screenID
258
258
  rect:(struct CGRect)rect
259
259
  uti:(NSString *)uti
260
260
  compressionQuality:(CGFloat)compressionQuality
@@ -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
  }
@@ -13,6 +13,7 @@
13
13
  #import "FBTestMacros.h"
14
14
  #import "FBXPath.h"
15
15
  #import "FBXCodeCompatibility.h"
16
+ #import "FBXMLGenerationOptions.h"
16
17
  #import "XCUIElement.h"
17
18
  #import "XCUIElement+FBFind.h"
18
19
  #import "XCUIElement+FBUtilities.h"
@@ -52,16 +53,29 @@
52
53
  - (void)testSingleDescendantXMLRepresentation
53
54
  {
54
55
  XCElementSnapshot *snapshot = self.destinationSnapshot;
55
- NSString *xmlStr = [FBXPath xmlStringWithRootElement:snapshot excludingAttributes:nil];
56
+ NSString *xmlStr = [FBXPath xmlStringWithRootElement:snapshot options:nil];
56
57
  XCTAssertNotNil(xmlStr);
57
58
  NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\"/>\n", snapshot.wdType, snapshot.wdType, snapshot.wdName, snapshot.wdLabel, snapshot.wdEnabled ? @"true" : @"false", snapshot.wdVisible ? @"true" : @"false", snapshot.wdAccessible ? @"true" : @"false", [snapshot.wdRect[@"x"] stringValue], [snapshot.wdRect[@"y"] stringValue], [snapshot.wdRect[@"width"] stringValue], [snapshot.wdRect[@"height"] stringValue], snapshot.wdIndex];
58
59
  XCTAssertEqualObjects(xmlStr, expectedXml);
59
60
  }
60
61
 
62
+ - (void)testSingleDescendantXMLRepresentationWithScope
63
+ {
64
+ XCElementSnapshot *snapshot = self.destinationSnapshot;
65
+ NSString *scope = @"AppiumAUT";
66
+ FBXMLGenerationOptions *options = [[FBXMLGenerationOptions new] withScope:scope];
67
+ NSString *xmlStr = [FBXPath xmlStringWithRootElement:snapshot options:options];
68
+ XCTAssertNotNil(xmlStr);
69
+ NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@>\n <%@ type=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\"/>\n</%@>\n", scope, snapshot.wdType, snapshot.wdType, snapshot.wdName, snapshot.wdLabel, snapshot.wdEnabled ? @"true" : @"false", snapshot.wdVisible ? @"true" : @"false", snapshot.wdAccessible ? @"true" : @"false", [snapshot.wdRect[@"x"] stringValue], [snapshot.wdRect[@"y"] stringValue], [snapshot.wdRect[@"width"] stringValue], [snapshot.wdRect[@"height"] stringValue], snapshot.wdIndex, scope];
70
+ XCTAssertEqualObjects(xmlStr, expectedXml);
71
+ }
72
+
61
73
  - (void)testSingleDescendantXMLRepresentationWithoutAttributes
62
74
  {
63
75
  XCElementSnapshot *snapshot = self.destinationSnapshot;
64
- NSString *xmlStr = [FBXPath xmlStringWithRootElement:snapshot excludingAttributes:@[@"visible", @"enabled", @"index", @"blabla"]];
76
+ FBXMLGenerationOptions *options = [[FBXMLGenerationOptions new]
77
+ withExcludedAttributes:@[@"visible", @"enabled", @"index", @"blabla"]];
78
+ NSString *xmlStr = [FBXPath xmlStringWithRootElement:snapshot options:options];
65
79
  XCTAssertNotNil(xmlStr);
66
80
  NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" name=\"%@\" label=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\"/>\n", snapshot.wdType, snapshot.wdType, snapshot.wdName, snapshot.wdLabel, snapshot.wdAccessible ? @"true" : @"false", [snapshot.wdRect[@"x"] stringValue], [snapshot.wdRect[@"y"] stringValue], [snapshot.wdRect[@"width"] stringValue], [snapshot.wdRect[@"height"] stringValue]];
67
81
  XCTAssertEqualObjects(xmlStr, expectedXml);