appium-webdriveragent 3.15.1 → 3.16.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/WebDriverAgent.xcodeproj/project.pbxproj +12 -0
- package/WebDriverAgent.xcodeproj/project.xcworkspace/xcuserdata/elf.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.h +9 -6
- package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +4 -6
- package/WebDriverAgentLib/Commands/FBDebugCommands.m +6 -3
- 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-Runner.app.zip +0 -0
- package/WebDriverAgentTests/IntegrationTests/FBXPathIntegrationTests.m +16 -2
- package/WebDriverAgentTests/UnitTests/FBXPathTests.m +28 -15
- package/package.json +2 -2
|
@@ -347,6 +347,10 @@
|
|
|
347
347
|
71414EDA2670A1EE003A8C5D /* LRUCacheNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 71414ED32670A1ED003A8C5D /* LRUCacheNode.m */; };
|
|
348
348
|
71414EDB2670A1EE003A8C5D /* LRUCacheNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 71414ED32670A1ED003A8C5D /* LRUCacheNode.m */; };
|
|
349
349
|
714801D11FA9D9FA00DC5997 /* FBSDKVersionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 714801D01FA9D9FA00DC5997 /* FBSDKVersionTests.m */; };
|
|
350
|
+
714D88CC2733FB970074A925 /* FBXMLGenerationOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 714D88CA2733FB970074A925 /* FBXMLGenerationOptions.h */; };
|
|
351
|
+
714D88CD2733FB970074A925 /* FBXMLGenerationOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 714D88CA2733FB970074A925 /* FBXMLGenerationOptions.h */; };
|
|
352
|
+
714D88CE2733FB970074A925 /* FBXMLGenerationOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 714D88CB2733FB970074A925 /* FBXMLGenerationOptions.m */; };
|
|
353
|
+
714D88CF2733FB970074A925 /* FBXMLGenerationOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 714D88CB2733FB970074A925 /* FBXMLGenerationOptions.m */; };
|
|
350
354
|
714EAA0D2673FDFE005C5B47 /* FBCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 714EAA0B2673FDFE005C5B47 /* FBCapabilities.h */; };
|
|
351
355
|
714EAA0E2673FDFE005C5B47 /* FBCapabilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 714EAA0B2673FDFE005C5B47 /* FBCapabilities.h */; };
|
|
352
356
|
714EAA0F2673FDFE005C5B47 /* FBCapabilities.m in Sources */ = {isa = PBXBuildFile; fileRef = 714EAA0C2673FDFE005C5B47 /* FBCapabilities.m */; };
|
|
@@ -974,6 +978,8 @@
|
|
|
974
978
|
71414ED32670A1ED003A8C5D /* LRUCacheNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LRUCacheNode.m; sourceTree = "<group>"; };
|
|
975
979
|
714801D01FA9D9FA00DC5997 /* FBSDKVersionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSDKVersionTests.m; sourceTree = "<group>"; };
|
|
976
980
|
714CA3C61DC23186000F12C9 /* FBXPathIntegrationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBXPathIntegrationTests.m; sourceTree = "<group>"; };
|
|
981
|
+
714D88CA2733FB970074A925 /* FBXMLGenerationOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBXMLGenerationOptions.h; sourceTree = "<group>"; };
|
|
982
|
+
714D88CB2733FB970074A925 /* FBXMLGenerationOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBXMLGenerationOptions.m; sourceTree = "<group>"; };
|
|
977
983
|
714EAA0B2673FDFE005C5B47 /* FBCapabilities.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBCapabilities.h; sourceTree = "<group>"; };
|
|
978
984
|
714EAA0C2673FDFE005C5B47 /* FBCapabilities.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBCapabilities.m; sourceTree = "<group>"; };
|
|
979
985
|
7150348521A6DAD600A0F4BA /* FBImageUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBImageUtils.h; sourceTree = "<group>"; };
|
|
@@ -1942,6 +1948,8 @@
|
|
|
1942
1948
|
EE7E271B1D06C69F001BEC7B /* FBXCTestCaseImplementationFailureHoldingProxy.m */,
|
|
1943
1949
|
EE35AD791E3B80C000A02D78 /* FBXCTestDaemonsProxy.h */,
|
|
1944
1950
|
EE35AD7A1E3B80C000A02D78 /* FBXCTestDaemonsProxy.m */,
|
|
1951
|
+
714D88CA2733FB970074A925 /* FBXMLGenerationOptions.h */,
|
|
1952
|
+
714D88CB2733FB970074A925 /* FBXMLGenerationOptions.m */,
|
|
1945
1953
|
712A0C861DA3E55D007D02E5 /* FBXPath-Private.h */,
|
|
1946
1954
|
711084421DA3AA7500F913D6 /* FBXPath.h */,
|
|
1947
1955
|
711084431DA3AA7500F913D6 /* FBXPath.m */,
|
|
@@ -2277,6 +2285,7 @@
|
|
|
2277
2285
|
641EE63E2240C5CA00173FCB /* _XCTestImplementation.h in Headers */,
|
|
2278
2286
|
641EE63F2240C5CA00173FCB /* FBTouchActionCommands.h in Headers */,
|
|
2279
2287
|
641EE6402240C5CA00173FCB /* FBTouchIDCommands.h in Headers */,
|
|
2288
|
+
714D88CD2733FB970074A925 /* FBXMLGenerationOptions.h in Headers */,
|
|
2280
2289
|
641EE6412240C5CA00173FCB /* XCUIApplication.h in Headers */,
|
|
2281
2290
|
641EE6422240C5CA00173FCB /* FBCustomCommands.h in Headers */,
|
|
2282
2291
|
641EE6432240C5CA00173FCB /* _XCTestCaseInterruptionException.h in Headers */,
|
|
@@ -2665,6 +2674,7 @@
|
|
|
2665
2674
|
EE35AD261E3B77D600A02D78 /* XCApplicationMonitor_iOS.h in Headers */,
|
|
2666
2675
|
EE3A18661CDE734B00DE4205 /* FBKeyboard.h in Headers */,
|
|
2667
2676
|
AD6C269C1CF2494200F8B5FF /* XCUIApplication+FBHelpers.h in Headers */,
|
|
2677
|
+
714D88CC2733FB970074A925 /* FBXMLGenerationOptions.h in Headers */,
|
|
2668
2678
|
EE35AD101E3B77D600A02D78 /* _XCTestObservationCenterImplementation.h in Headers */,
|
|
2669
2679
|
AD6C26981CF2481700F8B5FF /* XCUIDevice+FBHelpers.h in Headers */,
|
|
2670
2680
|
71A7EAF91E224648001DA4F2 /* FBClassChainQueryParser.h in Headers */,
|
|
@@ -3102,6 +3112,7 @@
|
|
|
3102
3112
|
641EE5DC2240C5CA00173FCB /* XCUIApplication+FBAlert.m in Sources */,
|
|
3103
3113
|
641EE5DD2240C5CA00173FCB /* FBAppiumActionsSynthesizer.m in Sources */,
|
|
3104
3114
|
641EE70F2240CE4800173FCB /* FBTVNavigationTracker.m in Sources */,
|
|
3115
|
+
714D88CF2733FB970074A925 /* FBXMLGenerationOptions.m in Sources */,
|
|
3105
3116
|
641EE5DE2240C5CA00173FCB /* XCUIApplication+FBTouchAction.m in Sources */,
|
|
3106
3117
|
641EE5DF2240C5CA00173FCB /* FBWebServer.m in Sources */,
|
|
3107
3118
|
641EE5E02240C5CA00173FCB /* FBTCPSocket.m in Sources */,
|
|
@@ -3253,6 +3264,7 @@
|
|
|
3253
3264
|
EE7E271F1D06C69F001BEC7B /* FBXCTestCaseImplementationFailureHoldingProxy.m in Sources */,
|
|
3254
3265
|
7155D704211DCEF400166C20 /* FBMjpegServer.m in Sources */,
|
|
3255
3266
|
EEDFE1221D9C06F800E6FFE5 /* XCUIDevice+FBHealthCheck.m in Sources */,
|
|
3267
|
+
714D88CE2733FB970074A925 /* FBXMLGenerationOptions.m in Sources */,
|
|
3256
3268
|
E444DCB424913C220060D7EB /* RoutingHTTPServer.m in Sources */,
|
|
3257
3269
|
7140974E1FAE20EE008FB2C5 /* FBBaseActionsSynthesizer.m in Sources */,
|
|
3258
3270
|
EEE3764A1D59FAE900ED88DD /* XCUIElement+FBWebDriverAttributes.m in Sources */,
|
|
Binary file
|
|
@@ -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
|
|
57
|
+
Return application elements tree in a form of xml string
|
|
54
58
|
|
|
55
|
-
@param
|
|
56
|
-
|
|
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 *)
|
|
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 [
|
|
184
|
+
return [self fb_xmlRepresentationWithOptions:nil];
|
|
184
185
|
}
|
|
185
186
|
|
|
186
|
-
- (NSString *)
|
|
187
|
+
- (NSString *)fb_xmlRepresentationWithOptions:(FBXMLGenerationOptions *)options
|
|
187
188
|
{
|
|
188
|
-
|
|
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
|
|
@@ -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 =
|
|
52
|
-
|
|
53
|
-
|
|
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) {
|
|
@@ -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
|
|
Binary file
|
|
@@ -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
|
|
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
|
-
|
|
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);
|
|
@@ -28,18 +28,24 @@
|
|
|
28
28
|
NSMutableDictionary *elementStore = [NSMutableDictionary dictionary];
|
|
29
29
|
int buffersize;
|
|
30
30
|
xmlChar *xmlbuff;
|
|
31
|
-
int rc =
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
int rc = xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL);
|
|
32
|
+
if (rc >= 0) {
|
|
33
|
+
rc = [FBXPath xmlRepresentationWithRootElement:(XCElementSnapshot *)element
|
|
34
|
+
writer:writer
|
|
35
|
+
elementStore:elementStore
|
|
36
|
+
query:query
|
|
37
|
+
excludingAttributes:excludedAttributes];
|
|
38
|
+
if (rc >= 0) {
|
|
39
|
+
rc = xmlTextWriterEndDocument(writer);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (rc >= 0) {
|
|
37
43
|
xmlDocDumpFormatMemory(doc, &xmlbuff, &buffersize, 1);
|
|
38
44
|
}
|
|
39
45
|
xmlFreeTextWriter(writer);
|
|
40
46
|
xmlFreeDoc(doc);
|
|
41
47
|
|
|
42
|
-
|
|
48
|
+
XCTAssertTrue(rc >= 0);
|
|
43
49
|
XCTAssertEqual(1, [elementStore count]);
|
|
44
50
|
|
|
45
51
|
NSString *result = [NSString stringWithCString:(const char *)xmlbuff encoding:NSUTF8StringEncoding];
|
|
@@ -72,12 +78,13 @@
|
|
|
72
78
|
- (void)testXPathPresentationBasedOnQueryMatchingAllAttributes
|
|
73
79
|
{
|
|
74
80
|
XCUIElementDouble *element = [XCUIElementDouble new];
|
|
81
|
+
element.wdValue = @"йоло<>&\"";
|
|
75
82
|
NSString *resultXml = [self xmlStringWithElement:element
|
|
76
83
|
xpathQuery:[NSString stringWithFormat:@"//%@[@*]", element.wdType]
|
|
77
84
|
excludingAttributes:@[@"visible"]];
|
|
78
85
|
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ type=\"%@\" value=\"%@\" name=\"%@\" label=\"%@\" enabled=\"%@\" visible=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" index=\"%lu\" private_indexPath=\"top\"/>\n",
|
|
79
|
-
element.wdType, element.wdType,
|
|
80
|
-
XCTAssertTrue([resultXml isEqualToString:
|
|
86
|
+
element.wdType, element.wdType, @"йоло<>&"", element.wdName, element.wdLabel, element.wdEnabled ? @"true" : @"false", element.wdVisible ? @"true" : @"false", element.wdAccessible ? @"true" : @"false", element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex];
|
|
87
|
+
XCTAssertTrue([resultXml isEqualToString:expectedXml]);
|
|
81
88
|
}
|
|
82
89
|
|
|
83
90
|
- (void)testXPathPresentationBasedOnQueryMatchingSomeAttributes
|
|
@@ -99,15 +106,21 @@
|
|
|
99
106
|
NSMutableDictionary *elementStore = [NSMutableDictionary dictionary];
|
|
100
107
|
XCUIElementDouble *root = [XCUIElementDouble new];
|
|
101
108
|
NSString *query = [NSString stringWithFormat:@"//%@", root.wdType];
|
|
102
|
-
int rc =
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
109
|
+
int rc = xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL);
|
|
110
|
+
if (rc >= 0) {
|
|
111
|
+
rc = [FBXPath xmlRepresentationWithRootElement:(XCElementSnapshot *)root
|
|
112
|
+
writer:writer
|
|
113
|
+
elementStore:elementStore
|
|
114
|
+
query:query
|
|
115
|
+
excludingAttributes:nil];
|
|
116
|
+
if (rc >= 0) {
|
|
117
|
+
rc = xmlTextWriterEndDocument(writer);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
107
120
|
if (rc < 0) {
|
|
108
121
|
xmlFreeTextWriter(writer);
|
|
109
122
|
xmlFreeDoc(doc);
|
|
110
|
-
|
|
123
|
+
XCTFail(@"Unable to create the source XML document");
|
|
111
124
|
}
|
|
112
125
|
|
|
113
126
|
xmlXPathObjectPtr queryResult = [FBXPath evaluate:query document:doc];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appium-webdriveragent",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.16.0",
|
|
4
4
|
"description": "Package bundling WebDriverAgent",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"ios-uicatalog": "^3.5.0",
|
|
55
55
|
"mocha": "^9.0.0",
|
|
56
56
|
"pre-commit": "^1.2.2",
|
|
57
|
-
"sinon": "^
|
|
57
|
+
"sinon": "^12.0.0",
|
|
58
58
|
"wd": "^1.11.4"
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|