appium-webdriveragent 13.2.0 → 13.2.2
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/WebDriverAgent.xcodeproj/project.pbxproj +12 -0
- package/WebDriverAgentLib/Commands/FBSessionCommands.m +171 -271
- package/WebDriverAgentLib/Info.plist +2 -2
- package/WebDriverAgentLib/Utilities/FBSettingsHandler.h +35 -0
- package/WebDriverAgentLib/Utilities/FBSettingsHandler.m +356 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## [13.2.2](https://github.com/appium/WebDriverAgent/compare/v13.2.1...v13.2.2) (2026-06-06)
|
|
2
|
+
|
|
3
|
+
### Miscellaneous Chores
|
|
4
|
+
|
|
5
|
+
* Refactor session creation handler ([#1149](https://github.com/appium/WebDriverAgent/issues/1149)) ([923b523](https://github.com/appium/WebDriverAgent/commit/923b523b55f880b921de2c95a82786ce0699cb9d))
|
|
6
|
+
|
|
7
|
+
## [13.2.1](https://github.com/appium/WebDriverAgent/compare/v13.2.0...v13.2.1) (2026-06-06)
|
|
8
|
+
|
|
9
|
+
### Miscellaneous Chores
|
|
10
|
+
|
|
11
|
+
* Refactor settings handling API ([#1148](https://github.com/appium/WebDriverAgent/issues/1148)) ([ff7ac36](https://github.com/appium/WebDriverAgent/commit/ff7ac368debb22659509169a0eca530bae3dc879))
|
|
12
|
+
|
|
1
13
|
## [13.2.0](https://github.com/appium/WebDriverAgent/compare/v13.1.3...v13.2.0) (2026-05-26)
|
|
2
14
|
|
|
3
15
|
### Features
|
|
@@ -522,6 +522,10 @@
|
|
|
522
522
|
71F3E7D525417FF400E0C22B /* FBSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = 71F3E7D225417FF400E0C22B /* FBSettings.h */; };
|
|
523
523
|
71F3E7D625417FF400E0C22B /* FBSettings.m in Sources */ = {isa = PBXBuildFile; fileRef = 71F3E7D325417FF400E0C22B /* FBSettings.m */; };
|
|
524
524
|
71F3E7D725417FF400E0C22B /* FBSettings.m in Sources */ = {isa = PBXBuildFile; fileRef = 71F3E7D325417FF400E0C22B /* FBSettings.m */; };
|
|
525
|
+
71F3E7D825417FF400E0C22C /* FBSettingsHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 71F3E7D625417FF400E0C22C /* FBSettingsHandler.h */; };
|
|
526
|
+
71F3E7D925417FF400E0C22C /* FBSettingsHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 71F3E7D625417FF400E0C22C /* FBSettingsHandler.h */; };
|
|
527
|
+
71F3E7DA25417FF400E0C22C /* FBSettingsHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 71F3E7D725417FF400E0C22C /* FBSettingsHandler.m */; };
|
|
528
|
+
71F3E7DB25417FF400E0C22C /* FBSettingsHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 71F3E7D725417FF400E0C22C /* FBSettingsHandler.m */; };
|
|
525
529
|
71F5BE23252E576C00EE9EBA /* XCUIElement+FBSwiping.h in Headers */ = {isa = PBXBuildFile; fileRef = 71F5BE21252E576C00EE9EBA /* XCUIElement+FBSwiping.h */; };
|
|
526
530
|
71F5BE24252E576C00EE9EBA /* XCUIElement+FBSwiping.h in Headers */ = {isa = PBXBuildFile; fileRef = 71F5BE21252E576C00EE9EBA /* XCUIElement+FBSwiping.h */; };
|
|
527
531
|
71F5BE25252E576C00EE9EBA /* XCUIElement+FBSwiping.m in Sources */ = {isa = PBXBuildFile; fileRef = 71F5BE22252E576C00EE9EBA /* XCUIElement+FBSwiping.m */; };
|
|
@@ -1114,6 +1118,8 @@
|
|
|
1114
1118
|
71E75E6C254824230099FC87 /* XCUIElementQuery+FBHelpers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "XCUIElementQuery+FBHelpers.m"; sourceTree = "<group>"; };
|
|
1115
1119
|
71F3E7D225417FF400E0C22B /* FBSettings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSettings.h; sourceTree = "<group>"; };
|
|
1116
1120
|
71F3E7D325417FF400E0C22B /* FBSettings.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSettings.m; sourceTree = "<group>"; };
|
|
1121
|
+
71F3E7D625417FF400E0C22C /* FBSettingsHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FBSettingsHandler.h; sourceTree = "<group>"; };
|
|
1122
|
+
71F3E7D725417FF400E0C22C /* FBSettingsHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBSettingsHandler.m; sourceTree = "<group>"; };
|
|
1117
1123
|
71F5BE21252E576C00EE9EBA /* XCUIElement+FBSwiping.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XCUIElement+FBSwiping.h"; sourceTree = "<group>"; };
|
|
1118
1124
|
71F5BE22252E576C00EE9EBA /* XCUIElement+FBSwiping.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "XCUIElement+FBSwiping.m"; sourceTree = "<group>"; };
|
|
1119
1125
|
71F5BE33252E5B2200EE9EBA /* FBElementSwipingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FBElementSwipingTests.m; sourceTree = "<group>"; };
|
|
@@ -1982,6 +1988,8 @@
|
|
|
1982
1988
|
EE9AB7921CAEDF0C008C271F /* FBRuntimeUtils.m */,
|
|
1983
1989
|
71F3E7D225417FF400E0C22B /* FBSettings.h */,
|
|
1984
1990
|
71F3E7D325417FF400E0C22B /* FBSettings.m */,
|
|
1991
|
+
71F3E7D625417FF400E0C22C /* FBSettingsHandler.h */,
|
|
1992
|
+
71F3E7D725417FF400E0C22C /* FBSettingsHandler.m */,
|
|
1985
1993
|
715AFABF1FFA29180053896D /* FBScreen.h */,
|
|
1986
1994
|
715AFAC01FFA29180053896D /* FBScreen.m */,
|
|
1987
1995
|
71C9EAAA25E8415A00470CD8 /* FBScreenshot.h */,
|
|
@@ -2333,6 +2341,7 @@
|
|
|
2333
2341
|
13DE7A50287C46BB003243C6 /* FBXCElementSnapshot.h in Headers */,
|
|
2334
2342
|
13DE7A56287CA1EC003243C6 /* FBXCElementSnapshotWrapper.h in Headers */,
|
|
2335
2343
|
71F3E7D525417FF400E0C22B /* FBSettings.h in Headers */,
|
|
2344
|
+
71F3E7D825417FF400E0C22C /* FBSettingsHandler.h in Headers */,
|
|
2336
2345
|
641EE63A2240C5CA00173FCB /* XCTest.h in Headers */,
|
|
2337
2346
|
641EE63B2240C5CA00173FCB /* FBAlertsMonitor.h in Headers */,
|
|
2338
2347
|
641EE63D2240C5CA00173FCB /* FBSession.h in Headers */,
|
|
@@ -2746,6 +2755,7 @@
|
|
|
2746
2755
|
719DCF152601EAFB000E765F /* FBNotificationsHelper.h in Headers */,
|
|
2747
2756
|
EE35AD4A1E3B77D600A02D78 /* XCTestExpectationDelegate-Protocol.h in Headers */,
|
|
2748
2757
|
71F3E7D425417FF400E0C22B /* FBSettings.h in Headers */,
|
|
2758
|
+
71F3E7D925417FF400E0C22C /* FBSettingsHandler.h in Headers */,
|
|
2749
2759
|
EE35AD641E3B77D600A02D78 /* XCTUIApplicationMonitor-Protocol.h in Headers */,
|
|
2750
2760
|
EE35AD591E3B77D600A02D78 /* XCTKVOExpectation.h in Headers */,
|
|
2751
2761
|
13DE7A43287C2A8D003243C6 /* FBXCAccessibilityElement.h in Headers */,
|
|
@@ -3159,6 +3169,7 @@
|
|
|
3159
3169
|
E444DCD624917A5E0060D7EB /* DDRange.m in Sources */,
|
|
3160
3170
|
641EE5D72240C5CA00173FCB /* FBScreenshotCommands.m in Sources */,
|
|
3161
3171
|
71F3E7D725417FF400E0C22B /* FBSettings.m in Sources */,
|
|
3172
|
+
71F3E7DA25417FF400E0C22C /* FBSettingsHandler.m in Sources */,
|
|
3162
3173
|
641EE5D92240C5CA00173FCB /* XCUIElement+FBPickerWheel.m in Sources */,
|
|
3163
3174
|
641EE5DA2240C5CA00173FCB /* XCUIApplicationProcessDelay.m in Sources */,
|
|
3164
3175
|
641EE5DB2240C5CA00173FCB /* FBXPath.m in Sources */,
|
|
@@ -3374,6 +3385,7 @@
|
|
|
3374
3385
|
EE158AB91CBD456F00A3E3F0 /* FBAlertViewCommands.m in Sources */,
|
|
3375
3386
|
71BB58F12B96511800CB9BFE /* FBVideoCommands.m in Sources */,
|
|
3376
3387
|
71F3E7D625417FF400E0C22B /* FBSettings.m in Sources */,
|
|
3388
|
+
71F3E7DB25417FF400E0C22C /* FBSettingsHandler.m in Sources */,
|
|
3377
3389
|
13DE7A57287CA1EC003243C6 /* FBXCElementSnapshotWrapper.m in Sources */,
|
|
3378
3390
|
71BB58F82B96531900CB9BFE /* FBScreenRecordingContainer.m in Sources */,
|
|
3379
3391
|
EE158AB31CBD456F00A3E3F0 /* XCUIElement+FBScrolling.m in Sources */,
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
#import "FBSessionCommands.h"
|
|
10
10
|
|
|
11
11
|
#import "FBCapabilities.h"
|
|
12
|
-
#import "FBClassChainQueryParser.h"
|
|
13
12
|
#import "FBConfiguration.h"
|
|
14
13
|
#import "FBExceptions.h"
|
|
15
14
|
#import "FBLogger.h"
|
|
@@ -17,8 +16,8 @@
|
|
|
17
16
|
#import "FBRouteRequest.h"
|
|
18
17
|
#import "FBSession.h"
|
|
19
18
|
#import "FBSettings.h"
|
|
19
|
+
#import "FBSettingsHandler.h"
|
|
20
20
|
#import "FBRuntimeUtils.h"
|
|
21
|
-
#import "FBActiveAppDetectionPoint.h"
|
|
22
21
|
#import "FBXCodeCompatibility.h"
|
|
23
22
|
#import "XCUIApplication+FBHelpers.h"
|
|
24
23
|
#import "XCUIApplication+FBQuiescence.h"
|
|
@@ -91,134 +90,35 @@
|
|
|
91
90
|
}
|
|
92
91
|
|
|
93
92
|
NSDictionary<NSString *, id> *capabilities;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
if (nil == (capabilities = FBParseCapabilities((NSDictionary *)request.arguments[@"capabilities"], &error))) {
|
|
100
|
-
return FBResponseWithStatus([FBCommandStatus sessionNotCreatedError:error.localizedDescription traceback:nil]);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
[FBConfiguration resetSessionSettings];
|
|
104
|
-
if (capabilities[FB_SETTING_USE_COMPACT_RESPONSES]) {
|
|
105
|
-
[FBConfiguration setShouldUseCompactResponses:[capabilities[FB_SETTING_USE_COMPACT_RESPONSES] boolValue]];
|
|
106
|
-
}
|
|
107
|
-
NSString *elementResponseAttributes = capabilities[FB_SETTING_ELEMENT_RESPONSE_ATTRIBUTES];
|
|
108
|
-
if (elementResponseAttributes) {
|
|
109
|
-
[FBConfiguration setElementResponseAttributes:elementResponseAttributes];
|
|
110
|
-
}
|
|
111
|
-
if (capabilities[FB_CAP_MAX_TYPING_FREQUENCY]) {
|
|
112
|
-
[FBConfiguration setMaxTypingFrequency:[capabilities[FB_CAP_MAX_TYPING_FREQUENCY] unsignedIntegerValue]];
|
|
113
|
-
}
|
|
114
|
-
if (capabilities[FB_CAP_USE_SINGLETON_TEST_MANAGER]) {
|
|
115
|
-
[FBConfiguration setShouldUseSingletonTestManager:[capabilities[FB_CAP_USE_SINGLETON_TEST_MANAGER] boolValue]];
|
|
116
|
-
}
|
|
117
|
-
if (capabilities[FB_CAP_DISABLE_AUTOMATIC_SCREENSHOTS]) {
|
|
118
|
-
if ([capabilities[FB_CAP_DISABLE_AUTOMATIC_SCREENSHOTS] boolValue]) {
|
|
119
|
-
[FBConfiguration disableScreenshots];
|
|
120
|
-
} else {
|
|
121
|
-
[FBConfiguration enableScreenshots];
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
if (capabilities[FB_CAP_SHOULD_TERMINATE_APP]) {
|
|
125
|
-
[FBConfiguration setShouldTerminateApp:[capabilities[FB_CAP_SHOULD_TERMINATE_APP] boolValue]];
|
|
126
|
-
}
|
|
127
|
-
NSNumber *delay = capabilities[FB_CAP_EVENT_LOOP_IDLE_DELAY_SEC];
|
|
128
|
-
if ([delay doubleValue] > 0.0) {
|
|
129
|
-
[XCUIApplicationProcessDelay setEventLoopHasIdledDelay:[delay doubleValue]];
|
|
130
|
-
} else {
|
|
131
|
-
[XCUIApplicationProcessDelay disableEventLoopDelay];
|
|
93
|
+
id<FBResponsePayload> errorResponse = [self capabilitiesFromCreateSessionRequest:request
|
|
94
|
+
capabilitiesOut:&capabilities];
|
|
95
|
+
if (nil != errorResponse) {
|
|
96
|
+
return errorResponse;
|
|
132
97
|
}
|
|
133
98
|
|
|
134
|
-
|
|
135
|
-
FBConfiguration.waitForIdleTimeout = [capabilities[FB_SETTING_WAIT_FOR_IDLE_TIMEOUT] doubleValue];
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (nil == capabilities[FB_CAP_FORCE_SIMULATOR_SOFTWARE_KEYBOARD_PRESENCE] ||
|
|
139
|
-
[capabilities[FB_CAP_FORCE_SIMULATOR_SOFTWARE_KEYBOARD_PRESENCE] boolValue]) {
|
|
140
|
-
[FBConfiguration forceSimulatorSoftwareKeyboardPresence];
|
|
141
|
-
}
|
|
99
|
+
[self applyConfigurationFromCapabilities:capabilities];
|
|
142
100
|
|
|
143
101
|
NSString *bundleID = capabilities[FB_CAP_BUNDLE_ID];
|
|
144
102
|
NSString *initialUrl = capabilities[FB_CAP_INITIAL_URL];
|
|
145
103
|
XCUIApplication *app = nil;
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
XCUIApplicationState appState = app.state;
|
|
153
|
-
BOOL isAppRunning = appState >= XCUIApplicationStateRunningBackground;
|
|
154
|
-
if (!isAppRunning || (isAppRunning && forceAppLaunch)) {
|
|
155
|
-
app.fb_shouldWaitForQuiescence = nil == capabilities[FB_CAP_SHOULD_WAIT_FOR_QUIESCENCE]
|
|
156
|
-
|| [capabilities[FB_CAP_SHOULD_WAIT_FOR_QUIESCENCE] boolValue];
|
|
157
|
-
app.launchArguments = (NSArray<NSString *> *)capabilities[FB_CAP_ARGUMENTS] ?: @[];
|
|
158
|
-
app.launchEnvironment = (NSDictionary <NSString *, NSString *> *)capabilities[FB_CAP_ENVIRNOMENT] ?: @{};
|
|
159
|
-
if (nil != initialUrl) {
|
|
160
|
-
if (app.running) {
|
|
161
|
-
[app terminate];
|
|
162
|
-
}
|
|
163
|
-
id<FBResponsePayload> errorResponse = [self openDeepLink:initialUrl
|
|
164
|
-
withApplication:bundleID
|
|
165
|
-
timeout:capabilities[FB_CAP_APP_LAUNCH_STATE_TIMEOUT_SEC]];
|
|
166
|
-
if (nil != errorResponse) {
|
|
167
|
-
return errorResponse;
|
|
168
|
-
}
|
|
169
|
-
} else {
|
|
170
|
-
NSTimeInterval defaultTimeout = _XCTApplicationStateTimeout();
|
|
171
|
-
if (nil != capabilities[FB_CAP_APP_LAUNCH_STATE_TIMEOUT_SEC]) {
|
|
172
|
-
_XCTSetApplicationStateTimeout([capabilities[FB_CAP_APP_LAUNCH_STATE_TIMEOUT_SEC] doubleValue]);
|
|
173
|
-
}
|
|
174
|
-
@try {
|
|
175
|
-
[app launch];
|
|
176
|
-
} @catch (NSException *e) {
|
|
177
|
-
return FBResponseWithStatus([FBCommandStatus sessionNotCreatedError:e.reason traceback:nil]);
|
|
178
|
-
} @finally {
|
|
179
|
-
if (nil != capabilities[FB_CAP_APP_LAUNCH_STATE_TIMEOUT_SEC]) {
|
|
180
|
-
_XCTSetApplicationStateTimeout(defaultTimeout);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
if (!app.running) {
|
|
185
|
-
NSString *errorMsg = [NSString stringWithFormat:@"Cannot launch %@ application. Make sure the correct bundle identifier has been provided in capabilities and check the device log for possible crash report occurrences", bundleID];
|
|
186
|
-
return FBResponseWithStatus([FBCommandStatus sessionNotCreatedError:errorMsg
|
|
187
|
-
traceback:nil]);
|
|
188
|
-
}
|
|
189
|
-
} else if (appState == XCUIApplicationStateRunningBackground && !forceAppLaunch) {
|
|
190
|
-
if (nil != initialUrl) {
|
|
191
|
-
id<FBResponsePayload> errorResponse = [self openDeepLink:initialUrl
|
|
192
|
-
withApplication:bundleID
|
|
193
|
-
timeout:nil];
|
|
194
|
-
if (nil != errorResponse) {
|
|
195
|
-
return errorResponse;
|
|
196
|
-
}
|
|
197
|
-
} else {
|
|
198
|
-
[app activate];
|
|
199
|
-
}
|
|
200
|
-
}
|
|
104
|
+
errorResponse = [self prepareApplicationForSessionWithBundleID:bundleID
|
|
105
|
+
initialUrl:initialUrl
|
|
106
|
+
capabilities:capabilities
|
|
107
|
+
application:&app];
|
|
108
|
+
if (nil != errorResponse) {
|
|
109
|
+
return errorResponse;
|
|
201
110
|
}
|
|
202
111
|
|
|
203
112
|
if (nil != initialUrl && nil == bundleID) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
113
|
+
errorResponse = [self openDeepLink:initialUrl
|
|
114
|
+
withApplication:nil
|
|
115
|
+
timeout:capabilities[FB_CAP_APP_LAUNCH_STATE_TIMEOUT_SEC]];
|
|
207
116
|
if (nil != errorResponse) {
|
|
208
117
|
return errorResponse;
|
|
209
118
|
}
|
|
210
119
|
}
|
|
211
120
|
|
|
212
|
-
|
|
213
|
-
[FBSession initWithApplication:app
|
|
214
|
-
defaultAlertAction:(id)capabilities[FB_SETTING_DEFAULT_ALERT_ACTION]];
|
|
215
|
-
} else {
|
|
216
|
-
[FBSession initWithApplication:app];
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
if (nil != capabilities[FB_CAP_USE_NATIVE_CACHING_STRATEGY]) {
|
|
220
|
-
FBSession.activeSession.useNativeCachingStrategy = [capabilities[FB_CAP_USE_NATIVE_CACHING_STRATEGY] boolValue];
|
|
221
|
-
}
|
|
121
|
+
[self initializeSessionWithApplication:app capabilities:capabilities];
|
|
222
122
|
|
|
223
123
|
return FBResponseWithObject(FBSessionCommands.sessionInformation);
|
|
224
124
|
}
|
|
@@ -324,192 +224,192 @@
|
|
|
324
224
|
|
|
325
225
|
+ (id<FBResponsePayload>)handleGetSettings:(FBRouteRequest *)request
|
|
326
226
|
{
|
|
327
|
-
return FBResponseWithObject(
|
|
328
|
-
@{
|
|
329
|
-
FB_SETTING_USE_COMPACT_RESPONSES: @([FBConfiguration shouldUseCompactResponses]),
|
|
330
|
-
FB_SETTING_ELEMENT_RESPONSE_ATTRIBUTES: [FBConfiguration elementResponseAttributes],
|
|
331
|
-
FB_SETTING_MJPEG_SERVER_SCREENSHOT_QUALITY: @([FBConfiguration mjpegServerScreenshotQuality]),
|
|
332
|
-
FB_SETTING_MJPEG_SERVER_FRAMERATE: @([FBConfiguration mjpegServerFramerate]),
|
|
333
|
-
FB_SETTING_MJPEG_SCALING_FACTOR: @([FBConfiguration mjpegScalingFactor]),
|
|
334
|
-
FB_SETTING_MJPEG_FIX_ORIENTATION: @([FBConfiguration mjpegShouldFixOrientation]),
|
|
335
|
-
FB_SETTING_SCREENSHOT_QUALITY: @([FBConfiguration screenshotQuality]),
|
|
336
|
-
FB_SETTING_KEYBOARD_AUTOCORRECTION: @([FBConfiguration keyboardAutocorrection]),
|
|
337
|
-
FB_SETTING_KEYBOARD_PREDICTION: @([FBConfiguration keyboardPrediction]),
|
|
338
|
-
FB_SETTING_SNAPSHOT_MAX_DEPTH: @([FBConfiguration snapshotMaxDepth]),
|
|
339
|
-
FB_SETTING_SNAPSHOT_MAX_CHILDREN: @([FBConfiguration snapshotMaxChildren]),
|
|
340
|
-
FB_SETTING_USE_FIRST_MATCH: @([FBConfiguration useFirstMatch]),
|
|
341
|
-
FB_SETTING_WAIT_FOR_IDLE_TIMEOUT: @([FBConfiguration waitForIdleTimeout]),
|
|
342
|
-
FB_SETTING_ANIMATION_COOL_OFF_TIMEOUT: @([FBConfiguration animationCoolOffTimeout]),
|
|
343
|
-
FB_SETTING_BOUND_ELEMENTS_BY_INDEX: @([FBConfiguration boundElementsByIndex]),
|
|
344
|
-
FB_SETTING_REDUCE_MOTION: @([FBConfiguration reduceMotionEnabled]),
|
|
345
|
-
FB_SETTING_DEFAULT_ACTIVE_APPLICATION: request.session.defaultActiveApplication,
|
|
346
|
-
FB_SETTING_ACTIVE_APP_DETECTION_POINT: FBActiveAppDetectionPoint.sharedInstance.stringCoordinates,
|
|
347
|
-
FB_SETTING_ACCEPT_ALERT_BUTTON_SELECTOR: FBConfiguration.acceptAlertButtonSelector,
|
|
348
|
-
FB_SETTING_DISMISS_ALERT_BUTTON_SELECTOR: FBConfiguration.dismissAlertButtonSelector,
|
|
349
|
-
FB_SETTING_AUTO_CLICK_ALERT_SELECTOR: FBConfiguration.autoClickAlertSelector,
|
|
350
|
-
FB_SETTING_DEFAULT_ALERT_ACTION: request.session.defaultAlertAction ?: @"",
|
|
351
|
-
FB_SETTING_MAX_TYPING_FREQUENCY: @([FBConfiguration maxTypingFrequency]),
|
|
352
|
-
FB_SETTING_RESPECT_SYSTEM_ALERTS: @([FBConfiguration shouldRespectSystemAlerts]),
|
|
353
|
-
FB_SETTING_USE_CLEAR_TEXT_SHORTCUT: @([FBConfiguration useClearTextShortcut]),
|
|
354
|
-
FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE: @([FBConfiguration includeHittableInPageSource]),
|
|
355
|
-
FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE: @([FBConfiguration includeNativeFrameInPageSource]),
|
|
356
|
-
FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE: @([FBConfiguration includeMinMaxValueInPageSource]),
|
|
357
|
-
FB_SETTING_INCLUDE_CUSTOM_ACTIONS_IN_PAGE_SOURCE: @([FBConfiguration includeCustomActionsInPageSource]),
|
|
358
|
-
FB_SETTING_ENFORCE_CUSTOM_SNAPSHOTS: @([FBConfiguration enforceCustomSnapshots]),
|
|
359
|
-
FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE: @([FBConfiguration limitXpathContextScope]),
|
|
360
|
-
#if !TARGET_OS_TV
|
|
361
|
-
FB_SETTING_SCREENSHOT_ORIENTATION: [FBConfiguration humanReadableScreenshotOrientation],
|
|
362
|
-
#endif
|
|
363
|
-
}
|
|
364
|
-
);
|
|
227
|
+
return FBResponseWithObject([FBSettingsHandler currentSettingsForSession:request.session]);
|
|
365
228
|
}
|
|
366
229
|
|
|
367
|
-
// TODO if we get lots more settings, handling them with a series of if-statements will be unwieldy
|
|
368
|
-
// and this should be refactored
|
|
369
230
|
+ (id<FBResponsePayload>)handleSetSettings:(FBRouteRequest *)request
|
|
370
231
|
{
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
}
|
|
376
|
-
if (nil != [settings objectForKey:FB_SETTING_ELEMENT_RESPONSE_ATTRIBUTES]) {
|
|
377
|
-
[FBConfiguration setElementResponseAttributes:(NSString *)[settings objectForKey:FB_SETTING_ELEMENT_RESPONSE_ATTRIBUTES]];
|
|
378
|
-
}
|
|
379
|
-
if (nil != [settings objectForKey:FB_SETTING_MJPEG_SERVER_SCREENSHOT_QUALITY]) {
|
|
380
|
-
[FBConfiguration setMjpegServerScreenshotQuality:[[settings objectForKey:FB_SETTING_MJPEG_SERVER_SCREENSHOT_QUALITY] unsignedIntegerValue]];
|
|
381
|
-
}
|
|
382
|
-
if (nil != [settings objectForKey:FB_SETTING_MJPEG_SERVER_FRAMERATE]) {
|
|
383
|
-
[FBConfiguration setMjpegServerFramerate:[[settings objectForKey:FB_SETTING_MJPEG_SERVER_FRAMERATE] unsignedIntegerValue]];
|
|
384
|
-
}
|
|
385
|
-
if (nil != [settings objectForKey:FB_SETTING_SCREENSHOT_QUALITY]) {
|
|
386
|
-
[FBConfiguration setScreenshotQuality:[[settings objectForKey:FB_SETTING_SCREENSHOT_QUALITY] unsignedIntegerValue]];
|
|
387
|
-
}
|
|
388
|
-
if (nil != [settings objectForKey:FB_SETTING_MJPEG_SCALING_FACTOR]) {
|
|
389
|
-
[FBConfiguration setMjpegScalingFactor:[[settings objectForKey:FB_SETTING_MJPEG_SCALING_FACTOR] floatValue]];
|
|
390
|
-
}
|
|
391
|
-
if (nil != [settings objectForKey:FB_SETTING_MJPEG_FIX_ORIENTATION]) {
|
|
392
|
-
[FBConfiguration setMjpegShouldFixOrientation:[[settings objectForKey:FB_SETTING_MJPEG_FIX_ORIENTATION] boolValue]];
|
|
232
|
+
id settingsArgument = request.arguments[@"settings"];
|
|
233
|
+
if (nil != settingsArgument && ![settingsArgument isKindOfClass:NSDictionary.class]) {
|
|
234
|
+
return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:@"settings must be a dictionary"
|
|
235
|
+
traceback:nil]);
|
|
393
236
|
}
|
|
394
|
-
|
|
395
|
-
|
|
237
|
+
NSDictionary *settings = settingsArgument ?: @{};
|
|
238
|
+
FBCommandStatus *status = [FBSettingsHandler applySettings:settings
|
|
239
|
+
toSession:request.session];
|
|
240
|
+
if (status.hasError) {
|
|
241
|
+
return FBResponseWithStatus(status);
|
|
396
242
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
if (
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
if (nil != [settings objectForKey:FB_SETTING_USE_FIRST_MATCH]) {
|
|
410
|
-
[FBConfiguration setUseFirstMatch:[[settings objectForKey:FB_SETTING_USE_FIRST_MATCH] boolValue]];
|
|
411
|
-
}
|
|
412
|
-
if (nil != [settings objectForKey:FB_SETTING_BOUND_ELEMENTS_BY_INDEX]) {
|
|
413
|
-
[FBConfiguration setBoundElementsByIndex:[[settings objectForKey:FB_SETTING_BOUND_ELEMENTS_BY_INDEX] boolValue]];
|
|
243
|
+
return [self handleGetSettings:request];
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
#pragma mark - Session Creation Helpers
|
|
248
|
+
|
|
249
|
+
+ (nullable id<FBResponsePayload>)capabilitiesFromCreateSessionRequest:(FBRouteRequest *)request
|
|
250
|
+
capabilitiesOut:(NSDictionary<NSString *, id> *_Nonnull *_Nonnull)capabilitiesOut
|
|
251
|
+
{
|
|
252
|
+
if (![request.arguments[@"capabilities"] isKindOfClass:NSDictionary.class]) {
|
|
253
|
+
return FBResponseWithStatus([FBCommandStatus sessionNotCreatedError:@"'capabilities' is mandatory to create a new session"
|
|
254
|
+
traceback:nil]);
|
|
414
255
|
}
|
|
415
|
-
|
|
416
|
-
|
|
256
|
+
NSError *error;
|
|
257
|
+
NSDictionary<NSString *, id> *capabilities = FBParseCapabilities((NSDictionary *)request.arguments[@"capabilities"], &error);
|
|
258
|
+
if (nil == capabilities) {
|
|
259
|
+
return FBResponseWithStatus([FBCommandStatus sessionNotCreatedError:error.localizedDescription traceback:nil]);
|
|
417
260
|
}
|
|
418
|
-
|
|
419
|
-
|
|
261
|
+
*capabilitiesOut = capabilities;
|
|
262
|
+
return nil;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
+ (void)applyConfigurationFromCapabilities:(NSDictionary<NSString *, id> *)capabilities
|
|
266
|
+
{
|
|
267
|
+
[FBConfiguration resetSessionSettings];
|
|
268
|
+
if (capabilities[FB_SETTING_USE_COMPACT_RESPONSES]) {
|
|
269
|
+
[FBConfiguration setShouldUseCompactResponses:[capabilities[FB_SETTING_USE_COMPACT_RESPONSES] boolValue]];
|
|
420
270
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
error:&error]) {
|
|
425
|
-
return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:error.localizedDescription
|
|
426
|
-
traceback:nil]);
|
|
427
|
-
}
|
|
271
|
+
NSString *elementResponseAttributes = capabilities[FB_SETTING_ELEMENT_RESPONSE_ATTRIBUTES];
|
|
272
|
+
if (elementResponseAttributes) {
|
|
273
|
+
[FBConfiguration setElementResponseAttributes:elementResponseAttributes];
|
|
428
274
|
}
|
|
429
|
-
if (
|
|
430
|
-
[FBConfiguration
|
|
275
|
+
if (capabilities[FB_CAP_MAX_TYPING_FREQUENCY]) {
|
|
276
|
+
[FBConfiguration setMaxTypingFrequency:[capabilities[FB_CAP_MAX_TYPING_FREQUENCY] unsignedIntegerValue]];
|
|
431
277
|
}
|
|
432
|
-
if (
|
|
433
|
-
[FBConfiguration
|
|
278
|
+
if (capabilities[FB_CAP_USE_SINGLETON_TEST_MANAGER]) {
|
|
279
|
+
[FBConfiguration setShouldUseSingletonTestManager:[capabilities[FB_CAP_USE_SINGLETON_TEST_MANAGER] boolValue]];
|
|
434
280
|
}
|
|
435
|
-
if (
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
281
|
+
if (capabilities[FB_CAP_DISABLE_AUTOMATIC_SCREENSHOTS]) {
|
|
282
|
+
if ([capabilities[FB_CAP_DISABLE_AUTOMATIC_SCREENSHOTS] boolValue]) {
|
|
283
|
+
[FBConfiguration disableScreenshots];
|
|
284
|
+
} else {
|
|
285
|
+
[FBConfiguration enableScreenshots];
|
|
440
286
|
}
|
|
441
287
|
}
|
|
442
|
-
if (
|
|
443
|
-
[FBConfiguration
|
|
444
|
-
}
|
|
445
|
-
if (nil != [settings objectForKey:FB_SETTING_ANIMATION_COOL_OFF_TIMEOUT]) {
|
|
446
|
-
[FBConfiguration setAnimationCoolOffTimeout:[[settings objectForKey:FB_SETTING_ANIMATION_COOL_OFF_TIMEOUT] doubleValue]];
|
|
447
|
-
}
|
|
448
|
-
if ([[settings objectForKey:FB_SETTING_DEFAULT_ALERT_ACTION] isKindOfClass:NSString.class]) {
|
|
449
|
-
request.session.defaultAlertAction = [settings[FB_SETTING_DEFAULT_ALERT_ACTION] lowercaseString];
|
|
450
|
-
}
|
|
451
|
-
if (nil != [settings objectForKey:FB_SETTING_MAX_TYPING_FREQUENCY]) {
|
|
452
|
-
[FBConfiguration setMaxTypingFrequency:[[settings objectForKey:FB_SETTING_MAX_TYPING_FREQUENCY] unsignedIntegerValue]];
|
|
453
|
-
}
|
|
454
|
-
if (nil != [settings objectForKey:FB_SETTING_USE_CLEAR_TEXT_SHORTCUT]) {
|
|
455
|
-
[FBConfiguration setUseClearTextShortcut:[[settings objectForKey:FB_SETTING_USE_CLEAR_TEXT_SHORTCUT] boolValue]];
|
|
456
|
-
}
|
|
457
|
-
if (nil != [settings objectForKey:FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE]) {
|
|
458
|
-
[FBConfiguration setIncludeHittableInPageSource:[[settings objectForKey:FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE] boolValue]];
|
|
459
|
-
}
|
|
460
|
-
if (nil != [settings objectForKey:FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE]) {
|
|
461
|
-
[FBConfiguration setIncludeNativeFrameInPageSource:[[settings objectForKey:FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE] boolValue]];
|
|
462
|
-
}
|
|
463
|
-
if (nil != [settings objectForKey:FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE]) {
|
|
464
|
-
[FBConfiguration setIncludeMinMaxValueInPageSource:[[settings objectForKey:FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE] boolValue]];
|
|
288
|
+
if (capabilities[FB_CAP_SHOULD_TERMINATE_APP]) {
|
|
289
|
+
[FBConfiguration setShouldTerminateApp:[capabilities[FB_CAP_SHOULD_TERMINATE_APP] boolValue]];
|
|
465
290
|
}
|
|
466
|
-
|
|
467
|
-
|
|
291
|
+
NSNumber *delay = capabilities[FB_CAP_EVENT_LOOP_IDLE_DELAY_SEC];
|
|
292
|
+
if ([delay doubleValue] > 0.0) {
|
|
293
|
+
[XCUIApplicationProcessDelay setEventLoopHasIdledDelay:[delay doubleValue]];
|
|
294
|
+
} else {
|
|
295
|
+
[XCUIApplicationProcessDelay disableEventLoopDelay];
|
|
468
296
|
}
|
|
469
|
-
if (nil != [
|
|
470
|
-
|
|
297
|
+
if (nil != capabilities[FB_SETTING_WAIT_FOR_IDLE_TIMEOUT]) {
|
|
298
|
+
FBConfiguration.waitForIdleTimeout = [capabilities[FB_SETTING_WAIT_FOR_IDLE_TIMEOUT] doubleValue];
|
|
471
299
|
}
|
|
472
|
-
if (nil
|
|
473
|
-
|
|
300
|
+
if (nil == capabilities[FB_CAP_FORCE_SIMULATOR_SOFTWARE_KEYBOARD_PRESENCE] ||
|
|
301
|
+
[capabilities[FB_CAP_FORCE_SIMULATOR_SOFTWARE_KEYBOARD_PRESENCE] boolValue]) {
|
|
302
|
+
[FBConfiguration forceSimulatorSoftwareKeyboardPresence];
|
|
474
303
|
}
|
|
304
|
+
}
|
|
475
305
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
306
|
+
+ (nullable id<FBResponsePayload>)prepareApplicationForSessionWithBundleID:(nullable NSString *)bundleID
|
|
307
|
+
initialUrl:(nullable NSString *)initialUrl
|
|
308
|
+
capabilities:(NSDictionary<NSString *, id> *)capabilities
|
|
309
|
+
application:(XCUIApplication *_Nullable *_Nonnull)applicationOut
|
|
310
|
+
{
|
|
311
|
+
if (nil == bundleID) {
|
|
312
|
+
*applicationOut = nil;
|
|
313
|
+
return nil;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
XCUIApplication *app = [[XCUIApplication alloc] initWithBundleIdentifier:bundleID];
|
|
317
|
+
BOOL forceAppLaunch = nil == capabilities[FB_CAP_FORCE_APP_LAUNCH]
|
|
318
|
+
|| [capabilities[FB_CAP_FORCE_APP_LAUNCH] boolValue];
|
|
319
|
+
XCUIApplicationState appState = app.state;
|
|
320
|
+
BOOL isAppRunning = appState >= XCUIApplicationStateRunningBackground;
|
|
321
|
+
|
|
322
|
+
if (!isAppRunning || (isAppRunning && forceAppLaunch)) {
|
|
323
|
+
id<FBResponsePayload> errorResponse = [self launchApplication:app
|
|
324
|
+
bundleID:bundleID
|
|
325
|
+
initialUrl:initialUrl
|
|
326
|
+
capabilities:capabilities];
|
|
327
|
+
if (nil != errorResponse) {
|
|
328
|
+
return errorResponse;
|
|
329
|
+
}
|
|
330
|
+
} else if (appState == XCUIApplicationStateRunningBackground && !forceAppLaunch) {
|
|
331
|
+
id<FBResponsePayload> errorResponse = [self activateBackgroundApplication:app
|
|
332
|
+
bundleID:bundleID
|
|
333
|
+
initialUrl:initialUrl];
|
|
334
|
+
if (nil != errorResponse) {
|
|
335
|
+
return errorResponse;
|
|
483
336
|
}
|
|
484
337
|
}
|
|
485
|
-
#endif
|
|
486
338
|
|
|
487
|
-
|
|
339
|
+
*applicationOut = app;
|
|
340
|
+
return nil;
|
|
488
341
|
}
|
|
489
342
|
|
|
343
|
+
+ (nullable id<FBResponsePayload>)launchApplication:(XCUIApplication *)app
|
|
344
|
+
bundleID:(NSString *)bundleID
|
|
345
|
+
initialUrl:(nullable NSString *)initialUrl
|
|
346
|
+
capabilities:(NSDictionary<NSString *, id> *)capabilities
|
|
347
|
+
{
|
|
348
|
+
app.fb_shouldWaitForQuiescence = nil == capabilities[FB_CAP_SHOULD_WAIT_FOR_QUIESCENCE]
|
|
349
|
+
|| [capabilities[FB_CAP_SHOULD_WAIT_FOR_QUIESCENCE] boolValue];
|
|
350
|
+
app.launchArguments = (NSArray<NSString *> *)capabilities[FB_CAP_ARGUMENTS] ?: @[];
|
|
351
|
+
app.launchEnvironment = (NSDictionary<NSString *, NSString *> *)capabilities[FB_CAP_ENVIRNOMENT] ?: @{};
|
|
352
|
+
|
|
353
|
+
if (nil != initialUrl) {
|
|
354
|
+
if (app.running) {
|
|
355
|
+
[app terminate];
|
|
356
|
+
}
|
|
357
|
+
id<FBResponsePayload> errorResponse = [self openDeepLink:initialUrl
|
|
358
|
+
withApplication:bundleID
|
|
359
|
+
timeout:capabilities[FB_CAP_APP_LAUNCH_STATE_TIMEOUT_SEC]];
|
|
360
|
+
if (nil != errorResponse) {
|
|
361
|
+
return errorResponse;
|
|
362
|
+
}
|
|
363
|
+
} else {
|
|
364
|
+
NSTimeInterval defaultTimeout = _XCTApplicationStateTimeout();
|
|
365
|
+
if (nil != capabilities[FB_CAP_APP_LAUNCH_STATE_TIMEOUT_SEC]) {
|
|
366
|
+
_XCTSetApplicationStateTimeout([capabilities[FB_CAP_APP_LAUNCH_STATE_TIMEOUT_SEC] doubleValue]);
|
|
367
|
+
}
|
|
368
|
+
@try {
|
|
369
|
+
[app launch];
|
|
370
|
+
} @catch (NSException *e) {
|
|
371
|
+
return FBResponseWithStatus([FBCommandStatus sessionNotCreatedError:e.reason traceback:nil]);
|
|
372
|
+
} @finally {
|
|
373
|
+
if (nil != capabilities[FB_CAP_APP_LAUNCH_STATE_TIMEOUT_SEC]) {
|
|
374
|
+
_XCTSetApplicationStateTimeout(defaultTimeout);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
490
378
|
|
|
491
|
-
|
|
379
|
+
if (!app.running) {
|
|
380
|
+
NSString *errorMsg = [NSString stringWithFormat:@"Cannot launch %@ application. Make sure the correct bundle identifier has been provided in capabilities and check the device log for possible crash report occurrences", bundleID];
|
|
381
|
+
return FBResponseWithStatus([FBCommandStatus sessionNotCreatedError:errorMsg traceback:nil]);
|
|
382
|
+
}
|
|
383
|
+
return nil;
|
|
384
|
+
}
|
|
492
385
|
|
|
493
|
-
+ (
|
|
494
|
-
|
|
386
|
+
+ (nullable id<FBResponsePayload>)activateBackgroundApplication:(XCUIApplication *)app
|
|
387
|
+
bundleID:(NSString *)bundleID
|
|
388
|
+
initialUrl:(nullable NSString *)initialUrl
|
|
495
389
|
{
|
|
496
|
-
if (
|
|
497
|
-
[
|
|
498
|
-
[session disableAlertsMonitor];
|
|
499
|
-
return [FBCommandStatus ok];
|
|
390
|
+
if (nil != initialUrl) {
|
|
391
|
+
return [self openDeepLink:initialUrl withApplication:bundleID timeout:nil];
|
|
500
392
|
}
|
|
393
|
+
[app activate];
|
|
394
|
+
return nil;
|
|
395
|
+
}
|
|
501
396
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
397
|
+
+ (void)initializeSessionWithApplication:(nullable XCUIApplication *)app
|
|
398
|
+
capabilities:(NSDictionary<NSString *, id> *)capabilities
|
|
399
|
+
{
|
|
400
|
+
if (capabilities[FB_SETTING_DEFAULT_ALERT_ACTION]) {
|
|
401
|
+
[FBSession initWithApplication:app
|
|
402
|
+
defaultAlertAction:(id)capabilities[FB_SETTING_DEFAULT_ALERT_ACTION]];
|
|
403
|
+
} else {
|
|
404
|
+
[FBSession initWithApplication:app];
|
|
405
|
+
}
|
|
406
|
+
if (nil != capabilities[FB_CAP_USE_NATIVE_CACHING_STRATEGY]) {
|
|
407
|
+
FBSession.activeSession.useNativeCachingStrategy = [capabilities[FB_CAP_USE_NATIVE_CACHING_STRATEGY] boolValue];
|
|
408
|
+
}
|
|
511
409
|
}
|
|
512
410
|
|
|
411
|
+
#pragma mark - Helpers
|
|
412
|
+
|
|
513
413
|
+ (NSString *)buildTimestamp
|
|
514
414
|
{
|
|
515
415
|
return [NSString stringWithFormat:@"%@ %@",
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
<key>CFBundlePackageType</key>
|
|
16
16
|
<string>FMWK</string>
|
|
17
17
|
<key>CFBundleShortVersionString</key>
|
|
18
|
-
<string>13.2.
|
|
18
|
+
<string>13.2.2</string>
|
|
19
19
|
<key>CFBundleSignature</key>
|
|
20
20
|
<string>????</string>
|
|
21
21
|
<key>CFBundleVersion</key>
|
|
22
|
-
<string>13.2.
|
|
22
|
+
<string>13.2.2</string>
|
|
23
23
|
<key>NSPrincipalClass</key>
|
|
24
24
|
<string/>
|
|
25
25
|
</dict>
|
|
@@ -0,0 +1,35 @@
|
|
|
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.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#import <Foundation/Foundation.h>
|
|
10
|
+
|
|
11
|
+
@class FBCommandStatus;
|
|
12
|
+
@class FBSession;
|
|
13
|
+
|
|
14
|
+
NS_ASSUME_NONNULL_BEGIN
|
|
15
|
+
|
|
16
|
+
@interface FBSettingsHandler : NSObject
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Applies the given settings dictionary to FBConfiguration and the active session.
|
|
20
|
+
* JSON null values are normalized to nil. Nil is applied only for settings that
|
|
21
|
+
* support clearing (e.g. alert action and selectors); other keys are skipped so
|
|
22
|
+
* null does not get coerced to NO/0. Unknown keys are skipped.
|
|
23
|
+
*
|
|
24
|
+
* @return nil on success, or an FBCommandStatus describing the validation error.
|
|
25
|
+
*/
|
|
26
|
+
+ (nullable FBCommandStatus *)applySettings:(NSDictionary *)settings toSession:(FBSession *)session;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Returns the current values for all known settings.
|
|
30
|
+
*/
|
|
31
|
+
+ (NSDictionary *)currentSettingsForSession:(FBSession *)session;
|
|
32
|
+
|
|
33
|
+
@end
|
|
34
|
+
|
|
35
|
+
NS_ASSUME_NONNULL_END
|
|
@@ -0,0 +1,356 @@
|
|
|
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.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
#import "FBSettingsHandler.h"
|
|
10
|
+
|
|
11
|
+
#import "FBActiveAppDetectionPoint.h"
|
|
12
|
+
#import "FBClassChainQueryParser.h"
|
|
13
|
+
#import "FBCommandStatus.h"
|
|
14
|
+
#import "FBConfiguration.h"
|
|
15
|
+
#import "FBSession.h"
|
|
16
|
+
#import "FBSettings.h"
|
|
17
|
+
|
|
18
|
+
typedef FBCommandStatus * _Nullable (^FBSettingApplyBlock)(FBSession *session, id value);
|
|
19
|
+
typedef id _Nonnull (^FBSettingGetBlock)(FBSession *session);
|
|
20
|
+
|
|
21
|
+
static id FBNormalizedSettingValue(id value)
|
|
22
|
+
{
|
|
23
|
+
return value == NSNull.null ? nil : value;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static NSSet<NSString *> *FBNilClearableSettingKeys(void)
|
|
27
|
+
{
|
|
28
|
+
static NSSet<NSString *> *keys;
|
|
29
|
+
static dispatch_once_t onceToken;
|
|
30
|
+
dispatch_once(&onceToken, ^{
|
|
31
|
+
keys = [NSSet setWithObjects:
|
|
32
|
+
FB_SETTING_DEFAULT_ALERT_ACTION,
|
|
33
|
+
FB_SETTING_ACCEPT_ALERT_BUTTON_SELECTOR,
|
|
34
|
+
FB_SETTING_DISMISS_ALERT_BUTTON_SELECTOR,
|
|
35
|
+
FB_SETTING_AUTO_CLICK_ALERT_SELECTOR,
|
|
36
|
+
nil];
|
|
37
|
+
});
|
|
38
|
+
return keys;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@implementation FBSettingsHandler
|
|
42
|
+
|
|
43
|
+
+ (NSDictionary<NSString *, FBSettingApplyBlock> *)settersMap
|
|
44
|
+
{
|
|
45
|
+
static NSDictionary<NSString *, FBSettingApplyBlock> *settersMap;
|
|
46
|
+
static dispatch_once_t onceToken;
|
|
47
|
+
dispatch_once(&onceToken, ^{
|
|
48
|
+
NSMutableDictionary<NSString *, FBSettingApplyBlock> *map = [NSMutableDictionary dictionary];
|
|
49
|
+
map[FB_SETTING_USE_COMPACT_RESPONSES] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
50
|
+
[FBConfiguration setShouldUseCompactResponses:[value boolValue]];
|
|
51
|
+
return nil;
|
|
52
|
+
};
|
|
53
|
+
map[FB_SETTING_ELEMENT_RESPONSE_ATTRIBUTES] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
54
|
+
[FBConfiguration setElementResponseAttributes:(NSString *)value];
|
|
55
|
+
return nil;
|
|
56
|
+
};
|
|
57
|
+
map[FB_SETTING_MJPEG_SERVER_SCREENSHOT_QUALITY] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
58
|
+
[FBConfiguration setMjpegServerScreenshotQuality:[value unsignedIntegerValue]];
|
|
59
|
+
return nil;
|
|
60
|
+
};
|
|
61
|
+
map[FB_SETTING_MJPEG_SERVER_FRAMERATE] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
62
|
+
[FBConfiguration setMjpegServerFramerate:[value unsignedIntegerValue]];
|
|
63
|
+
return nil;
|
|
64
|
+
};
|
|
65
|
+
map[FB_SETTING_SCREENSHOT_QUALITY] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
66
|
+
[FBConfiguration setScreenshotQuality:[value unsignedIntegerValue]];
|
|
67
|
+
return nil;
|
|
68
|
+
};
|
|
69
|
+
map[FB_SETTING_MJPEG_SCALING_FACTOR] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
70
|
+
[FBConfiguration setMjpegScalingFactor:[value floatValue]];
|
|
71
|
+
return nil;
|
|
72
|
+
};
|
|
73
|
+
map[FB_SETTING_MJPEG_FIX_ORIENTATION] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
74
|
+
[FBConfiguration setMjpegShouldFixOrientation:[value boolValue]];
|
|
75
|
+
return nil;
|
|
76
|
+
};
|
|
77
|
+
map[FB_SETTING_KEYBOARD_AUTOCORRECTION] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
78
|
+
[FBConfiguration setKeyboardAutocorrection:[value boolValue]];
|
|
79
|
+
return nil;
|
|
80
|
+
};
|
|
81
|
+
map[FB_SETTING_KEYBOARD_PREDICTION] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
82
|
+
[FBConfiguration setKeyboardPrediction:[value boolValue]];
|
|
83
|
+
return nil;
|
|
84
|
+
};
|
|
85
|
+
map[FB_SETTING_RESPECT_SYSTEM_ALERTS] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
86
|
+
[FBConfiguration setShouldRespectSystemAlerts:[value boolValue]];
|
|
87
|
+
return nil;
|
|
88
|
+
};
|
|
89
|
+
map[FB_SETTING_SNAPSHOT_MAX_DEPTH] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
90
|
+
[FBConfiguration setSnapshotMaxDepth:[value intValue]];
|
|
91
|
+
return nil;
|
|
92
|
+
};
|
|
93
|
+
map[FB_SETTING_SNAPSHOT_MAX_CHILDREN] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
94
|
+
[FBConfiguration setSnapshotMaxChildren:[value intValue]];
|
|
95
|
+
return nil;
|
|
96
|
+
};
|
|
97
|
+
map[FB_SETTING_USE_FIRST_MATCH] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
98
|
+
[FBConfiguration setUseFirstMatch:[value boolValue]];
|
|
99
|
+
return nil;
|
|
100
|
+
};
|
|
101
|
+
map[FB_SETTING_BOUND_ELEMENTS_BY_INDEX] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
102
|
+
[FBConfiguration setBoundElementsByIndex:[value boolValue]];
|
|
103
|
+
return nil;
|
|
104
|
+
};
|
|
105
|
+
map[FB_SETTING_REDUCE_MOTION] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
106
|
+
[FBConfiguration setReduceMotionEnabled:[value boolValue]];
|
|
107
|
+
return nil;
|
|
108
|
+
};
|
|
109
|
+
map[FB_SETTING_DEFAULT_ACTIVE_APPLICATION] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
110
|
+
session.defaultActiveApplication = (NSString *)value;
|
|
111
|
+
return nil;
|
|
112
|
+
};
|
|
113
|
+
map[FB_SETTING_ACTIVE_APP_DETECTION_POINT] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
114
|
+
NSError *error;
|
|
115
|
+
if (![FBActiveAppDetectionPoint.sharedInstance setCoordinatesWithString:(NSString *)value
|
|
116
|
+
error:&error]) {
|
|
117
|
+
return [FBCommandStatus invalidArgumentErrorWithMessage:error.localizedDescription
|
|
118
|
+
traceback:nil];
|
|
119
|
+
}
|
|
120
|
+
return nil;
|
|
121
|
+
};
|
|
122
|
+
map[FB_SETTING_ACCEPT_ALERT_BUTTON_SELECTOR] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
123
|
+
[FBConfiguration setAcceptAlertButtonSelector:(NSString *)value];
|
|
124
|
+
return nil;
|
|
125
|
+
};
|
|
126
|
+
map[FB_SETTING_DISMISS_ALERT_BUTTON_SELECTOR] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
127
|
+
[FBConfiguration setDismissAlertButtonSelector:(NSString *)value];
|
|
128
|
+
return nil;
|
|
129
|
+
};
|
|
130
|
+
map[FB_SETTING_AUTO_CLICK_ALERT_SELECTOR] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
131
|
+
return [self configureAutoClickAlertWithSelector:(NSString *)value forSession:session];
|
|
132
|
+
};
|
|
133
|
+
map[FB_SETTING_WAIT_FOR_IDLE_TIMEOUT] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
134
|
+
[FBConfiguration setWaitForIdleTimeout:[value doubleValue]];
|
|
135
|
+
return nil;
|
|
136
|
+
};
|
|
137
|
+
map[FB_SETTING_ANIMATION_COOL_OFF_TIMEOUT] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
138
|
+
[FBConfiguration setAnimationCoolOffTimeout:[value doubleValue]];
|
|
139
|
+
return nil;
|
|
140
|
+
};
|
|
141
|
+
map[FB_SETTING_DEFAULT_ALERT_ACTION] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
142
|
+
if (nil == value) {
|
|
143
|
+
session.defaultAlertAction = nil;
|
|
144
|
+
} else if ([value isKindOfClass:NSString.class]) {
|
|
145
|
+
session.defaultAlertAction = [(NSString *)value lowercaseString];
|
|
146
|
+
}
|
|
147
|
+
return nil;
|
|
148
|
+
};
|
|
149
|
+
map[FB_SETTING_MAX_TYPING_FREQUENCY] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
150
|
+
[FBConfiguration setMaxTypingFrequency:[value unsignedIntegerValue]];
|
|
151
|
+
return nil;
|
|
152
|
+
};
|
|
153
|
+
map[FB_SETTING_USE_CLEAR_TEXT_SHORTCUT] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
154
|
+
[FBConfiguration setUseClearTextShortcut:[value boolValue]];
|
|
155
|
+
return nil;
|
|
156
|
+
};
|
|
157
|
+
map[FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
158
|
+
[FBConfiguration setIncludeHittableInPageSource:[value boolValue]];
|
|
159
|
+
return nil;
|
|
160
|
+
};
|
|
161
|
+
map[FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
162
|
+
[FBConfiguration setIncludeNativeFrameInPageSource:[value boolValue]];
|
|
163
|
+
return nil;
|
|
164
|
+
};
|
|
165
|
+
map[FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
166
|
+
[FBConfiguration setIncludeMinMaxValueInPageSource:[value boolValue]];
|
|
167
|
+
return nil;
|
|
168
|
+
};
|
|
169
|
+
map[FB_SETTING_INCLUDE_CUSTOM_ACTIONS_IN_PAGE_SOURCE] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
170
|
+
[FBConfiguration setIncludeCustomActionsInPageSource:[value boolValue]];
|
|
171
|
+
return nil;
|
|
172
|
+
};
|
|
173
|
+
map[FB_SETTING_ENFORCE_CUSTOM_SNAPSHOTS] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
174
|
+
[FBConfiguration setEnforceCustomSnapshots:[value boolValue]];
|
|
175
|
+
return nil;
|
|
176
|
+
};
|
|
177
|
+
map[FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
178
|
+
[FBConfiguration setLimitXpathContextScope:[value boolValue]];
|
|
179
|
+
return nil;
|
|
180
|
+
};
|
|
181
|
+
#if !TARGET_OS_TV
|
|
182
|
+
map[FB_SETTING_SCREENSHOT_ORIENTATION] = ^FBCommandStatus *(FBSession *session, id value) {
|
|
183
|
+
NSError *error;
|
|
184
|
+
if (![FBConfiguration setScreenshotOrientation:(NSString *)value error:&error]) {
|
|
185
|
+
return [FBCommandStatus invalidArgumentErrorWithMessage:error.localizedDescription
|
|
186
|
+
traceback:nil];
|
|
187
|
+
}
|
|
188
|
+
return nil;
|
|
189
|
+
};
|
|
190
|
+
#endif
|
|
191
|
+
settersMap = map.copy;
|
|
192
|
+
});
|
|
193
|
+
return settersMap;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
+ (NSDictionary<NSString *, FBSettingGetBlock> *)gettersMap
|
|
197
|
+
{
|
|
198
|
+
static NSDictionary<NSString *, FBSettingGetBlock> *gettersMap;
|
|
199
|
+
static dispatch_once_t onceToken;
|
|
200
|
+
dispatch_once(&onceToken, ^{
|
|
201
|
+
NSMutableDictionary<NSString *, FBSettingGetBlock> *map = [NSMutableDictionary dictionary];
|
|
202
|
+
map[FB_SETTING_USE_COMPACT_RESPONSES] = ^id(FBSession *session) {
|
|
203
|
+
return @([FBConfiguration shouldUseCompactResponses]);
|
|
204
|
+
};
|
|
205
|
+
map[FB_SETTING_ELEMENT_RESPONSE_ATTRIBUTES] = ^id(FBSession *session) {
|
|
206
|
+
return [FBConfiguration elementResponseAttributes];
|
|
207
|
+
};
|
|
208
|
+
map[FB_SETTING_MJPEG_SERVER_SCREENSHOT_QUALITY] = ^id(FBSession *session) {
|
|
209
|
+
return @([FBConfiguration mjpegServerScreenshotQuality]);
|
|
210
|
+
};
|
|
211
|
+
map[FB_SETTING_MJPEG_SERVER_FRAMERATE] = ^id(FBSession *session) {
|
|
212
|
+
return @([FBConfiguration mjpegServerFramerate]);
|
|
213
|
+
};
|
|
214
|
+
map[FB_SETTING_MJPEG_SCALING_FACTOR] = ^id(FBSession *session) {
|
|
215
|
+
return @([FBConfiguration mjpegScalingFactor]);
|
|
216
|
+
};
|
|
217
|
+
map[FB_SETTING_MJPEG_FIX_ORIENTATION] = ^id(FBSession *session) {
|
|
218
|
+
return @([FBConfiguration mjpegShouldFixOrientation]);
|
|
219
|
+
};
|
|
220
|
+
map[FB_SETTING_SCREENSHOT_QUALITY] = ^id(FBSession *session) {
|
|
221
|
+
return @([FBConfiguration screenshotQuality]);
|
|
222
|
+
};
|
|
223
|
+
map[FB_SETTING_KEYBOARD_AUTOCORRECTION] = ^id(FBSession *session) {
|
|
224
|
+
return @([FBConfiguration keyboardAutocorrection]);
|
|
225
|
+
};
|
|
226
|
+
map[FB_SETTING_KEYBOARD_PREDICTION] = ^id(FBSession *session) {
|
|
227
|
+
return @([FBConfiguration keyboardPrediction]);
|
|
228
|
+
};
|
|
229
|
+
map[FB_SETTING_SNAPSHOT_MAX_DEPTH] = ^id(FBSession *session) {
|
|
230
|
+
return @([FBConfiguration snapshotMaxDepth]);
|
|
231
|
+
};
|
|
232
|
+
map[FB_SETTING_SNAPSHOT_MAX_CHILDREN] = ^id(FBSession *session) {
|
|
233
|
+
return @([FBConfiguration snapshotMaxChildren]);
|
|
234
|
+
};
|
|
235
|
+
map[FB_SETTING_USE_FIRST_MATCH] = ^id(FBSession *session) {
|
|
236
|
+
return @([FBConfiguration useFirstMatch]);
|
|
237
|
+
};
|
|
238
|
+
map[FB_SETTING_WAIT_FOR_IDLE_TIMEOUT] = ^id(FBSession *session) {
|
|
239
|
+
return @([FBConfiguration waitForIdleTimeout]);
|
|
240
|
+
};
|
|
241
|
+
map[FB_SETTING_ANIMATION_COOL_OFF_TIMEOUT] = ^id(FBSession *session) {
|
|
242
|
+
return @([FBConfiguration animationCoolOffTimeout]);
|
|
243
|
+
};
|
|
244
|
+
map[FB_SETTING_BOUND_ELEMENTS_BY_INDEX] = ^id(FBSession *session) {
|
|
245
|
+
return @([FBConfiguration boundElementsByIndex]);
|
|
246
|
+
};
|
|
247
|
+
map[FB_SETTING_REDUCE_MOTION] = ^id(FBSession *session) {
|
|
248
|
+
return @([FBConfiguration reduceMotionEnabled]);
|
|
249
|
+
};
|
|
250
|
+
map[FB_SETTING_DEFAULT_ACTIVE_APPLICATION] = ^id(FBSession *session) {
|
|
251
|
+
return session.defaultActiveApplication;
|
|
252
|
+
};
|
|
253
|
+
map[FB_SETTING_ACTIVE_APP_DETECTION_POINT] = ^id(FBSession *session) {
|
|
254
|
+
return FBActiveAppDetectionPoint.sharedInstance.stringCoordinates;
|
|
255
|
+
};
|
|
256
|
+
map[FB_SETTING_ACCEPT_ALERT_BUTTON_SELECTOR] = ^id(FBSession *session) {
|
|
257
|
+
return FBConfiguration.acceptAlertButtonSelector;
|
|
258
|
+
};
|
|
259
|
+
map[FB_SETTING_DISMISS_ALERT_BUTTON_SELECTOR] = ^id(FBSession *session) {
|
|
260
|
+
return FBConfiguration.dismissAlertButtonSelector;
|
|
261
|
+
};
|
|
262
|
+
map[FB_SETTING_AUTO_CLICK_ALERT_SELECTOR] = ^id(FBSession *session) {
|
|
263
|
+
return FBConfiguration.autoClickAlertSelector;
|
|
264
|
+
};
|
|
265
|
+
map[FB_SETTING_DEFAULT_ALERT_ACTION] = ^id(FBSession *session) {
|
|
266
|
+
return session.defaultAlertAction ?: @"";
|
|
267
|
+
};
|
|
268
|
+
map[FB_SETTING_MAX_TYPING_FREQUENCY] = ^id(FBSession *session) {
|
|
269
|
+
return @([FBConfiguration maxTypingFrequency]);
|
|
270
|
+
};
|
|
271
|
+
map[FB_SETTING_RESPECT_SYSTEM_ALERTS] = ^id(FBSession *session) {
|
|
272
|
+
return @([FBConfiguration shouldRespectSystemAlerts]);
|
|
273
|
+
};
|
|
274
|
+
map[FB_SETTING_USE_CLEAR_TEXT_SHORTCUT] = ^id(FBSession *session) {
|
|
275
|
+
return @([FBConfiguration useClearTextShortcut]);
|
|
276
|
+
};
|
|
277
|
+
map[FB_SETTING_INCLUDE_HITTABLE_IN_PAGE_SOURCE] = ^id(FBSession *session) {
|
|
278
|
+
return @([FBConfiguration includeHittableInPageSource]);
|
|
279
|
+
};
|
|
280
|
+
map[FB_SETTING_INCLUDE_NATIVE_FRAME_IN_PAGE_SOURCE] = ^id(FBSession *session) {
|
|
281
|
+
return @([FBConfiguration includeNativeFrameInPageSource]);
|
|
282
|
+
};
|
|
283
|
+
map[FB_SETTING_INCLUDE_MIN_MAX_VALUE_IN_PAGE_SOURCE] = ^id(FBSession *session) {
|
|
284
|
+
return @([FBConfiguration includeMinMaxValueInPageSource]);
|
|
285
|
+
};
|
|
286
|
+
map[FB_SETTING_INCLUDE_CUSTOM_ACTIONS_IN_PAGE_SOURCE] = ^id(FBSession *session) {
|
|
287
|
+
return @([FBConfiguration includeCustomActionsInPageSource]);
|
|
288
|
+
};
|
|
289
|
+
map[FB_SETTING_ENFORCE_CUSTOM_SNAPSHOTS] = ^id(FBSession *session) {
|
|
290
|
+
return @([FBConfiguration enforceCustomSnapshots]);
|
|
291
|
+
};
|
|
292
|
+
map[FB_SETTING_LIMIT_XPATH_CONTEXT_SCOPE] = ^id(FBSession *session) {
|
|
293
|
+
return @([FBConfiguration limitXpathContextScope]);
|
|
294
|
+
};
|
|
295
|
+
#if !TARGET_OS_TV
|
|
296
|
+
map[FB_SETTING_SCREENSHOT_ORIENTATION] = ^id(FBSession *session) {
|
|
297
|
+
return [FBConfiguration humanReadableScreenshotOrientation];
|
|
298
|
+
};
|
|
299
|
+
#endif
|
|
300
|
+
gettersMap = map.copy;
|
|
301
|
+
});
|
|
302
|
+
return gettersMap;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
+ (NSDictionary *)currentSettingsForSession:(FBSession *)session
|
|
306
|
+
{
|
|
307
|
+
NSDictionary<NSString *, FBSettingGetBlock> *gettersMap = [self gettersMap];
|
|
308
|
+
NSMutableDictionary *settings = [NSMutableDictionary dictionaryWithCapacity:gettersMap.count];
|
|
309
|
+
for (NSString *key in gettersMap) {
|
|
310
|
+
settings[key] = gettersMap[key](session);
|
|
311
|
+
}
|
|
312
|
+
return settings.copy;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
+ (nullable FBCommandStatus *)applySettings:(NSDictionary *)settings toSession:(FBSession *)session
|
|
316
|
+
{
|
|
317
|
+
NSDictionary<NSString *, FBSettingApplyBlock> *settersMap = [self settersMap];
|
|
318
|
+
NSSet<NSString *> *nilClearableKeys = FBNilClearableSettingKeys();
|
|
319
|
+
for (NSString *key in settings) {
|
|
320
|
+
FBSettingApplyBlock handler = settersMap[key];
|
|
321
|
+
if (nil == handler) {
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
id value = FBNormalizedSettingValue(settings[key]);
|
|
325
|
+
if (nil == value && ![nilClearableKeys containsObject:key]) {
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
FBCommandStatus *status = handler(session, value);
|
|
329
|
+
if (status.hasError) {
|
|
330
|
+
return status;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return nil;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
+ (FBCommandStatus *)configureAutoClickAlertWithSelector:(NSString *)selector
|
|
337
|
+
forSession:(FBSession *)session
|
|
338
|
+
{
|
|
339
|
+
if (0 == [selector length]) {
|
|
340
|
+
[FBConfiguration setAutoClickAlertSelector:selector];
|
|
341
|
+
[session disableAlertsMonitor];
|
|
342
|
+
return [FBCommandStatus ok];
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
NSError *error;
|
|
346
|
+
FBClassChain *parsedChain = [FBClassChainQueryParser parseQuery:selector error:&error];
|
|
347
|
+
if (nil == parsedChain) {
|
|
348
|
+
return [FBCommandStatus invalidSelectorErrorWithMessage:error.localizedDescription
|
|
349
|
+
traceback:nil];
|
|
350
|
+
}
|
|
351
|
+
[FBConfiguration setAutoClickAlertSelector:selector];
|
|
352
|
+
[session enableAlertsMonitor];
|
|
353
|
+
return [FBCommandStatus ok];
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
@end
|