I'm writing some tests for an Angular directive and I need to simulate user input into an input field. I tried to do this:
element.find('input').val('some value').trigger('input');
but it didn't work. Triggering change
didn't work either. I know I can access the element scope directly with element.scope()
and change it, but it seems more natural to change the input's value and let Angular do the data binding.
For what it's worth, I've checked out input(name).enter(value)
from Angular ngScenario, and it seems to do the same as I did:
...
input.val(value);
input.trigger(event || (supportInputEvent ? 'input' : 'change'));
...
What am I missing? Is there a better way to test user input in this case?
(I made a jsFiddler script to illustrate the question)
UPDATE
I think some clarification is needed. I'm not trying to change the DOM nor the scope outside Angular realm per se. I have a directive that renders an input box bound to a property of the directive's scope. I'm writing automated tests to ensure the directive does what it's supposed to do, and what one test should do is to simulate some input so that the directive scope gets updated and I can assert that some behavior is performed on that input. As I mentioned earlier, I can change the directive's scope from the test code by using element.scope()
, but I'd rather change the input's value and let Angular do its thing.
After spending some more time researching and testing, I've figured out what was wrong: jqLite registers event handlers using addEventHandler
and they don't get triggered by jQuery trigger
function. My jsFiddle script wasn't working because Angular's script was being loaded before jQuery's (and therefore was using jqLite). I updated the script to load everything in the correct order so that Angular uses jQuery on
function to register event handlers, and now it simulates changes on the input box and tells Angular to do the data binding.
My test code wasn't working for the very same reason. I fixed it by changing the scripts order as well. If I didn't happen to be using jQuery, I would have to trigger the event by calling dispatchEvent
instead of trigger
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With