使用特定的keyCode测试Jasmine中的keydown事件

Mic*_*ley 10 javascript unit-testing jasmine angularjs karma-runner

我正在为AngularJS指令编写测试,该指令<textarea>在按下某些键时触发事件.根据我的手动测试,一切正常.我想要做得很好,也有一个完整的单元测试套件,但是我遇到了一个我自己无法解决的问题:

我想在我的测试中发送一个特定keyCodetriggerHandler()调用,但我找不到一种方法来指定实际工作的密钥.我知道有关构建和发送具有特定数据的事件的主题的许多问题和答案,但它们都不适用于我的设置:

我的设置

  • 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
Run Code Online (Sandbox Code Playgroud)

奇怪的是,我可以在Chrome中键入控制台中的前3行,并看到正在创建事件keyCode属性设置为40.所以看起来应该可以正常工作.

此外,当我像这样调用最后一行时,textarea.triggerHandler("keydown");它工作,并触发事件处理程序.然而,没有keyCode合作,所以这是毫无意义的.

我怀疑它可能与针对DOM运行的测试的性质有关,该DOM与浏览器中运行的常规页面不同.但我无法弄清楚!

Mar*_*coL 10

我已经使用以下解决方案来测试它,并根据这个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);
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你

更新

今天我发现并测试了这个解决方案,它提供了更广泛的浏览器覆盖范围(支持传统支持):

https://gist.github.com/termi/4654819

所有的功劳都归功于这个GIST的作者.该代码确实支持Safari,PhantomJS和IE9 - 前2个测试.

  • 链接的代码在PhantomJS 1.9.8中不起作用.`TypeError:'undefined'不是函数(评估'Function.prototype.call.bind(Object.prototype.hasOwnProperty)')` (2认同)