使用特定的 keyCode 在 Jasmine 中测试 keydown 事件 [英] testing keydown events in Jasmine with specific keyCode
问题描述
我正在为 AngularJS 指令编写测试,该指令在按下某些键时会触发 事件.根据我的手动测试,一切正常.我也想变得优秀并拥有一个完整的单元测试套件,但我遇到了一个我无法自己解决的问题:
I am writing tests for an AngularJS directive which fires events of a <textarea>
when certain keys are pressed. It all works fine per my manual testing. I want to be good and have a full unit-test suite too, but I have run into a problem I can't solve on my own:
我想在我的测试中的 triggerHandler()
调用中发送一个特定的 keyCode
,但我找不到指定密钥的方法确实有效.我知道有很多关于使用特定数据构建和发送事件的问题和答案,但没有一个适用于我的设置:
I want to send a specific keyCode
in my triggerHandler()
call in my test, but I can't find a way to specify the key that actually works. I am aware of a lot of questions and answers on the topic of building and sending events with specific data, but none of them work on my setup:
- Karma 测试运行器
- 运行测试的 PhantomJS 浏览器(但也尝试了 Firefox 和 Chrome 没有成功)
- 我没有使用 jQuery,我希望有一个常规的 JS 解决方案.一定有!
var event = document.createEvent("Events");
event.initEvent("keydown", true, true);
event.keyCode = 40; // in debugging the test in Firefox, the event object can be seen to have no "keyCode" property even after this step
textarea.triggerHandler(event); // my keydown handler does not fire
奇怪的是,我可以在 Chrome 的控制台中输入前 3 行,然后看到正在创建事件, keyCode
属性设置为 40.所以看起来它应该工作.
The strange thing is, I can type the first 3 lines into the console in Chrome and see that the event is being created with the keyCode
property set to 40.
So it seems like it should work.
此外,当我像这样调用最后一行 textarea.triggerHandler("keydown");
时,它可以工作并触发事件处理程序.但是,没有 keyCode
可以使用,因此毫无意义.
Also, when I call the last line like this textarea.triggerHandler("keydown");
it works and the event handler is triggered. However, there is no keyCode
to work with, so it is pointless.
我怀疑这可能与针对 DOM 运行的测试的性质有关,该 DOM 与在浏览器中运行的常规页面不同.但我想不通!
I suspect it may be something to do with the nature of the test running against a DOM that is different to a regular page running in the browser. But I can't figure it out!
推荐答案
我已经使用以下解决方案对其进行了测试,并基于此 SO 答案.它在 Safari 中不起作用 - 尝试了数百万个其他解决方案但没有任何成功......
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);
希望能帮到你
今天我发现并测试了这个解决方案,它提供了更广泛的浏览器覆盖范围(启用旧版支持):
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
所有功劳都归功于此 GIST 的作者.该代码确实支持 Safari、PhantomJS 和 IE9 - 针对前 2 个进行了测试.
All the credit goes to the author of this GIST. The code does support Safari, PhantomJS and IE9 - tested for the first 2.
这篇关于使用特定的 keyCode 在 Jasmine 中测试 keydown 事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!