Unable to simulate keypress event in Angular 2 unit test (Jasmine)

46,486

Solution 1

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

Solution 2

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);

Solution 3

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.

Share:
46,486
Akanksha Gaur
Author by

Akanksha Gaur

Engineering Manager with 12 years of full-stack development experience using Angular, Java, Python, Google Cloud, Kubernetes, AppEngine, WebAPI 2.0, C#, ASP.NET Core Programming Languages: Java, C#, Python Platforms: Google Cloud, Azure Scripting Languages: JavaScript, Typescript Frameworks: Angular, Spring Boot, Flask, ASP.NET Core

Updated on February 17, 2021

Comments

  • Akanksha Gaur
    Akanksha Gaur over 3 years

    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?