8

I would like to write some tests for some input filtering code in a text box. For most tests, I can just call setValue and trigger the change event, which is easy to do. However, in this case, because I want to test that the input gets filtered out (or not), I can't just setValue() directly.

I tried dispatching keydown, keyup, keypress, textinput events. I can see that the handlers for them are being called, but the text doesn't actually show in the text box Note that this only "works" in Firefox, I understand the code would look different for other browsers.

function dispatch(target, eventType, charCode) {
   var evt = document.createEvent("KeyboardEvent");
   evt.initKeyEvent(
     eventType,
     true,
     true,
     window,
     false,
     false,
     false,
     false,
     charCode,
     0
   );
   target.dispatchEvent(evt);
}


var id = document.getElementById('id');
id.onkeydown = id.onkeyup = id.onkeypress = function() {console.log(arguments)}

dispatch(id, 'keydown', 65);
dispatch(id, 'keyup', 65);
dispatch(id, 'keypress', 65);
dispatch(id, 'textinput', 65);
// I can see the handlers were called but it doesn't display in the text box

I understand this has restrictions because we don't want web apps to just pretend like they are acting for the user. However, this is for testing my own application and I could launch Firefox with a specific profile and install plugins, or even write my own if I know it will help.

What I am after is to avoid using Selenium, I want to keep Java out of my JS tests because not only is it slow, but I have to re-implement a lot of the DOM querying in Java.

After all this, the question is, does anybody know how to get that code to actually modify the input? Tweaking settings, installing plugins?

List of questions that don't answer my question

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
  • So what's stopping you from writing a NPAPI extension in firefox to allow triggering native keyboard events? True enough, it's not the most simple thing to do, but there's a fair bit of documentation out there about building plugins (and the part where you link it to a javascript function is relatively easy). I can't help with the details, for I have only minimal experience in this, but the entire thing is definitely possible. – David Mulder Mar 08 '13 at 21:45
  • @DavidMulder Nothing is stopping me, it would require me to write a different plugin for all platforms that I want to test on, so that's a negative. If that's the only way, I'll probably do that. It feels like it's possible, but I'm looking for solid confirmation that it will be possible. Maybe there's already a plugin? – Ruan Mendes Mar 08 '13 at 22:26
  • Which version of FF are you on? Untrusted key events are refused by editors (such as a text box) since FF 12. Here's a bugzilla link: https://bugzilla.mozilla.org/show_bug.cgi?id=749185 – Satyajit Mar 08 '13 at 22:51
  • @Satyajit I would not want to stay on an old version of FF to get this to work, I 'd prefer a plugin – Ruan Mendes Mar 11 '13 at 15:57
  • 1
    @JuanMendes: I have the same aversion to the Java stack :) So I'm trying to build a selenium like implementation in pure JS (with node/express emulating the selenium server). Currently I'm only targetting chrome, you can see the project here if interested: https://github.com/djfm/browsercontrol. There is not much doc yet, but the tests are pretty comprehensive (just run mocha to see). Unfortunately I'm stuck at the same event triggering issue right now. – djfm Jan 04 '15 at 13:13

1 Answers1

1

I just found out that the following code does work in Chrome at least. No go in firefox or IE http://jsfiddle.net/D2s5T/14/

function dispatch(target, eventType, char) {
   var evt = document.createEvent("TextEvent");    
   evt.initTextEvent (eventType, true, true, window, char, 0, "en-US");
   target.focus();
   target.dispatchEvent(evt);
}
dispatch(el, "textInput", "a");
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217