I am writing tests for an AngularJS directive which fires events of a when certain keys are pressed. It all works fine per my manual testing. I
I've used the following solution to test it and having it working in Chrome, FF, PhantomJS and IE9+ based on this SO answer. It doesn't work in Safari - tried millions of other solution without any success...
function jsKeydown(code){
var oEvent = document.createEvent('KeyboardEvent');
// Chromium Hack: filter this otherwise Safari will complain
if( navigator.userAgent.toLowerCase().indexOf('chrome') > -1 ){
Object.defineProperty(oEvent, 'keyCode', {
get : function() {
return this.keyCodeVal;
}
});
Object.defineProperty(oEvent, 'which', {
get : function() {
return this.keyCodeVal;
}
});
}
if (oEvent.initKeyboardEvent) {
oEvent.initKeyboardEvent("keydown", true, true, document.defaultView, false, false, false, false, code, code);
} else {
oEvent.initKeyEvent("keydown", true, true, document.defaultView, false, false, false, false, code, 0);
}
oEvent.keyCodeVal = code;
if (oEvent.keyCode !== code) {
console.log("keyCode mismatch " + oEvent.keyCode + "(" + oEvent.which + ") -> "+ code);
}
document.getElementById("idToUseHere").dispatchEvent(oEvent);
}
// press DEL key
jsKeydown(46);
Hope it helps
Today I've found and tested this solution which is offers a much wider coverage of browsers (enabling the legacy support):
https://gist.github.com/termi/4654819
All the credit goes to the author of this GIST. The code does support Safari, PhantomJS and IE9 - tested for the first 2.
Adding to @MarcoL answer, I'd like to point out for future readers who might stumble on this question, that the methods initKeyboardEvent
and initKeyEvent
are deprecated methods, and should no longer be used. See here and here.
Instead as the MDN docs suggested, events should be created via their respective constructor.