Search code examples
angularangular-test

Angular integration testing: how to specify the target on a MouseEvent


I am trying to invoke a click event in my integration testing by using "triggerEventHandler" on one of the HTML elements. I expected that the "target" property of the event to be set by "triggerEventHandler". That is not happening. When I execute the test, the following error is logged in console: "Cannot read property 'tagName' of null" and this happens when I try to get the tagName of the target element.

How should I implement this test?

VIEW

<h1 class="h1-class" (click)="click($event)" (contextmenu)="rightClick($event)">H1</h1>
<h2 class="h2-class" (click)="click($event)" (contextmenu)="rightClick($event)">H2</h2>

COMPONENT

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'biq-dbg',
  templateUrl: './biq-dbg.component.html',
  styleUrls: ['./biq-dbg.component.less']
})

export class BiqDbgComponent implements OnInit {

  constructor() {
  }

  ngOnInit() {
  }

  click(event: MouseEvent) {
    console.log(event);
    let targetElement = event.target as HTMLElement;
    if (targetElement.tagName.toLocaleLowerCase() == "h1")
      console.log("H1 was clicked");
    if (targetElement.tagName.toLocaleLowerCase() == "h2")
      console.log("H2 was clicked");
  }

  rightClick(event: MouseEvent) {
    console.log(event);
    let targetElement = event.target as HTMLElement;
    if (targetElement.tagName.toLocaleLowerCase() == "h1")
      console.log("H1 was right-clicked");
    if (targetElement.tagName.toLocaleLowerCase() == "h2")
      console.log("H2 was right-clicked");
  }
}

SPEC

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser'

import { BiqDbgComponent } from './biq-dbg.component';

fdescribe('BiqDbgComponent', () => {
  let component: BiqDbgComponent;
  let fixture: ComponentFixture<BiqDbgComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ BiqDbgComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(BiqDbgComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('h1 should react to click', () => {
    let h1 = fixture.debugElement.query(By.css(".h1-class"));
    let mouseEvent: MouseEvent = new MouseEvent("click", { clientX: 10, clientY: 20, button: 0});

    h1.triggerEventHandler("click", mouseEvent);
    fixture.detectChanges();
  })

  fit('h1 should react to right-click', () => {
    let h1 = fixture.debugElement.query(By.css(".h1-class"));
    let mouseEvent: MouseEvent = new MouseEvent("contextmenu", { clientX: 10, clientY: 20, button: 2});

    h1.triggerEventHandler("contextmenu", mouseEvent);
    fixture.detectChanges();
  })
});

Solution

  • "triggerEventHandler" doesn't simulate a real event, all that is does is calling all listeners for a given eventName.

    In order to simulate a real event, like a mouse click or mouse right click you will have to use "dispatchEvent(event)": How to simulate a mouse click using javascript.