Add a test to ensure that we dispatch keydown and keyup events when multiple keys...
authordbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 12 Aug 2019 17:13:55 +0000 (17:13 +0000)
committerdbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 12 Aug 2019 17:13:55 +0000 (17:13 +0000)
https://bugs.webkit.org/show_bug.cgi?id=200548

Reviewed by Darin Adler.

Tools:

Expose infrastructure to simulate a literal raw key down and a literal key up event.

* TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
* TestRunnerShared/UIScriptContext/UIScriptController.h:
(WTR::UIScriptController::rawKeyDown):
(WTR::UIScriptController::rawKeyUp):
* WebKitTestRunner/ios/UIScriptControllerIOS.h:
* WebKitTestRunner/ios/UIScriptControllerIOS.mm:
(WTR::UIScriptControllerIOS::rawKeyDown):
(WTR::UIScriptControllerIOS::rawKeyUp):

LayoutTests:

Add a test. Skip the test for now until we have the fixes for <rdar://problem/53613454> and <rdar://problem/54001139>.

* fast/events/ios/multiple-key-press-and-release-ordering-expected.txt: Added.
* fast/events/ios/multiple-key-press-and-release-ordering.html: Added.
* platform/ios/TestExpectations:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248531 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/events/ios/multiple-key-press-and-release-ordering-expected.txt [new file with mode: 0644]
LayoutTests/fast/events/ios/multiple-key-press-and-release-ordering.html [new file with mode: 0644]
LayoutTests/platform/ios/TestExpectations
Tools/ChangeLog
Tools/TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl
Tools/TestRunnerShared/UIScriptContext/UIScriptController.h
Tools/WebKitTestRunner/ios/UIScriptControllerIOS.h
Tools/WebKitTestRunner/ios/UIScriptControllerIOS.mm

index 5ff5c22..60dda5d 100644 (file)
@@ -1,3 +1,16 @@
+2019-08-12  Daniel Bates  <dabates@apple.com>
+
+        Add a test to ensure that we dispatch keydown and keyup events when multiple keys are pressed at the same time
+        https://bugs.webkit.org/show_bug.cgi?id=200548
+
+        Reviewed by Darin Adler.
+
+        Add a test. Skip the test for now until we have the fixes for <rdar://problem/53613454> and <rdar://problem/54001139>.
+
+        * fast/events/ios/multiple-key-press-and-release-ordering-expected.txt: Added.
+        * fast/events/ios/multiple-key-press-and-release-ordering.html: Added.
+        * platform/ios/TestExpectations:
+
 2019-08-11  Alicia Boya GarcĂ­a  <aboya@igalia.com>
 
         [MSE][GStreamer] Don't use vorbisparse
diff --git a/LayoutTests/fast/events/ios/multiple-key-press-and-release-ordering-expected.txt b/LayoutTests/fast/events/ios/multiple-key-press-and-release-ordering-expected.txt
new file mode 100644 (file)
index 0000000..2e6f45f
--- /dev/null
@@ -0,0 +1,21 @@
+This tests that pressing and releasing keys dispatches DOM keydown and keyup events in the same order the keys were pressed and released.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+
+Press e, g then release e, g (in order):
+type: keydown, key: e, code: KeyE, keyIdentifier: U+0045, keyCode: 69, charCode: 0, keyCode: 69, which: 69, altKey: false, ctrlKey: false, metaKey: false, shiftKey: false, location: 0, keyLocation: 0
+type: keydown, key: g, code: KeyG, keyIdentifier: U+0047, keyCode: 71, charCode: 0, keyCode: 71, which: 71, altKey: false, ctrlKey: false, metaKey: false, shiftKey: false, location: 0, keyLocation: 0
+type: keyup, key: e, code: KeyE, keyIdentifier: U+0045, keyCode: 69, charCode: 0, keyCode: 69, which: 69, altKey: false, ctrlKey: false, metaKey: false, shiftKey: false, location: 0, keyLocation: 0
+type: keyup, key: g, code: KeyG, keyIdentifier: U+0047, keyCode: 71, charCode: 0, keyCode: 71, which: 71, altKey: false, ctrlKey: false, metaKey: false, shiftKey: false, location: 0, keyLocation: 0
+
+Press the Left Option, Right Option then release the Left Option, Right Option (in order):
+type: keydown, key: Alt, code: AltLeft, keyIdentifier: Alt, keyCode: 18, charCode: 0, keyCode: 18, which: 18, altKey: true, ctrlKey: false, metaKey: false, shiftKey: false, location: 1, keyLocation: 1
+type: keydown, key: Alt, code: AltRight, keyIdentifier: Alt, keyCode: 18, charCode: 0, keyCode: 18, which: 18, altKey: true, ctrlKey: false, metaKey: false, shiftKey: false, location: 2, keyLocation: 2
+type: keyup, key: Alt, code: AltLeft, keyIdentifier: Alt, keyCode: 18, charCode: 0, keyCode: 18, which: 18, altKey: false, ctrlKey: false, metaKey: false, shiftKey: false, location: 1, keyLocation: 1
+type: keyup, key: Alt, code: AltRight, keyIdentifier: Alt, keyCode: 18, charCode: 0, keyCode: 18, which: 18, altKey: false, ctrlKey: false, metaKey: false, shiftKey: false, location: 2, keyLocation: 2
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/events/ios/multiple-key-press-and-release-ordering.html b/LayoutTests/fast/events/ios/multiple-key-press-and-release-ordering.html
new file mode 100644 (file)
index 0000000..faba58c
--- /dev/null
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../resources/js-test.js"></script>
+<script src="../../../resources/ui-helper.js"></script>
+</head>
+<body>
+<script>
+window.jsTestIsAsync = true;
+
+// Move rawKeyDown() and rawKeyUp() to ui-helper.js if they turn out to be useful in other tests.
+function rawKeyDown(key)
+{
+    if (!window.testRunner)
+        return Promise.resolve();
+
+    return new Promise((resolve) => {
+        testRunner.runUIScript(`uiController.rawKeyDown("${key}");`, resolve);
+    });
+}
+
+function rawKeyUp(key)
+{
+    if (!window.testRunner)
+        return Promise.resolve();
+
+    return new Promise((resolve) => {
+        testRunner.runUIScript(`uiController.rawKeyUp("${key}");`, resolve);
+    });
+}
+
+function logKeyEvent(event)
+{
+    let pieces = [];
+    for (let propertyName of ["type", "key", "code", "keyIdentifier", "keyCode", "charCode", "keyCode", "which", "altKey", "ctrlKey", "metaKey", "shiftKey", "location", "keyLocation"])
+        pieces.push(`${propertyName}: ${event[propertyName]}`);
+    debug(pieces.join(", "));
+}
+
+async function runTest()
+{
+    document.body.addEventListener("keydown", logKeyEvent);
+    document.body.addEventListener("keyup", logKeyEvent);
+
+    debug("<br>Press e, g then release e, g (in order):");
+
+    let keyEvent;
+    keyEvent = await UIHelper.callFunctionAndWaitForEvent(() => rawKeyDown("e"), document.body, "keydown");
+    if (keyEvent.key !== "e")
+        testFailed("Did not press e");
+    keyEvent = await UIHelper.callFunctionAndWaitForEvent(() => rawKeyDown("g"), document.body, "keydown");
+    if (keyEvent.key !== "g")
+        testFailed("Did not press g");
+    await UIHelper.callFunctionAndWaitForEvent(() => rawKeyUp("e"), document.body, "keyup");
+    await UIHelper.callFunctionAndWaitForEvent(() => rawKeyUp("g"), document.body, "keyup");
+
+    debug("<br>Press the Left Option, Right Option then release the Left Option, Right Option (in order):");
+
+    keyEvent = await UIHelper.callFunctionAndWaitForEvent(() => rawKeyDown("leftAlt"), document.body, "keydown");
+    if (keyEvent.key !== "Alt" || keyEvent.location !== 1)
+        testFailed("Did not press left Option");
+    keyEvent = await UIHelper.callFunctionAndWaitForEvent(() => rawKeyDown("rightAlt"), document.body, "keydown");
+    if (keyEvent.key !== "Alt" || keyEvent.location !== 2)
+        testFailed("Did not press right Option");
+    await UIHelper.callFunctionAndWaitForEvent(() => rawKeyUp("leftAlt"), document.body, "keyup");
+    await UIHelper.callFunctionAndWaitForEvent(() => rawKeyUp("rightAlt"), document.body, "keyup");
+
+    document.body.removeEventListener("keydown", logKeyEvent);
+    document.body.removeEventListener("keyup", logKeyEvent);
+    finishJSTest();
+}
+
+description("This tests that pressing and releasing keys dispatches DOM keydown and keyup events in the same order the keys were pressed and released.");
+runTest();
+</script>
+</body>
+</html>
index 8f28b17..9c82483 100644 (file)
@@ -3363,3 +3363,5 @@ http/tests/quicklook/submit-form-blocked.html [ Pass Failure ]
 # rdar://54049321 (REGRESSION: editing/pasteboard/paste-does-not-fire-promises-while-sanitizing-web-content.html Failing)
 editing/pasteboard/paste-does-not-fire-promises-while-sanitizing-web-content.html [ Failure ]
 
+# Skip until we have the fixes for <rdar://problem/53613454> and <rdar://problem/54001139>.
+fast/events/ios/multiple-key-press-and-release-ordering.html [ Skip ]
index 1943030..62d1004 100644 (file)
@@ -1,3 +1,21 @@
+2019-08-12  Daniel Bates  <dabates@apple.com>
+
+        Add a test to ensure that we dispatch keydown and keyup events when multiple keys are pressed at the same time
+        https://bugs.webkit.org/show_bug.cgi?id=200548
+
+        Reviewed by Darin Adler.
+
+        Expose infrastructure to simulate a literal raw key down and a literal key up event.
+
+        * TestRunnerShared/UIScriptContext/Bindings/UIScriptController.idl:
+        * TestRunnerShared/UIScriptContext/UIScriptController.h:
+        (WTR::UIScriptController::rawKeyDown):
+        (WTR::UIScriptController::rawKeyUp):
+        * WebKitTestRunner/ios/UIScriptControllerIOS.h:
+        * WebKitTestRunner/ios/UIScriptControllerIOS.mm:
+        (WTR::UIScriptControllerIOS::rawKeyDown):
+        (WTR::UIScriptControllerIOS::rawKeyUp):
+
 2019-08-12  Thibault Saunier  <tsaunier@igalia.com>
 
         [GStreamer][WebRTC] Handle broken data in the libwebrtc GStreamer decoders
index d90efa6..7fffc77 100644 (file)
@@ -74,6 +74,9 @@ interface UIScriptController {
     void keyDown(DOMString character, object modifierArray);
     void toggleCapsLock(object callback);
 
+    void rawKeyDown(DOMString key);
+    void rawKeyUp(DOMString key);
+
     // eventsJSON describes a series of user events in JSON form. For the keys, see HIDEventGenerator.mm.
     // For example, this JSON describes a touch down followed by a touch up (i.e. a single tap).
     //  {
index f0fc377..f813300 100644 (file)
@@ -147,6 +147,9 @@ public:
     virtual void keyDown(JSStringRef character, JSValueRef modifierArray) { notImplemented(); }
     virtual void toggleCapsLock(JSValueRef callback) { notImplemented(); }
 
+    virtual void rawKeyDown(JSStringRef) { notImplemented(); }
+    virtual void rawKeyUp(JSStringRef) { notImplemented(); }
+
     virtual void keyboardAccessoryBarNext() { notImplemented(); }
     virtual void keyboardAccessoryBarPrevious() { notImplemented(); }
 
index efcd187..d8d4331 100644 (file)
@@ -64,6 +64,10 @@ public:
     void enterText(JSStringRef text) override;
     void typeCharacterUsingHardwareKeyboard(JSStringRef character, JSValueRef) override;
     void keyDown(JSStringRef character, JSValueRef modifierArray) override;
+
+    void rawKeyDown(JSStringRef) override;
+    void rawKeyUp(JSStringRef) override;
+
     void dismissFormAccessoryView() override;
     void dismissFilePicker(JSValueRef) override;
     JSRetainPtr<JSStringRef> selectFormPopoverTitle() const override;
index dac2926..3e0bdec 100644 (file)
@@ -460,6 +460,22 @@ static UIPhysicalKeyboardEvent *createUIPhysicalKeyboardEvent(NSString *hidInput
     return keyboardEvent;
 }
 
+void UIScriptControllerIOS::rawKeyDown(JSStringRef key)
+{
+    // Key can be either a single Unicode code point or the name of a special key (e.g. "downArrow").
+    // HIDEventGenerator knows how to map these special keys to the appropriate keycode.
+    [[HIDEventGenerator sharedHIDEventGenerator] keyDown:toWTFString(toWK(key))];
+    [[HIDEventGenerator sharedHIDEventGenerator] sendMarkerHIDEventWithCompletionBlock:^{ /* Do nothing */ }];
+}
+
+void UIScriptControllerIOS::rawKeyUp(JSStringRef key)
+{
+    // Key can be either a single Unicode code point or the name of a special key (e.g. "downArrow").
+    // HIDEventGenerator knows how to map these special keys to the appropriate keycode.
+    [[HIDEventGenerator sharedHIDEventGenerator] keyUp:toWTFString(toWK(key))];
+    [[HIDEventGenerator sharedHIDEventGenerator] sendMarkerHIDEventWithCompletionBlock:^{ /* Do nothing */ }];
+}
+
 void UIScriptControllerIOS::keyDown(JSStringRef character, JSValueRef modifierArray)
 {
     // Character can be either a single Unicode code point or the name of a special key (e.g. "downArrow").