From efae2c3f4053458fc709cd1a1cee79e11dd1ba0c Mon Sep 17 00:00:00 2001 From: Mykola Mokhnach Date: Wed, 3 Mar 2021 19:42:14 +0100 Subject: [PATCH] feat: Add a possibility to provide key names (#60) --- README.md | 2 +- .../Commands/FBElementCommands.m | 7 +- .../Utilities/AMKeyboardUtils.h | 29 +++++++ .../Utilities/AMKeyboardUtils.m | 78 +++++++++++++++++++ .../project.pbxproj | 8 ++ 5 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 WebDriverAgentMac/WebDriverAgentLib/Utilities/AMKeyboardUtils.h create mode 100644 WebDriverAgentMac/WebDriverAgentLib/Utilities/AMKeyboardUtils.m diff --git a/README.md b/README.md index a1e2cf6..8c153f0 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ Send keys to the given element or to the application under test Name | Type | Required | Description | Example --- | --- | --- | --- | --- element | string | no | Unique identifier of the element to send the keys to. If unset then keys are sent to the current application under test. | 21045BC8-013C-43BD-9B1E-4C6DC7AB0744 -keys | array | yes | Array of keys to type. Each item could either be a string, that represents a key itself (see the official documentation on XCUIElement's [typeKey:modifierFlags: method](https://developer.apple.com/documentation/xctest/xcuielement/1500604-typekey?language=objc) and on [XCUIKeyboardKey constants](https://developer.apple.com/documentation/xctest/xcuikeyboardkey?language=objc)) or a dictionary with `key` and `modifierFlags` entries, if the key should also be entered with modifiers. | ['h', 'i'] or [{key: 'h', modifierFlags: 1 << 1}, {key: 'i', modifierFlags: 1 << 2}] | +keys | array | yes | Array of keys to type. Each item could either be a string, that represents a key itself (see the official documentation on XCUIElement's [typeKey:modifierFlags: method](https://developer.apple.com/documentation/xctest/xcuielement/1500604-typekey?language=objc) and on [XCUIKeyboardKey constants](https://developer.apple.com/documentation/xctest/xcuikeyboardkey?language=objc)) or a dictionary with `key` and `modifierFlags` entries, if the key should also be entered with modifiers. | ['h', 'i'] or [{key: 'h', modifierFlags: 1 << 1}, {key: 'i', modifierFlags: 1 << 2}] or ['XCUIKeyboardKeyEscape'] | ### macos: source diff --git a/WebDriverAgentMac/WebDriverAgentLib/Commands/FBElementCommands.m b/WebDriverAgentMac/WebDriverAgentLib/Commands/FBElementCommands.m index 66717df..f85a13c 100644 --- a/WebDriverAgentMac/WebDriverAgentLib/Commands/FBElementCommands.m +++ b/WebDriverAgentMac/WebDriverAgentLib/Commands/FBElementCommands.m @@ -10,6 +10,7 @@ #import "FBElementCommands.h" #import "AMGeometryUtils.h" +#import "AMKeyboardUtils.h" #import "FBConfiguration.h" #import "FBRoute.h" #import "FBRouteRequest.h" @@ -458,7 +459,8 @@ + (NSArray *)routes } for (id item in (NSArray *)keys) { if ([item isKindOfClass:NSString.class]) { - [destination typeKey:(NSString *)item modifierFlags:XCUIKeyModifierNone]; + NSString *keyValue = AMKeyValueForName(item) ?: item; + [destination typeKey:keyValue modifierFlags:XCUIKeyModifierNone]; } else if ([item isKindOfClass:NSDictionary.class]) { id key = [(NSDictionary *)item objectForKey:@"key"]; if (![key isKindOfClass:NSString.class]) { @@ -471,7 +473,8 @@ + (NSArray *)routes if ([modifiers isKindOfClass:NSNumber.class]) { modifierFlags = [(NSNumber *)modifiers unsignedIntValue]; } - [destination typeKey:(NSString *)key modifierFlags:modifierFlags]; + NSString *keyValue = AMKeyValueForName(key) ?: key; + [destination typeKey:keyValue modifierFlags:modifierFlags]; } else { NSString *message = @"All items of the 'keys' array must be either dictionaries or strings"; return FBResponseWithStatus([FBCommandStatus invalidArgumentErrorWithMessage:message diff --git a/WebDriverAgentMac/WebDriverAgentLib/Utilities/AMKeyboardUtils.h b/WebDriverAgentMac/WebDriverAgentLib/Utilities/AMKeyboardUtils.h new file mode 100644 index 0000000..3d9828e --- /dev/null +++ b/WebDriverAgentMac/WebDriverAgentLib/Utilities/AMKeyboardUtils.h @@ -0,0 +1,29 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + Transforms key name to its string representation, which could be used with XCTest + + @param name one of available keyboard key names defined in https://developer.apple.com/documentation/xctest/xcuikeyboardkey?language=objc + @return Either the key value or nil if no matches have been found + */ +NSString *_Nullable AMKeyValueForName(NSString *name); + +NS_ASSUME_NONNULL_END diff --git a/WebDriverAgentMac/WebDriverAgentLib/Utilities/AMKeyboardUtils.m b/WebDriverAgentMac/WebDriverAgentLib/Utilities/AMKeyboardUtils.m new file mode 100644 index 0000000..b779879 --- /dev/null +++ b/WebDriverAgentMac/WebDriverAgentLib/Utilities/AMKeyboardUtils.m @@ -0,0 +1,78 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * See the NOTICE file distributed with this work for additional + * information regarding copyright ownership. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "AMKeyboardUtils.h" + +NSString *AMKeyValueForName(NSString *name) +{ + static dispatch_once_t onceKeys; + static NSDictionary *keysMapping; + dispatch_once(&onceKeys, ^{ + keysMapping = @{ + @"XCUIKeyboardKeyDelete": XCUIKeyboardKeyDelete, + @"XCUIKeyboardKeyReturn": XCUIKeyboardKeyReturn, + @"XCUIKeyboardKeyEnter": XCUIKeyboardKeyEnter, + @"XCUIKeyboardKeyTab": XCUIKeyboardKeyTab, + @"XCUIKeyboardKeySpace": XCUIKeyboardKeySpace, + @"XCUIKeyboardKeyEscape": XCUIKeyboardKeyEscape, + + @"XCUIKeyboardKeyUpArrow": XCUIKeyboardKeyUpArrow, + @"XCUIKeyboardKeyDownArrow": XCUIKeyboardKeyDownArrow, + @"XCUIKeyboardKeyLeftArrow": XCUIKeyboardKeyLeftArrow, + @"XCUIKeyboardKeyRightArrow": XCUIKeyboardKeyRightArrow, + + @"XCUIKeyboardKeyF1": XCUIKeyboardKeyF1, + @"XCUIKeyboardKeyF2": XCUIKeyboardKeyF2, + @"XCUIKeyboardKeyF3": XCUIKeyboardKeyF3, + @"XCUIKeyboardKeyF4": XCUIKeyboardKeyF4, + @"XCUIKeyboardKeyF5": XCUIKeyboardKeyF5, + @"XCUIKeyboardKeyF6": XCUIKeyboardKeyF6, + @"XCUIKeyboardKeyF7": XCUIKeyboardKeyF7, + @"XCUIKeyboardKeyF8": XCUIKeyboardKeyF8, + @"XCUIKeyboardKeyF9": XCUIKeyboardKeyF9, + @"XCUIKeyboardKeyF10": XCUIKeyboardKeyF10, + @"XCUIKeyboardKeyF11": XCUIKeyboardKeyF11, + @"XCUIKeyboardKeyF12": XCUIKeyboardKeyF12, + @"XCUIKeyboardKeyF13": XCUIKeyboardKeyF13, + @"XCUIKeyboardKeyF14": XCUIKeyboardKeyF14, + @"XCUIKeyboardKeyF15": XCUIKeyboardKeyF15, + @"XCUIKeyboardKeyF16": XCUIKeyboardKeyF16, + @"XCUIKeyboardKeyF17": XCUIKeyboardKeyF17, + @"XCUIKeyboardKeyF18": XCUIKeyboardKeyF18, + @"XCUIKeyboardKeyF19": XCUIKeyboardKeyF19, + + @"XCUIKeyboardKeyForwardDelete": XCUIKeyboardKeyForwardDelete, + @"XCUIKeyboardKeyHome": XCUIKeyboardKeyHome, + @"XCUIKeyboardKeyEnd": XCUIKeyboardKeyEnd, + @"XCUIKeyboardKeyPageUp": XCUIKeyboardKeyPageUp, + @"XCUIKeyboardKeyPageDown": XCUIKeyboardKeyPageDown, + @"XCUIKeyboardKeyClear": XCUIKeyboardKeyClear, + @"XCUIKeyboardKeyHelp": XCUIKeyboardKeyHelp, + + @"XCUIKeyboardKeyCapsLock": XCUIKeyboardKeyCapsLock, + @"XCUIKeyboardKeyShift": XCUIKeyboardKeyShift, + @"XCUIKeyboardKeyControl": XCUIKeyboardKeyControl, + @"XCUIKeyboardKeyOption": XCUIKeyboardKeyOption, + @"XCUIKeyboardKeyCommand": XCUIKeyboardKeyCommand, + @"XCUIKeyboardKeyRightShift": XCUIKeyboardKeyRightShift, + @"XCUIKeyboardKeyRightControl": XCUIKeyboardKeyRightControl, + @"XCUIKeyboardKeyRightOption": XCUIKeyboardKeyRightOption, + @"XCUIKeyboardKeyRightCommand": XCUIKeyboardKeyRightCommand, + @"XCUIKeyboardKeySecondaryFn": XCUIKeyboardKeySecondaryFn + }; + }); + return keysMapping[name]; +} diff --git a/WebDriverAgentMac/WebDriverAgentMac.xcodeproj/project.pbxproj b/WebDriverAgentMac/WebDriverAgentMac.xcodeproj/project.pbxproj index 4b8b43c..3cba950 100644 --- a/WebDriverAgentMac/WebDriverAgentMac.xcodeproj/project.pbxproj +++ b/WebDriverAgentMac/WebDriverAgentMac.xcodeproj/project.pbxproj @@ -172,6 +172,8 @@ 7199B3D42565B25E000B5C51 /* WebDriverAgentLib.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 7199B3AB2565B122000B5C51 /* WebDriverAgentLib.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 719E6A6E25822DB800777988 /* XCUIApplication+AMUIInterruptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 719E6A6C25822DB800777988 /* XCUIApplication+AMUIInterruptions.h */; }; 719E6A6F25822DB800777988 /* XCUIApplication+AMUIInterruptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 719E6A6D25822DB800777988 /* XCUIApplication+AMUIInterruptions.m */; }; + 71AA30BF25EFF81900151CED /* AMKeyboardUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 71AA30BD25EFF81900151CED /* AMKeyboardUtils.h */; }; + 71AA30C025EFF81900151CED /* AMKeyboardUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 71AA30BE25EFF81900151CED /* AMKeyboardUtils.m */; }; 71B00E8E2566D4BA0010DA73 /* AMIntegrationTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 71B00E8D2566D4BA0010DA73 /* AMIntegrationTestCase.m */; }; 71B00E9B2566D7B00010DA73 /* WebDriverAgentLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7199B3AB2565B122000B5C51 /* WebDriverAgentLib.framework */; }; 71B00EA02566D9570010DA73 /* AMFindElementTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 71B00E9F2566D9570010DA73 /* AMFindElementTests.m */; }; @@ -390,6 +392,8 @@ 7199B3AE2565B122000B5C51 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 719E6A6C25822DB800777988 /* XCUIApplication+AMUIInterruptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "XCUIApplication+AMUIInterruptions.h"; sourceTree = ""; }; 719E6A6D25822DB800777988 /* XCUIApplication+AMUIInterruptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "XCUIApplication+AMUIInterruptions.m"; sourceTree = ""; }; + 71AA30BD25EFF81900151CED /* AMKeyboardUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AMKeyboardUtils.h; sourceTree = ""; }; + 71AA30BE25EFF81900151CED /* AMKeyboardUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AMKeyboardUtils.m; sourceTree = ""; }; 71B00E8B2566D4B90010DA73 /* IntegrationTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IntegrationTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 71B00E8D2566D4BA0010DA73 /* AMIntegrationTestCase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AMIntegrationTestCase.m; sourceTree = ""; }; 71B00E8F2566D4BA0010DA73 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -653,6 +657,8 @@ 7168D5A8258B847900EEFA12 /* LRUCache */, 713A9D3A2566AA2300118D07 /* AMGeometryUtils.h */, 713A9D3B2566AA2300118D07 /* AMGeometryUtils.m */, + 71AA30BD25EFF81900151CED /* AMKeyboardUtils.h */, + 71AA30BE25EFF81900151CED /* AMKeyboardUtils.m */, 718D2C302567FED3005F533B /* AMSessionCapabilities.h */, 718D2C312567FED3005F533B /* AMSessionCapabilities.m */, 718D2BF125678B4E005F533B /* AMSnapshotUtils.h */, @@ -787,6 +793,7 @@ 7109BFD42565B51E006BFD13 /* FBRunLoopSpinner.h in Headers */, 7109C0632565B5FD006BFD13 /* HTTPServer.h in Headers */, 7109C04B2565B5E0006BFD13 /* DDRange.h in Headers */, + 71AA30BF25EFF81900151CED /* AMKeyboardUtils.h in Headers */, 7109C0382565B5B9006BFD13 /* NSExpression+FBFormat.h in Headers */, 7180C1E8257A94F4008FA870 /* XCPointerEventPath.h in Headers */, 714CA6FC2566461100353B27 /* FBDebugCommands.h in Headers */, @@ -1068,6 +1075,7 @@ 714CA7072566487B00353B27 /* FBXPath.m in Sources */, 7109C0692565B605006BFD13 /* HTTPResponseProxy.m in Sources */, 718D2C0E2567AA03005F533B /* XCUIElement+AMEditable.m in Sources */, + 71AA30C025EFF81900151CED /* AMKeyboardUtils.m in Sources */, 713A9D382566A83800118D07 /* FBElementCommands.m in Sources */, 7109C05F2565B5F8006BFD13 /* HTTPMessage.m in Sources */, 714CA7022566475200353B27 /* XCUIApplication+AMSource.m in Sources */,