appium-webdriveragent 9.13.0 → 9.14.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 +6 -0
- package/WebDriverAgent.xcodeproj/project.pbxproj +12 -0
- package/WebDriverAgentLib/Categories/XCUIApplication+FBHelpers.m +15 -1
- package/WebDriverAgentLib/Categories/XCUIElement+FBMinMax.h +34 -0
- package/WebDriverAgentLib/Categories/XCUIElement+FBMinMax.m +76 -0
- package/WebDriverAgentLib/Categories/XCUIElement+FBWebDriverAttributes.m +11 -0
- package/WebDriverAgentLib/Commands/FBSessionCommands.m +4 -0
- package/WebDriverAgentLib/Info.plist +2 -2
- package/WebDriverAgentLib/Routing/FBElement.h +6 -0
- package/WebDriverAgentLib/Utilities/FBConfiguration.h +12 -0
- package/WebDriverAgentLib/Utilities/FBConfiguration.m +11 -0
- package/WebDriverAgentLib/Utilities/FBElementHelpers.h +9 -1
- package/WebDriverAgentLib/Utilities/FBElementHelpers.m +5 -0
- package/WebDriverAgentLib/Utilities/FBSettings.h +1 -1
- package/WebDriverAgentLib/Utilities/FBSettings.m +1 -0
- package/WebDriverAgentLib/Utilities/FBXPath.m +54 -0
- package/WebDriverAgentLib/Utilities/XCTestPrivateSymbols.h +8 -0
- package/WebDriverAgentLib/Utilities/XCTestPrivateSymbols.m +17 -1
- package/WebDriverAgentTests/IntegrationTests/FBElementAttributeTests.m +10 -0
- package/WebDriverAgentTests/UnitTests/FBXPathTests.m +6 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [9.14.0](https://github.com/appium/WebDriverAgent/compare/v9.13.0...v9.14.0) (2025-06-09)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* add minimum and maximum value attributes to page source ([#1031](https://github.com/appium/WebDriverAgent/issues/1031)) ([0e4e7e7](https://github.com/appium/WebDriverAgent/commit/0e4e7e7c483b9196edae576481f4e37f99fc8705))
|
|
6
|
+
|
|
1
7
|
## [9.13.0](https://github.com/appium/WebDriverAgent/compare/v9.12.0...v9.13.0) (2025-06-05)
|
|
2
8
|
|
|
3
9
|
### Features
|
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
objects = {
|
|
8
8
|
|
|
9
9
|
/* Begin PBXBuildFile section */
|
|
10
|
+
0E0413382DF1E15100AF007C /* XCUIElement+FBMinMax.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E0413372DF1E15100AF007C /* XCUIElement+FBMinMax.m */; };
|
|
11
|
+
0E0413392DF1E15100AF007C /* XCUIElement+FBMinMax.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E0413372DF1E15100AF007C /* XCUIElement+FBMinMax.m */; };
|
|
12
|
+
0E04133B2DF1E15900AF007C /* XCUIElement+FBMinMax.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E04133A2DF1E15900AF007C /* XCUIElement+FBMinMax.h */; };
|
|
13
|
+
0E04133C2DF1E15900AF007C /* XCUIElement+FBMinMax.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E04133A2DF1E15900AF007C /* XCUIElement+FBMinMax.h */; };
|
|
10
14
|
1357E296233D05240054BDB8 /* XCUIHitPointResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 1357E295233D05240054BDB8 /* XCUIHitPointResult.h */; };
|
|
11
15
|
1357E297233D05240054BDB8 /* XCUIHitPointResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 1357E295233D05240054BDB8 /* XCUIHitPointResult.h */; };
|
|
12
16
|
13815F6F2328D20400CDAB61 /* FBActiveAppDetectionPoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 13815F6D2328D20400CDAB61 /* FBActiveAppDetectionPoint.h */; };
|
|
@@ -918,6 +922,8 @@
|
|
|
918
922
|
/* End PBXCopyFilesBuildPhase section */
|
|
919
923
|
|
|
920
924
|
/* Begin PBXFileReference section */
|
|
925
|
+
0E0413372DF1E15100AF007C /* XCUIElement+FBMinMax.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "XCUIElement+FBMinMax.m"; sourceTree = "<group>"; };
|
|
926
|
+
0E04133A2DF1E15900AF007C /* XCUIElement+FBMinMax.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XCUIElement+FBMinMax.h"; sourceTree = "<group>"; };
|
|
921
927
|
1357E295233D05240054BDB8 /* XCUIHitPointResult.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XCUIHitPointResult.h; sourceTree = "<group>"; };
|
|
922
928
|
13815F6D2328D20400CDAB61 /* FBActiveAppDetectionPoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBActiveAppDetectionPoint.h; sourceTree = "<group>"; };
|
|
923
929
|
13815F6E2328D20400CDAB61 /* FBActiveAppDetectionPoint.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBActiveAppDetectionPoint.m; sourceTree = "<group>"; };
|
|
@@ -1785,6 +1791,8 @@
|
|
|
1785
1791
|
EE8DDD7C20C5733B004D4925 /* XCUIElement+FBForceTouch.m */,
|
|
1786
1792
|
EE9AB7471CAEDF0C008C271F /* XCUIElement+FBIsVisible.h */,
|
|
1787
1793
|
EE9AB7481CAEDF0C008C271F /* XCUIElement+FBIsVisible.m */,
|
|
1794
|
+
0E04133A2DF1E15900AF007C /* XCUIElement+FBMinMax.h */,
|
|
1795
|
+
0E0413372DF1E15100AF007C /* XCUIElement+FBMinMax.m */,
|
|
1788
1796
|
7136A4771E8918E60024FC3D /* XCUIElement+FBPickerWheel.h */,
|
|
1789
1797
|
7136A4781E8918E60024FC3D /* XCUIElement+FBPickerWheel.m */,
|
|
1790
1798
|
71D3B3D3267FC7260076473D /* XCUIElement+FBResolve.h */,
|
|
@@ -2377,6 +2385,7 @@
|
|
|
2377
2385
|
641EE6782240C5CA00173FCB /* XCTNSNotificationExpectation.h in Headers */,
|
|
2378
2386
|
641EE6792240C5CA00173FCB /* XCUIRecorderNodeFinder.h in Headers */,
|
|
2379
2387
|
641EE67A2240C5CA00173FCB /* XCUIElement+FBAccessibility.h in Headers */,
|
|
2388
|
+
0E04133C2DF1E15900AF007C /* XCUIElement+FBMinMax.h in Headers */,
|
|
2380
2389
|
641EE67B2240C5CA00173FCB /* XCUIRecorderUtilities.h in Headers */,
|
|
2381
2390
|
6496A5DA230D6EB30087F8CB /* AXSettings.h in Headers */,
|
|
2382
2391
|
641EE67C2240C5CA00173FCB /* XCTestCaseRun.h in Headers */,
|
|
@@ -2701,6 +2710,7 @@
|
|
|
2701
2710
|
EEE9B4721CD02B88009D2030 /* FBRunLoopSpinner.h in Headers */,
|
|
2702
2711
|
EE3A18621CDE618F00DE4205 /* FBErrorBuilder.h in Headers */,
|
|
2703
2712
|
EE35AD261E3B77D600A02D78 /* XCApplicationMonitor_iOS.h in Headers */,
|
|
2713
|
+
0E04133B2DF1E15900AF007C /* XCUIElement+FBMinMax.h in Headers */,
|
|
2704
2714
|
EE3A18661CDE734B00DE4205 /* FBKeyboard.h in Headers */,
|
|
2705
2715
|
AD6C269C1CF2494200F8B5FF /* XCUIApplication+FBHelpers.h in Headers */,
|
|
2706
2716
|
714D88CC2733FB970074A925 /* FBXMLGenerationOptions.h in Headers */,
|
|
@@ -3202,6 +3212,7 @@
|
|
|
3202
3212
|
71BB58F92B96531900CB9BFE /* FBScreenRecordingContainer.m in Sources */,
|
|
3203
3213
|
641EE6152240C5CA00173FCB /* XCUIElement+FBScrolling.m in Sources */,
|
|
3204
3214
|
641EE6162240C5CA00173FCB /* FBSessionCommands.m in Sources */,
|
|
3215
|
+
0E0413392DF1E15100AF007C /* XCUIElement+FBMinMax.m in Sources */,
|
|
3205
3216
|
641EE6192240C5CA00173FCB /* FBConfiguration.m in Sources */,
|
|
3206
3217
|
641EE61A2240C5CA00173FCB /* FBElementCache.m in Sources */,
|
|
3207
3218
|
71F5BE26252E576C00EE9EBA /* XCUIElement+FBSwiping.m in Sources */,
|
|
@@ -3249,6 +3260,7 @@
|
|
|
3249
3260
|
13DE7A45287C2A8D003243C6 /* FBXCAccessibilityElement.m in Sources */,
|
|
3250
3261
|
641EE70E2240CE4800173FCB /* FBTVNavigationTracker.m in Sources */,
|
|
3251
3262
|
71BD20741F86116100B36EC2 /* XCUIApplication+FBTouchAction.m in Sources */,
|
|
3263
|
+
0E0413382DF1E15100AF007C /* XCUIElement+FBMinMax.m in Sources */,
|
|
3252
3264
|
EE158AE71CBD456F00A3E3F0 /* FBWebServer.m in Sources */,
|
|
3253
3265
|
715557D4211DBCE700613B26 /* FBTCPSocket.m in Sources */,
|
|
3254
3266
|
EE3A18631CDE618F00DE4205 /* FBErrorBuilder.m in Sources */,
|
|
@@ -49,6 +49,8 @@ static NSString* const FBExclusionAttributeFocused = @"focused";
|
|
|
49
49
|
static NSString* const FBExclusionAttributePlaceholderValue = @"placeholderValue";
|
|
50
50
|
static NSString* const FBExclusionAttributeNativeFrame = @"nativeFrame";
|
|
51
51
|
static NSString* const FBExclusionAttributeTraits = @"traits";
|
|
52
|
+
static NSString* const FBExclusionAttributeMinValue = @"minValue";
|
|
53
|
+
static NSString* const FBExclusionAttributeMaxValue = @"maxValue";
|
|
52
54
|
|
|
53
55
|
_Nullable id extractIssueProperty(id issue, NSString *propertyName) {
|
|
54
56
|
SEL selector = NSSelectorFromString(propertyName);
|
|
@@ -211,6 +213,8 @@ NSDictionary<NSString *, NSString *> *customExclusionAttributesMap(void) {
|
|
|
211
213
|
FBExclusionAttributePlaceholderValue,
|
|
212
214
|
FBExclusionAttributeNativeFrame,
|
|
213
215
|
FBExclusionAttributeTraits,
|
|
216
|
+
FBExclusionAttributeMinValue,
|
|
217
|
+
FBExclusionAttributeMaxValue,
|
|
214
218
|
nil];
|
|
215
219
|
|
|
216
220
|
for (NSString *key in attributeBlocks) {
|
|
@@ -248,7 +252,7 @@ NSDictionary<NSString *, NSString *> *customExclusionAttributesMap(void) {
|
|
|
248
252
|
|
|
249
253
|
{
|
|
250
254
|
// Base attributes common to every element
|
|
251
|
-
NSMutableDictionary<NSString *,
|
|
255
|
+
NSMutableDictionary<NSString *, id(^)(void)> *blocks =
|
|
252
256
|
[@{
|
|
253
257
|
FBExclusionAttributeFrame: ^{
|
|
254
258
|
return NSStringFromCGRect(wrappedSnapshot.wdFrame);
|
|
@@ -282,6 +286,16 @@ NSDictionary<NSString *, NSString *> *customExclusionAttributesMap(void) {
|
|
|
282
286
|
};
|
|
283
287
|
}
|
|
284
288
|
|
|
289
|
+
// Only for elements that support min/max value
|
|
290
|
+
if (FBDoesElementSupportMinMaxValue(elementType)) {
|
|
291
|
+
blocks[FBExclusionAttributeMinValue] = ^{
|
|
292
|
+
return wrappedSnapshot.wdMinValue;
|
|
293
|
+
};
|
|
294
|
+
blocks[FBExclusionAttributeMaxValue] = ^{
|
|
295
|
+
return wrappedSnapshot.wdMaxValue;
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
|
|
285
299
|
return [blocks copy];
|
|
286
300
|
}
|
|
287
301
|
|
|
@@ -0,0 +1,34 @@
|
|
|
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 <WebDriverAgentLib/FBXCElementSnapshotWrapper.h>
|
|
11
|
+
|
|
12
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
13
|
+
|
|
14
|
+
@interface XCUIElement (FBMinMax)
|
|
15
|
+
|
|
16
|
+
/*! Minimum value (minValue) – may be nil if the element does not have this attribute */
|
|
17
|
+
@property (nonatomic, readonly, nullable) NSNumber *fb_minValue;
|
|
18
|
+
|
|
19
|
+
/*! Maximum value (maxValue) - may be nil if the element does not have this attribute */
|
|
20
|
+
@property (nonatomic, readonly, nullable) NSNumber *fb_maxValue;
|
|
21
|
+
|
|
22
|
+
@end
|
|
23
|
+
|
|
24
|
+
@interface FBXCElementSnapshotWrapper (FBMinMax)
|
|
25
|
+
|
|
26
|
+
/*! Minimum value (minValue) – may be nil if the element does not have this attribute */
|
|
27
|
+
@property (nonatomic, readonly, nullable) NSNumber *fb_minValue;
|
|
28
|
+
|
|
29
|
+
/*! Maximum value (maxValue) - may be nil if the element does not have this attribute */
|
|
30
|
+
@property (nonatomic, readonly, nullable) NSNumber *fb_maxValue;
|
|
31
|
+
|
|
32
|
+
@end
|
|
33
|
+
|
|
34
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,76 @@
|
|
|
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 "FBLogger.h"
|
|
11
|
+
#import "XCUIElement+FBMinMax.h"
|
|
12
|
+
#import "FBXCElementSnapshotWrapper+Helpers.h"
|
|
13
|
+
#import "XCUIElement+FBUtilities.h"
|
|
14
|
+
#import "XCTestPrivateSymbols.h"
|
|
15
|
+
|
|
16
|
+
@interface FBXCElementSnapshotWrapper (FBMinMaxInternal)
|
|
17
|
+
|
|
18
|
+
- (NSNumber *)fb_numericAttribute:(NSString *)attributeName symbol:(NSNumber *)symbol;
|
|
19
|
+
|
|
20
|
+
@end
|
|
21
|
+
|
|
22
|
+
@implementation XCUIElement (FBMinMax)
|
|
23
|
+
|
|
24
|
+
- (NSNumber *)fb_minValue
|
|
25
|
+
{
|
|
26
|
+
@autoreleasepool {
|
|
27
|
+
id<FBXCElementSnapshot> snapshot = [self fb_standardSnapshot];
|
|
28
|
+
return [[FBXCElementSnapshotWrapper ensureWrapped:snapshot] fb_minValue];
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
- (NSNumber *)fb_maxValue
|
|
33
|
+
{
|
|
34
|
+
@autoreleasepool {
|
|
35
|
+
id<FBXCElementSnapshot> snapshot = [self fb_standardSnapshot];
|
|
36
|
+
return [[FBXCElementSnapshotWrapper ensureWrapped:snapshot] fb_maxValue];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@end
|
|
41
|
+
|
|
42
|
+
@implementation FBXCElementSnapshotWrapper (FBMinMax)
|
|
43
|
+
|
|
44
|
+
- (NSNumber *)fb_minValue
|
|
45
|
+
{
|
|
46
|
+
return [self fb_numericAttribute:FB_XCAXACustomMinValueAttributeName
|
|
47
|
+
symbol:FB_XCAXACustomMinValueAttribute];
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
- (NSNumber *)fb_maxValue
|
|
51
|
+
{
|
|
52
|
+
return [self fb_numericAttribute:FB_XCAXACustomMaxValueAttributeName
|
|
53
|
+
symbol:FB_XCAXACustomMaxValueAttribute];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
- (NSNumber *)fb_numericAttribute:(NSString *)attributeName symbol:(NSNumber *)symbol
|
|
57
|
+
{
|
|
58
|
+
NSNumber *cached = (self.snapshot.additionalAttributes ?: @{})[symbol];
|
|
59
|
+
if (cached) {
|
|
60
|
+
return cached;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
NSError *error = nil;
|
|
64
|
+
NSNumber *raw = [self fb_attributeValue:attributeName error:&error];
|
|
65
|
+
if (nil != raw) {
|
|
66
|
+
NSMutableDictionary *updated = [NSMutableDictionary dictionaryWithDictionary:self.additionalAttributes ?: @{}];
|
|
67
|
+
updated[symbol] = raw;
|
|
68
|
+
self.snapshot.additionalAttributes = updated.copy;
|
|
69
|
+
return raw;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
[FBLogger logFmt:@"[FBMinMax] Cannot determine %@ for %@: %@", attributeName, self.fb_description, error.localizedDescription];
|
|
73
|
+
return nil;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@end
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
#import "XCTestPrivateSymbols.h"
|
|
24
24
|
#import "XCUIHitPointResult.h"
|
|
25
25
|
#import "FBAccessibilityTraits.h"
|
|
26
|
+
#import "XCUIElement+FBMinMax.h"
|
|
26
27
|
|
|
27
28
|
#define BROKEN_RECT CGRectMake(-1, -1, 0, 0)
|
|
28
29
|
|
|
@@ -76,6 +77,16 @@
|
|
|
76
77
|
return [self valueForKey:[FBElementUtils wdAttributeNameForAttributeName:name]];
|
|
77
78
|
}
|
|
78
79
|
|
|
80
|
+
- (NSNumber *)wdMinValue
|
|
81
|
+
{
|
|
82
|
+
return self.fb_minValue;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
- (NSNumber *)wdMaxValue
|
|
86
|
+
{
|
|
87
|
+
return self.fb_maxValue;
|
|
88
|
+
}
|
|
89
|
+
|
|
79
90
|
- (NSString *)wdValue
|
|
80
91
|
{
|
|
81
92
|
id value = self.value;
|
|
@@ -355,6 +355,7 @@
|
|
|
355
355
|
FB_SETTING_USE_CLEAR_TEXT_SHORTCUT: @([FBConfiguration useClearTextShortcut]),
|
|
356
356
|
FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE: @([FBConfiguration includeHittableInPageSource]),
|
|
357
357
|
FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE: @([FBConfiguration includeNativeFrameInPageSource]),
|
|
358
|
+
FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE: @([FBConfiguration includeMinMaxValueInPageSource]),
|
|
358
359
|
FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE: @([FBConfiguration limitXpathContextScope]),
|
|
359
360
|
#if !TARGET_OS_TV
|
|
360
361
|
FB_SETTING_SCREENSHOT_ORIENTATION: [FBConfiguration humanReadableScreenshotOrientation],
|
|
@@ -463,6 +464,9 @@
|
|
|
463
464
|
if (nil != [settings objectForKey:FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE]) {
|
|
464
465
|
[FBConfiguration setIncludeNativeFrameInPageSource:[[settings objectForKey:FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE] boolValue]];
|
|
465
466
|
}
|
|
467
|
+
if (nil != [settings objectForKey:FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE]) {
|
|
468
|
+
[FBConfiguration setIncludeMinMaxValueInPageSource:[[settings objectForKey:FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE] boolValue]];
|
|
469
|
+
}
|
|
466
470
|
if (nil != [settings objectForKey:FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE]) {
|
|
467
471
|
[FBConfiguration setLimitXpathContextScope:[[settings objectForKey:FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE] boolValue]];
|
|
468
472
|
}
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
<key>CFBundlePackageType</key>
|
|
16
16
|
<string>FMWK</string>
|
|
17
17
|
<key>CFBundleShortVersionString</key>
|
|
18
|
-
<string>9.
|
|
18
|
+
<string>9.14.0</string>
|
|
19
19
|
<key>CFBundleSignature</key>
|
|
20
20
|
<string>????</string>
|
|
21
21
|
<key>CFBundleVersion</key>
|
|
22
|
-
<string>9.
|
|
22
|
+
<string>9.14.0</string>
|
|
23
23
|
<key>NSPrincipalClass</key>
|
|
24
24
|
<string/>
|
|
25
25
|
</dict>
|
|
@@ -71,6 +71,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
71
71
|
/*! Element's placeholder value */
|
|
72
72
|
@property (nonatomic, readonly, copy, nullable) NSString *wdPlaceholderValue;
|
|
73
73
|
|
|
74
|
+
/*! Element's minimum value */
|
|
75
|
+
@property (nonatomic, readonly, strong, nullable) NSNumber *wdMinValue;
|
|
76
|
+
|
|
77
|
+
/*! Element's maximum value */
|
|
78
|
+
@property (nonatomic, readonly, strong, nullable) NSNumber *wdMaxValue;
|
|
79
|
+
|
|
74
80
|
/**
|
|
75
81
|
Returns value of given property specified in WebDriver Spec
|
|
76
82
|
Check the FBElement protocol to get list of supported attributes.
|
|
@@ -359,6 +359,18 @@ typedef NS_ENUM(NSInteger, FBConfigurationKeyboardPreference) {
|
|
|
359
359
|
+ (void)setIncludeNativeFrameInPageSource:(BOOL)enabled;
|
|
360
360
|
+ (BOOL)includeNativeFrameInPageSource;
|
|
361
361
|
|
|
362
|
+
/**
|
|
363
|
+
* Whether to include `minValue`/`maxValue` attributes in the page source.
|
|
364
|
+
* These attributes are retrieved from native element snapshots and represent
|
|
365
|
+
* value boundaries for elements like sliders or progress indicators.
|
|
366
|
+
* This may affect performance if used on many elements.
|
|
367
|
+
* Disabled by default.
|
|
368
|
+
*
|
|
369
|
+
* @param enabled Either YES or NO
|
|
370
|
+
*/
|
|
371
|
+
+ (void)setIncludeMinMaxValueInPageSource:(BOOL)enabled;
|
|
372
|
+
+ (BOOL)includeMinMaxValueInPageSource;
|
|
373
|
+
|
|
362
374
|
@end
|
|
363
375
|
|
|
364
376
|
NS_ASSUME_NONNULL_END
|
|
@@ -63,6 +63,7 @@ static UIInterfaceOrientation FBScreenshotOrientation;
|
|
|
63
63
|
#endif
|
|
64
64
|
static BOOL FBShouldIncludeHittableInPageSource = NO;
|
|
65
65
|
static BOOL FBShouldIncludeNativeFrameInPageSource = NO;
|
|
66
|
+
static BOOL FBShouldIncludeMinMaxValueInPageSource = NO;
|
|
66
67
|
|
|
67
68
|
@implementation FBConfiguration
|
|
68
69
|
|
|
@@ -664,4 +665,14 @@ static BOOL FBShouldIncludeNativeFrameInPageSource = NO;
|
|
|
664
665
|
return FBShouldIncludeNativeFrameInPageSource;
|
|
665
666
|
}
|
|
666
667
|
|
|
668
|
+
+ (void)setIncludeMinMaxValueInPageSource:(BOOL)enabled
|
|
669
|
+
{
|
|
670
|
+
FBShouldIncludeMinMaxValueInPageSource = enabled;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
+ (BOOL)includeMinMaxValueInPageSource
|
|
674
|
+
{
|
|
675
|
+
return FBShouldIncludeMinMaxValueInPageSource;
|
|
676
|
+
}
|
|
677
|
+
|
|
667
678
|
@end
|
|
@@ -15,8 +15,16 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
15
15
|
Checks if the element is a text field
|
|
16
16
|
|
|
17
17
|
@param elementType XCTest element type
|
|
18
|
-
@return YES if the
|
|
18
|
+
@return YES if the element is a text field
|
|
19
19
|
*/
|
|
20
20
|
BOOL FBDoesElementSupportInnerText(XCUIElementType elementType);
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
Checks if the element supports min/max value attributes
|
|
24
|
+
|
|
25
|
+
@param elementType XCTest element type
|
|
26
|
+
@return YES if the element type supports min/max value attributes
|
|
27
|
+
*/
|
|
28
|
+
BOOL FBDoesElementSupportMinMaxValue(XCUIElementType elementType);
|
|
29
|
+
|
|
22
30
|
NS_ASSUME_NONNULL_END
|
|
@@ -15,3 +15,8 @@ BOOL FBDoesElementSupportInnerText(XCUIElementType elementType) {
|
|
|
15
15
|
|| elementType == XCUIElementTypeSearchField
|
|
16
16
|
|| elementType == XCUIElementTypeSecureTextField;
|
|
17
17
|
}
|
|
18
|
+
|
|
19
|
+
BOOL FBDoesElementSupportMinMaxValue(XCUIElementType elementType) {
|
|
20
|
+
return elementType == XCUIElementTypeSlider
|
|
21
|
+
|| elementType == XCUIElementTypeStepper;
|
|
22
|
+
}
|
|
@@ -42,6 +42,6 @@ extern NSString* const FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE;
|
|
|
42
42
|
extern NSString* const FB_SETTING_AUTO_CLICK_ALERT_SELECTOR;
|
|
43
43
|
extern NSString *const FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE;
|
|
44
44
|
extern NSString *const FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE;
|
|
45
|
-
|
|
45
|
+
extern NSString *const FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE;
|
|
46
46
|
|
|
47
47
|
NS_ASSUME_NONNULL_END
|
|
@@ -38,3 +38,4 @@ NSString* const FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE = @"limitXPathContextScope"
|
|
|
38
38
|
NSString* const FB_SETTING_AUTO_CLICK_ALERT_SELECTOR = @"autoClickAlertSelector";
|
|
39
39
|
NSString* const FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE = @"includeHittableInPageSource";
|
|
40
40
|
NSString* const FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE = @"includeNativeFrameInPageSource";
|
|
41
|
+
NSString* const FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE = @"includeMinMaxValueInPageSource";
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
#import "XCUIElement+FBUtilities.h"
|
|
23
23
|
#import "XCUIElement+FBWebDriverAttributes.h"
|
|
24
24
|
#import "XCTestPrivateSymbols.h"
|
|
25
|
+
#import "FBElementHelpers.h"
|
|
25
26
|
|
|
26
27
|
|
|
27
28
|
@interface FBElementAttribute : NSObject
|
|
@@ -113,6 +114,14 @@
|
|
|
113
114
|
|
|
114
115
|
@end
|
|
115
116
|
|
|
117
|
+
@interface FBMinValueAttribute : FBElementAttribute
|
|
118
|
+
|
|
119
|
+
@end
|
|
120
|
+
|
|
121
|
+
@interface FBMaxValueAttribute : FBElementAttribute
|
|
122
|
+
|
|
123
|
+
@end
|
|
124
|
+
|
|
116
125
|
#if TARGET_OS_TV
|
|
117
126
|
|
|
118
127
|
@interface FBFocusedAttribute : FBElementAttribute
|
|
@@ -374,6 +383,11 @@ static NSString *const topNodeIndexPath = @"top";
|
|
|
374
383
|
// Include nativeFrame only when requested
|
|
375
384
|
[includedAttributes removeObject:FBNativeFrameAttribute.class];
|
|
376
385
|
}
|
|
386
|
+
if (!FBConfiguration.includeMinMaxValueInPageSource) {
|
|
387
|
+
// minValue/maxValue are retrieved from private APIs and may be slow on deep trees
|
|
388
|
+
[includedAttributes removeObject:FBMinValueAttribute.class];
|
|
389
|
+
[includedAttributes removeObject:FBMaxValueAttribute.class];
|
|
390
|
+
}
|
|
377
391
|
if (nil != excludedAttributes) {
|
|
378
392
|
for (NSString *excludedAttributeName in excludedAttributes) {
|
|
379
393
|
for (Class supportedAttribute in FBElementAttribute.supportedAttributes) {
|
|
@@ -437,6 +451,16 @@ static NSString *const topNodeIndexPath = @"top";
|
|
|
437
451
|
if (includedAttributes && ![includedAttributes containsObject:attributeCls]) {
|
|
438
452
|
continue;
|
|
439
453
|
}
|
|
454
|
+
// Text-input placeholder (only for elements that support inner text)
|
|
455
|
+
if ((attributeCls == FBPlaceholderValueAttribute.class) &&
|
|
456
|
+
!FBDoesElementSupportInnerText(element.elementType)) {
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
// Only for elements that support min/max value
|
|
460
|
+
if ((attributeCls == FBMinValueAttribute.class || attributeCls == FBMaxValueAttribute.class) &&
|
|
461
|
+
!FBDoesElementSupportMinMaxValue(element.elementType)) {
|
|
462
|
+
continue;
|
|
463
|
+
}
|
|
440
464
|
int rc = [attributeCls recordWithWriter:writer
|
|
441
465
|
forElement:[FBXCElementSnapshotWrapper ensureWrapped:element]];
|
|
442
466
|
if (rc < 0) {
|
|
@@ -597,6 +621,8 @@ static NSString *const FBAbstractMethodInvocationException = @"AbstractMethodInv
|
|
|
597
621
|
FBPlaceholderValueAttribute.class,
|
|
598
622
|
FBTraitsAttribute.class,
|
|
599
623
|
FBNativeFrameAttribute.class,
|
|
624
|
+
FBMinValueAttribute.class,
|
|
625
|
+
FBMaxValueAttribute.class,
|
|
600
626
|
];
|
|
601
627
|
}
|
|
602
628
|
|
|
@@ -860,3 +886,31 @@ static NSString *const FBAbstractMethodInvocationException = @"AbstractMethodInv
|
|
|
860
886
|
}
|
|
861
887
|
|
|
862
888
|
@end
|
|
889
|
+
|
|
890
|
+
@implementation FBMinValueAttribute
|
|
891
|
+
|
|
892
|
+
+ (NSString *)name
|
|
893
|
+
{
|
|
894
|
+
return @"minValue";
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
+ (NSString *)valueForElement:(id<FBElement>)element
|
|
898
|
+
{
|
|
899
|
+
return [element.wdMinValue stringValue];
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
@end
|
|
903
|
+
|
|
904
|
+
@implementation FBMaxValueAttribute
|
|
905
|
+
|
|
906
|
+
+ (NSString *)name
|
|
907
|
+
{
|
|
908
|
+
return @"maxValue";
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
+ (NSString *)valueForElement:(id<FBElement>)element
|
|
912
|
+
{
|
|
913
|
+
return [element.wdMaxValue stringValue];
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
@end
|
|
@@ -22,6 +22,14 @@ extern NSString *FB_XCAXAIsElementAttributeName;
|
|
|
22
22
|
/*! Accessibility identifier for visible frame attribute */
|
|
23
23
|
extern NSString *FB_XCAXAVisibleFrameAttributeName;
|
|
24
24
|
|
|
25
|
+
/*! Accessibility identifier для минимума */
|
|
26
|
+
extern NSNumber *FB_XCAXACustomMinValueAttribute;
|
|
27
|
+
extern NSString *FB_XCAXACustomMinValueAttributeName;
|
|
28
|
+
|
|
29
|
+
/*! Accessibility identifier для максимума */
|
|
30
|
+
extern NSNumber *FB_XCAXACustomMaxValueAttribute;
|
|
31
|
+
extern NSString *FB_XCAXACustomMaxValueAttributeName;
|
|
32
|
+
|
|
25
33
|
/*! Getter for XCTest logger */
|
|
26
34
|
extern id<XCDebugLogDelegate> (*XCDebugLogger)(void);
|
|
27
35
|
|
|
@@ -19,6 +19,10 @@ NSString *FB_XCAXAIsVisibleAttributeName = @"XC_kAXXCAttributeIsVisible";
|
|
|
19
19
|
NSNumber *FB_XCAXAIsElementAttribute;
|
|
20
20
|
NSString *FB_XCAXAIsElementAttributeName = @"XC_kAXXCAttributeIsElement";
|
|
21
21
|
NSString *FB_XCAXAVisibleFrameAttributeName = @"XC_kAXXCAttributeVisibleFrame";
|
|
22
|
+
NSNumber *FB_XCAXACustomMinValueAttribute;
|
|
23
|
+
NSString *FB_XCAXACustomMinValueAttributeName = @"XC_kAXXCAttributeMinValue";
|
|
24
|
+
NSNumber *FB_XCAXACustomMaxValueAttribute;
|
|
25
|
+
NSString *FB_XCAXACustomMaxValueAttributeName = @"XC_kAXXCAttributeMaxValue";
|
|
22
26
|
|
|
23
27
|
void (*XCSetDebugLogger)(id <XCDebugLogDelegate>);
|
|
24
28
|
id<XCDebugLogDelegate> (*XCDebugLogger)(void);
|
|
@@ -42,6 +46,16 @@ __attribute__((constructor)) void FBLoadXCTestSymbols(void)
|
|
|
42
46
|
|
|
43
47
|
NSCAssert(FB_XCAXAIsVisibleAttribute != nil , @"Failed to retrieve FB_XCAXAIsVisibleAttribute", FB_XCAXAIsVisibleAttribute);
|
|
44
48
|
NSCAssert(FB_XCAXAIsElementAttribute != nil , @"Failed to retrieve FB_XCAXAIsElementAttribute", FB_XCAXAIsElementAttribute);
|
|
49
|
+
|
|
50
|
+
NSString *XC_kAXXCAttributeMinValue = *(NSString *__autoreleasing *)FBRetrieveXCTestSymbol([FB_XCAXACustomMinValueAttributeName UTF8String]);
|
|
51
|
+
NSString *XC_kAXXCAttributeMaxValue = *(NSString *__autoreleasing *)FBRetrieveXCTestSymbol([FB_XCAXACustomMaxValueAttributeName UTF8String]);
|
|
52
|
+
|
|
53
|
+
NSArray<NSNumber *> *minMaxAttrs = XCAXAccessibilityAttributesForStringAttributes(@[XC_kAXXCAttributeMinValue, XC_kAXXCAttributeMaxValue]);
|
|
54
|
+
FB_XCAXACustomMinValueAttribute = minMaxAttrs[0];
|
|
55
|
+
FB_XCAXACustomMaxValueAttribute = minMaxAttrs[1];
|
|
56
|
+
|
|
57
|
+
NSCAssert(FB_XCAXACustomMinValueAttribute != nil, @"Failed to retrieve FB_XCAXACustomMinValueAttribute", FB_XCAXACustomMinValueAttribute);
|
|
58
|
+
NSCAssert(FB_XCAXACustomMaxValueAttribute != nil, @"Failed to retrieve FB_XCAXACustomMaxValueAttribute", FB_XCAXACustomMaxValueAttribute);
|
|
45
59
|
}
|
|
46
60
|
|
|
47
61
|
void *FBRetrieveXCTestSymbol(const char *name)
|
|
@@ -74,7 +88,9 @@ NSArray<NSString*> *FBCustomAttributeNames(void)
|
|
|
74
88
|
dispatch_once(&onceCustomAttributeNamesToken, ^{
|
|
75
89
|
customNames = @[
|
|
76
90
|
FB_XCAXAIsVisibleAttributeName,
|
|
77
|
-
FB_XCAXAIsElementAttributeName
|
|
91
|
+
FB_XCAXAIsElementAttributeName,
|
|
92
|
+
FB_XCAXACustomMinValueAttributeName,
|
|
93
|
+
FB_XCAXACustomMaxValueAttributeName
|
|
78
94
|
];
|
|
79
95
|
});
|
|
80
96
|
return customNames;
|
|
@@ -180,8 +180,18 @@
|
|
|
180
180
|
XCTAssertNil(element.wdName);
|
|
181
181
|
XCTAssertNil(element.wdLabel);
|
|
182
182
|
XCTAssertTrue([element.wdValue containsString:@"50"]);
|
|
183
|
+
|
|
184
|
+
NSNumber *minValue = element.wdMinValue;
|
|
185
|
+
NSNumber *maxValue = element.wdMaxValue;
|
|
186
|
+
|
|
187
|
+
XCTAssertNotNil(minValue, @"Slider minValue should not be nil");
|
|
188
|
+
XCTAssertNotNil(maxValue, @"Slider maxValue should not be nil");
|
|
189
|
+
|
|
190
|
+
XCTAssertEqualObjects(minValue, @0);
|
|
191
|
+
XCTAssertEqualObjects(maxValue, @1);
|
|
183
192
|
}
|
|
184
193
|
|
|
194
|
+
|
|
185
195
|
- (void)testActivityIndicatorAttributes
|
|
186
196
|
{
|
|
187
197
|
XCUIElement *element = self.testedApplication.activityIndicators.element;
|
|
@@ -64,8 +64,8 @@
|
|
|
64
64
|
xpathQuery:nil
|
|
65
65
|
excludingAttributes:nil];
|
|
66
66
|
NSLog(@"[DefaultXPath] Result XML:\n%@", resultXml);
|
|
67
|
-
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\"
|
|
68
|
-
element.wdType, element.wdType, element.wdValue, element.wdName, element.wdLabel, FBBoolToString(element.wdEnabled), FBBoolToString(element.wdVisible), FBBoolToString(element.wdAccessible), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex, element.
|
|
67
|
+
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\" traits=\"%@\" private_indexPath=\"top\"/>\n",
|
|
68
|
+
element.wdType, element.wdType, element.wdValue, element.wdName, element.wdLabel, FBBoolToString(element.wdEnabled), FBBoolToString(element.wdVisible), FBBoolToString(element.wdAccessible), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex, element.wdTraits];
|
|
69
69
|
XCTAssertTrue([resultXml isEqualToString: expectedXml]);
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -76,8 +76,8 @@
|
|
|
76
76
|
NSString *resultXml = [self xmlStringWithElement:(id<FBXCElementSnapshot>)element
|
|
77
77
|
xpathQuery:nil
|
|
78
78
|
excludingAttributes:@[@"type", @"visible", @"value", @"index", @"traits", @"nativeFrame"]];
|
|
79
|
-
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ name=\"%@\" label=\"%@\" enabled=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\"
|
|
80
|
-
element.wdType, element.wdName, element.wdLabel, FBBoolToString(element.wdEnabled), FBBoolToString(element.wdAccessible), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"]
|
|
79
|
+
NSString *expectedXml = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<%@ name=\"%@\" label=\"%@\" enabled=\"%@\" accessible=\"%@\" x=\"%@\" y=\"%@\" width=\"%@\" height=\"%@\" private_indexPath=\"top\"/>\n",
|
|
80
|
+
element.wdType, element.wdName, element.wdLabel, FBBoolToString(element.wdEnabled), FBBoolToString(element.wdAccessible), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"]];
|
|
81
81
|
XCTAssertEqualObjects(resultXml, expectedXml);
|
|
82
82
|
}
|
|
83
83
|
|
|
@@ -90,8 +90,8 @@
|
|
|
90
90
|
NSString *resultXml = [self xmlStringWithElement:(id<FBXCElementSnapshot>)element
|
|
91
91
|
xpathQuery:[NSString stringWithFormat:@"//%@[@*]", element.wdType]
|
|
92
92
|
excludingAttributes:@[@"visible"]];
|
|
93
|
-
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\" hittable=\"%@\"
|
|
94
|
-
element.wdType, element.wdType, @"йоло<>&"", element.wdName, @"a b", FBBoolToString(element.wdEnabled), FBBoolToString(element.wdVisible), FBBoolToString(element.wdAccessible), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex, FBBoolToString(element.wdHittable), element.
|
|
93
|
+
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\" hittable=\"%@\" traits=\"%@\" nativeFrame=\"%@\" private_indexPath=\"top\"/>\n",
|
|
94
|
+
element.wdType, element.wdType, @"йоло<>&"", element.wdName, @"a b", FBBoolToString(element.wdEnabled), FBBoolToString(element.wdVisible), FBBoolToString(element.wdAccessible), element.wdRect[@"x"], element.wdRect[@"y"], element.wdRect[@"width"], element.wdRect[@"height"], element.wdIndex, FBBoolToString(element.wdHittable), element.wdTraits, NSStringFromCGRect(element.wdNativeFrame)];
|
|
95
95
|
XCTAssertEqualObjects(expectedXml, resultXml);
|
|
96
96
|
}
|
|
97
97
|
|