36

I am using a directive to get the data from input used as a filter text.

here is my hostlistener in the directive:

@HostListener('input', ['$event.target.value'])
  public onChangeFilter(event: any): void {
    console.log('input event fired, value: ' + event);
    this.columnFiltering.filterString = event;
    this.filterChanged.emit({filtering: this.columnFiltering});
  }

this code is working perfectly, I am unable to unit test the same.

I have subscribed to the filterChanged EventEmitter, in my unit test to check the value.

I tried simulating keypress event to change value and also tried settings value attribute. None of these is working for me.

here is my spec file:

describe('Table View', () => {
  let fixture: ComponentFixture<any>;
    let context: TableComponent;
   beforeEach(() => {
     TestBed.configureTestingModule({
          providers: [
            TableComponent,
          ],
          imports: [TableModule],
      });
      fixture = TestBed.createComponent(TableComponent);
      context = fixture.componentInstance;
    });
it('should allow filter', () => {
      const element = fixture.nativeElement;
      context.config = config;
      fixture.detectChanges();

      let tableChangeCount = 0;
      let tableEvent: any;
      context.tableChanged.subscribe((event: any) => {
        tableChangeCount++;
        tableEvent = event;
      });
      // Check if table exists
      let inputElement = element.querySelectorAll('tr')[1].querySelector('input');
    let e = new KeyboardEvent("keypress", {
            key: "a",
            bubbles: true,
            cancelable: true,
          });
          inputElement.dispatchEvent(e);
 });

});

I tried setting value:

let attrs = inputElement.attributes;
      inputElement.setAttribute('value', 'abc');
       for (let i = attrs.length - 1; i >= 0; i--) {
         // Attribute value is set correctly
         if (attrs[i].name === 'value') {
         console.log(attrs[i].name + "->" + attrs[i].value);
         }
       }

Can anyone please help me, how can I unit test the same?

8
  • "here is my spec file:" ... can you show a complete test so we can try and find out what you're doing wrong. Commented Dec 14, 2016 at 6:09
  • added full test test, there was a button click for sort and refresh, its working correctly.. m stuck here Commented Dec 14, 2016 at 6:14
  • Where is your expectation? Commented Dec 14, 2016 at 6:15
  • host event listener should fire Commented Dec 14, 2016 at 6:17
  • 2
    Have you tried dispatching the input event instead of keypress? Commented Dec 14, 2016 at 6:25

3 Answers 3

61

I've had some trouble simulating a keypress in a unit test also. But came across an answer by Seyed Jalal Hosseini. It might be what you're after.

If you're attempting to simulate a keypress you can trigger an event by calling dispatchEvent(new Event('keypress')); on the element.

Here is the answer I'm referring to which gives more detail : https://stackoverflow.com/a/37956877/4081730

If you want to set the key that was pressed, this can be done also.

const event = new KeyboardEvent("keypress",{
    "key": "Enter"
});
el.dispatchEvent(event);

Further information I've just come across: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events

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

3 Comments

KeyboardEvent constructor not supported for IE
@r0bb077, as this is for testing purposes only, you could configure Karma to use Chrome, which I think it does by default: karma-runner.github.io/3.0/config/browsers.html
No doubt, just thought I'd note this for anyone looking to ensure it works across multiple browsers, especially for those flat earthers who still use IE :)
9

If you wish to use a key code (or "which"), you can do this:

// @HostListener('document:keypress')

const escapeEvent: any = document.createEvent('CustomEvent');
escapeEvent.which = 27;
escapeEvent.initEvent('keypress', true, true);
document.dispatchEvent(escapeEvent);

Comments

2
it('should trigger a TAB keypress event on an element', () => {
    const tabKeypress = new KeyboardEvent('keypress', {
      // @ts-ignore
      keyCode: 9, // Tab Key
      cancelable: true
    });
const myTableEle = debugEle.nativeElement.querySelector('.your-element');
    myTableEle.dispatchEvent(tabKeypress);
    fixture.detectChanges();
});

// @ts-ignore :- is to remove TS warning because keyCode is deprecated. Its not needed in case you want to set "key" property of KeyboardEvent.

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.