diff options
Diffstat (limited to 'testing/mochitest/tests/Harness_sanity/test_sanityEventUtils.html')
-rw-r--r-- | testing/mochitest/tests/Harness_sanity/test_sanityEventUtils.html | 526 |
1 files changed, 526 insertions, 0 deletions
diff --git a/testing/mochitest/tests/Harness_sanity/test_sanityEventUtils.html b/testing/mochitest/tests/Harness_sanity/test_sanityEventUtils.html new file mode 100644 index 0000000000..6135c65adf --- /dev/null +++ b/testing/mochitest/tests/Harness_sanity/test_sanityEventUtils.html @@ -0,0 +1,526 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Profiling test suite for EventUtils</title> + <script type="text/javascript"> + var start = new Date(); + </script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <script type="text/javascript"> + var loadTime = new Date(); + </script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> +</head> +<body onload="starttest()"> +<input type="radio" id="radioTarget1" name="group">Radio Target 1</input> +<input id="textBoxA"> +<input id="textBoxB"> +<input id="testMouseEvent" type="button" value="click"> +<input id="testKeyEvent" > +<input id="testStrEvent" > +<div id="scrollB" style="width: 190px;height: 250px;overflow:auto"> +<p>blah blah blah blah</p> +<p>blah blah blah blah</p> +<p>blah blah blah blah</p> +<p>blah blah blah blah</p> +<p>blah blah blah blah</p> +<p>blah blah blah blah</p> +<p>blah blah blah blah</p> +<p>blah blah blah blah</p> +</div> +<script class="testbody" type="text/javascript"> +const kStrictKeyPressEvents = + SpecialPowers.getBoolPref("dom.keyboardevent.keypress.dispatch_non_printable_keys_only_system_group_in_content"); +const kStrictKeyDownKeyUpEvents = + SpecialPowers.getBoolPref("dom.keyboardevent.dispatch_during_composition"); + +info("\nProfile::EventUtilsLoadTime: " + (loadTime - start) + "\n"); +function starttest() { + SimpleTest.waitForFocus( + async function () { + SimpleTest.waitForExplicitFinish(); + var startTime = new Date(); + var check = false; + function doCheck() { + check = true; + } + + /* test send* functions */ + $("testMouseEvent").addEventListener("click", doCheck, {once: true}); + sendMouseEvent({type:'click'}, "testMouseEvent"); + is(check, true, 'sendMouseEvent should dispatch click event'); + + check = false; + $("testKeyEvent").addEventListener("keypress", doCheck, {once: true}); + $("testKeyEvent").focus(); + sendChar("x"); + is($("testKeyEvent").value, "x", "sendChar should work"); + is(check, true, "sendChar should dispatch keyPress"); + $("testKeyEvent").value = ""; + + $("testStrEvent").focus(); + sendString("string"); + is($("testStrEvent").value, "string", "sendString should work"); + $("testStrEvent").value = ""; + + var keydown = false; + var keypress = false; + $("testKeyEvent").focus(); + $("testKeyEvent").addEventListener("keydown", function() { keydown = true; }, {once: true}); + $("testKeyEvent").addEventListener("keypress", function() { keypress = true; }, {once: true}); + sendKey("DOWN"); + ok(keydown, "sendKey should dispatch keyDown"); + if (kStrictKeyPressEvents) { + ok(!keypress, "sendKey shouldn't dispatch keyPress for non-printable key"); + } else { + ok(keypress, "sendKey should dispatch keyPress even for non-printable key"); + } + + /* test synthesizeMouse* */ + //focus trick enables us to run this in iframes + $("radioTarget1").addEventListener('focus', function (aEvent) { + synthesizeMouse($("radioTarget1"), 1, 1, {}); + is($("radioTarget1").checked, true, "synthesizeMouse should work") + $("radioTarget1").checked = false; + disableNonTestMouseEvents(true); + synthesizeMouse($("radioTarget1"), 1, 1, {}); + is($("radioTarget1").checked, true, "synthesizeMouse should still work with non-test mouse events disabled"); + $("radioTarget1").checked = false; + disableNonTestMouseEvents(false); + }, {once: true}); + $("radioTarget1").focus(); + + //focus trick enables us to run this in iframes + $("textBoxA").addEventListener("focus", function (aEvent) { + check = false; + $("textBoxA").addEventListener("click", function() { check = true; }, { once: true }); + synthesizeMouseAtCenter($("textBoxA"), {}); + is(check, true, 'synthesizeMouse should dispatch mouse event'); + + check = false; + $("scrollB").addEventListener("click", function() { check = true; }, { once: true }); + synthesizeMouseExpectEvent($("scrollB"), 1, 1, {}, $("scrollB"), "click", "synthesizeMouseExpectEvent should fire click event"); + is(check, true, 'synthesizeMouse should dispatch mouse event'); + }, {once: true}); + $("textBoxA").focus(); + + /** + * TODO: testing synthesizeWheel requires a setTimeout + * since there is delay between the scroll event and a check, so for now just test + * that we can successfully call it to avoid having setTimeout vary the runtime metric. + * Testing of this method is currently done here: + * toolkit/content/tests/chrome/test_mousescroll.xul + */ + synthesizeWheel($("scrollB"), 5, 5, {'deltaY': 10.0, deltaMode: WheelEvent.DOM_DELTA_LINE}); + + /* test synthesizeKey* */ + check = false; + $("testKeyEvent").addEventListener("keypress", doCheck, {once:true}); + $("testKeyEvent").focus(); + sendString("a"); + is($("testKeyEvent").value, "a", "synthesizeKey should work"); + is(check, true, "synthesizeKey should dispatch keyPress"); + $("testKeyEvent").value = ""; + + // If |.code| value is not specified explicitly, it should be computed + // from the |.key| value or |.keyCode| value. If a printable key is + // specified, the |.code| value should be guessed with US-English + // keyboard layout. + for (let test of [{ arg: "KEY_Enter", code: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN }, + { arg: "VK_RETURN", code: "Enter", keyCode: KeyboardEvent.DOM_VK_RETURN }, + { arg: "KEY_Backspace", code: "Backspace", keyCode: KeyboardEvent.DOM_VK_BACK_SPACE }, + { arg: "KEY_Delete", code: "Delete", keyCode: KeyboardEvent.DOM_VK_DELETE }, + { arg: "KEY_Home", code: "Home", keyCode: KeyboardEvent.DOM_VK_HOME }, + { arg: "KEY_End", code: "End", keyCode: KeyboardEvent.DOM_VK_END }, + { arg: "KEY_ArrowDown", code: "ArrowDown", keyCode: KeyboardEvent.DOM_VK_DOWN }, + { arg: "KEY_ArrowUp", code: "ArrowUp", keyCode: KeyboardEvent.DOM_VK_UP }, + { arg: "KEY_ArrowLeft", code: "ArrowLeft", keyCode: KeyboardEvent.DOM_VK_LEFT }, + { arg: "KEY_ArrowRight", code: "ArrowRight", keyCode: KeyboardEvent.DOM_VK_RIGHT }, + { arg: "KEY_Shift", code: "ShiftLeft", keyCode: KeyboardEvent.DOM_VK_SHIFT }, + { arg: "KEY_Control", code: "ControlLeft", keyCode: KeyboardEvent.DOM_VK_CONTROL }, + { arg: "a", code: "KeyA", keyCode: KeyboardEvent.DOM_VK_A }, + { arg: "B", code: "KeyB", keyCode: KeyboardEvent.DOM_VK_B }, + { arg: " ", code: "Space", keyCode: KeyboardEvent.DOM_VK_SPACE }, + { arg: "0", code: "Digit0", keyCode: KeyboardEvent.DOM_VK_0 }, + { arg: "(", code: "Digit9", keyCode: KeyboardEvent.DOM_VK_9 }, + { arg: "!", code: "Digit1", keyCode: KeyboardEvent.DOM_VK_1 }, + { arg: "[", code: "BracketLeft", keyCode: KeyboardEvent.DOM_VK_OPEN_BRACKET }, + { arg: ";", code: "Semicolon", keyCode: KeyboardEvent.DOM_VK_SEMICOLON }, + { arg: "\"", code: "Quote", keyCode: KeyboardEvent.DOM_VK_QUOTE }, + { arg: "~", code: "Backquote", keyCode: KeyboardEvent.DOM_VK_BACK_QUOTE }, + { arg: "<", code: "Comma", keyCode: KeyboardEvent.DOM_VK_COMMA }, + { arg: ".", code: "Period", keyCode: KeyboardEvent.DOM_VK_PERIOD }]) { + let testKeydown, keyup; + $("testKeyEvent").focus(); + $("testKeyEvent").addEventListener("keydown", (e) => { testKeydown = e; }, {once: true}); + $("testKeyEvent").addEventListener("keyup", (e) => { keyup = e; }, {once: true}); + synthesizeKey(test.arg); + is(testKeydown.code, test.code, `Synthesizing "${test.arg}" should set code value of "keydown" to "${test.code}"`); + is(testKeydown.keyCode, test.keyCode, `Synthesizing "${test.arg}" should set keyCode value of "keydown" to "${test.keyCode}"`); + is(keyup.code, test.code, `Synthesizing "${test.arg}" key should set code value of "keyup" to "${test.code}"`); + is(keyup.keyCode, test.keyCode, `Synthesizing "${test.arg}" key should set keyCode value of "keyup" to "${test.keyCode}"`); + $("testKeyEvent").value = ""; + } + + /* test synthesizeComposition */ + var description = ""; + var keydownEvent = null; + var keyupEvent = null; + function onKeyDown(aEvent) { + ok(!keydownEvent, description + "keydown should be fired only once" + (keydownEvent ? keydownEvent.key : "") + ", " + (keyupEvent ? keyupEvent.key : "")); + keydownEvent = aEvent; + } + function onKeyUp(aEvent) { + ok(!keyupEvent, description + "keyup should be fired only once"); + keyupEvent = aEvent; + } + function resetKeyDownAndKeyUp(aDescription) { + description = aDescription + ": "; + keydownEvent = null; + keyupEvent = null; + check = false; + } + function checkKeyDownAndKeyUp(aKeyDown, aKeyUp) { + if (aKeyDown && (!aKeyDown.inComposition || kStrictKeyDownKeyUpEvents)) { + is(keydownEvent.keyCode, aKeyDown.keyCode, + description + "keydown event should be dispatched (checking keyCode)"); + is(keydownEvent.key, aKeyDown.key, + description + "keydown event should be dispatched (checking key)"); + } else { + is(keydownEvent, null, + description + "keydown event shouldn't be fired"); + } + if (aKeyUp && (!aKeyUp.inComposition || kStrictKeyDownKeyUpEvents)) { + is(keyupEvent.keyCode, aKeyUp.keyCode, + description + "keyup event should be dispatched (checking keyCode)"); + is(keyupEvent.key, aKeyUp.key, + description + "keyup event should be dispatched (checking key)"); + } else { + is(keyupEvent, null, + description + "keyup event shouldn't be fired"); + } + } + $("textBoxB").addEventListener("keydown", onKeyDown); + $("textBoxB").addEventListener("keyup", onKeyUp); + + $("textBoxB").focus(); + + // If key event is not specified, fake keydown and keyup events which are + // marked as "processed by IME" should be fired. + resetKeyDownAndKeyUp("synthesizing eCompositionStart without specifying keyboard event"); + window.addEventListener("compositionstart", doCheck, {once: true}); + synthesizeComposition({type: "compositionstart"}); + ok(check, description + "synthesizeComposition() should dispatch compositionstart"); + checkKeyDownAndKeyUp({inComposition: false, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}, + {inComposition: true, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}); + + resetKeyDownAndKeyUp("trying to synthesize eCompositionUpdate directly without specifying keyboard event"); + window.addEventListener("compositionupdate", doCheck, {once: true}); + synthesizeComposition({type: "compositionupdate", data: "a"}); + ok(!check, description + "synthesizeComposition() should not dispatch compositionupdate without error"); + checkKeyDownAndKeyUp(null, null); + + resetKeyDownAndKeyUp("synthesizing eCompositionChange without specifying keyboard event"); + window.addEventListener("text", doCheck, {once: true}); + synthesizeCompositionChange( + { "composition": + { "string": "a", + "clauses": + [ + { "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE } + ] + }, + "caret": { "start": 1, "length": 0 } + } + ); + ok(check, description + "synthesizeCompositionChange should cause dispatching a DOM text event"); + checkKeyDownAndKeyUp({inComposition: true, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}, + {inComposition: true, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}); + + resetKeyDownAndKeyUp("synthesizing eCompositionChange for removing clauses without specifying keyboard event"); + synthesizeCompositionChange( + { "composition": + { "string": "a", + "clauses": + [ + { "length": 0, "attr": 0 } + ] + }, + "caret": { "start": 1, "length": 0 } + } + ); + checkKeyDownAndKeyUp({inComposition: true, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}, + {inComposition: true, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}); + + resetKeyDownAndKeyUp("trying to synthesize eCompositionEnd directly without specifying keyboard event"); + window.addEventListener("compositionend", doCheck, {once: true}); + synthesizeComposition({type: "compositionend", data: "a"}); + ok(!check, description + "synthesizeComposition() should not dispatch compositionend"); + checkKeyDownAndKeyUp(null, null); + + resetKeyDownAndKeyUp("synthesizing eCompositionCommit without specifying keyboard event"); + synthesizeComposition({type: "compositioncommit", data: "a"}); + ok(check, description + "synthesizeComposition() should dispatch compositionend"); + checkKeyDownAndKeyUp({inComposition: true, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}, + {inComposition: false, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}); + + var querySelectedText = synthesizeQuerySelectedText(); + ok(querySelectedText, "query selected text event result is null"); + ok(querySelectedText.succeeded, "query selected text event failed"); + is(querySelectedText.offset, 1, + "query selected text event returns wrong offset"); + is(querySelectedText.text, "", + "query selected text event returns wrong selected text"); + $("textBoxB").value = ""; + + querySelectedText = synthesizeQuerySelectedText(); + ok(querySelectedText, "query selected text event result is null"); + ok(querySelectedText.succeeded, "query selected text event failed"); + is(querySelectedText.offset, 0, + "query selected text event returns wrong offset"); + is(querySelectedText.text, "", + "query selected text event returns wrong selected text"); + var endTime = new Date(); + info("\nProfile::EventUtilsRunTime: " + (endTime-startTime) + "\n"); + + // In most cases, automated tests shouldn't try to synthesize + // compositionstart manually. Let's check if synthesizeCompositionChange() + // dispatches compositionstart automatically. + resetKeyDownAndKeyUp("synthesizing eCompositionChange without specifying keyboard event when there is no composition"); + window.addEventListener("compositionstart", doCheck, {once: true}); + synthesizeCompositionChange( + { "composition": + { "string": "a", + "clauses": + [ + { "length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE } + ] + }, + "caret": { "start": 1, "length": 0 } + } + ); + ok(check, description + "synthesizeCompositionChange should dispatch \"compositionstart\" automatically if there is no composition"); + checkKeyDownAndKeyUp({inComposition: false, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}, + {inComposition: true, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}); + + resetKeyDownAndKeyUp("synthesizing eCompositionCommitAsIs without specifying keyboard event"); + synthesizeComposition({type: "compositioncommitasis"}); + checkKeyDownAndKeyUp({inComposition: true, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}, + {inComposition: false, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}); + + // If key event is specified, keydown event which is marked as "processed + // by IME" should be fired and keyup event which is NOT marked as so + // should be fired too. + resetKeyDownAndKeyUp("synthesizing eCompositionStart with specifying keyboard event"); + synthesizeComposition({type: "compositionstart", key: {key: "a"}}); + checkKeyDownAndKeyUp({inComposition: false, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}, + {inComposition: true, keyCode: KeyboardEvent.DOM_VK_A, key: "a"}); + + resetKeyDownAndKeyUp("synthesizing eCompositionChange with specifying keyboard event"); + synthesizeCompositionChange( + {"composition": + {"string": "b", "clauses": [ + {"length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE} + ]}, + "caret": {"start": 1, "length": 0}, + "key": {key: "b"}, + } + ); + checkKeyDownAndKeyUp({inComposition: true, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}, + {inComposition: true, keyCode: KeyboardEvent.DOM_VK_B, key: "b"}); + + resetKeyDownAndKeyUp("synthesizing eCompositionCommit with specifying keyboard event"); + synthesizeComposition({type: "compositioncommit", data: "c", key: {key: "KEY_Enter"}}); + checkKeyDownAndKeyUp({inComposition: true, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}, + {inComposition: false, keyCode: KeyboardEvent.DOM_VK_RETURN, key: "Enter"}); + + // keyup shouldn't be dispatched automatically if type is specified as keydown + resetKeyDownAndKeyUp("synthesizing eCompositionStart with specifying keyboard event whose type is keydown"); + synthesizeComposition({type: "compositionstart", key: {key: "a", type: "keydown"}}); + checkKeyDownAndKeyUp({inComposition: false, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}, + null); + + resetKeyDownAndKeyUp("synthesizing eCompositionChange with specifying keyboard event whose type is keydown"); + synthesizeCompositionChange( + {"composition": + {"string": "b", "clauses": [ + {"length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE} + ]}, + "caret": {"start": 1, "length": 0}, + "key": {key: "b", type: "keydown"}, + } + ); + checkKeyDownAndKeyUp({inComposition: true, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}, + null); + + resetKeyDownAndKeyUp("synthesizing eCompositionCommit with specifying keyboard event whose type is keydown"); + synthesizeComposition({type: "compositioncommit", data: "c", key: {key: "KEY_Enter", type: "keydown"}}); + checkKeyDownAndKeyUp({inComposition: true, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}, + null); + + // keydown shouldn't be dispatched automatically if type is specified as keyup + resetKeyDownAndKeyUp("synthesizing eCompositionStart with specifying keyboard event whose type is keyup"); + synthesizeComposition({type: "compositionstart", key: {key: "a", type: "keyup"}}); + checkKeyDownAndKeyUp(null, + {inComposition: true, keyCode: KeyboardEvent.DOM_VK_A, key: "a"}); + + resetKeyDownAndKeyUp("synthesizing eCompositionChange with specifying keyboard event whose type is keyup"); + synthesizeCompositionChange( + {"composition": + {"string": "b", "clauses": [ + {"length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE} + ]}, + "caret": {"start": 1, "length": 0}, + "key": {key: "b", type: "keyup"}, + } + ); + checkKeyDownAndKeyUp(null, + {inComposition: true, keyCode: KeyboardEvent.DOM_VK_B, key: "b"}); + + resetKeyDownAndKeyUp("synthesizing eCompositionCommit with specifying keyboard event whose type is keyup"); + synthesizeComposition({type: "compositioncommit", data: "c", key: {key: "KEY_Enter", type: "keyup"}}); + checkKeyDownAndKeyUp(null, + {inComposition: false, keyCode: KeyboardEvent.DOM_VK_RETURN, key: "Enter"}); + + // keydown event shouldn't be marked as "processed by IME" if doNotMarkKeydownAsProcessed is true + resetKeyDownAndKeyUp("synthesizing eCompositionStart with specifying keyboard event whose doNotMarkKeydownAsProcessed is true"); + synthesizeComposition({type: "compositionstart", key: {key: "a", doNotMarkKeydownAsProcessed: true}}); + checkKeyDownAndKeyUp({inComposition: false, keyCode: KeyboardEvent.DOM_VK_A, key: "a"}, + {inComposition: true, keyCode: KeyboardEvent.DOM_VK_A, key: "a"}); + + resetKeyDownAndKeyUp("synthesizing eCompositionChange with specifying keyboard event whose doNotMarkKeydownAsProcessed is true"); + synthesizeCompositionChange( + {"composition": + {"string": "b", "clauses": [ + {"length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE} + ]}, + "caret": {"start": 1, "length": 0}, + "key": {key: "b", doNotMarkKeydownAsProcessed: true}, + } + ); + checkKeyDownAndKeyUp({inComposition: true, keyCode: KeyboardEvent.DOM_VK_B, key: "b"}, + {inComposition: true, keyCode: KeyboardEvent.DOM_VK_B, key: "b"}); + + resetKeyDownAndKeyUp("synthesizing eCompositionCommit with specifying keyboard event whose doNotMarkKeydownAsProcessed is true"); + synthesizeComposition({type: "compositioncommit", data: "c", key: {key: "KEY_Enter", doNotMarkKeydownAsProcessed: true}}); + checkKeyDownAndKeyUp({inComposition: true, keyCode: KeyboardEvent.DOM_VK_RETURN, key: "Enter"}, + {inComposition: false, keyCode: KeyboardEvent.DOM_VK_RETURN, key: "Enter"}); + + // keyup event should be marked as "processed by IME" if markKeyupAsProcessed is true + resetKeyDownAndKeyUp("synthesizing eCompositionStart with specifying keyboard event whose markKeyupAsProcessed is true"); + synthesizeComposition({type: "compositionstart", key: {key: "a", markKeyupAsProcessed: true}}); + checkKeyDownAndKeyUp({inComposition: false, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}, + {inComposition: true, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}); + + resetKeyDownAndKeyUp("synthesizing eCompositionChange with specifying keyboard event whose markKeyupAsProcessed is true"); + synthesizeCompositionChange( + {"composition": + {"string": "b", "clauses": [ + {"length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE} + ]}, + "caret": {"start": 1, "length": 0}, + "key": {key: "b", markKeyupAsProcessed: true}, + } + ); + checkKeyDownAndKeyUp({inComposition: true, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}, + {inComposition: true, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}); + + resetKeyDownAndKeyUp("synthesizing eCompositionCommit with specifying keyboard event whose markKeyupAsProcessed is true"); + synthesizeComposition({type: "compositioncommit", data: "c", key: {key: "KEY_Enter", markKeyupAsProcessed: true}}); + checkKeyDownAndKeyUp({inComposition: true, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}, + {inComposition: false, keyCode: KeyboardEvent.DOM_VK_PROCESSKEY, key: "Process"}); + + // If key event is explicitly declared with null, keyboard events shouldn't + // be fired for emulating text inputs without keyboard such as voice input or something. + resetKeyDownAndKeyUp("synthesizing eCompositionStart with specifying keyboard event as null"); + synthesizeComposition({type: "compositionstart", key: null}); + checkKeyDownAndKeyUp(null, null); + + resetKeyDownAndKeyUp("synthesizing eCompositionChange with specifying keyboard event as null"); + synthesizeCompositionChange( + {"composition": + {"string": "b", "clauses": [ + {"length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE} + ]}, + "caret": {"start": 1, "length": 0}, + "key": null, + } + ); + checkKeyDownAndKeyUp(null, null); + + resetKeyDownAndKeyUp("synthesizing eCompositionCommit with specifying keyboard event as null"); + synthesizeComposition({type: "compositioncommit", data: "c", key: null}); + checkKeyDownAndKeyUp(null, null); + + // If key event is explicitly declared with empty object, keyboard events + // shouldn't be fired for emulating text inputs without keyboard such as + // voice input or something. + resetKeyDownAndKeyUp("synthesizing eCompositionStart with specifying keyboard event as empty"); + synthesizeComposition({type: "compositionstart", key: {}}); + checkKeyDownAndKeyUp(null, null); + + resetKeyDownAndKeyUp("synthesizing eCompositionChange with specifying keyboard event as empty"); + synthesizeCompositionChange( + {"composition": + {"string": "b", "clauses": [ + {"length": 1, "attr": COMPOSITION_ATTR_RAW_CLAUSE} + ]}, + "caret": {"start": 1, "length": 0}, + "key": {}, + } + ); + checkKeyDownAndKeyUp(null, null); + + resetKeyDownAndKeyUp("synthesizing eCompositionCommit with specifying keyboard event as empty"); + synthesizeComposition({type: "compositioncommit", data: "c", key: {}}); + checkKeyDownAndKeyUp(null, null); + + $("textBoxB").removeEventListener("keydown", onKeyDown); + $("textBoxB").removeEventListener("keyup", onKeyUp); + + + // Async event synthesizing. + // On Android this does not work. + if (navigator.userAgent.includes("Android")) { + SimpleTest.finish(); + return; + } + + await (async function () { + await SpecialPowers.pushPrefEnv({set: [["test.events.async.enabled", true]]}); + try { + disableNonTestMouseEvents(true); + let mouseMoveCount = 0; + let waitForAllSynthesizedMouseMove = + new Promise(resolve => { + window.addEventListener("mousemove", function onMouseMove(aEvent) { + mouseMoveCount++; + is(aEvent.target, $("testMouseEvent"), + `The mousemove event target of ${ + mouseMoveCount + } should be the input#testMouseEvent, but ${ + aEvent.target.nodeName + }`); + if (mouseMoveCount === 30) { + window.removeEventListener("mousemove", onMouseMove, { capture: true }); + resolve(); + } + }, { capture: true }); + }); + for (let i = 0; i < 30; i++) { + synthesizeMouse($("testMouseEvent"), 3 + i % 2, 3 + i % 2, { type: "mousemove" }); + } + await waitForAllSynthesizedMouseMove; + } finally { + disableNonTestMouseEvents(false); + } + })(); + + SimpleTest.finish(); + } + ); +}; +</script> +</body> +</html> |