简体   繁体   English

在angularjs测试中使用element.triggerHandler()进行粘贴和按键事件似乎没有效果

[英]Using element.triggerHandler() in angularjs tests for paste and keypress events doesn't seem to have an effect

Wondering if someone out there can shed some light on how to properly use element.triggerHandler() for the paste and keypress events inside of an angularjs unit test. 想知道是否有人可以阐明如何正确使用element.triggerHandler()进行angularjs单元测试中的pastekeypress事件。

I have two directives, one for limiting the ability of a user to continue firing keypress events in an element once a length limit has been reached. 我有两个指令,一个指令用于限制用户达到长度限制后继续触发元素中的keypress事件的能力。 The second is to prevent the user from pasting text into an element if the length of the text would exceed a limit. 第二个是防止文本长度超出限制的用户将文本粘贴到元素中。

See the following plunker for a full example including my failing tests: https://plnkr.co/edit/5Yyv2cnn3dRKzsj2Lj61?p=preview 有关完整的示例,包括失败的测试,请参见以下插件: https ://plnkr.co/edit/5Yyv2cnn3dRKzsj2Lj61?p=preview

For the paste test I know I'm not using the correct syntax but have been unable to find how to properly do this. 对于paste测试,我知道我没有使用正确的语法,但是无法找到正确执行此操作的方法。 Any suggestions? 有什么建议么?

element.triggerHandler('paste', 'astring')

For the keypress test, I believe I'm firing the event correctly but it doesn't seem to be updating the value of the element (retrieved using element.val() ) 对于keypress测试,我相信我正确触发了该事件,但是它似乎没有更新element的值(使用element.val()检索)

Been stuck on this for a bit, any help would be greatly appreciated. 坚持了一下,任何帮助将不胜感激。 Thanks! 谢谢!

Let's us start with a short breakdown of what might happen ( really up to the browser implementation ) when a user presses and releases the 1 key with the focus on an input: 让我们首先简要分析一下当用户按下并释放1键(专注于输入)时可能发生的情况( 实际上取决于浏览器的实现 ):

  1. Event keydown is fired 事件keydown被触发
  2. Event keypress is fired 事件keypress被触发
  3. Value of input is changed to 1 and event input is fired 输入的值更改为1并触发事件input
  4. Event keyup is fired 事件keyup已触发

There is no way in JS to actually simulate a user pressing a key. JS中无法实际模拟用户按下按键的方式。 What you can simulate are the things that (usually) happen when a user does so, for example the steps above. 您可以模拟的是用户这样做时通常发生的事情,例如上述步骤。

The triggerHandler function executes all handlers bound with jQuery for the specified event type on the specific element. triggerHandler函数针对特定元素上的指定事件类型执行与jQuery绑定的所有处理程序。

So using triggerHandler with keypress will not simulate a user pressing a key, it will only fire the event, like step 2 above. 因此,使用triggerHandlerkeypress不会模拟用户按下一个键,它只会触发事件,就像上面的步骤2。 The value will not be changed, since that happens in another step. 该值将不会更改,因为这会在另一个步骤中发生。

Now, one would think that in your tests for the limitKeypressLength directive, you can simply simulate the first part of step 3 above yourself (just setting the value manually): 现在,人们会认为,在对limitKeypressLength指令的测试中,您可以简单地模拟自己之上的第3步的第一部分(只需手动设置值):

for (var i = 0; i < 10; i++) {  
  element.triggerHandler({type: 'keypress', keyCode: 49});
  element.val(element.val() + '1');
}

expect(element.val()).toBe('1111111111');

element.triggerHandler('keypress', {which: 49});
element.val(element.val() + '1');

expect(element.val()).toBe('1111111111');

This will not work however, since even if the eleventh keypress event is caught in your directive, the code below will still execute and update the value. 但是,这将不起作用,因为即使您的指令中捕获到第11个按键事件,下面的代码仍将执行并更新该值。

The basic functionality of the limitKeypressLength directive is to listen on the keypress event and either call event.preventDefault or not based. limitKeypressLength指令的基本功能是侦听limitKeypressLength事件,然后调用event.preventDefault或不基于。 This is what you want to test. 这是您要测试的。

For example: 例如:

// Set value to something longer than allowed
element.val('123456789123456789');

// Create the event
var e = jQuery.Event('keypress', {
  keyCode: 49
});

// Create a spy
spyOn(e, 'preventDefault');

// preventDefault should not have been called yet
expect(e.preventDefault).not.toHaveBeenCalled();

// Trigger the event
element.triggerHandler(e);

// Assert that preventDefault has been called
expect(e.preventDefault).toHaveBeenCalled();

Demo: https://plnkr.co/edit/ktmcBGSuTdMnvqVRlkeQ?p=preview 演示: https //plnkr.co/edit/ktmcBGSuTdMnvqVRlkeQ?p = preview

Now you can as easily test for when the elements value is set to equal/below the allowed value. 现在,您可以轻松地测试何时将元素值设置为等于/低于允许值。

Basically the same goes for the limitPasteLength directive, since its purpose is also to call preventDefault based on a condition, only that there is some additional mocking to do. 基本上, limitPasteLength指令也是limitPasteLength ,因为它的目的也是基于条件调用preventDefault ,只是要做一些附加的模拟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么 jQuery 的 triggerHandler() 不能阻止内联事件? - Why jQuery's triggerHandler() doesn't prevent inline events? jQuery .toggle()+ addClass()似乎没有达到预期的效果 - jQuery .toggle() + addClass() doesn't seem to have desired effect 使用angularjs时在哪里包含javascript文件。 我所做的似乎不起作用 - Where to include javascript files while using angularjs. What i have done doesn't seem to be working 我想使用这两个事件进行搜索:按键和鼠标单击,但它们似乎无法协同工作 - I want to search using both events: Keypress and Mouse click but they don't seem to be working together 为什么jQuery triggerHandler()有效,但是trigger()没有? - Why jQuery triggerHandler() works but trigger() doesn't? 为什么jQuery触发器或triggerHandler不起作用? - Why jQuery trigger or triggerHandler doesn't work? 按键事件如何与不会引起任何关注的元素一起使用 - How does keypress events works with element which doesn't take any focus browser.storage.local.set似乎没有任何作用 - browser.storage.local.set doesn't seem to have any effect Tab 按键不会改变焦点元素 - Tab keypress doesn't change focused element 使用in检查元素是否存在似乎不起作用 - Checking if element is present using in doesn't seem to work as it should
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM