appium-webdriveragent 9.4.1 → 9.5.1
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 +12 -0
- package/WebDriverAgentLib/Categories/XCUIElement+FBClassChain.h +2 -1
- package/WebDriverAgentLib/Commands/FBElementCommands.m +1 -0
- package/WebDriverAgentLib/Commands/FBSessionCommands.m +29 -0
- package/WebDriverAgentLib/Info.plist +2 -2
- package/WebDriverAgentLib/Routing/FBCommandStatus.h +1 -1
- package/WebDriverAgentLib/Routing/FBCommandStatus.m +5 -0
- package/WebDriverAgentLib/Routing/FBResponsePayload.m +4 -1
- package/WebDriverAgentLib/Routing/FBSession.h +16 -0
- package/WebDriverAgentLib/Routing/FBSession.m +42 -7
- package/WebDriverAgentLib/Utilities/FBConfiguration.h +6 -0
- package/WebDriverAgentLib/Utilities/FBConfiguration.m +12 -0
- package/WebDriverAgentLib/Utilities/FBSettings.h +1 -0
- package/WebDriverAgentLib/Utilities/FBSettings.m +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [9.5.1](https://github.com/appium/WebDriverAgent/compare/v9.5.0...v9.5.1) (2025-04-10)
|
|
2
|
+
|
|
3
|
+
### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* Make sure we don't store element snapshot in the cache ([#1001](https://github.com/appium/WebDriverAgent/issues/1001)) ([cfe052b](https://github.com/appium/WebDriverAgent/commit/cfe052bb3adb3f3b24d0a34f386c60cf1516b308))
|
|
6
|
+
|
|
7
|
+
## [9.5.0](https://github.com/appium/WebDriverAgent/compare/v9.4.1...v9.5.0) (2025-04-10)
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* Add support for the autoClickAlertSelector setting ([#1002](https://github.com/appium/WebDriverAgent/issues/1002)) ([fd31b95](https://github.com/appium/WebDriverAgent/commit/fd31b9589199d0a7bc76919f6aa7c7c74c498b90))
|
|
12
|
+
|
|
1
13
|
## [9.4.1](https://github.com/appium/WebDriverAgent/compare/v9.4.0...v9.4.1) (2025-04-05)
|
|
2
14
|
|
|
3
15
|
### Miscellaneous Chores
|
|
@@ -50,7 +50,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
50
50
|
@return an array of descendants matching given class chain
|
|
51
51
|
@throws FBUnknownAttributeException if any of predicates in the chain contains unknown attribute(s)
|
|
52
52
|
*/
|
|
53
|
-
- (NSArray<XCUIElement *> *)fb_descendantsMatchingClassChain:(NSString *)classChainQuery
|
|
53
|
+
- (NSArray<XCUIElement *> *)fb_descendantsMatchingClassChain:(NSString *)classChainQuery
|
|
54
|
+
shouldReturnAfterFirstMatch:(BOOL)shouldReturnAfterFirstMatch;
|
|
54
55
|
|
|
55
56
|
@end
|
|
56
57
|
|
|
@@ -269,6 +269,7 @@
|
|
|
269
269
|
NSString *focusedUUID = [elementCache storeElement:(useNativeCachingStrategy
|
|
270
270
|
? focusedElement
|
|
271
271
|
: [focusedElement fb_stableInstanceWithUid:focusedElement.fb_uid])];
|
|
272
|
+
focusedElement.lastSnapshot = nil;
|
|
272
273
|
if (focusedUUID && [focusedUUID isEqualToString:(id)request.parameters[@"uuid"]]) {
|
|
273
274
|
isFocused = YES;
|
|
274
275
|
}
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
#import "FBSessionCommands.h"
|
|
11
11
|
|
|
12
12
|
#import "FBCapabilities.h"
|
|
13
|
+
#import "FBClassChainQueryParser.h"
|
|
13
14
|
#import "FBConfiguration.h"
|
|
14
15
|
#import "FBExceptions.h"
|
|
15
16
|
#import "FBLogger.h"
|
|
@@ -347,6 +348,7 @@
|
|
|
347
348
|
FB_SETTING_INCLUDE_NON_MODAL_ELEMENTS: @([FBConfiguration includeNonModalElements]),
|
|
348
349
|
FB_SETTING_ACCEPT_ALERT_BUTTON_SELECTOR: FBConfiguration.acceptAlertButtonSelector,
|
|
349
350
|
FB_SETTING_DISMISS_ALERT_BUTTON_SELECTOR: FBConfiguration.dismissAlertButtonSelector,
|
|
351
|
+
FB_SETTING_AUTO_CLICK_ALERT_SELECTOR: FBConfiguration.autoClickAlertSelector,
|
|
350
352
|
FB_SETTING_DEFAULT_ALERT_ACTION: request.session.defaultAlertAction ?: @"",
|
|
351
353
|
FB_SETTING_MAX_TYPING_FREQUENCY: @([FBConfiguration maxTypingFrequency]),
|
|
352
354
|
FB_SETTING_RESPECT_SYSTEM_ALERTS: @([FBConfiguration shouldRespectSystemAlerts]),
|
|
@@ -431,6 +433,13 @@
|
|
|
431
433
|
if (nil != [settings objectForKey:FB_SETTING_DISMISS_ALERT_BUTTON_SELECTOR]) {
|
|
432
434
|
[FBConfiguration setDismissAlertButtonSelector:(NSString *)[settings objectForKey:FB_SETTING_DISMISS_ALERT_BUTTON_SELECTOR]];
|
|
433
435
|
}
|
|
436
|
+
if (nil != [settings objectForKey:FB_SETTING_AUTO_CLICK_ALERT_SELECTOR]) {
|
|
437
|
+
FBCommandStatus *status = [self.class configureAutoClickAlertWithSelector:settings[FB_SETTING_AUTO_CLICK_ALERT_SELECTOR]
|
|
438
|
+
forSession:request.session];
|
|
439
|
+
if (status.hasError) {
|
|
440
|
+
return FBResponseWithStatus(status);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
434
443
|
if (nil != [settings objectForKey:FB_SETTING_WAIT_FOR_IDLE_TIMEOUT]) {
|
|
435
444
|
[FBConfiguration setWaitForIdleTimeout:[[settings objectForKey:FB_SETTING_WAIT_FOR_IDLE_TIMEOUT] doubleValue]];
|
|
436
445
|
}
|
|
@@ -467,6 +476,26 @@
|
|
|
467
476
|
|
|
468
477
|
#pragma mark - Helpers
|
|
469
478
|
|
|
479
|
+
+ (FBCommandStatus *)configureAutoClickAlertWithSelector:(NSString *)selector
|
|
480
|
+
forSession:(FBSession *)session
|
|
481
|
+
{
|
|
482
|
+
if (0 == [selector length]) {
|
|
483
|
+
[FBConfiguration setAutoClickAlertSelector:selector];
|
|
484
|
+
[session disableAlertsMonitor];
|
|
485
|
+
return [FBCommandStatus ok];
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
NSError *error;
|
|
489
|
+
FBClassChain *parsedChain = [FBClassChainQueryParser parseQuery:selector error:&error];
|
|
490
|
+
if (nil == parsedChain) {
|
|
491
|
+
return [FBCommandStatus invalidSelectorErrorWithMessage:error.localizedDescription
|
|
492
|
+
traceback:nil];
|
|
493
|
+
}
|
|
494
|
+
[FBConfiguration setAutoClickAlertSelector:selector];
|
|
495
|
+
[session enableAlertsMonitor];
|
|
496
|
+
return [FBCommandStatus ok];
|
|
497
|
+
}
|
|
498
|
+
|
|
470
499
|
+ (NSString *)buildTimestamp
|
|
471
500
|
{
|
|
472
501
|
return [NSString stringWithFormat:@"%@ %@",
|
|
@@ -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.5.1</string>
|
|
19
19
|
<key>CFBundleSignature</key>
|
|
20
20
|
<string>????</string>
|
|
21
21
|
<key>CFBundleVersion</key>
|
|
22
|
-
<string>9.
|
|
22
|
+
<string>9.5.1</string>
|
|
23
23
|
<key>NSPrincipalClass</key>
|
|
24
24
|
<string/>
|
|
25
25
|
</dict>
|
|
@@ -19,7 +19,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
19
19
|
@property (nonatomic, nullable, readonly) NSString* message;
|
|
20
20
|
@property (nonatomic, nullable, readonly) NSString* traceback;
|
|
21
21
|
@property (nonatomic, readonly) HTTPStatusCode statusCode;
|
|
22
|
-
|
|
22
|
+
@property (nonatomic, readonly) BOOL hasError;
|
|
23
23
|
|
|
24
24
|
+ (instancetype)ok;
|
|
25
25
|
|
|
@@ -109,6 +109,11 @@ static NSString *const FB_NO_SUCH_DRIVER_MSG = @"A session is either terminated
|
|
|
109
109
|
return self;
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
- (BOOL)hasError
|
|
113
|
+
{
|
|
114
|
+
return self.statusCode != kHTTPStatusCodeOK;
|
|
115
|
+
}
|
|
116
|
+
|
|
112
117
|
+ (instancetype)ok
|
|
113
118
|
{
|
|
114
119
|
return [[FBCommandStatus alloc] initWithValue:nil];
|
|
@@ -55,7 +55,9 @@ XCUIElement *maybeStable(XCUIElement *element)
|
|
|
55
55
|
id<FBResponsePayload> FBResponseWithCachedElement(XCUIElement *element, FBElementCache *elementCache, BOOL compact)
|
|
56
56
|
{
|
|
57
57
|
[elementCache storeElement:maybeStable(element)];
|
|
58
|
-
|
|
58
|
+
NSDictionary *response = FBDictionaryResponseWithElement(element, compact);
|
|
59
|
+
element.lastSnapshot = nil;
|
|
60
|
+
return FBResponseWithStatus([FBCommandStatus okWithValue:response]);
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
id<FBResponsePayload> FBResponseWithCachedElements(NSArray<XCUIElement *> *elements, FBElementCache *elementCache, BOOL compact)
|
|
@@ -64,6 +66,7 @@ id<FBResponsePayload> FBResponseWithCachedElements(NSArray<XCUIElement *> *eleme
|
|
|
64
66
|
for (XCUIElement *element in elements) {
|
|
65
67
|
[elementCache storeElement:maybeStable(element)];
|
|
66
68
|
[elementsResponse addObject:FBDictionaryResponseWithElement(element, compact)];
|
|
69
|
+
element.lastSnapshot = nil;
|
|
67
70
|
}
|
|
68
71
|
return FBResponseWithStatus([FBCommandStatus okWithValue:elementsResponse]);
|
|
69
72
|
}
|
|
@@ -121,6 +121,22 @@ extern NSString* const FB_SAFARI_BUNDLE_ID;
|
|
|
121
121
|
*/
|
|
122
122
|
- (NSUInteger)applicationStateWithBundleId:(NSString *)bundleIdentifier;
|
|
123
123
|
|
|
124
|
+
/**
|
|
125
|
+
Allows to enable automated session alerts monitoring.
|
|
126
|
+
Repeated calls are ignored if alerts monitoring has been already enabled.
|
|
127
|
+
|
|
128
|
+
@returns YES if the actual alerts monitoring state has been changed
|
|
129
|
+
*/
|
|
130
|
+
- (BOOL)enableAlertsMonitor;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
Allows to disable automated alerts monitoring
|
|
134
|
+
Repeated calls are ignored if alerts monitoring has been already disabled.
|
|
135
|
+
|
|
136
|
+
@returns YES if the actual alerts monitoring state has been changed
|
|
137
|
+
*/
|
|
138
|
+
- (BOOL)disableAlertsMonitor;
|
|
139
|
+
|
|
124
140
|
@end
|
|
125
141
|
|
|
126
142
|
NS_ASSUME_NONNULL_END
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
#import "FBXCTestDaemonsProxy.h"
|
|
26
26
|
#import "XCUIApplication+FBQuiescence.h"
|
|
27
27
|
#import "XCUIElement.h"
|
|
28
|
+
#import "XCUIElement+FBClassChain.h"
|
|
28
29
|
|
|
29
30
|
/*!
|
|
30
31
|
The intial value for the default application property.
|
|
@@ -53,6 +54,22 @@ NSString *const FB_SAFARI_BUNDLE_ID = @"com.apple.mobilesafari";
|
|
|
53
54
|
|
|
54
55
|
- (void)didDetectAlert:(FBAlert *)alert
|
|
55
56
|
{
|
|
57
|
+
NSString *autoClickAlertSelector = FBConfiguration.autoClickAlertSelector;
|
|
58
|
+
if ([autoClickAlertSelector length] > 0) {
|
|
59
|
+
@try {
|
|
60
|
+
NSArray<XCUIElement*> *matches = [alert.alertElement fb_descendantsMatchingClassChain:autoClickAlertSelector
|
|
61
|
+
shouldReturnAfterFirstMatch:YES];
|
|
62
|
+
if (matches.count > 0) {
|
|
63
|
+
[[matches objectAtIndex:0] tap];
|
|
64
|
+
}
|
|
65
|
+
} @catch (NSException *e) {
|
|
66
|
+
[FBLogger logFmt:@"Could not click at the alert element '%@'. Original error: %@",
|
|
67
|
+
autoClickAlertSelector, e.description];
|
|
68
|
+
}
|
|
69
|
+
// This setting has priority over other settings if enabled
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
56
73
|
if (nil == self.defaultAlertAction || 0 == self.defaultAlertAction.length) {
|
|
57
74
|
return;
|
|
58
75
|
}
|
|
@@ -125,23 +142,41 @@ static FBSession *_activeSession = nil;
|
|
|
125
142
|
defaultAlertAction:(NSString *)defaultAlertAction
|
|
126
143
|
{
|
|
127
144
|
FBSession *session = [self.class initWithApplication:application];
|
|
128
|
-
session.alertsMonitor = [[FBAlertsMonitor alloc] init];
|
|
129
|
-
session.alertsMonitor.delegate = (id<FBAlertsMonitorDelegate>)session;
|
|
130
145
|
session.defaultAlertAction = [defaultAlertAction lowercaseString];
|
|
131
|
-
[session
|
|
146
|
+
[session enableAlertsMonitor];
|
|
132
147
|
return session;
|
|
133
148
|
}
|
|
134
149
|
|
|
150
|
+
- (BOOL)enableAlertsMonitor
|
|
151
|
+
{
|
|
152
|
+
if (nil != self.alertsMonitor) {
|
|
153
|
+
return NO;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
self.alertsMonitor = [[FBAlertsMonitor alloc] init];
|
|
157
|
+
self.alertsMonitor.delegate = (id<FBAlertsMonitorDelegate>)self;
|
|
158
|
+
[self.alertsMonitor enable];
|
|
159
|
+
return YES;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
- (BOOL)disableAlertsMonitor
|
|
163
|
+
{
|
|
164
|
+
if (nil == self.alertsMonitor) {
|
|
165
|
+
return NO;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
[self.alertsMonitor disable];
|
|
169
|
+
self.alertsMonitor = nil;
|
|
170
|
+
return YES;
|
|
171
|
+
}
|
|
172
|
+
|
|
135
173
|
- (void)kill
|
|
136
174
|
{
|
|
137
175
|
if (nil == _activeSession) {
|
|
138
176
|
return;
|
|
139
177
|
}
|
|
140
178
|
|
|
141
|
-
|
|
142
|
-
[self.alertsMonitor disable];
|
|
143
|
-
self.alertsMonitor = nil;
|
|
144
|
-
}
|
|
179
|
+
[self disableAlertsMonitor];
|
|
145
180
|
|
|
146
181
|
FBScreenRecordingPromise *activeScreenRecording = FBScreenRecordingContainer.sharedInstance.screenRecordingPromise;
|
|
147
182
|
if (nil != activeScreenRecording) {
|
|
@@ -283,6 +283,12 @@ typedef NS_ENUM(NSInteger, FBConfigurationKeyboardPreference) {
|
|
|
283
283
|
+ (void)setDismissAlertButtonSelector:(NSString *)classChainSelector;
|
|
284
284
|
+ (NSString *)dismissAlertButtonSelector;
|
|
285
285
|
|
|
286
|
+
/**
|
|
287
|
+
Sets class chain selector to apply for an automated alert click
|
|
288
|
+
*/
|
|
289
|
+
+ (void)setAutoClickAlertSelector:(NSString *)classChainSelector;
|
|
290
|
+
+ (NSString *)autoClickAlertSelector;
|
|
291
|
+
|
|
286
292
|
/**
|
|
287
293
|
* Whether to use HIDEvent for text clear.
|
|
288
294
|
* By default this is enabled and HIDEvent is used for text clear.
|
|
@@ -51,6 +51,7 @@ static BOOL FBShouldBoundElementsByIndex;
|
|
|
51
51
|
static BOOL FBIncludeNonModalElements;
|
|
52
52
|
static NSString *FBAcceptAlertButtonSelector;
|
|
53
53
|
static NSString *FBDismissAlertButtonSelector;
|
|
54
|
+
static NSString *FBAutoClickAlertSelector;
|
|
54
55
|
static NSTimeInterval FBWaitForIdleTimeout;
|
|
55
56
|
static NSTimeInterval FBAnimationCoolOffTimeout;
|
|
56
57
|
static BOOL FBShouldUseCompactResponses;
|
|
@@ -429,6 +430,16 @@ static UIInterfaceOrientation FBScreenshotOrientation;
|
|
|
429
430
|
return FBDismissAlertButtonSelector;
|
|
430
431
|
}
|
|
431
432
|
|
|
433
|
+
+ (void)setAutoClickAlertSelector:(NSString *)classChainSelector
|
|
434
|
+
{
|
|
435
|
+
FBAutoClickAlertSelector = classChainSelector;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
+ (NSString *)autoClickAlertSelector
|
|
439
|
+
{
|
|
440
|
+
return FBAutoClickAlertSelector;
|
|
441
|
+
}
|
|
442
|
+
|
|
432
443
|
+ (void)setUseClearTextShortcut:(BOOL)enabled
|
|
433
444
|
{
|
|
434
445
|
FBUseClearTextShortcut = enabled;
|
|
@@ -509,6 +520,7 @@ static UIInterfaceOrientation FBScreenshotOrientation;
|
|
|
509
520
|
FBIncludeNonModalElements = NO;
|
|
510
521
|
FBAcceptAlertButtonSelector = @"";
|
|
511
522
|
FBDismissAlertButtonSelector = @"";
|
|
523
|
+
FBAutoClickAlertSelector = @"";
|
|
512
524
|
FBWaitForIdleTimeout = 10.;
|
|
513
525
|
FBAnimationCoolOffTimeout = 2.;
|
|
514
526
|
// 50 should be enough for the majority of the cases. The performance is acceptable for values up to 100.
|
|
@@ -39,6 +39,7 @@ extern NSString* const FB_SETTING_MAX_TYPING_FREQUENCY;
|
|
|
39
39
|
extern NSString* const FB_SETTING_RESPECT_SYSTEM_ALERTS;
|
|
40
40
|
extern NSString* const FB_SETTING_USE_CLEAR_TEXT_SHORTCUT;
|
|
41
41
|
extern NSString* const FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE;
|
|
42
|
+
extern NSString* const FB_SETTING_AUTO_CLICK_ALERT_SELECTOR;
|
|
42
43
|
|
|
43
44
|
|
|
44
45
|
NS_ASSUME_NONNULL_END
|
|
@@ -35,3 +35,4 @@ NSString* const FB_SETTING_MAX_TYPING_FREQUENCY = @"maxTypingFrequency";
|
|
|
35
35
|
NSString* const FB_SETTING_RESPECT_SYSTEM_ALERTS = @"respectSystemAlerts";
|
|
36
36
|
NSString* const FB_SETTING_USE_CLEAR_TEXT_SHORTCUT = @"useClearTextShortcut";
|
|
37
37
|
NSString* const FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE = @"limitXPathContextScope";
|
|
38
|
+
NSString* const FB_SETTING_AUTO_CLICK_ALERT_SELECTOR = @"autoClickAlertSelector";
|