Changeset 233131 in webkit
- Timestamp:
- Jun 23, 2018 12:17:09 PM (6 years ago)
- Location:
- trunk/Source
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebDriver/ChangeLog
r233122 r233131 1 2018-06-21 Brian Burg <bburg@apple.com> 2 3 Web Automation: key actions should support multiple pressed virtual keys 4 https://bugs.webkit.org/show_bug.cgi?id=186899 5 <rdar://problem/38222248> 6 7 Reviewed by Timothy Hatcher. 8 9 Adopt new protocol command argument types. 10 11 * Session.cpp: 12 (WebDriver::Session::performActions): 13 1 14 2018-06-23 Yusuke Suzuki <utatane.tea@gmail.com> 2 15 -
trunk/Source/WebDriver/Session.cpp
r233122 r233131 2319 2319 if (currentState.pressedKey) 2320 2320 state->setString("pressedCharKey"_s, currentState.pressedKey.value()); 2321 if (currentState.pressedVirtualKey) 2322 state->setString("pressedVirtualKey"_s, currentState.pressedVirtualKey.value()); 2321 if (currentState.pressedVirtualKey) { 2322 // FIXME: support parsing and tracking multiple virtual keys. 2323 Ref<JSON::Array> virtualKeys = JSON::Array::create(); 2324 virtualKeys->pushString(currentState.pressedVirtualKey.value()); 2325 state->setArray("pressedVirtualKeys"_s, WTFMove(virtualKeys)); 2326 } 2323 2327 break; 2324 2328 } -
trunk/Source/WebKit/ChangeLog
r233122 r233131 1 2018-06-21 Brian Burg <bburg@apple.com> 2 3 Web Automation: key actions should support multiple pressed virtual keys 4 https://bugs.webkit.org/show_bug.cgi?id=186899 5 <rdar://problem/38222248> 6 7 Reviewed by Timothy Hatcher. 8 9 This patch changes the protocol to allow multiple virtual keys per input source state. 10 Chords like Cmd-Shift-A and Shift-F12 must be represented this way as they are encoded 11 in the VirtualKey enum rather than as an ASCII char. 12 13 * UIProcess/Automation/Automation.json: 14 * UIProcess/Automation/SimulatedInputDispatcher.h: 15 * UIProcess/Automation/SimulatedInputDispatcher.cpp: 16 (WebKit::SimulatedInputDispatcher::transitionInputSourceToState): 17 * UIProcess/Automation/WebAutomationSession.cpp: 18 (WebKit::WebAutomationSession::simulateKeyboardInteraction): 19 (WebKit::WebAutomationSession::performKeyboardInteractions): 20 (WebKit::WebAutomationSession::performInteractionSequence): 21 22 * UIProcess/Automation/WebAutomationSession.h: 23 * UIProcess/Automation/gtk/WebAutomationSessionGtk.cpp: 24 (WebKit::WebAutomationSession::platformSimulateKeyboardInteraction): 25 * UIProcess/Automation/ios/WebAutomationSessionIOS.mm: 26 (WebKit::WebAutomationSession::platformSimulateKeyboardInteraction): 27 * UIProcess/Automation/mac/WebAutomationSessionMac.mm: 28 (WebKit::WebAutomationSession::platformSimulateKeyboardInteraction): 29 Also clean up the signature of WebAutomationSession::platformSimulateKeyboardInteraction 30 to use a variant instead of mutually exclusive optional values with different types. 31 1 32 2018-06-23 Yusuke Suzuki <utatane.tea@gmail.com> 2 33 -
trunk/Source/WebKit/UIProcess/Automation/Automation.json
r232150 r233131 291 291 { "name": "sourceId", "type": "string", "description": "The input source whose state is described by this object." }, 292 292 { "name": "pressedCharKey", "type": "string", "optional": true, "description": "For 'keyboard' input sources, specifies a character key that has 'pressed' state. Unmentioned character keys are assumed to have a 'released' state." }, 293 { "name": "pressedVirtualKey ", "$ref": "VirtualKey", "optional": true, "description": "For 'keyboard' input sources, specifies a virtual key that hasa 'pressed' state. Unmentioned virtual keys are assumed to have a 'released' state." },293 { "name": "pressedVirtualKeys", "type": "array", "items": { "$ref": "VirtualKey" }, "optional": true, "description": "For 'keyboard' input sources, specifies virtual keys that have a 'pressed' state. Unmentioned virtual keys are assumed to have a 'released' state." }, 294 294 { "name": "pressedButton", "$ref": "MouseButton", "optional": true, "description": "For 'mouse' input sources, specifies which mouse button has a 'pressed' state. Unmentioned mouse buttons are assumed to have a 'released' state." }, 295 295 { "name": "origin", "$ref": "MouseMoveOrigin", "optional": true, "description": "For 'mouse' input sources, specifies the origin type of a mouse move transition. Defaults to 'Viewport' if omitted."}, -
trunk/Source/WebKit/UIProcess/Automation/SimulatedInputDispatcher.cpp
r231767 r233131 268 268 case SimulatedInputSourceType::Keyboard: 269 269 // The "dispatch a key{Down,Up} action" algorithms (§17.4 Dispatching Actions). 270 if ((!a.pressedCharKey && b.pressedCharKey) || (!a.pressedVirtualKey && b.pressedVirtualKey)) 271 m_client.simulateKeyboardInteraction(m_page, KeyboardInteraction::KeyPress, b.pressedVirtualKey, b.pressedCharKey, WTFMove(eventDispatchFinished)); 272 else if ((a.pressedCharKey && !b.pressedCharKey) || (a.pressedVirtualKey && !b.pressedVirtualKey)) 273 m_client.simulateKeyboardInteraction(m_page, KeyboardInteraction::KeyRelease, a.pressedVirtualKey, a.pressedCharKey, WTFMove(eventDispatchFinished)); 274 else 270 if (!a.pressedCharKey && b.pressedCharKey) 271 m_client.simulateKeyboardInteraction(m_page, KeyboardInteraction::KeyPress, b.pressedCharKey.value(), WTFMove(eventDispatchFinished)); 272 else if (a.pressedCharKey && !b.pressedCharKey) 273 m_client.simulateKeyboardInteraction(m_page, KeyboardInteraction::KeyRelease, b.pressedCharKey.value(), WTFMove(eventDispatchFinished)); 274 else if (a.pressedVirtualKeys != b.pressedVirtualKeys) { 275 for (VirtualKey key : b.pressedVirtualKeys) { 276 if (!a.pressedVirtualKeys.contains(key)) 277 m_client.simulateKeyboardInteraction(m_page, KeyboardInteraction::KeyPress, key, WTFMove(eventDispatchFinished)); 278 } 279 280 for (VirtualKey key : a.pressedVirtualKeys) { 281 if (!b.pressedVirtualKeys.contains(key)) 282 m_client.simulateKeyboardInteraction(m_page, KeyboardInteraction::KeyRelease, key, WTFMove(eventDispatchFinished)); 283 } 284 } else 275 285 eventDispatchFinished(std::nullopt); 276 286 break; -
trunk/Source/WebKit/UIProcess/Automation/SimulatedInputDispatcher.h
r231767 r233131 53 53 using KeyboardInteraction = Inspector::Protocol::Automation::KeyboardInteractionType; 54 54 using VirtualKey = Inspector::Protocol::Automation::VirtualKey; 55 using VirtualKeySet = HashSet<VirtualKey, WTF::IntHash<VirtualKey>, WTF::StrongEnumHashTraits<VirtualKey>>; 55 56 using CharKey = char; // For WebDriver, this only needs to support ASCII characters on 102-key keyboard. 56 57 using MouseButton = WebMouseEvent::Button; … … 67 68 struct SimulatedInputSourceState { 68 69 std::optional<CharKey> pressedCharKey; 69 std::optional<VirtualKey> pressedVirtualKey;70 VirtualKeySet pressedVirtualKeys; 70 71 std::optional<MouseButton> pressedMouseButton; 71 72 std::optional<MouseMoveOrigin> origin; … … 116 117 virtual ~Client() { } 117 118 virtual void simulateMouseInteraction(WebPageProxy&, MouseInteraction, WebMouseEvent::Button, const WebCore::IntPoint& locationInView, AutomationCompletionHandler&&) = 0; 118 virtual void simulateKeyboardInteraction(WebPageProxy&, KeyboardInteraction, std::optional<VirtualKey>, std::optional<CharKey>, AutomationCompletionHandler&&) = 0;119 virtual void simulateKeyboardInteraction(WebPageProxy&, KeyboardInteraction, WTF::Variant<VirtualKey, CharKey>&&, AutomationCompletionHandler&&) = 0; 119 120 virtual void viewportInViewCenterPointOfElement(WebPageProxy&, uint64_t frameID, const String& nodeHandle, Function<void (std::optional<WebCore::IntPoint>, std::optional<AutomationCommandError>)>&&) = 0; 120 121 }; -
trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.cpp
r233122 r233131 1480 1480 } 1481 1481 1482 void WebAutomationSession::simulateKeyboardInteraction(WebPageProxy& page, KeyboardInteraction interaction, std::optional<VirtualKey> virtualKey, std::optional<CharKey> charKey, CompletionHandler<void(std::optional<AutomationCommandError>)>&& completionHandler)1482 void WebAutomationSession::simulateKeyboardInteraction(WebPageProxy& page, KeyboardInteraction interaction, WTF::Variant<VirtualKey, CharKey>&& key, CompletionHandler<void(std::optional<AutomationCommandError>)>&& completionHandler) 1483 1483 { 1484 1484 // Bridge the flushed callback to our command's completion handler. … … 1492 1492 callbackInMap = WTFMove(keyboardEventsFlushedCallback); 1493 1493 1494 platformSimulateKeyboardInteraction(page, interaction, virtualKey, charKey);1494 platformSimulateKeyboardInteraction(page, interaction, WTFMove(key)); 1495 1495 1496 1496 // Wait for keyboardEventsFlushedCallback to run when all events are handled. … … 1638 1638 bool foundVirtualKey = interactionObject->getString("key"_s, virtualKeyString); 1639 1639 if (foundVirtualKey) { 1640 autovirtualKey = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::VirtualKey>(virtualKeyString);1640 std::optional<VirtualKey> virtualKey = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::VirtualKey>(virtualKeyString); 1641 1641 if (!virtualKey) 1642 1642 ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "An interaction in the 'interactions' parameter has an invalid 'key' value."); 1643 1643 1644 1644 actionsToPerform.uncheckedAppend([this, page, interactionType, virtualKey] { 1645 platformSimulateKeyboardInteraction(*page, interactionType.value(), virtualKey , std::nullopt);1645 platformSimulateKeyboardInteraction(*page, interactionType.value(), virtualKey.value()); 1646 1646 }); 1647 1647 } … … 1796 1796 sourceState.pressedCharKey = pressedCharKeyString.characterAt(0); 1797 1797 1798 String pressedVirtualKeyString; 1799 if (stateObject->getString("pressedVirtualKey"_s, pressedVirtualKeyString)) 1800 sourceState.pressedVirtualKey = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::VirtualKey>(pressedVirtualKeyString); 1798 RefPtr<JSON::Array> pressedVirtualKeysArray; 1799 if (stateObject->getArray("pressedVirtualKeys"_s, pressedVirtualKeysArray)) { 1800 VirtualKeySet pressedVirtualKeys { }; 1801 1802 for (auto it = pressedVirtualKeysArray->begin(); it != pressedVirtualKeysArray->end(); ++it) { 1803 String pressedVirtualKeyString; 1804 if (!(*it)->asString(pressedVirtualKeyString)) 1805 ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "Encountered a non-string virtual key value."); 1806 1807 std::optional<VirtualKey> parsedVirtualKey = Inspector::Protocol::AutomationHelpers::parseEnumValueFromString<Inspector::Protocol::Automation::VirtualKey>(pressedVirtualKeyString); 1808 if (!parsedVirtualKey) 1809 ASYNC_FAIL_WITH_PREDEFINED_ERROR_AND_DETAILS(InvalidParameter, "Encountered an unknown virtual key value."); 1810 else 1811 pressedVirtualKeys.add(parsedVirtualKey.value()); 1812 } 1813 1814 sourceState.pressedVirtualKeys = pressedVirtualKeys; 1815 } 1801 1816 1802 1817 String pressedButtonString; … … 1927 1942 1928 1943 1929 void WebAutomationSession::platformSimulateKeyboardInteraction(WebPageProxy&, KeyboardInteraction, std::optional<VirtualKey>, std::optional<CharKey>)1944 void WebAutomationSession::platformSimulateKeyboardInteraction(WebPageProxy&, KeyboardInteraction, WTF::Variant<VirtualKey, CharKey>&&) 1930 1945 { 1931 1946 } -
trunk/Source/WebKit/UIProcess/Automation/WebAutomationSession.h
r233122 r233131 138 138 // SimulatedInputDispatcher::Client API 139 139 void simulateMouseInteraction(WebPageProxy&, MouseInteraction, WebMouseEvent::Button, const WebCore::IntPoint& locationInView, AutomationCompletionHandler&&) final; 140 void simulateKeyboardInteraction(WebPageProxy&, KeyboardInteraction, std::optional<VirtualKey>, std::optional<CharKey>, AutomationCompletionHandler&&) final;140 void simulateKeyboardInteraction(WebPageProxy&, KeyboardInteraction, WTF::Variant<VirtualKey, CharKey>&&, AutomationCompletionHandler&&) final; 141 141 void viewportInViewCenterPointOfElement(WebPageProxy&, uint64_t frameID, const String& nodeHandle, Function<void (std::optional<WebCore::IntPoint>, std::optional<AutomationCommandError>)>&&) final; 142 142 … … 234 234 void platformSimulateMouseInteraction(WebPageProxy&, MouseInteraction, WebMouseEvent::Button, const WebCore::IntPoint& locationInView, WebEvent::Modifiers keyModifiers); 235 235 // Simulates a single virtual or char key being pressed/released, such as 'a', Control, F-keys, Numpad keys, etc. as allowed by the protocol. 236 void platformSimulateKeyboardInteraction(WebPageProxy&, KeyboardInteraction, std::optional<VirtualKey>, std::optional<CharKey>);236 void platformSimulateKeyboardInteraction(WebPageProxy&, KeyboardInteraction, WTF::Variant<VirtualKey, CharKey>&&); 237 237 // Simulates key presses to produce the codepoints in a string. One or more code points are delivered atomically at grapheme cluster boundaries. 238 238 void platformSimulateKeySequence(WebPageProxy&, const String&); -
trunk/Source/WebKit/UIProcess/Automation/gtk/WebAutomationSessionGtk.cpp
r230988 r233131 295 295 } 296 296 297 void WebAutomationSession::platformSimulateKeyboardInteraction(WebPageProxy& page, KeyboardInteraction interaction, std::optional<VirtualKey> virtualKey, std::optional<CharKey> charKey)297 void WebAutomationSession::platformSimulateKeyboardInteraction(WebPageProxy& page, KeyboardInteraction interaction, WTF::Variant<VirtualKey, CharKey>&& key) 298 298 { 299 299 ASSERT(virtualKey.has_value() || charKey.has_value()); 300 300 301 301 unsigned keyCode; 302 if (virtualKey.has_value()) 303 keyCode = keyCodeForVirtualKey(virtualKey.value()); 304 else 305 keyCode = gdk_unicode_to_keyval(g_utf8_get_char(&charKey.value())); 302 WTF::switchOn(key, 303 [&] (VirtualKey virtualKey) { 304 keyCode = keyCodeForVirtualKey(virtualKey); 305 }, 306 [&] (CharKey charKey) { 307 keyCode = gdk_unicode_to_keyval(g_utf8_get_char(&charKey)); 308 } 309 ); 306 310 unsigned modifiers = modifiersForKeyCode(keyCode); 307 311 -
trunk/Source/WebKit/UIProcess/Automation/ios/WebAutomationSessionIOS.mm
r232236 r233131 66 66 #pragma mark Commands for Platform: 'iOS' 67 67 68 void WebAutomationSession::platformSimulateKeyboardInteraction(WebPageProxy& page, KeyboardInteraction interaction, std::optional<VirtualKey> virtualKey, std::optional<CharKey> charKey)68 void WebAutomationSession::platformSimulateKeyboardInteraction(WebPageProxy& page, KeyboardInteraction interaction, WTF::Variant<VirtualKey, CharKey>&& key) 69 69 { 70 ASSERT(virtualKey.has_value() || charKey.has_value());71 72 70 // The modifiers changed by the virtual key when it is pressed or released. 73 71 WebEventFlags changedModifiers = 0; … … 80 78 81 79 // Figure out the effects of sticky modifiers. 82 if (virtualKey.has_value()) { 83 charCode = charCodeForVirtualKey(virtualKey.value()); 84 charCodeIgnoringModifiers = charCodeIgnoringModifiersForVirtualKey(virtualKey.value()); 80 WTF::switchOn(key, 81 [&] (VirtualKey virtualKey) { 82 charCode = charCodeForVirtualKey(virtualKey); 83 charCodeIgnoringModifiers = charCodeIgnoringModifiersForVirtualKey(virtualKey); 85 84 86 switch (virtualKey.value()) { 87 case VirtualKey::Shift: 88 changedModifiers |= WebEventFlagMaskShift; 89 break; 90 case VirtualKey::Control: 91 changedModifiers |= WebEventFlagMaskControl; 92 break; 93 case VirtualKey::Alternate: 94 changedModifiers |= WebEventFlagMaskAlternate; 95 break; 96 case VirtualKey::Meta: 97 // The 'meta' key does not exist on Apple keyboards and is usually 98 // mapped to the Command key when using third-party keyboards. 99 case VirtualKey::Command: 100 changedModifiers |= WebEventFlagMaskCommand; 101 break; 102 default: 103 break; 85 switch (virtualKey) { 86 case VirtualKey::Shift: 87 changedModifiers |= WebEventFlagMaskShift; 88 break; 89 case VirtualKey::Control: 90 changedModifiers |= WebEventFlagMaskControl; 91 break; 92 case VirtualKey::Alternate: 93 changedModifiers |= WebEventFlagMaskAlternate; 94 break; 95 case VirtualKey::Meta: 96 // The 'meta' key does not exist on Apple keyboards and is usually 97 // mapped to the Command key when using third-party keyboards. 98 case VirtualKey::Command: 99 changedModifiers |= WebEventFlagMaskCommand; 100 break; 101 default: 102 break; 103 } 104 }, 105 [&] (CharKey charKey) { 106 charCode = (unichar)charKey; 107 charCodeIgnoringModifiers = (unichar)charKey; 104 108 } 105 } 106 107 if (charKey.has_value()) { 108 charCode = (unichar)charKey.value(); 109 charCodeIgnoringModifiers = (unichar)charKey.value(); 110 } 109 ); 111 110 112 111 // FIXME: consider using UIKit SPI to normalize 'characters', i.e., changing * to Shift-8, -
trunk/Source/WebKit/UIProcess/Automation/mac/WebAutomationSessionMac.mm
r232807 r233131 426 426 } 427 427 428 void WebAutomationSession::platformSimulateKeyboardInteraction(WebPageProxy& page, KeyboardInteraction interaction, std::optional<VirtualKey> virtualKey, std::optional<CharKey> charKey)428 void WebAutomationSession::platformSimulateKeyboardInteraction(WebPageProxy& page, KeyboardInteraction interaction, WTF::Variant<VirtualKey, CharKey>&& key) 429 429 { 430 430 // FIXME: this function and the Automation protocol enum should probably adopt key names 431 431 // from W3C UIEvents standard. For more details: https://w3c.github.io/uievents-code/ 432 433 ASSERT(virtualKey.has_value() || charKey.has_value());434 432 435 433 bool isStickyModifier = false; … … 439 437 std::optional<unichar> charCodeIgnoringModifiers; 440 438 441 if (virtualKey.has_value()) { 442 isStickyModifier = virtualKeyHasStickyModifier(virtualKey.value()); 443 changedModifiers = eventModifierFlagsForVirtualKey(virtualKey.value()); 444 keyCode = keyCodeForVirtualKey(virtualKey.value()); 445 charCode = charCodeForVirtualKey(virtualKey.value()); 446 charCodeIgnoringModifiers = charCodeIgnoringModifiersForVirtualKey(virtualKey.value()); 447 } 448 449 if (charKey.has_value()) { 450 charCode = (unichar)charKey.value(); 451 charCodeIgnoringModifiers = (unichar)charKey.value(); 452 } 439 WTF::switchOn(key, 440 [&] (VirtualKey virtualKey) { 441 isStickyModifier = virtualKeyHasStickyModifier(virtualKey); 442 changedModifiers = eventModifierFlagsForVirtualKey(virtualKey); 443 keyCode = keyCodeForVirtualKey(virtualKey); 444 charCode = charCodeForVirtualKey(virtualKey); 445 charCodeIgnoringModifiers = charCodeIgnoringModifiersForVirtualKey(virtualKey); 446 }, 447 [&] (CharKey charKey) { 448 charCode = (unichar)charKey; 449 charCodeIgnoringModifiers = (unichar)charKey; 450 } 451 ); 453 452 454 453 // FIXME: consider using AppKit SPI to normalize 'characters', i.e., changing * to Shift-8,
Note: See TracChangeset
for help on using the changeset viewer.