8

In vanilla JS you can simulate a key up on an input by doing:

testComponent.dispatchEvent(new Event("keyup"))

However doing this in the angular-cli unit test or in the console doesn't trigger this function in my component, which responds to key events by:

  @HostListener('keyup', ['$event'])
  onKeyUp(event: KeyboardEvent) {

Any ideas?

3 Answers 3

15

You should create an event

const event = new KeyboardEvent('keyup', {
      bubbles : true, cancelable : true, shiftKey : false
});

And then get the reference of the debugElement using css selector

const input = debugElement.query(By.css('#id_of_element'));

And then reference of native html element from the previous one

const inputElement = input.nativeElement;

Assign the value for the native element as , now the text field value contains 12.

inputElement.value = 12;

finally dispatch the key up event

inputElement.dispatchEvent(event);

it will trigger the function

Dont forget to add the following line in before each and make sure you define debugElement

debugElement = fixture.debugElement;

Hope it helps

Sign up to request clarification or add additional context in comments.

Comments

0

I my case somehow value was empty to I had to explicitly define it:

function generateKeyUpEvent(value: string): KeyboardEvent {
    const event: KeyboardEvent = new KeyboardEvent('keyup', { bubbles: true, cancelable: true });
    Object.defineProperty(event, 'target', { value: { value } });
    return event;
}

and then despatch in my test case:

component.input.nativeElement.dispatchEvent(generateKeyUpEvent('a'));

Comments

0

In my component I have

<textarea [(ngModel)]="selectedAnswer" (keyup)="textAnswerChanged()"></textarea>

I needed to test that typing in the field will call a service method which is called from textAnswerChanged(). Just dispatching a keyup event is not enough to trigger the ngModel to change. You must dispatch 2 events.

  • KeyboardEvent('input') - causes ngModel to update
  • KeyboardEvent('keyup') - causes (keyup) on the <textarea> to fire
it('should update the selected answer when a value is typed', () => {
  const textArea = element.querySelector('textarea') as HTMLTextAreaElement;

  spyOn(injectedExampleSvc, 'changeAnswer');
  
  //no selection initially
  expect(component.selectedAnswer).toBeUndefined();

  textArea.value = 'foo';
  textArea.dispatchEvent(new KeyboardEvent('input'));
  textArea.dispatchEvent(new KeyboardEvent('keyup'));
  fixture.detectChanges();

  expect(component.selectedAnswer).toEqual('foo');
  expect(injectedExampleSvc.changeAnswer).toHaveBeenCalled();
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.