appium-webdriveragent 9.4.1 → 9.5.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 CHANGED
@@ -1,3 +1,9 @@
1
+ ## [9.5.0](https://github.com/appium/WebDriverAgent/compare/v9.4.1...v9.5.0) (2025-04-10)
2
+
3
+ ### Features
4
+
5
+ * Add support for the autoClickAlertSelector setting ([#1002](https://github.com/appium/WebDriverAgent/issues/1002)) ([fd31b95](https://github.com/appium/WebDriverAgent/commit/fd31b9589199d0a7bc76919f6aa7c7c74c498b90))
6
+
1
7
  ## [9.4.1](https://github.com/appium/WebDriverAgent/compare/v9.4.0...v9.4.1) (2025-04-05)
2
8
 
3
9
  ### 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 shouldReturnAfterFirstMatch:(BOOL)shouldReturnAfterFirstMatch;
53
+ - (NSArray<XCUIElement *> *)fb_descendantsMatchingClassChain:(NSString *)classChainQuery
54
+ shouldReturnAfterFirstMatch:(BOOL)shouldReturnAfterFirstMatch;
54
55
 
55
56
  @end
56
57
 
@@ -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.4.1</string>
18
+ <string>9.5.0</string>
19
19
  <key>CFBundleSignature</key>
20
20
  <string>????</string>
21
21
  <key>CFBundleVersion</key>
22
- <string>9.4.1</string>
22
+ <string>9.5.0</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];
@@ -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.alertsMonitor enable];
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
- if (nil != self.alertsMonitor) {
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";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium-webdriveragent",
3
- "version": "9.4.1",
3
+ "version": "9.5.0",
4
4
  "description": "Package bundling WebDriverAgent",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",