javascript 使用特定的 keyCode 在 Jasmine 中测试 keydown 事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22574431/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
testing keydown events in Jasmine with specific keyCode
提问by Michael Bromley
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:
我正在为 AngularJS 指令编写测试,该指令<textarea>
在按下某些键时会触发 a 事件。根据我的手动测试,一切正常。我也想变得优秀并拥有一个完整的单元测试套件,但我遇到了一个我无法自己解决的问题:
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 lotof questions and answers on the topic of building and sending events with specific data, but none of them work on my setup:
我想在我的测试中keyCode
在我的triggerHandler()
电话中发送一个特定的,但我找不到指定实际工作的密钥的方法。我知道很多关于使用特定数据构建和发送事件的问题和答案,但它们都不适用于我的设置:
My setup
我的设置
- Karma test runner
- PhantomJS browser running the tests (but also tried Firefox and Chrome without success)
- I'm not using jQuery and I'm hoping there is a regular JS solution. There must be!
- Karma 测试运行器
- 运行测试的 PhantomJS 浏览器(但也尝试过 Firefox 和 Chrome 没有成功)
- 我没有使用 jQuery,我希望有一个常规的 JS 解决方案。必须有!
Test code
测试代码
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
The strange thing is, I can type the first 3 lines into the console in Chrome and see that the event is being created withthe keyCode
property set to 40.
So it seems like it should work.
奇怪的是,我可以键入第3行到Chrome的控制台,看到正在创建的事件与该keyCode
属性设置为40,所以它看起来像它应该工作。
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.
此外,当我像这样调用最后一行时,textarea.triggerHandler("keydown");
它会起作用并且事件处理程序被触发。但是,没有keyCode
可使用的,因此毫无意义。
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!
我怀疑这可能与针对 DOM 运行的测试的性质有关,该 DOM 与在浏览器中运行的常规页面不同。但我想不通!
采纳答案by MarcoL
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...
我已使用以下解决方案对其进行测试,并根据此SO answer使其在 Chrome、FF、PhantomJS 和 IE9+ 中运行。它在 Safari 中不起作用 - 尝试了数百万个其他解决方案但没有成功......
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
希望能帮助到你
Update
更新
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
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.
所有的功劳都归功于这个 GIST 的作者。该代码确实支持 Safari、PhantomJS 和 IE9 - 针对前 2 个进行了测试。
回答by JeanPaul A.
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.
添加到@MarcoL 答案中,我想向可能会偶然发现这个问题的未来读者指出,这些方法initKeyboardEvent
和initKeyEvent
是已弃用的方法,不应再使用。请参阅此处和此处。
Instead as the MDN docs suggested, events should be created via their respective constructor.
相反,正如 MDN 文档所建议的那样,事件应该通过它们各自的构造函数来创建。