Bug 700199 EventUtils.js should use synthesized events for sendKey(), sendChar() and sendString() rather than untrusted events r=smaug+ehsan+dolske+enndeakin
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 16 Dec 2011 22:38:45 +0900
changeset 84429 f720be43486d77d085411307852b7702c00a0960
parent 84428 b4d0179b5a70aa89503db0e47b863e5888399958
child 84430 e218f75ccc41d957718fce88c7403f6def13bf77
push id519
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 00:38:35 +0000
treeherdermozilla-beta@788ea1ef610b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs700199
milestone11.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 700199 EventUtils.js should use synthesized events for sendKey(), sendChar() and sendString() rather than untrusted events r=smaug+ehsan+dolske+enndeakin
browser/base/content/test/browser_sanitizeDialog_treeView.js
browser/devtools/styleinspector/test/browser_ruleview_editor.js
browser/devtools/styleinspector/test/browser_ruleview_ui.js
content/html/content/test/test_bug388794.html
content/html/content/test/test_bug424698.html
content/html/content/test/test_bug558788-1.html
docshell/test/navigation/test_bug386782.html
docshell/test/navigation/test_bug430624.html
docshell/test/navigation/test_bug430723.html
editor/composer/test/test_bug389350.html
editor/libeditor/html/tests/test_bug432225.html
editor/libeditor/html/tests/test_bug455992.html
editor/libeditor/html/tests/test_bug456244.html
editor/libeditor/html/tests/test_bug487524.html
editor/libeditor/html/tests/test_bug607584.xul
editor/libeditor/text/tests/test_bug641466.html
layout/base/tests/bug106855-1-ref.html
layout/base/tests/bug106855-1.html
layout/base/tests/bug106855-2.html
layout/base/tests/bug240933-1.html
layout/base/tests/bug240933-2.html
layout/base/tests/bug482484.html
layout/base/tests/bug512295-1.html
layout/base/tests/bug512295-2.html
layout/base/tests/bug602141-1.html
layout/base/tests/bug602141-2.html
layout/base/tests/bug602141-3.html
layout/base/tests/bug602141-4.html
layout/base/tests/bug612271-1.html
layout/base/tests/bug612271-2.html
layout/base/tests/bug612271-3.html
layout/base/tests/bug613433-1.html
layout/base/tests/bug613433-2.html
layout/base/tests/bug613433-3.html
layout/forms/test/bug477700_subframe.html
layout/forms/test/test_bug345267.html
layout/forms/test/test_bug365410.html
layout/forms/test/test_bug446663.html
layout/forms/test/test_bug542914.html
layout/forms/test/test_bug563642.html
layout/generic/test/test_bug633762.html
mobile/android/chrome/tests/browser_escape.js
mobile/android/chrome/tests/browser_select.js
mobile/xul/chrome/tests/browser_escape.js
mobile/xul/chrome/tests/browser_select.js
testing/mochitest/tests/SimpleTest/EventUtils.js
testing/mochitest/tests/test_sanity.html
testing/mochitest/tests/test_sanityEventUtils.html
toolkit/components/passwordmgr/test/test_basic_form_autocomplete.html
toolkit/components/satchel/test/test_form_autocomplete.html
toolkit/content/tests/chrome/test_hiddenitems.xul
toolkit/content/tests/chrome/test_hiddenpaging.xul
toolkit/content/tests/chrome/test_richlist_direction.xul
--- a/browser/base/content/test/browser_sanitizeDialog_treeView.js
+++ b/browser/base/content/test/browser_sanitizeDialog_treeView.js
@@ -396,18 +396,19 @@ WindowHelper.prototype = {
    *        The amount and direction to move
    */
   moveGrippyBy: function (aDelta) {
     if (aDelta === 0)
       return;
     let key = aDelta < 0 ? "UP" : "DOWN";
     let abs = Math.abs(aDelta);
     let treechildren = this.getTree().treeBoxObject.treeBody;
+    treechildren.focus();
     for (let i = 0; i < abs; i++) {
-      EventUtils.sendKey(key, treechildren);
+      EventUtils.sendKey(key);
     }
   },
 
   /**
    * Selects a duration in the duration dropdown.
    *
    * @param aDurVal
    *        One of the Sanitizer.TIMESPAN_* values
--- a/browser/devtools/styleinspector/test/browser_ruleview_editor.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_editor.js
@@ -36,17 +36,17 @@ function testReturnCommit()
   clearBody();
   let span = createSpan();
   _editableField({
     element: span,
     initial: "explicit initial",
     start: function() {
       is(span.inplaceEditor.input.value, "explicit initial", "Explicit initial value should be used.");
       span.inplaceEditor.input.value = "Test Value";
-      EventUtils.sendKey("return", span.inplaceEditor.input);
+      EventUtils.sendKey("return");
     },
     done: expectDone("Test Value", true, testBlurCommit)
   });
   span.focus();
 }
 
 function testBlurCommit()
 {
@@ -69,34 +69,34 @@ function testAdvanceCharCommit()
   clearBody();
   let span = createSpan();
   _editableField({
     element: span,
     advanceChars: ":",
     start: function() {
       let input = span.inplaceEditor.input;
       for each (let ch in "Test:") {
-        EventUtils.sendChar(ch, input);
+        EventUtils.sendChar(ch);
       }
     },
     done: expectDone("Test", true, testEscapeCancel)
   });
   span.focus();
 }
 
 function testEscapeCancel()
 {
   clearBody();
   let span = createSpan();
   _editableField({
     element: span,
     initial: "initial text",
     start: function() {
       span.inplaceEditor.input.value = "Test Value";
-      EventUtils.sendKey("escape", span.inplaceEditor.input);
+      EventUtils.sendKey("escape");
     },
     done: expectDone("initial text", false, finishTest)
   });
   span.focus();
 }
 
 
 function finishTest()
--- a/browser/devtools/styleinspector/test/browser_ruleview_ui.js
+++ b/browser/devtools/styleinspector/test/browser_ruleview_ui.js
@@ -115,17 +115,17 @@ function testCreateNew()
       waitForEditorBlur(aEditor, function() {
         expectChange();
         is(textProp.value, "purple", "Text prop should have been changed.");
         testEditProperty();
       });
 
       aEditor.input.blur();
     });
-    EventUtils.sendKey("return", input);
+    EventUtils.sendKey("return", ruleDialog);
   });
 
   EventUtils.synthesizeMouse(elementRuleEditor.closeBrace, 1, 1,
                              { },
                              ruleDialog);
 }
 
 function testEditProperty()
@@ -143,21 +143,21 @@ function testEditProperty()
       waitForEditorBlur(aEditor, function() {
         expectChange();
         is(idRuleEditor.rule.style.getPropertyValue("border-color"), "red",
            "border-color should have been set.");
         testDisableProperty();
       });
 
       for each (let ch in "red;") {
-        EventUtils.sendChar(ch, input);
+        EventUtils.sendChar(ch, ruleDialog);
       }
     });
     for each (let ch in "border-color:") {
-      EventUtils.sendChar(ch, input);
+      EventUtils.sendChar(ch, ruleDialog);
     }
   });
 
   EventUtils.synthesizeMouse(propEditor.nameSpan, 1, 1,
                              { },
                              ruleDialog);
 }
 
--- a/content/html/content/test/test_bug388794.html
+++ b/content/html/content/test/test_bug388794.html
@@ -57,17 +57,18 @@ var hrefs = {
   test3: "data:text/html,?testImage.x=0&testImage.y=0",
   test4: "data:text/html,?x=0&y=0",
   test5: "data:text/html,?testImage.x=5&testImage.y=5",
   test6: "data:text/html,?x=5&y=5",
 };
 
 function submitForm(idNum) {
   $("test"+idNum).setAttribute("onload", "frameLoaded(this)");
-  sendKey("return", "test" + idNum + "image");
+  $("test" + idNum + "image").focus();
+  sendKey("return");
 }
 
 function submitFormMouse(idNum) {
   $("test"+idNum).setAttribute("onload", "frameLoaded(this)");
   synthesizeMouse($("test" + idNum + "image"), 5, 5, {});
 }
 
 addLoadEvent(function() {
--- a/content/html/content/test/test_bug424698.html
+++ b/content/html/content/test/test_bug424698.html
@@ -71,17 +71,17 @@ isnot(i.offsetWidth, 0, "Textarea didn't
 is(i.value, "test2", "Hiding/showing textarea should not affect value");
 i.defaultValue = "test3";
 is(i.value, "test3", "Setting textarea defaultValue after hide/show should work");
 
 // Make sure typing works ok
 i = $("target2");
 i.focus(); // Otherwise editor gets confused when we send the key events
 is(i.value, "", "Textarea value should be empty string in second control");
-sendString("2test2", "target2");
+sendString("2test2");
 is(i.value, "2test2", 'We just typed the string "2test2"');
 i.defaultValue = "2test3";
 is(i.value, "2test2", "Setting textarea defaultValue after typing should not work");
 i.style.display = "none";
 is(i.offsetWidth, 0, "Second textarea didn't hide?");
 i.style.display = "";
 isnot(i.offsetWidth, 0, "Second textarea didn't show?");
 is(i.value, "2test2", "Hiding/showing second textarea should not affect value");
--- a/content/html/content/test/test_bug558788-1.html
+++ b/content/html/content/test/test_bug558788-1.html
@@ -116,17 +116,17 @@ function checkInputEmail()
   gContent.appendChild(element);
   checkValidApplies(element);
 
   element.focus();
 
   synthesizeKey("a", {});
   checkInvalidApplies(element);
 
-  sendString("@b.c", element);
+  sendString("@b.c");
   checkValidApplies(element);
 
   synthesizeKey("VK_BACK_SPACE", {});
   for (var i=0; i<4; ++i) {
     if (i == 1) {
       // a@b is a valid value.
       checkValidApplies(element);
     } else {
@@ -146,17 +146,17 @@ function checkInputURL()
   gContent.appendChild(element);
   checkValidApplies(element);
 
   element.focus();
 
   synthesizeKey("h", {});
   checkInvalidApplies(element);
 
-  sendString("ttp://mozilla.org", element);
+  sendString("ttp://mozilla.org");
   checkValidApplies(element);
 
   for (var i=0; i<13; ++i) {
     synthesizeKey("VK_BACK_SPACE", {});
     checkValidApplies(element);
   }
 
   synthesizeKey("VK_BACK_SPACE", {});
--- a/docshell/test/navigation/test_bug386782.html
+++ b/docshell/test/navigation/test_bug386782.html
@@ -61,24 +61,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 
     function beginTest() {
       netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
       gTest.window.document.body.focus();
 
       // WARNING: If the following test fails, give the setTimeout() in the onload()
       // a bit longer; the doc hasn't had enough time to setup its editor.
       is(gTest.window.document.body.innerHTML, gTest.expectedBodyBeforeEdit, "Is doc setup yet");
-      
-      sendChar('E', gTest.window.document.body);
-      sendChar('D', gTest.window.document.body);
-      sendChar('I', gTest.window.document.body);
-      sendChar('T', gTest.window.document.body);
-      sendChar('E', gTest.window.document.body);
-      sendChar('D', gTest.window.document.body);
-      sendChar(' ', gTest.window.document.body);
+      sendString('EDITED ', gTest.window);
       is(gTest.window.document.body.innerHTML, gTest.expectedBodyAfterEdit, "Editing failed.");
 
       gTest.window.location = 'data:text/html;charset=utf-8,SomeOtherDocument';
       SimpleTest.waitForFocus(goBack, gTest.window);
     }
     
     function goBack() {
       netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
@@ -98,22 +91,17 @@ https://bugzilla.mozilla.org/show_bug.cg
       gTest.window.document.execCommand("undo", false, null);
       is(gTest.window.document.body.innerHTML, gTest.expectedBodyBeforeEdit, "Can we undo?");
 
       gTest.window.document.execCommand("redo", false, null);
       is(gTest.window.document.body.innerHTML, gTest.expectedBodyAfterEdit, "Can we redo?");
             
       // Check that we can still edit the page.
       gTest.window.document.body.focus();
-      sendChar('T', gTest.window.document.body);
-      sendChar('W', gTest.window.document.body);
-      sendChar('I', gTest.window.document.body);
-      sendChar('C', gTest.window.document.body);
-      sendChar('E', gTest.window.document.body);
-      sendChar(' ', gTest.window.document.body);
+      sendString('TWICE ', gTest.window);
       is(gTest.window.document.body.innerHTML, gTest.expectedBodyAfterSecondEdit, "Can we still edit?");
       
       gTest.window.close();
       goNext();
       
     }
     
   </script>
--- a/docshell/test/navigation/test_bug430624.html
+++ b/docshell/test/navigation/test_bug430624.html
@@ -31,22 +31,18 @@ function onLoad() {
 function onReload() {
   var iframe = window.frames[0].frameElement;
   SimpleTest.waitForFocus(doTest, iframe.contentWindow);
   iframe.contentDocument.body.focus();
 }
 
 function doTest() {
   var bodyElement = window.frames[0].frameElement.contentDocument.body;
-  sendChar('S', bodyElement);
-  sendChar('t', bodyElement);
-  sendChar('i', bodyElement);
-  sendChar('l', bodyElement);
-  sendChar('l', bodyElement);
-  sendChar(' ', bodyElement);
+  bodyElement.focus();
+  sendString('Still ', window.frames[0].frameElement.contentWindow);
 
   is(bodyElement.innerHTML, "Still contentEditable", "Check we're contentEditable after reload");
 
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 
--- a/docshell/test/navigation/test_bug430723.html
+++ b/docshell/test/navigation/test_bug430723.html
@@ -57,34 +57,40 @@ var nextTest =function() {
 }
 
 var step1 =function() {
   window.is(testWindow.location, gTallRedBoxURI, "Ensure red page loaded.");
   
   // Navigate down and up.
   is(testWindow.document.body.scrollTop, 0,
      "Page1: Ensure we scrollpane is at the top before we start scrolling.");
+  testWindow.focus();
   sendKey('DOWN', testWindow);
-  sendKey('UP', testWindow);
-  setTimeout(function() {
-    is(testWindow.document.body.scrollTop, 0,
-       "Page1: Ensure we can scroll down and up, back to the top.");  
-    
-    // Nav to blue box page. This should fire step2.
-    testWindow.location = gTallBlueBoxURI;
-  }, 0);
+  SimpleTest.executeSoon(function() {
+    isnot(testWindow.document.body.scrollTop, 0,
+          "Page1: Ensure we can scroll down.");
+    sendKey('UP', testWindow);
+    SimpleTest.executeSoon(function() {
+      is(testWindow.document.body.scrollTop, 0,
+         "Page1: Ensure we can scroll up, back to the top.");  
+
+      // Nav to blue box page. This should fire step2.
+      testWindow.location = gTallBlueBoxURI;
+    });
+  });
 }
 
 
 var step2 =function() {    
   window.is(testWindow.location, gTallBlueBoxURI, "Ensure blue page loaded.");
 
   // Scroll around a bit.
   is(testWindow.document.body.scrollTop, 0,
      "Page2: Ensure we scrollpane is at the top before we start scrolling.");
+  testWindow.focus();
   sendKey('DOWN', testWindow);
   sendKey('DOWN', testWindow);
   sendKey('DOWN', testWindow);
   setTimeout(function() {
     isnot(testWindow.document.body.scrollTop, 0,
           "Page2: Ensure we could scrol.");  
     
     // Navigate backwards. This should fire step3.
@@ -94,16 +100,17 @@ var step2 =function() {
 
 var step3 =function() {
   window.is(testWindow.location, gTallRedBoxURI,
             "Ensure red page restored from history.");
 
   // Check we can still scroll with the keys.
   is(testWindow.document.body.scrollTop, 0,
      "Page1Again: Ensure scroll pane at top before we scroll.");  
+  testWindow.focus();
   sendKey('DOWN', testWindow);
   setTimeout(function() {
     isnot(testWindow.document.body.scrollTop, 0,
           "Page2Again: Ensure we can still scroll.");  
     
     testWindow.close();
     window.SimpleTest.finish();
   }, 0);
--- a/editor/composer/test/test_bug389350.html
+++ b/editor/composer/test/test_bug389350.html
@@ -10,19 +10,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 <script type="text/javascript">
 
 function runTest() {
   var e = document.getElementById("edit");
   e.contentDocument.designMode='on';
   e.style.display='block';
   e.focus();
-  sendChar('a', e.contentDocument);
-  sendChar('b', e.contentDocument);
-  sendChar('c', e.contentDocument);
+  sendString('abc');
   var expected = "<head></head><body>abc</body>";
   var result = e.contentDocument.documentElement.innerHTML;
   is(result, expected, "iframe with designmode on had incorrect content");
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(runTest);
--- a/editor/libeditor/html/tests/test_bug432225.html
+++ b/editor/libeditor/html/tests/test_bug432225.html
@@ -53,22 +53,17 @@ function runTest() {
 function addWords(aLimit) {
   netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   if (aLimit == 0) {
     is(isSpellingCheckOk(), true, "All misspellings accounted for.");
     SimpleTest.finish();
     return;
   }
   getEdit().focus();
-  sendChar('a', editDoc());
-  sendChar('a', editDoc());
-  sendChar(' ', editDoc());
-  sendChar('O', editDoc());
-  sendChar('K', editDoc());
-  sendChar(' ', editDoc());
+  sendString('aa OK ');
   gMisspeltWords.push("aa");
   setTimeout(function() { addWords(aLimit-1); }, 0);
 }
 
 function isSpellingCheckOk() {
   var sel = getSpellCheckSelection();
   var numWords = sel.rangeCount;
   
--- a/editor/libeditor/html/tests/test_bug455992.html
+++ b/editor/libeditor/html/tests/test_bug455992.html
@@ -22,43 +22,43 @@ function runTest() {
     e = doc.getElementById(id + "_span");
     e.focus();
     return e;
   }
 
   function test_begin_bs(e) {
     const msg = "BACKSPACE at beginning of contenteditable inline element";
     var before = e.parentNode.childNodes[0].nodeValue;
-    sendKey("back_space", e);
+    sendKey("back_space");
     is(e.parentNode.childNodes[0].nodeValue, before, msg + " with id=" + e.id);
     is(e.innerHTML, "X", msg + " with id=" + e.id);
   }
 
   function test_begin_space(e) {
     const msg = "SPACE at beginning of contenteditable inline element";
     var before = e.parentNode.childNodes[0].nodeValue;
-    sendChar(" ", e);
+    sendChar(" ");
     is(e.parentNode.childNodes[0].nodeValue, before, msg + " with id=" + e.id);
     is(e.innerHTML, "&nbsp;X", msg + " with id=" + e.id);
   }
 
   function test_end_delete(e) {
     const msg = "DEL at end of contenteditable inline element";
     var before = e.parentNode.childNodes[2].nodeValue;
-    sendKey("right", e);
-    sendKey("delete", e);
+    sendKey("right");
+    sendKey("delete");
     is(e.parentNode.childNodes[2].nodeValue, before, msg + " with id=" + e.id);
     is(e.innerHTML, "X", msg + " with id=" + e.id);
   }
 
   function test_end_space(e) {
     const msg = "SPACE at end of contenteditable inline element";
     var before = e.parentNode.childNodes[2].nodeValue;
-    sendKey("right", e);
-    sendChar(" ", e);
+    sendKey("right");
+    sendChar(" ");
     is(e.parentNode.childNodes[2].nodeValue, before, msg + " with id=" + e.id);
     is(e.innerHTML, "X" + (e.tagName=="SPAN" ? "&nbsp;" : " <br>"), msg + " with id=" + e.id);
   }
 
   test_begin_bs(select("t1"));
   test_begin_space(select("t2"));
   test_end_delete(select("t3"));
   test_end_space(select("t4"));
--- a/editor/libeditor/html/tests/test_bug456244.html
+++ b/editor/libeditor/html/tests/test_bug456244.html
@@ -22,34 +22,34 @@ function runTest() {
     e = doc.getElementById(id + "_span");
     e.focus();
     return e;
   }
 
   function test_end_bs(e) {
     const msg = "Deleting all text in contenteditable inline element";
     var before = e.parentNode.childNodes[0].nodeValue;
-    sendKey("right", e);
-    sendKey("back_space", e);
-    sendKey("back_space", e);
+    sendKey("right");
+    sendKey("back_space");
+    sendKey("back_space");
     is(e.parentNode.childNodes[0].nodeValue, before, msg + " with id=" + e.id);
     is(e.innerHTML, "", msg + " with id=" + e.id);
   }
 
   test_end_bs(select("t1"));
   test_end_bs(setupIframe('i1',0));
 
   {
     const msg = "Deleting all text in contenteditable body element";
     var e = document.getElementById('i2');
     var doc = e.contentDocument;
     doc.body.setAttribute("contenteditable", "true");
     doc.body.focus();
-    sendKey("right", doc.body);
-    sendKey("back_space", doc.body);
+    sendKey("right");
+    sendKey("back_space");
     is(doc.body.innerHTML, "<br>", msg + " with id=" + e.id);
   }
 
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(runTest);
--- a/editor/libeditor/html/tests/test_bug487524.html
+++ b/editor/libeditor/html/tests/test_bug487524.html
@@ -26,29 +26,29 @@ function runTest() {
   var selection = doc.defaultView.getSelection();
   selection.removeAllRanges();
 
   var range = doc.createRange();
   range.setStart(li1,0);
   range.setEnd(li1.nextSibling,0);
   selection.addRange(range);
 
-  sendKey('delete', li1);
+  sendKey('delete');
   is(doc.body.innerHTML,'<ul><li>two</li><ul><li>a</li></ul></ul>','delete 1st LI');
 
   var li2 = setupIframe(i1,'<ul><li id="li2">two</li><ul><li>a</li></ul></ul>','li2')
   selection = doc.defaultView.getSelection();
   selection.removeAllRanges();
 
   range = doc.createRange();
   range.setStart(li2,0);
   range.setEnd(li2.nextSibling.firstChild,0);
   selection.addRange(range);
 
-  sendKey('delete', li2);
+  sendKey('delete');
   is(doc.body.innerHTML,'<ul><ul><li>a</li></ul></ul>','delete 2nd LI');
 
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(runTest);
 </script>
--- a/editor/libeditor/html/tests/test_bug607584.xul
+++ b/editor/libeditor/html/tests/test_bug607584.xul
@@ -52,22 +52,23 @@ https://bugzilla.mozilla.org/show_bug.cg
       },
   
     onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
     {
         if (aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP)
         {
           var editor = this.mEditor.getEditor(this.mEditor.contentWindow);
           if (editor) {
+              this.mEditor.focus();
               editor instanceof Components.interfaces.nsIHTMLEditor;
               editor.returnInParagraphCreatesNewParagraph = true;
               editor.insertHTML("<p id='foo'>this is a paragraph carrying id 'foo'</p>");
               var p = editor.document.getElementById('foo')
               editor.beginningOfDocument();
-              sendKey("return", p);
+              sendKey("return");
               var firstP = p.parentNode.firstElementChild;
               var lastP  = p.parentNode.lastElementChild;
               var isOk = firstP.nodeName.toLowerCase() == "p" &&
 	                       firstP.id == "foo" &&
 	                       lastP.id == "";
               ok(isOk, "CR in a paragraph with an ID should not create two paragraphs of same ID");
               progress.removeProgressListener(this);
               SimpleTest.finish();
--- a/editor/libeditor/text/tests/test_bug641466.html
+++ b/editor/libeditor/text/tests/test_bug641466.html
@@ -21,20 +21,20 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 /** Test for Bug 641466 **/
 SimpleTest.waitForExplicitFinish();
 SimpleTest.waitForFocus(function() {
   function doTest(element) {
     element.focus();
     element.selectionStart = 4;
     element.selectionEnd = 4;
-    synthesizeKey("VK_BACKSPACE", {});
-    synthesizeKey("VK_BACKSPACE", {});
-    synthesizeKey("VK_BACKSPACE", {});
-    synthesizeKey("VK_BACKSPACE", {});
+    synthesizeKey("VK_BACK_SPACE", {});
+    synthesizeKey("VK_BACK_SPACE", {});
+    synthesizeKey("VK_BACK_SPACE", {});
+    synthesizeKey("VK_BACK_SPACE", {});
 
     ok(element.value, "", "4 backspaces should delete all of the characters in the " + element.localName);
   }
 
   doTest(document.querySelector("input"));
   doTest(document.querySelector("textarea"));
 
   SimpleTest.finish();
--- a/layout/base/tests/bug106855-1-ref.html
+++ b/layout/base/tests/bug106855-1-ref.html
@@ -12,16 +12,16 @@ y
 <script>
   // Position the caret at the last line
   var sel = window.getSelection();
   sel.removeAllRanges();
 
   var area = document.getElementById('t');
   area.focus();
 
-  sendKey('RIGHT', window);  // now after "A"
-  sendKey('RIGHT', window);  // 
-  sendKey('RIGHT', window);  // 
-  sendKey('RIGHT', window);  // now at the last line
+  sendKey('RIGHT');  // now after "A"
+  sendKey('RIGHT');  // 
+  sendKey('RIGHT');  // 
+  sendKey('RIGHT');  // now at the last line
 </script>
 
 </body>
 </html>
--- a/layout/base/tests/bug106855-1.html
+++ b/layout/base/tests/bug106855-1.html
@@ -12,14 +12,14 @@ y
 <script>
   // Position the caret at the last line
   var sel = window.getSelection();
   sel.removeAllRanges();
 
   var area = document.getElementById('t');
   area.focus();
 
-  sendKey('DOWN', window);  // now after "A"
-  sendKey('DOWN', window);  // 
-  sendKey('DOWN', window);  // now at the last line
+  sendKey('DOWN');  // now after "A"
+  sendKey('DOWN');  // 
+  sendKey('DOWN');  // now at the last line
 </script>
 </body>
 </html>
--- a/layout/base/tests/bug106855-2.html
+++ b/layout/base/tests/bug106855-2.html
@@ -12,15 +12,15 @@ y
 <script>
   // Position the caret at the last line
   var sel = window.getSelection();
   sel.removeAllRanges();
 
   var area = document.getElementById('t');
   area.focus();
 
-  sendKey('DOWN', window);  // now after "A"
-  sendKey('DOWN', window);  // 
-  sendKey('DOWN', window);  // 
-  sendKey('DOWN', window);  // now at the last line
+  sendKey('DOWN');  // now after "A"
+  sendKey('DOWN');  // 
+  sendKey('DOWN');  // 
+  sendKey('DOWN');  // now at the last line
 </script>
 </body>
 </html>
--- a/layout/base/tests/bug240933-1.html
+++ b/layout/base/tests/bug240933-1.html
@@ -2,12 +2,12 @@
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
 </head>
 <body>
 <textarea id="t" rows="4"></textarea>
 <script>
   var area = document.getElementById('t');
   area.focus();
 
-  sendKey('ENTER', "t"); // press Enter once
+  sendKey('ENTER'); // press Enter once
 </script>
 </body>
 </html>
--- a/layout/base/tests/bug240933-2.html
+++ b/layout/base/tests/bug240933-2.html
@@ -2,14 +2,14 @@
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
 </head>
 <body>
 <textarea id="t" rows="4"></textarea>
 <script>
   var area = document.getElementById('t');
   area.focus();
 
-  sendKey('ENTER', "t"); // press Enter twice
-  sendKey('ENTER', "t");
-  sendKey('BACK_SPACE', "t"); // press Backspace once
+  sendKey('ENTER'); // press Enter twice
+  sendKey('ENTER');
+  sendKey('BACK_SPACE'); // press Backspace once
 </script>
 </body>
 </html>
--- a/layout/base/tests/bug482484.html
+++ b/layout/base/tests/bug482484.html
@@ -10,13 +10,13 @@
   var p = document.getElementById('p');
   var sel = window.getSelection();
   sel.removeAllRanges();
   var range = document.createRange();
   range.setStart(p.firstChild, 0)
   range.setEnd(p.firstChild, 0);
   sel.addRange(range);
 
-  sendKey('UP', div);  // move UP
-  sendChar('A', div);  // insert "A"
+  sendKey('UP');  // move UP
+  sendChar('A');  // insert "A"
 </script>
 </body>
 </html>
--- a/layout/base/tests/bug512295-1.html
+++ b/layout/base/tests/bug512295-1.html
@@ -14,17 +14,17 @@ x
   var range = document.createRange();
   var p = document.getElementById('p');
   var t = p.firstChild;
   range.setStart(t, 1);
   range.setEnd(t, 1);
   sel.addRange(range);
   p.parentNode.focus();
 
-  sendKey('DOWN', window);  // now after "1"
-  sendKey('DOWN', window);  // now make sure we get to the end
-  sendKey('DOWN', window);  // now make sure we get to the end
-  sendKey('DOWN', window);  // now make sure we get to the end
-  sendKey('DOWN', window);  // now make sure we get to the end
-  sendKey('DOWN', window);  // now make sure we get to the end
+  sendKey('DOWN');  // now after "1"
+  sendKey('DOWN');  // now make sure we get to the end
+  sendKey('DOWN');  // now make sure we get to the end
+  sendKey('DOWN');  // now make sure we get to the end
+  sendKey('DOWN');  // now make sure we get to the end
+  sendKey('DOWN');  // now make sure we get to the end
 </script>
 </body>
 </html>
--- a/layout/base/tests/bug512295-2.html
+++ b/layout/base/tests/bug512295-2.html
@@ -14,17 +14,17 @@ x
   var range = document.createRange();
   var p = document.getElementById('p');
   var t = p.firstChild;
   range.setStart(t, 1);
   range.setEnd(t, 1);
   sel.addRange(range);
   p.parentNode.focus();
 
-  sendKey('DOWN', window);  // now after "1"
-  sendKey('DOWN', window);  // now below the P element
-  sendKey('UP', window);    // now before the "1"
-  sendKey('UP', window);    // now before the "A"
-  sendKey('UP', window);    // now before the "A"
-  sendKey('UP', window);    // now before the "A"
+  sendKey('DOWN');  // now after "1"
+  sendKey('DOWN');  // now below the P element
+  sendKey('UP');    // now before the "1"
+  sendKey('UP');    // now before the "A"
+  sendKey('UP');    // now before the "A"
+  sendKey('UP');    // now before the "A"
 </script>
 </body>
 </html>
--- a/layout/base/tests/bug602141-1.html
+++ b/layout/base/tests/bug602141-1.html
@@ -10,12 +10,12 @@
   var range = document.createRange();
   var x = document.getElementById('x');
   var t = x.firstChild;
   range.setStart(t, 10);
   range.setEnd(t, 10);
   sel.addRange(range);
   x.focus();
 
-  sendKey('RIGHT', window); // Try to move the caret one position to the right
+  sendKey('RIGHT'); // Try to move the caret one position to the right
 </script>
 </body>
 </html>
--- a/layout/base/tests/bug602141-2.html
+++ b/layout/base/tests/bug602141-2.html
@@ -12,12 +12,12 @@
   var range = document.createRange();
   var x = document.getElementById('x');
   var t = x.firstChild;
   range.setStart(t, 12);
   range.setEnd(t, 12);
   sel.addRange(range);
   x.focus();
 
-  sendKey('RIGHT', window); // Try to move the caret one position to the right
+  sendKey('RIGHT'); // Try to move the caret one position to the right
 </script>
 </body>
 </html>
--- a/layout/base/tests/bug602141-3.html
+++ b/layout/base/tests/bug602141-3.html
@@ -10,12 +10,12 @@ noteditable<span id="x" contenteditable=
   var range = document.createRange();
   var x = document.getElementById('x');
   var t = x.firstChild;
   range.setStart(t, 10);
   range.setEnd(t, 10);
   sel.addRange(range);
   x.focus();
 
-  sendKey('RIGHT', window); // Try to move the caret one position to the right
+  sendKey('RIGHT'); // Try to move the caret one position to the right
 </script>
 </body>
 </html>
--- a/layout/base/tests/bug602141-4.html
+++ b/layout/base/tests/bug602141-4.html
@@ -10,12 +10,12 @@
   var range = document.createRange();
   var x = document.getElementById('x');
   var t = x.firstChild;
   range.setStart(t, 10);
   range.setEnd(t, 10);
   sel.addRange(range);
   x.focus();
 
-  sendKey('RIGHT', window); // Try to move the caret one position to the right
+  sendKey('RIGHT'); // Try to move the caret one position to the right
 </script>
 </body>
 </html>
--- a/layout/base/tests/bug612271-1.html
+++ b/layout/base/tests/bug612271-1.html
@@ -3,13 +3,13 @@
 </head>
 <body>
  <textarea id="target" style="height: 100px"
     onkeydown="this.style.display='block';this.style.height='200px';">foo</textarea>
 <script>
   var t = document.querySelector("textarea");
   t.focus();
   t.selectionStart = t.selectionEnd = t.value.length;
-  sendKey('ENTER', "target");
+  sendKey('ENTER');
   document.body.appendChild(document.createTextNode(t.selectionStart + " - " + t.selectionEnd));
 </script>
 </body>
 </html>
--- a/layout/base/tests/bug612271-2.html
+++ b/layout/base/tests/bug612271-2.html
@@ -3,13 +3,13 @@
 </head>
 <body>
   <textarea id="target" style="height: 100px"
     onkeypress="this.style.display='block';this.style.height='200px';">foo</textarea>
 <script>
   var t = document.querySelector("textarea");
   t.focus();
   t.selectionStart = t.selectionEnd = t.value.length;
-  sendKey('ENTER', "target");
+  sendKey('ENTER');
   document.body.appendChild(document.createTextNode(t.selectionStart + " - " + t.selectionEnd));
 </script>
 </body>
 </html>
--- a/layout/base/tests/bug612271-3.html
+++ b/layout/base/tests/bug612271-3.html
@@ -3,13 +3,13 @@
 </head>
 <body>
   <textarea id="target" style="height: 100px"
     onkeyup="this.style.display='block';this.style.height='200px';">foo</textarea>
 <script>
   var t = document.querySelector("textarea");
   t.focus();
   t.selectionStart = t.selectionEnd = t.value.length;
-  sendKey('ENTER', "target");
+  sendKey('ENTER');
   document.body.appendChild(document.createTextNode(t.selectionStart + " - " + t.selectionEnd));
 </script>
 </body>
 </html>
--- a/layout/base/tests/bug613433-1.html
+++ b/layout/base/tests/bug613433-1.html
@@ -7,18 +7,18 @@
         overflow-x: auto;
       }
     </style>
     <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
     <script>
       function test() {
         document.querySelector("div").focus();
         // type a character, then press backspace to delete it
-        sendKey("X", "div1");
-        sendKey("BACK_SPACE", "div1");
+        sendChar("X");
+        sendKey("BACK_SPACE");
         document.documentElement.removeAttribute("class");
       }
     </script>
   </head>
   <body onload="test()">
     <div id="div1" contenteditable></div>
   </body>
 </html>
--- a/layout/base/tests/bug613433-2.html
+++ b/layout/base/tests/bug613433-2.html
@@ -7,18 +7,18 @@
         overflow-y: auto;
       }
     </style>
     <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
     <script>
       function test() {
         document.querySelector("div").focus();
         // type a character, then press backspace to delete it
-        sendKey("X", "div1");
-        sendKey("BACK_SPACE", "div1");
+        sendChar("X");
+        sendKey("BACK_SPACE");
         document.documentElement.removeAttribute("class");
       }
     </script>
   </head>
   <body onload="test()">
     <div id="div1" contenteditable></div>
   </body>
 </html>
--- a/layout/base/tests/bug613433-3.html
+++ b/layout/base/tests/bug613433-3.html
@@ -7,18 +7,18 @@
         overflow: auto;
       }
     </style>
     <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
     <script>
       function test() {
         document.querySelector("div").focus();
         // type a character, then press backspace to delete it
-        sendKey("X", "div1");
-        sendKey("BACK_SPACE", "div1");
+        sendChar("X");
+        sendKey("BACK_SPACE");
         document.documentElement.removeAttribute("class");
       }
     </script>
   </head>
   <body onload="test()">
     <div id="div1" contenteditable></div>
   </body>
 </html>
--- a/layout/forms/test/bug477700_subframe.html
+++ b/layout/forms/test/bug477700_subframe.html
@@ -9,16 +9,17 @@
                                   encodeURIComponent(arg3), "*");
       }
 
       function $(arg) { return document.getElementById(arg); }
 
       window.addEventListener("message",
         function(evt) {
           doIs(evt.data, "start", "Unexpected message");
+          $("target").focus();
           sendString("Test");
           var t = $("target");
           doIs(t.value, "Test", "Typing should work");
           (function() {
             netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
             t.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor.undo(1);
           })()
           doIs(t.value, "", "Undo should work");
--- a/layout/forms/test/test_bug345267.html
+++ b/layout/forms/test/test_bug345267.html
@@ -78,16 +78,16 @@ is($("target").value, "abcdefghijklm",
 
 $("target").value = "";
 sendString("abcde");
 is($("target").value, "abc", "Typing should be limited by maxlength");
 
 $("target").value = "";
 sendString("ad");
 sendKey("left");
-sendString("bc")
+sendString("bc");
 is($("target").value, "abd", "Typing should be limited by maxlength again");
 
 </script>
 </pre>
 </body>
 </html>
 
--- a/layout/forms/test/test_bug365410.html
+++ b/layout/forms/test/test_bug365410.html
@@ -73,31 +73,31 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script type="application/javascript">
 
 /** Test for Bug 365410 **/
 
 function pageUpDownTest(id,index) {
   var elm = document.getElementById(id);
   elm.focus();
   elm.selectedIndex = 0;
-  sendKey("page_down", elm);
-  sendKey("page_down", elm);
-  sendKey("page_up", elm);
-  sendKey("page_down", elm);
+  sendKey("page_down");
+  sendKey("page_down");
+  sendKey("page_up");
+  sendKey("page_down");
   is(elm.selectedIndex, index, "pageUpDownTest: selectedIndex for " + id + " is " + index);
 }
 
 function upDownTest(id,index) {
   var elm = document.getElementById(id);
   elm.focus();
   elm.selectedIndex = 0;
-  sendKey("down", elm);
-  sendKey("down", elm);
-  sendKey("up", elm);
-  sendKey("down", elm);
+  sendKey("down");
+  sendKey("down");
+  sendKey("up");
+  sendKey("down");
   is(elm.selectedIndex, index, "upDownTest: selectedIndex for " + id + " is " + index);
 }
 
 function setHeight(id, h) {
   var elm = document.getElementById(id);
   elm.style.height = h + 'px';
 }
 
--- a/layout/forms/test/test_bug446663.html
+++ b/layout/forms/test/test_bug446663.html
@@ -43,37 +43,37 @@ function inputListener() {
   $(id).removeEventListener("input", inputListener, false);
 }
 
 var id = 'bug446663_a'
 var elm = document.getElementById(id);
 elm.focus();
 var x = document.body.offsetHeight;
 $(id).addEventListener("input", inputListener, false);
-sendChar('1',elm);
+sendChar('1');
 is(inputHappened, true, "How come no input?");
-sendChar('3',elm);
-sendKey('LEFT',elm)
-sendChar('2',elm);
+sendChar('3');
+sendKey('LEFT')
+sendChar('2');
 elm.blur();
 x = document.body.offsetHeight;
 is(elm.value, '123', id + " edit");
 test_edit_cmds(id)
 
 id = 'bug446663_b'
 elm = document.getElementById(id);
 elm.focus();
-sendChar('1',elm);
+sendChar('1');
 elm.style.display = 'none'
 var x = document.body.offsetHeight;
 elm.style.display = 'inline'
 x = document.body.offsetHeight;
-sendChar('3',elm);
-sendKey('LEFT',elm)
-sendChar('2',elm);
+sendChar('3');
+sendKey('LEFT')
+sendChar('2');
 elm.blur();
 x = document.body.offsetHeight;
 is(elm.value, '123', id + " edit");
 test_edit_cmds(id)
 
 </script>
 </pre>
 </body>
--- a/layout/forms/test/test_bug542914.html
+++ b/layout/forms/test/test_bug542914.html
@@ -54,35 +54,37 @@ function runTests(callback, type) {
   document.body.offsetHeight;
   b.focus();
   is(b.value, "some value", "The value does not change after being shown");
 
   var c = $("c");
 
   // Make sure that the control accepts input events without explicit initialization
   is(c.value, "", "Control is empty initially");
-  sendChar("a", c);
+  c.focus();
+  sendChar("a");
   is(c.value, "a", "Control accepts input without explicit initialization");
   // Make sure that the control retains its caret position
   c.focus();
   c.blur();
   c.focus();
-  sendChar("b", c);
+  sendChar("b");
   is(c.value, "ab", "Control retains caret position after being re-focused");
 
   var d = document.createElement("input");
   d.setAttribute("type", type);
   $("display").appendChild(d);
   document.body.offsetHeight;
 
   // Make sure dynamically injected inputs work as expected
   is(d.value, "", "Dynamic control's initial value should be empty");
   d.value = "new";
+  d.focus();
   is(d.value, "new", "Dynamic control's value can be set before initialization");
-  sendChar("x", d);
+  sendChar("x");
   is(d.value, "xnew", "Dynamic control accepts keyboard input without explicit initialization");
   $("display").removeChild(d);
   is(d.value, "xnew", "Dynamic control retains value after being removed from the document");
 
   callback();
 }
 
 var gPreviousType = "text";
--- a/layout/forms/test/test_bug563642.html
+++ b/layout/forms/test/test_bug563642.html
@@ -36,33 +36,33 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script type="application/javascript">
 
 /** Test for Bug 563642 **/
 
 function pageUpDownTest(id,index) {
   var elm = document.getElementById(id);
   elm.focus();
   elm.selectedIndex = 0;
-  sendKey("page_down", elm);
-  sendKey("page_down", elm);
-  sendKey("page_down", elm);
-  sendKey("page_up", elm);
-  sendKey("page_down", elm);
+  sendKey("page_down");
+  sendKey("page_down");
+  sendKey("page_down");
+  sendKey("page_up");
+  sendKey("page_down");
   is(elm.selectedIndex, index, "pageUpDownTest: selectedIndex for " + id + " is " + index);
 }
 
 function upDownTest(id,index) {
   var elm = document.getElementById(id);
   elm.focus();
   elm.selectedIndex = 0;
-  sendKey("down", elm);
-  sendKey("down", elm);
-  sendKey("down", elm);
-  sendKey("up", elm);
-  sendKey("down", elm);
+  sendKey("down");
+  sendKey("down");
+  sendKey("down");
+  sendKey("up");
+  sendKey("down");
   is(elm.selectedIndex, index, "upDownTest: selectedIndex for " + id + " is " + index);
 }
 
 function runTest() {
   pageUpDownTest("test1",3);
   pageUpDownTest("test2",4);
   pageUpDownTest("test3",-1);
   pageUpDownTest("test4",-1);
--- a/layout/generic/test/test_bug633762.html
+++ b/layout/generic/test/test_bug633762.html
@@ -29,17 +29,17 @@ function runTests() {
   // flush layout
   doc.documentElement.offsetLeft;
   // click in middle of iframe document to give it focus
   synthesizeMouseAtCenter(i, {}, win);
   win.focus();
   // record scrolltop
   scrollTopBefore = doc.body.scrollTop;
   // send up arrow key event
-  sendKey("UP", doc.body);
+  sendKey("UP");
 
   setTimeout("finish();", 0);
 }
 
 function finish() {
   // assert that scroll top is now less than before
   ok(scrollTopBefore > doc.body.scrollTop, "pressing up arrow should scroll up");
   SimpleTest.finish();
--- a/mobile/android/chrome/tests/browser_escape.js
+++ b/mobile/android/chrome/tests/browser_escape.js
@@ -93,17 +93,17 @@ function testGoBack() {
     }
   });
 }
 
 function testReturnToOwner() {
   tab1 = Browser.addTab("about:blank", true);
   tab2 = Browser.addTab("about:blank", true, tab1);
   is(Browser.selectedTab, tab2, "tab2 is selected");
-  EventUtils.sendKey("ESCAPE", window);
+  EventUtils.sendKey("ESCAPE");
   is(Browser.selectedTab, tab1, "tab1 is selected");
   closeTabs();
   testContextMenu();
 }
 
 function testContextMenu() {
   ContextHelper.showPopup({
     json: {
--- a/mobile/android/chrome/tests/browser_select.js
+++ b/mobile/android/chrome/tests/browser_select.js
@@ -42,17 +42,17 @@ function onPageReady() {
 
   waitFor(closeSelect, function() { return document.getElementById("select-container").hidden == false; });
 }
 
 function closeSelect() {
   let selectui = document.getElementById("select-container");
   is(selectui.hidden, false, "Select UI should be open");
 
-  EventUtils.sendKey("ESCAPE", window);
+  EventUtils.sendKey("ESCAPE");
 
   waitFor(tapOnMultiSelect, function() { return document.getElementById("select-container").hidden == true; });
 }
 
 function tapOnMultiSelect() {
   let selectui = document.getElementById("select-container");
   is(selectui.hidden, true, "Select UI should be hidden");
 
@@ -65,17 +65,17 @@ function tapOnMultiSelect() {
   waitFor(onUIReady, function() { return document.getElementById("select-container").hidden == false; });
 }
 
 function onUIReady() {
   let selectui = document.getElementById("select-container");
   is(selectui.hidden, false, "Select UI should be open");
   is(SelectHelperUI._selectedIndexes, 7, "Select UI should have the 8th option selected:" + SelectHelperUI._selectedIndexes);
 
-  EventUtils.sendKey("ESCAPE", window);
+  EventUtils.sendKey("ESCAPE");
 
   // Close our tab when finished
   Browser.closeTab(new_tab);
   is(selectui.hidden, true, "Select UI should be hidden");
 
   // We must finialize the tests
   finish();
 }
--- a/mobile/xul/chrome/tests/browser_escape.js
+++ b/mobile/xul/chrome/tests/browser_escape.js
@@ -93,17 +93,17 @@ function testGoBack() {
     }
   });
 }
 
 function testReturnToOwner() {
   tab1 = Browser.addTab("about:blank", true);
   tab2 = Browser.addTab("about:blank", true, tab1);
   is(Browser.selectedTab, tab2, "tab2 is selected");
-  EventUtils.sendKey("ESCAPE", window);
+  EventUtils.sendKey("ESCAPE");
   is(Browser.selectedTab, tab1, "tab1 is selected");
   closeTabs();
   testContextMenu();
 }
 
 function testContextMenu() {
   ContextHelper.showPopup({
     json: {
--- a/mobile/xul/chrome/tests/browser_select.js
+++ b/mobile/xul/chrome/tests/browser_select.js
@@ -42,17 +42,17 @@ function onPageReady() {
 
   waitFor(closeSelect, function() { return document.getElementById("select-container").hidden == false; });
 }
 
 function closeSelect() {
   let selectui = document.getElementById("select-container");
   is(selectui.hidden, false, "Select UI should be open");
 
-  EventUtils.sendKey("ESCAPE", window);
+  EventUtils.sendKey("ESCAPE");
 
   waitFor(tapOnMultiSelect, function() { return document.getElementById("select-container").hidden == true; });
 }
 
 function tapOnMultiSelect() {
   let selectui = document.getElementById("select-container");
   is(selectui.hidden, true, "Select UI should be hidden");
 
@@ -65,17 +65,17 @@ function tapOnMultiSelect() {
   waitFor(onUIReady, function() { return document.getElementById("select-container").hidden == false; });
 }
 
 function onUIReady() {
   let selectui = document.getElementById("select-container");
   is(selectui.hidden, false, "Select UI should be open");
   is(SelectHelperUI._selectedIndexes, 7, "Select UI should have the 8th option selected:" + SelectHelperUI._selectedIndexes);
 
-  EventUtils.sendKey("ESCAPE", window);
+  EventUtils.sendKey("ESCAPE");
 
   // Close our tab when finished
   Browser.closeTab(new_tab);
   is(selectui.hidden, true, "Select UI should be hidden");
 
   // We must finialize the tests
   finish();
 }
--- a/testing/mochitest/tests/SimpleTest/EventUtils.js
+++ b/testing/mochitest/tests/SimpleTest/EventUtils.js
@@ -68,115 +68,49 @@ function sendMouseEvent(aEvent, aTarget,
                        screenXArg, screenYArg, clientXArg, clientYArg,
                        ctrlKeyArg, altKeyArg, shiftKeyArg, metaKeyArg,
                        buttonArg, relatedTargetArg);
 
   SpecialPowers.dispatchEvent(aWindow, aTarget, event);
 }
 
 /**
- * Send the char aChar to the node with id aTarget.  If aTarget is not
- * provided, use "target".  This method handles casing of chars (sends the
- * right charcode, and sends a shift key for uppercase chars).  No other
- * modifiers are handled at this point.
- *
- * For now this method only works for English letters (lower and upper case)
- * and the digits 0-9.
- *
- * Returns true if the keypress event was accepted (no calls to preventDefault
- * or anything like that), false otherwise.
- */
-function sendChar(aChar, aTarget) {
-  // DOM event charcodes match ASCII (JS charcodes) for a-zA-Z0-9.
-  var hasShift = (aChar == aChar.toUpperCase());
-  var charCode = aChar.charCodeAt(0);
-  var keyCode = charCode;
-  if (!hasShift) {
-    // For lowercase letters, the keyCode is actually 32 less than the charCode
-    keyCode -= 0x20;
-  }
-
-  return __doEventDispatch(aTarget, charCode, keyCode, hasShift);
-}
-
-/**
- * Send the string aStr to the node with id aTarget.  If aTarget is not
- * provided, use "target".
+ * Send the char aChar to the focused element.  This method handles casing of
+ * chars (sends the right charcode, and sends a shift key for uppercase chars).
+ * No other modifiers are handled at this point.
  *
  * For now this method only works for English letters (lower and upper case)
  * and the digits 0-9.
  */
-function sendString(aStr, aTarget) {
+function sendChar(aChar, aWindow) {
+  // DOM event charcodes match ASCII (JS charcodes) for a-zA-Z0-9.
+  var hasShift = (aChar == aChar.toUpperCase());
+  synthesizeKey(aChar, { shiftKey: hasShift }, aWindow);
+}
+
+/**
+ * Send the string aStr to the focused element.
+ *
+ * For now this method only works for English letters (lower and upper case)
+ * and the digits 0-9.
+ */
+function sendString(aStr, aWindow) {
   for (var i = 0; i < aStr.length; ++i) {
-    sendChar(aStr.charAt(i), aTarget);
+    sendChar(aStr.charAt(i), aWindow);
   }
 }
 
 /**
- * Send the non-character key aKey to the node with id aTarget. If aTarget is
- * not provided, use "target".  The name of the key should be a lowercase
- * version of the part that comes after "DOM_VK_" in the KeyEvent constant
- * name for this key.  No modifiers are handled at this point.
- *
- * Returns true if the keypress event was accepted (no calls to preventDefault
- * or anything like that), false otherwise.
- */
-function sendKey(aKey, aTarget) {
-  keyName = "DOM_VK_" + aKey.toUpperCase();
-
-  if (!KeyEvent[keyName]) {
-    throw "Unknown key: " + keyName;
-  }
-
-  return __doEventDispatch(aTarget, 0, KeyEvent[keyName], false);
-}
-
-/**
- * Actually perform event dispatch given a charCode, keyCode, and boolean for
- * whether "shift" was pressed.  Send the event to the node with id aTarget.  If
- * aTarget is not provided, use "target".
- *
- * Returns true if the keypress event was accepted (no calls to preventDefault
- * or anything like that), false otherwise.
+ * Send the non-character key aKey to the focused node.  The name of the key
+ * should be a lowercase version of the part that comes after "DOM_VK_" in the
+ * KeyEvent constant name for this key.  No modifiers are handled at this point.
  */
-function __doEventDispatch(aTarget, aCharCode, aKeyCode, aHasShift) {
-  if (aTarget === undefined) {
-    aTarget = "target";
-  }
-
-  var event = document.createEvent("KeyEvents");
-  event.initKeyEvent("keydown", true, true, document.defaultView,
-                     false, false, aHasShift, false,
-                     aKeyCode, 0);
-  var accepted = SpecialPowers.dispatchEvent(window, aTarget, event);
-
-  // Preventing the default keydown action also prevents the default
-  // keypress action.
-  event = document.createEvent("KeyEvents");
-  if (aCharCode) {
-    event.initKeyEvent("keypress", true, true, document.defaultView,
-                       false, false, aHasShift, false,
-                       0, aCharCode);
-  } else {
-    event.initKeyEvent("keypress", true, true, document.defaultView,
-                       false, false, aHasShift, false,
-                       aKeyCode, 0);
-  }
-  if (!accepted) {
-    event.preventDefault();
-  }
-  accepted = SpecialPowers.dispatchEvent(window, aTarget, event);
-
-  // Always send keyup
-  var event = document.createEvent("KeyEvents");
-  event.initKeyEvent("keyup", true, true, document.defaultView,
-                     false, false, aHasShift, false,
-                     aKeyCode, 0);
-  SpecialPowers.dispatchEvent(window, aTarget, event);
-  return accepted;
+function sendKey(aKey, aWindow) {
+  keyName = "VK_" + aKey.toUpperCase();
+  synthesizeKey(keyName, { shiftKey: false }, aWindow);
 }
 
 /**
  * Parse the key modifier flags from aEvent. Used to share code between
  * synthesizeMouse and synthesizeKey.
  */
 function _parseModifiers(aEvent)
 {
@@ -388,33 +322,37 @@ function _computeKeyCodeFromChar(aChar)
  *
  * aWindow is optional, and defaults to the current window object.
  */
 function synthesizeKey(aKey, aEvent, aWindow)
 {
   var utils = _getDOMWindowUtils(aWindow);
   if (utils) {
     var keyCode = 0, charCode = 0;
-    if (aKey.indexOf("VK_") == 0)
+    if (aKey.indexOf("VK_") == 0) {
       keyCode = KeyEvent["DOM_" + aKey];
-    else {
+      if (!keyCode) {
+        throw "Unknown key: " + aKey;
+      }
+    } else {
       charCode = aKey.charCodeAt(0);
       keyCode = _computeKeyCodeFromChar(aKey.charAt(0));
     }
 
     var modifiers = _parseModifiers(aEvent);
 
     if (aEvent.type == "keypress") {
       utils.sendKeyEvent(aEvent.type, charCode ? 0 : keyCode,
                          charCode, modifiers);
     } else if (aEvent.type) {
       utils.sendKeyEvent(aEvent.type, keyCode, 0, modifiers);
     } else {
       var keyDownDefaultHappened =
           utils.sendKeyEvent("keydown", keyCode, 0, modifiers);
+      // XXX Shouldn't dispatch keypress event if the key is a modifier key.
       utils.sendKeyEvent("keypress", charCode ? 0 : keyCode, charCode,
                          modifiers, !keyDownDefaultHappened);
       utils.sendKeyEvent("keyup", keyCode, 0, modifiers);
     }
   }
 }
 
 var _gSeenEvent = false;
--- a/testing/mochitest/tests/test_sanity.html
+++ b/testing/mochitest/tests/test_sanity.html
@@ -39,23 +39,23 @@ is(press1, true, "synthesizeKey should d
 var press2 = false;
 $("testKeyEvent2").focus();
 synthesizeKey("x", {});
 is($("testKeyEvent2").value, "", "synthesizeKey should respect keydown preventDefault");
 is(press2, true, "synthesizeKey should dispatch keyPress with default prevented");
 
 var press3 = false;
 $("testKeyEvent3").focus();
-sendChar("x", "testKeyEvent3")
+sendChar("x")
 is($("testKeyEvent3").value, "x", "sendChar should work");
 is(press3, true, "sendChar should dispatch keyPress");
 
 var press4 = false;
 $("testKeyEvent4").focus();
-sendChar("x", "testKeyEvent4")
+sendChar("x")
 is($("testKeyEvent4").value, "", "sendChar should respect keydown preventDefault");
 is(press4, true, "sendChar should dispatch keyPress with default prevented");
 
 
 </script>
 </pre>
 </body>
 </html>
--- a/testing/mochitest/tests/test_sanityEventUtils.html
+++ b/testing/mochitest/tests/test_sanityEventUtils.html
@@ -41,27 +41,29 @@ function starttest() {
       /* test send* functions */
       $("testMouseEvent").addEventListener("click", function() { check=true; }, false);
       sendMouseEvent({type:'click'}, "testMouseEvent");
       is(check, true, 'sendMouseEvent should dispatch click event');
       
       check = false;
       $("testKeyEvent").addEventListener("keypress", function() { check = true; }, false);
       $("testKeyEvent").focus();
-      sendChar("x", "testKeyEvent");
+      sendChar("x");
       is($("testKeyEvent").value, "x", "sendChar should work");
       is(check, true, "sendChar should dispatch keyPress");
       $("testKeyEvent").value = "";
     
-      sendString("string", "testStrEvent");
+      $("testStrEvent").focus();
+      sendString("string");
       is($("testStrEvent").value, "string", "sendString should work");
       $("testStrEvent").value = "";
     
       check = false;
-      sendKey("DOWN", "testKeyEvent");
+      $("testKeyEvent").focus();
+      sendKey("DOWN");
       is(check, true, "sendKey should dispatch keyPress");
     
       /* test synthesizeMouse* */
       //focus trick enables us to run this in iframes
       $("radioTarget1").addEventListener('focus', function (aEvent) {
         $("radioTarget1").removeEventListener('focus', arguments.callee, false);
         synthesizeMouse($("radioTarget1"), 1, 1, {});
         is($("radioTarget1").checked, true, "synthesizeMouse should work")
--- a/toolkit/components/passwordmgr/test/test_basic_form_autocomplete.html
+++ b/toolkit/components/passwordmgr/test/test_basic_form_autocomplete.html
@@ -638,17 +638,17 @@ function runTest(testNum) {
         gNextTestWillOpenPopup = false;
         break;
 
     case 109:
         // Test that the password field remains filled in after changing
         // the username.
         uname.focus();
         doKey("right");
-        sendChar("X", uname);
+        sendChar("X");
         // Trigger the 'blur' event on uname
         pword.focus();
         checkACForm("sXingleuser5", "singlepass5");
 
         pwmgr.removeLogin(login5);
         testNum = 499;
         gNextTestWillOpenPopup = true;
         break;
@@ -717,48 +717,50 @@ function runTest(testNum) {
         gNextTestWillOpenPopup = false;
         break;
 
     case 603:
         checkACForm("", "");
         pwmgr.removeLogin(login7);
 
         testNum = 699;
-        gNextTestWillOpenPopup = false;
+        gNextTestWillOpenPopup = true;
         break;
 
     case 700:
         // Turn our attention to form9 to test the dropdown - bug 497541
         uname = $_(9, "uname");
         pword = $_(9, "pword");
-        sendString("form9userAB", uname);
+        uname.focus();
+        sendString("form9userAB");
         gNextTestWillOpenPopup = true;
         break;
 
     case 701:
         checkACForm("form9userAB", "");
         uname.focus();
         doKey("left");
-        sendChar("A", uname);
+        sendChar("A");
         gNextTestWillOpenPopup = false;
         break;
 
     case 702:
         // check dropdown is updated after inserting "A"
         checkACForm("form9userAAB", "");
         checkMenuEntries(["form9userAAB"]);
         doKey("down");
         doKey("return");
         checkACForm("form9userAAB", "form9pass");
         gNextTestWillOpenPopup = false;
         break;
 
     case 703:
         pwmgr.addLogin(login8C);
-        sendChar("z", uname);
+        uname.focus();
+        sendChar("z");
         gNextTestWillOpenPopup = false;
         break;
 
     case 704:
         // check that empty results are cached - bug 496466
         checkMenuEntries([]);
 
         SimpleTest.finish();
--- a/toolkit/components/satchel/test/test_form_autocomplete.html
+++ b/toolkit/components/satchel/test/test_form_autocomplete.html
@@ -472,117 +472,131 @@ function runTest(testNum) {
         doKey("down");
         doKey("return");
         checkForm("");
 
         // Look at form 5, try to trigger autocomplete popup
         input = $_(5, "field3");
         restoreForm();
         testNum = 199;
-        sendChar("a", input);
+        input.focus();
+        sendChar("a");
         break;
 
     /* Test filtering as characters are typed. */
 
     case 200:
         checkMenuEntries(["a", "aa", "aaz", "aa\xe6", "az"]);
-        sendChar("a", input);
+        input.focus();
+        sendChar("a");
         break;
 
     case 201:
         checkMenuEntries(["aa", "aaz", "aa\xe6"]);
-        sendChar("\xc6", input);
+        input.focus();
+        sendChar("\xc6");
         break;
 
     case 202:
         checkMenuEntries(["aa\xe6"]);
         doKey("back_space");
         break;
 
     case 203:
         checkMenuEntries(["aa", "aaz", "aa\xe6"]);
         doKey("back_space");
         break;
 
     case 204:
         checkMenuEntries(["a", "aa", "aaz", "aa\xe6", "az"]);
-        sendChar("z", input);
+        input.focus();
+        sendChar("z");
         break;
 
     case 205:
         ok(getMenuEntries().length > 0, "checking typing in middle of text");
+        input.focus();
         doKey("left");
-        sendChar("a", input);
+        sendChar("a");
         break;
 
     case 206:
         checkMenuEntries(["aaz"]);
         fh.addEntry("field3", "aazq");
+        input.focus();
         doKey("right");
-        sendChar("q", input);
+        sendChar("q");
         break;
 
     case 207:
         // check that results were cached
         checkMenuEntries([]);
         fh.addEntry("field3", "aazqq");
-        sendChar("q", input);
+        input.focus();
+        sendChar("q");
         break;
 
     case 208:
         // check that empty results were cached - bug 496466
         checkMenuEntries([]);
         doKey("escape");
 
         // Look at form 6, try to trigger autocomplete popup
         input = $_(6, "field4");
         restoreForm();
         testNum = 249;
-        sendChar("a", input);
+        input.focus();
+        sendChar("a");
         break;
 
     /* Test substring matches and word boundary bonuses */
 
     case 250:
         // alphabetical results for first character
         checkMenuEntries(["aa a\xe6", "aba\xe6", "a\xe6"]);
-        sendChar("\xc6", input);
+        input.focus();
+        sendChar("\xc6");
         break;
 
     case 251:
         // prefix match comes first, then word boundary match
         // followed by substring match
         checkMenuEntries(["a\xe6", "aa a\xe6", "aba\xe6"]);
 
         restoreForm();
-        sendChar("b", input);
+        input.focus();
+        sendChar("b");
         break;
 
     case 252:
         checkMenuEntries(["bc d\xe6"]);
-        sendChar(" ", input);
+        input.focus();
+        sendChar(" ");
         break;
 
     case 253:
         // check that trailing space has no effect after single char.
         checkMenuEntries(["bc d\xe6"]);
-        sendChar("\xc6", input);
+        input.focus();
+        sendChar("\xc6");
         break;
 
     case 254:
         // check multi-word substring matches
         checkMenuEntries(["bc d\xe6", "aba\xe6"]);
+        input.focus();
         doKey("left");
-        sendChar("d", input);
+        sendChar("d");
         break;
 
     case 255:
         // check inserting in multi-word searches
         checkMenuEntries(["bc d\xe6"]);
-        sendChar("z", input);
+        input.focus();
+        sendChar("z");
         break;
 
     case 256:
         checkMenuEntries([]);
 
         // Look at form 7, try to trigger autocomplete popup
         input = $_(7, "field5");
         restoreForm();
@@ -625,17 +639,18 @@ function runTest(testNum) {
         doKey("down");
         break;
 
     case 305:
         checkMenuEntries([]);
         input.maxLength = 4;
 
         // now again with a character typed
-        sendChar("1", input);
+        input.focus();
+        sendChar("1");
         doKey("escape");
         doKey("down");
         break;
 
     case 306:
         checkMenuEntries(["1", "12", "123", "1234"]);
         input.maxLength = 3;
         doKey("escape");
--- a/toolkit/content/tests/chrome/test_hiddenitems.xul
+++ b/toolkit/content/tests/chrome/test_hiddenitems.xul
@@ -39,48 +39,49 @@ https://bugzilla.mozilla.org/show_bug.cg
   <script type="application/javascript"><![CDATA[
 
 /** Test for Bug 317422 **/
 SimpleTest.waitForExplicitFinish();
 
 function testListbox(id)
 {
   var listbox = document.getElementById(id);
+  listbox.focus();
   is(listbox.getRowCount(), 7, id + ": Returned the wrong number of rows");
   is(listbox.getItemAtIndex(2).id, id + "_item3", id + ": Should still return hidden items");
   listbox.selectedIndex = 0;
   is(listbox.selectedItem.id, id + "_item1", id + ": First item was not selected");
-  sendKey("DOWN", id);
+  sendKey("DOWN");
   is(listbox.selectedItem.id, id + "_item2", id + ": Down didn't move to second item");
-  sendKey("DOWN", id);
+  sendKey("DOWN");
   is(listbox.selectedItem.id, id + "_item4", id + ": Down didn't skip hidden item");
-  sendKey("DOWN", id);
+  sendKey("DOWN");
   is(listbox.selectedItem.id, id + "_item6", id + ": Down didn't skip collapsed item");
-  sendKey("UP", id);
+  sendKey("UP");
   is(listbox.selectedItem.id, id + "_item4", id + ": Up didn't skip collapsed item");
-  sendKey("UP", id);
+  sendKey("UP");
   is(listbox.selectedItem.id, id + "_item2", id + ": Up didn't skip hidden item");
   listbox.selectAll();
   is(listbox.selectedItems.length, 7, id + ": Should have still selected all items");
   listbox.invertSelection();
   is(listbox.selectedItems.length, 0, id + ": Should have unselected all items");
   listbox.selectedIndex = 2;
   ok(listbox.selectedItem == listbox.getItemAtIndex(2), id + ": Should have selected the hidden item");
   listbox.selectedIndex = 0;
-  sendKey("END", id);
+  sendKey("END");
   is(listbox.selectedItem.id, id + "_item6", id + ": Should have moved to the last unhidden item");
   sendMouseEvent({type: 'click'}, id + "_item1");
   ok(listbox.selectedItem == listbox.getItemAtIndex(0), id + ": Should have selected the first item");
   is(listbox.selectedItems.length, 1, id + ": Should only be one selected item");
   sendMouseEvent({type: 'click', shiftKey: true}, id + "_item6");
   is(listbox.selectedItems.length, 4, id + ": Should have selected all visible items");
   listbox.selectedIndex = 0;
-  sendKey("PAGE_DOWN", id);
+  sendKey("PAGE_DOWN");
   is(listbox.selectedItem.id, id + "_item6", id + ": Page down should go to the last visible item");
-  sendKey("PAGE_UP", id);
+  sendKey("PAGE_UP");
   is(listbox.selectedItem.id, id + "_item1", id + ": Page up should go to the first visible item");
 }
 
 window.onload = function runTests() {
   testListbox("richlistbox");
   testListbox("listbox");
   SimpleTest.finish();
 };
--- a/toolkit/content/tests/chrome/test_hiddenpaging.xul
+++ b/toolkit/content/tests/chrome/test_hiddenpaging.xul
@@ -66,33 +66,34 @@ https://bugzilla.mozilla.org/show_bug.cg
 
 /** Test for Bug 317422 **/
 SimpleTest.waitForExplicitFinish();
 
 function testRichlistbox()
 {
   var id = "richlistbox";
   var listbox = document.getElementById(id);
+  listbox.focus();
   listbox.selectedIndex = 0;
-  sendKey("PAGE_DOWN", id);
+  sendKey("PAGE_DOWN");
   is(listbox.selectedItem.id, id + "_item7", id + ": Page down should go to the item one visible page away");
   is(listbox.getIndexOfFirstVisibleRow(), 6, id + ": Page down should have scrolled down a visible page");
-  sendKey("PAGE_DOWN", id);
+  sendKey("PAGE_DOWN");
   is(listbox.selectedItem.id, id + "_item11", id + ": Second page down should go to the item two visible pages away");
   is(listbox.getIndexOfFirstVisibleRow(), 9, id + ": Second page down should not scroll beyond the end");
-  sendKey("PAGE_DOWN", id);
+  sendKey("PAGE_DOWN");
   is(listbox.selectedItem.id, id + "_item14", id + ": Third page down should go to the last visible item");
   is(listbox.getIndexOfFirstVisibleRow(), 9, id + ": Third page down should not have scrolled at all");
-  sendKey("PAGE_UP", id);
+  sendKey("PAGE_UP");
   is(listbox.selectedItem.id, id + "_item10", id + ": Page up should go to the item one visible page away");
   is(listbox.getIndexOfFirstVisibleRow(), 5, id + ": Page up should scroll up a visible page");
-  sendKey("PAGE_UP", id);
+  sendKey("PAGE_UP");
   is(listbox.selectedItem.id, id + "_item6", id + ": Second page up should go to the item two visible pages away");
   is(listbox.getIndexOfFirstVisibleRow(), 0, id + ": Second page up should not scroll beyond the start");
-  sendKey("PAGE_UP", id);
+  sendKey("PAGE_UP");
   is(listbox.selectedItem.id, id + "_item1", id + ": Third page up should return to the first visible item");
   is(listbox.getIndexOfFirstVisibleRow(), 0, id + ": Third page up should not have scrolled at all");
 }
 
 function testListbox()
 {
   var id = "listbox";
   var listbox = document.getElementById(id);
@@ -100,34 +101,35 @@ function testListbox()
   // Check that a scrollbar is visible by comparing the width of the listitem
   // with the width of the listbox. This is a simple way to do this without
   // checking the anonymous content.
   ok(listbox.firstChild.getBoundingClientRect().width < listbox.getBoundingClientRect().width - 10,
      id + ": Scrollbar visible");
 
   var rowHeight = listbox.firstChild.getBoundingClientRect().height;
 
+  listbox.focus();
   listbox.selectedIndex = 0;
-  sendKey("PAGE_DOWN", id);
+  sendKey("PAGE_DOWN");
   is(listbox.selectedItem.id, id + "_item8", id + ": Page down should go to the item one visible page away");
   is(listbox.getIndexOfFirstVisibleRow(), 7, id + ": Page down should have scrolled down a visible page");
-  sendKey("PAGE_DOWN", id);
+  sendKey("PAGE_DOWN");
   is(listbox.selectedItem.id, id + "_item13", id + ": Second page down should go to the item two visible pages away");
   is(listbox.getIndexOfFirstVisibleRow(), 9, id + ": Second page down should not scroll beyond the end");
-  sendKey("PAGE_DOWN", id);
+  sendKey("PAGE_DOWN");
   is(listbox.selectedItem.id, id + "_item14", id + ": Third page down should go to the last visible item");
   is(listbox.getIndexOfFirstVisibleRow(), 9, id + ": Third page down should not have scrolled at all");
-  sendKey("PAGE_UP", id);
+  sendKey("PAGE_UP");
   is(listbox.selectedItem.id, id + "_item9", id + ": Page up should go to the item one visible page away");
   // the listScrollbox seems to go haywire when scrolling up with hidden listitems
   todo_is(listbox.getIndexOfFirstVisibleRow(), 3, id + ": Page up should scroll up a visible page");
-  sendKey("PAGE_UP", id);
+  sendKey("PAGE_UP");
   is(listbox.selectedItem.id, id + "_item2", id + ": Second page up should go to the item two visible pages away");
   is(listbox.getIndexOfFirstVisibleRow(), 0, id + ": Second page up should not scroll beyond the start");
-  sendKey("PAGE_UP", id);
+  sendKey("PAGE_UP");
   is(listbox.selectedItem.id, id + "_item1", id + ": Third page up should return to the first visible item");
   is(listbox.getIndexOfFirstVisibleRow(), 0, id + ": Third page up should not have scrolled at all");
 
   var scrollHeight = document.getAnonymousNodes(listbox)[1].lastChild.scrollHeight;
   is(scrollHeight, rowHeight * 15, id + ": scrollHeight when rows set");
 
   listbox.minHeight = 50;
   scrollHeight = document.getAnonymousNodes(listbox)[1].lastChild.scrollHeight;
--- a/toolkit/content/tests/chrome/test_richlist_direction.xul
+++ b/toolkit/content/tests/chrome/test_richlist_direction.xul
@@ -41,34 +41,35 @@ function test_richlistbox()
   richListBox.appendItem("Test", "");
   richListBox.firstChild.nextSibling.id = "list-box-first";
   richListBox.lastChild.previousSibling.id = "list-box-last";
 
   // direction = "reverse", the values here are backwards due to the fact that
   // richlistboxes respond differently when a user initiates a selection
   richListBox.dir = "reverse";
   var count = richListBox.itemCount;
+  richListBox.focus();
   richListBox.selectedIndex = count - 1;
-  sendKey("DOWN", richListBox);
+  sendKey("DOWN");
   is(richListBox.currentIndex, count - 2, "Selection should move to the next item");
-  sendKey("UP", richListBox);
+  sendKey("UP");
   is(richListBox.currentIndex, count - 1, "Selection should move to the previous item");
-  sendKey("END", richListBox);
+  sendKey("END");
   is(richListBox.currentIndex, 0, "Selection should move to the last item");
-  sendKey("HOME", richListBox);
+  sendKey("HOME");
   is(richListBox.currentIndex, count - 1, "Selection should move to the first item");
   var currentIndex = richListBox.currentIndex;
   var index = getScrollIndexAmount(-1);
-  sendKey("PAGE_DOWN", richListBox);
+  sendKey("PAGE_DOWN");
   is(richListBox.currentIndex, index, "Selection should move to one page down");
   ok(richListBox.currentIndex < currentIndex, "Selection should move downwards");
-  sendKey("END", richListBox);
+  sendKey("END");
   currentIndex = richListBox.currentIndex;
   index = getScrollIndexAmount(1);
-  sendKey("PAGE_UP", richListBox);
+  sendKey("PAGE_UP");
   is(richListBox.currentIndex, index, "Selection should move to one page up");
   ok(richListBox.currentIndex > currentIndex, "Selection should move upwards");
   richListBox.selectedItem = richListBox.lastChild;
   richListBox.focus();
   synthesizeKey("VK_DOWN", {shiftKey: true, type: "keypress"}, window);
   let items = [richListBox.selectedItems[0],
                richListBox.selectedItems[1]];
   is(items[0], richListBox.lastChild, "The last element should still be selected");
@@ -82,39 +83,39 @@ function test_richlistbox()
            richListBox.selectedItems[1]];
   is(items[0], richListBox.lastChild, "The last element should still be selected");
   is(items[1], richListBox.lastChild.previousSibling, "Both elements should now be selected");
   richListBox.addEventListener("keypress", function(aEvent) {
     richListBox.removeEventListener("keypress", arguments.callee, true);
     aEvent.preventDefault();
   }, true);
   richListBox.selectedIndex = 1;
-  sendKey("HOME", richListBox);
+  sendKey("HOME");
   is(richListBox.selectedIndex, 1, "A stopped event should return indexing to normal");
 
   // direction = "normal"
   richListBox.dir = "normal";
   richListBox.selectedIndex = 0;
-  sendKey("DOWN", richListBox);
+  sendKey("DOWN");
   is(richListBox.currentIndex, 1, "Selection should move to the next item");
-  sendKey("UP", richListBox);
+  sendKey("UP");
   is(richListBox.currentIndex, 0, "Selection should move to the previous item");
-  sendKey("END", richListBox);
+  sendKey("END");
   is(richListBox.currentIndex, count - 1, "Selection should move to the last item");
-  sendKey("HOME", richListBox);
+  sendKey("HOME");
   is(richListBox.currentIndex, 0, "Selection should move to the first item");
   var currentIndex = richListBox.currentIndex;
   var index = richListBox.scrollOnePage(1);
-  sendKey("PAGE_DOWN", richListBox);
+  sendKey("PAGE_DOWN");
   is(richListBox.currentIndex, index, "Selection should move to one page down");
   ok(richListBox.currentIndex > currentIndex, "Selection should move downwards");
-  sendKey("END", richListBox);
+  sendKey("END");
   currentIndex = richListBox.currentIndex;
   index = richListBox.scrollOnePage(-1) + richListBox.currentIndex;
-  sendKey("PAGE_UP", richListBox);
+  sendKey("PAGE_UP");
   is(richListBox.currentIndex, index, "Selection should move to one page up");
   ok(richListBox.currentIndex < currentIndex, "Selection should move upwards");
   richListBox.selectedItem = richListBox.firstChild;
   richListBox.focus();
   synthesizeKey("VK_DOWN", {shiftKey: true, type: "keypress"}, window);
   items = [richListBox.selectedItems[0],
            richListBox.selectedItems[1]];
   is(items[0], richListBox.firstChild, "The last element should still be selected");