使用特定的keyCode测试Jasmine中的keydown事件
testing keydown events in Jasmine with specific keyCode
我正在为AngularJS指令编写测试,该指令在按下某些键时触发<textarea>
的事件。根据我的手动测试,这一切都很好。我也想做得好,有一个完整的单元测试套件,但是我遇到了一个我自己无法解决的问题:
triggerHandler()
调用中发送一个特定的keyCode
,但我找不到一种方法来指定实际工作的键。我知道有很多关于构建和发送带有特定数据的事件的问题和答案,但它们都不适用于我的设置:
我的设置- 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
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。所以看起来应该行得通。
另外,当我像这样调用最后一行textarea.triggerHandler("keydown");
时,它工作并且触发事件处理程序。然而,没有keyCode
可以使用,所以它是毫无意义的。
我怀疑这可能与针对不同于在浏览器中运行的常规页面的DOM运行的测试的性质有关。但是我想不出来!
我使用了以下解决方案来测试它,并根据这个SO答案在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);
希望有帮助
更新今天我发现并测试了这个解决方案,它提供了更广泛的浏览器覆盖范围(启用旧版本支持):
https://gist.github.com/termi/4654819所有的功劳归于这个GIST的作者。代码支持Safari, PhantomJS和IE9 -测试前2。
对于@MarcoL的回答,我想为将来可能会遇到这个问题的读者指出,方法initKeyboardEvent
和initKeyEvent
是已弃用的方法,不应该再使用。请看这里和这里。
按照MDN文档的建议,事件应该通过它们各自的构造函数来创建。
相关文章:
- Jasmine中返回Deferred的模拟嵌套函数
- Javascript tests - 如何比较 Jasmine 中的两个对象
- 使用 Jasmine 测试对象中的事件处理程序
- 如何正确引用Jasmine测试夹具中的图像
- Protractor Jasmine描述了嵌套在it块中的块
- 处理Jasmine测试中的javascript错误
- 监视由 Jasmine 中的另一个函数调用的函数
- 在 Jasmine 中加载具有依赖项的模块
- 预计浮点数数组接近 Jasmine 中的另一个数组
- 使用 requireJs 模拟 Jasmine 中的匿名模块调用
- Jasmine中的spyOn函数,该函数从数组中返回随机元素
- 访问Jasmine中的Meteor模板帮助程序函数进行集成测试
- 如何窥探Jasmine中的嵌套方法
- 忽略Jasmine中的描述
- Jasmine中的条件期望
- 测试Jasmine中的Rails Route
- Jasmine中的位置重新加载
- 无法在Jasmine中的嵌套描述函数中引用全局函数
- _foo 不是函数,当从 Jasmine 中的 init 方法调用时
- 使用特定的keyCode测试Jasmine中的keydown事件