appium-mac2-driver 3.1.0 → 3.2.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/CHANGELOG.md +7 -0
- package/README.md +1 -0
- package/WebDriverAgentMac/IntegrationTests/AMEditElementTests.m +2 -4
- package/WebDriverAgentMac/WebDriverAgentLib/Categories/XCUIElement+AMAttributes.h +4 -2
- package/WebDriverAgentMac/WebDriverAgentLib/Categories/XCUIElement+AMAttributes.m +30 -15
- package/WebDriverAgentMac/WebDriverAgentLib/Categories/XCUIElementQuery+AMHelpers.h +8 -0
- package/WebDriverAgentMac/WebDriverAgentLib/Categories/XCUIElementQuery+AMHelpers.m +17 -0
- package/WebDriverAgentMac/WebDriverAgentLib/Commands/FBSessionCommands.m +4 -0
- package/WebDriverAgentMac/WebDriverAgentLib/Utilities/AMSettings.h +3 -0
- package/WebDriverAgentMac/WebDriverAgentLib/Utilities/AMSettings.m +1 -1
- package/WebDriverAgentMac/WebDriverAgentLib/Utilities/FBConfiguration.h +3 -0
- package/WebDriverAgentMac/WebDriverAgentLib/Utilities/FBConfiguration.m +11 -0
- package/npm-shrinkwrap.json +2213 -208
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
## [3.2.0](https://github.com/appium/appium-mac2-driver/compare/v3.1.0...v3.2.0) (2025-11-11)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* Add a setting that allows to fetch full element text ([#347](https://github.com/appium/appium-mac2-driver/issues/347)) ([a8b9e7e](https://github.com/appium/appium-mac2-driver/commit/a8b9e7ee1c0b576c04eaafb8af0d8649330ffc3b))
|
|
7
|
+
|
|
1
8
|
## [3.1.0](https://github.com/appium/appium-mac2-driver/compare/v3.0.1...v3.1.0) (2025-10-01)
|
|
2
9
|
|
|
3
10
|
|
package/README.md
CHANGED
|
@@ -849,6 +849,7 @@ Name | Type | Description
|
|
|
849
849
|
--- | --- | ---
|
|
850
850
|
boundElementsByIndex | boolean | Whether to use elements binding by index (`true`) or by accessibility identifier (the default setting, `false`). It makes sense to switch the binding strategy to workaround stale element reference errors containing `Identity Binding` text in their descriptions. See the corresponding [Stack Overflow discussion](https://stackoverflow.com/questions/49307513/meaning-of-allelementsboundbyaccessibilityelement) to know more details on the difference between these two binding strategies.
|
|
851
851
|
useDefaultUiInterruptionsHandling | boolean | Whether to use the default XCTest UI interruptions handling (`true`, the default setting) or to disable it for the [Application Under Test](#application-under-test-concept) (`false`). It makes sense to disable the default handler if it is necessary to validate the interrupting element's presence in your test or do some other actions on it rather than just closing the view implicitly. Check [this WWDC presentation](https://developer.apple.com/videos/play/wwdc2020/10220/) from Apple to get more details on the UI interruptions handling.
|
|
852
|
+
fetchFullText | boolean | Whether to use custom snapshotting mechanism to fetch full element's text payload instead of the first 512 chars. By default, this setting is set to false, which makes the driver to use the standard XCTest's snapshotting mechanism. It's fast, but may also cut long textual payloads of various UI element's in order to optimize internal UI hierarchy snapshotting performance. If the performance is less important for you that the ability to validate full element's text then consider enabling this setting while calling [Get Element Text](https://www.w3.org/TR/webdriver1/#dfn-get-element-text) API.
|
|
852
853
|
|
|
853
854
|
|
|
854
855
|
## Scripts
|
|
@@ -38,8 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
- (void)testSendingTextIntoNonFocusedEdit
|
|
40
40
|
{
|
|
41
|
-
|
|
42
|
-
XCUIElement *edit = [self.testedApplication.textFields matchingPredicate:predicate].firstMatch;
|
|
41
|
+
XCUIElement *edit = self.testedApplication.textFields.firstMatch;
|
|
43
42
|
NSString *text = @"yolo😎";
|
|
44
43
|
[edit am_setValue:text];
|
|
45
44
|
XCTAssertTrue(edit.am_hasKeyboardInputFocus);
|
|
@@ -50,8 +49,7 @@
|
|
|
50
49
|
|
|
51
50
|
- (void)testSendingTextIntoNonFocusedEditWithPlaceholderText
|
|
52
51
|
{
|
|
53
|
-
|
|
54
|
-
XCUIElement *edit = [self.testedApplication.textFields matchingPredicate:predicate].firstMatch;
|
|
52
|
+
XCUIElement *edit = self.testedApplication.textFields.firstMatch;
|
|
55
53
|
NSString *text = @"yolo😎";
|
|
56
54
|
[edit am_setValue:text];
|
|
57
55
|
XCTAssertTrue(edit.am_hasKeyboardInputFocus);
|
|
@@ -34,9 +34,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
34
34
|
- (NSDictionary<NSString *, NSNumber *> *)am_rect;
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
|
-
Element text
|
|
37
|
+
Element text. If no text is found then an empty string is returned.
|
|
38
|
+
|
|
39
|
+
@throws Error if `fetchFullText` setting is enabled and there was an error while fetching the snapshot
|
|
38
40
|
*/
|
|
39
|
-
- (
|
|
41
|
+
- (NSString *)am_text;
|
|
40
42
|
|
|
41
43
|
/**
|
|
42
44
|
Element type represented as string
|
|
@@ -17,10 +17,12 @@
|
|
|
17
17
|
#import "XCUIElement+AMAttributes.h"
|
|
18
18
|
|
|
19
19
|
#import "AMGeometryUtils.h"
|
|
20
|
+
#import "FBConfiguration.h"
|
|
20
21
|
#import "FBElementTypeTransformer.h"
|
|
21
22
|
#import "FBElementUtils.h"
|
|
22
23
|
#import "FBExceptions.h"
|
|
23
24
|
#import "FBMacros.h"
|
|
25
|
+
#import "XCUIElementQuery+AMHelpers.h"
|
|
24
26
|
|
|
25
27
|
@implementation XCUIElement (AMAttributes)
|
|
26
28
|
|
|
@@ -64,23 +66,20 @@
|
|
|
64
66
|
|
|
65
67
|
- (NSString *)am_text
|
|
66
68
|
{
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return value;
|
|
69
|
+
if (!FBConfiguration.sharedConfiguration.fetchFullText) {
|
|
70
|
+
return [self am_textWithSource:self];
|
|
70
71
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
return placeholderValue;
|
|
78
|
-
}
|
|
79
|
-
NSString *title = self.title;
|
|
80
|
-
if (nil != title && title.length > 0) {
|
|
81
|
-
return title;
|
|
72
|
+
|
|
73
|
+
NSError *error;
|
|
74
|
+
XCUIElementQuery *query = [self valueForKey:@"query"];
|
|
75
|
+
id<XCUIElementAttributes> snapshot = [query am_uniqueSnapshotWithError:&error];
|
|
76
|
+
if (nil != snapshot) {
|
|
77
|
+
return [self am_textWithSource:snapshot];
|
|
82
78
|
}
|
|
83
|
-
|
|
79
|
+
|
|
80
|
+
NSString *reason = [NSString stringWithFormat:@"Cannot extract the full text of '%@' element. Original error: %@",
|
|
81
|
+
self.description, error.description];
|
|
82
|
+
@throw [NSException exceptionWithName:FBInvalidElementStateException reason:reason userInfo:@{}];
|
|
84
83
|
}
|
|
85
84
|
|
|
86
85
|
- (NSString *)am_type
|
|
@@ -94,4 +93,20 @@
|
|
|
94
93
|
return [predicate evaluateWithObject:self];
|
|
95
94
|
}
|
|
96
95
|
|
|
96
|
+
- (NSString *)am_textWithSource:(id<XCUIElementAttributes>)source
|
|
97
|
+
{
|
|
98
|
+
NSArray<NSString *> *candidates = @[
|
|
99
|
+
[FBElementUtils stringValueWithValue:source.value],
|
|
100
|
+
source.label,
|
|
101
|
+
source.placeholderValue,
|
|
102
|
+
source.title
|
|
103
|
+
];
|
|
104
|
+
for (NSString *text in candidates) {
|
|
105
|
+
if (nil != text && text.length > 0) {
|
|
106
|
+
return text;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return @"";
|
|
110
|
+
}
|
|
111
|
+
|
|
97
112
|
@end
|
|
@@ -34,6 +34,14 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
34
34
|
*/
|
|
35
35
|
- (NSArray<XCUIElement *> *)am_allMatches;
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
Returns single unique matching snapshot for the given query
|
|
39
|
+
|
|
40
|
+
@param error The error instance if there was a failure while retrieveing the snapshot
|
|
41
|
+
@returns The unqiue snapshot or nil if the element is stale
|
|
42
|
+
*/
|
|
43
|
+
- (nullable id<XCUIElementSnapshot>)am_uniqueSnapshotWithError:(NSError **)error;
|
|
44
|
+
|
|
37
45
|
@end
|
|
38
46
|
|
|
39
47
|
NS_ASSUME_NONNULL_END
|
|
@@ -32,4 +32,21 @@
|
|
|
32
32
|
: self.allElementsBoundByAccessibilityElement;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
- (id<XCUIElementSnapshot>)am_uniqueSnapshotWithError:(NSError **)error
|
|
36
|
+
{
|
|
37
|
+
SEL selector = NSSelectorFromString(@"uniqueMatchingSnapshotWithError:");
|
|
38
|
+
NSMethodSignature *signature = [self methodSignatureForSelector:selector];
|
|
39
|
+
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
|
|
40
|
+
invocation.target = self;
|
|
41
|
+
invocation.selector = selector;
|
|
42
|
+
|
|
43
|
+
[invocation setArgument:&error atIndex:2]; // index 0 = self, 1 = _cmd, 2 = first real argument
|
|
44
|
+
|
|
45
|
+
[invocation invoke];
|
|
46
|
+
|
|
47
|
+
__unsafe_unretained id returnValue = nil;
|
|
48
|
+
[invocation getReturnValue:&returnValue];
|
|
49
|
+
return returnValue;
|
|
50
|
+
}
|
|
51
|
+
|
|
35
52
|
@end
|
|
@@ -237,6 +237,7 @@ const static NSString *CAPABILITIES_KEY = @"capabilities";
|
|
|
237
237
|
@{
|
|
238
238
|
AM_BOUND_ELEMENTS_BY_INDEX_SETTING: @(FBSession.activeSession.boundElementsByIndex),
|
|
239
239
|
AM_USE_DEFAULT_UI_INTERRUPTIONS_HANDLING_SETTING: @(!application.am_doesNotHandleUIInterruptions),
|
|
240
|
+
AM_FETCH_FULL_TEXT: @(FBConfiguration.sharedConfiguration.fetchFullText),
|
|
240
241
|
}
|
|
241
242
|
);
|
|
242
243
|
}
|
|
@@ -252,6 +253,9 @@ const static NSString *CAPABILITIES_KEY = @"capabilities";
|
|
|
252
253
|
XCUIApplication *application = FBSession.activeSession.currentApplication;
|
|
253
254
|
application.am_doesNotHandleUIInterruptions = ![[settings objectForKey:AM_USE_DEFAULT_UI_INTERRUPTIONS_HANDLING_SETTING] boolValue];
|
|
254
255
|
}
|
|
256
|
+
if (nil != [settings objectForKey:AM_FETCH_FULL_TEXT]) {
|
|
257
|
+
FBConfiguration.sharedConfiguration.fetchFullText = [settings objectForKey:AM_FETCH_FULL_TEXT];
|
|
258
|
+
}
|
|
255
259
|
|
|
256
260
|
return [self handleGetSettings:request];
|
|
257
261
|
}
|
|
@@ -25,4 +25,7 @@ extern NSString* const AM_BOUND_ELEMENTS_BY_INDEX_SETTING;
|
|
|
25
25
|
See https://developer.apple.com/videos/play/wwdc2020/10220/ for more details */
|
|
26
26
|
extern NSString* const AM_USE_DEFAULT_UI_INTERRUPTIONS_HANDLING_SETTING;
|
|
27
27
|
|
|
28
|
+
/*! Whether to use custom snapshotting mechanism to fetch full element's text payload instead of the first 512 chars */
|
|
29
|
+
extern NSString* const AM_FETCH_FULL_TEXT;
|
|
30
|
+
|
|
28
31
|
NS_ASSUME_NONNULL_END
|
|
@@ -17,5 +17,5 @@
|
|
|
17
17
|
#import "AMSettings.h"
|
|
18
18
|
|
|
19
19
|
NSString* const AM_BOUND_ELEMENTS_BY_INDEX_SETTING = @"boundElementsByIndex";
|
|
20
|
-
|
|
21
20
|
NSString* const AM_USE_DEFAULT_UI_INTERRUPTIONS_HANDLING_SETTING = @"useDefaultUiInterruptionsHandling";
|
|
21
|
+
NSString* const AM_FETCH_FULL_TEXT = @"fetchFullText";
|
|
@@ -30,6 +30,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
30
30
|
/*! Enables XCTest automated screen recordings taking in Xcode 15+ */
|
|
31
31
|
@property BOOL automaticScreenRecordings;
|
|
32
32
|
|
|
33
|
+
/*! Whether to use custom snapshotting mechanism to fetch full element's text payload instead of the first 512 chars */
|
|
34
|
+
@property BOOL fetchFullText;
|
|
35
|
+
|
|
33
36
|
/**
|
|
34
37
|
The range of ports that the HTTP Server should attempt to bind on launch
|
|
35
38
|
*/
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
static NSUInteger const DefaultStartingPort = 10100;
|
|
13
13
|
static NSUInteger const DefaultPortRange = 100;
|
|
14
|
+
static BOOL FBFetchFullText = NO;
|
|
14
15
|
|
|
15
16
|
@implementation FBConfiguration
|
|
16
17
|
|
|
@@ -75,6 +76,16 @@ static FBConfiguration *instance;
|
|
|
75
76
|
forKey:@"DisableDiagnosticScreenRecordings"];
|
|
76
77
|
}
|
|
77
78
|
|
|
79
|
+
- (BOOL)fetchFullText
|
|
80
|
+
{
|
|
81
|
+
return FBFetchFullText;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
- (void)setFetchFullText:(BOOL)fetchFullText
|
|
85
|
+
{
|
|
86
|
+
FBFetchFullText = fetchFullText;
|
|
87
|
+
}
|
|
88
|
+
|
|
78
89
|
- (NSRange)bindingPortRange
|
|
79
90
|
{
|
|
80
91
|
// 'WebDriverAgent --port 8080' can be passed via the arguments to the process
|