| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- /**
- * Copyright (c) 2015-present, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- */
- #import "FBProtocolHelpers.h"
- #import "FBErrorBuilder.h"
- #import "FBLogger.h"
- static NSString *const W3C_ELEMENT_KEY = @"element-6066-11e4-a52e-4f735466cecf";
- static NSString *const JSONWP_ELEMENT_KEY = @"ELEMENT";
- static NSString *const APPIUM_PREFIX = @"appium";
- static NSString *const ALWAYS_MATCH_KEY = @"alwaysMatch";
- static NSString *const FIRST_MATCH_KEY = @"firstMatch";
- NSDictionary<NSString *, id> *FBToElementDict(id element)
- {
- return @{
- W3C_ELEMENT_KEY: element,
- JSONWP_ELEMENT_KEY: element
- };
- }
- id FBExtractElement(NSDictionary *src)
- {
- for (NSString* key in src) {
- if ([key.lowercaseString isEqualToString:W3C_ELEMENT_KEY.lowercaseString]
- || [key.lowercaseString isEqualToString:JSONWP_ELEMENT_KEY.lowercaseString]) {
- return src[key];
- }
- }
- return nil;
- }
- NSDictionary *FBCleanupElements(NSDictionary *src)
- {
- NSMutableDictionary *result = src.mutableCopy;
- for (NSString* key in src) {
- if ([key.lowercaseString isEqualToString:W3C_ELEMENT_KEY.lowercaseString]
- || [key.lowercaseString isEqualToString:JSONWP_ELEMENT_KEY.lowercaseString]) {
- [result removeObjectForKey:key];
- }
- }
- return result.copy;
- }
- NSArray<NSString *> *standardCapabilities(void)
- {
- static NSArray<NSString *> *standardCaps;
- static dispatch_once_t onceStandardCaps;
- dispatch_once(&onceStandardCaps, ^{
- standardCaps = @[
- @"browserName",
- @"browserVersion",
- @"platformName",
- @"acceptInsecureCerts",
- @"pageLoadStrategy",
- @"proxy",
- @"setWindowRect",
- @"timeouts",
- @"unhandledPromptBehavior"
- ];
- });
- return standardCaps;
- }
- BOOL isStandardCap(NSString *capName)
- {
- return [standardCapabilities() containsObject:capName];
- }
- NSDictionary<NSString *, id> *_Nullable mergeCaps(NSDictionary<NSString *, id> *primary, NSDictionary<NSString *, id> *secondary, NSError **error)
- {
- NSMutableDictionary<NSString *, id> *result = primary.mutableCopy;
- for (NSString *capName in secondary) {
- if (nil != result[capName]) {
- [[[FBErrorBuilder builder]
- withDescriptionFormat:@"Property '%@' should not exist on both primary (%@) and secondary (%@) objects", capName, primary, secondary]
- buildError:error];
- return nil;
- }
- [result setObject:(id) secondary[capName] forKey:capName];
- }
- return result.copy;
- }
- NSDictionary<NSString *, id> *_Nullable stripPrefixes(NSDictionary<NSString *, id> *caps, NSError **error)
- {
- NSString* prefix = [NSString stringWithFormat:@"%@:", APPIUM_PREFIX];
- NSMutableDictionary<NSString *, id> *filteredCaps = [NSMutableDictionary dictionary];
- NSMutableArray<NSString *> *badPrefixedCaps = [NSMutableArray array];
- for (NSString *capName in caps) {
- if (![capName hasPrefix:prefix]) {
- [filteredCaps setObject:(id) caps[capName] forKey:capName];
- continue;
- }
- NSString *strippedName = [capName substringFromIndex:prefix.length];
- [filteredCaps setObject:(id) caps[capName] forKey:strippedName];
- if (isStandardCap(strippedName)) {
- [badPrefixedCaps addObject:strippedName];
- }
- }
- if (badPrefixedCaps.count > 0) {
- [[[FBErrorBuilder builder]
- withDescriptionFormat:@"The capabilities %@ are standard and should not have the '%@' prefix", badPrefixedCaps, prefix]
- buildError:error];
- return nil;
- }
- return filteredCaps.copy;
- }
- NSDictionary<NSString *, id> *FBParseCapabilities(NSDictionary<NSString *, id> *caps, NSError **error)
- {
- NSDictionary<NSString *, id> *alwaysMatch = caps[ALWAYS_MATCH_KEY] ?: @{};
- NSArray<NSDictionary<NSString *, id> *> *firstMatch = caps[FIRST_MATCH_KEY] ?: @[];
- NSArray<NSDictionary<NSString *, id> *> *allFirstMatchCaps = firstMatch.count == 0 ? @[@{}] : firstMatch;
- NSDictionary<NSString *, id> *requiredCaps;
- if (nil == (requiredCaps = stripPrefixes(alwaysMatch, error))) {
- return nil;
- }
- for (NSDictionary<NSString *, id> *fmc in allFirstMatchCaps) {
- NSDictionary<NSString *, id> *strippedCaps;
- if (nil == (strippedCaps = stripPrefixes(fmc, error))) {
- return nil;
- }
- NSDictionary<NSString *, id> *mergedCaps;
- if (nil == (mergedCaps = mergeCaps(requiredCaps, strippedCaps, error))) {
- [FBLogger logFmt:@"%@", (*error).description];
- continue;
- }
- return mergedCaps;
- }
- [[[FBErrorBuilder builder]
- withDescriptionFormat:@"Could not find matching capabilities from %@", caps]
- buildError:error];
- return nil;
- }
|