question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

RouterTestingModule: `DebugElement.triggerEventHandler` errors for an anchor tag

See original GitHub issue

I’m submitting a … (check one with “x”)

[x] bug report
[ ] feature request
[ ] support request

Current behavior Given a RouterLink on an anchor tag like this:

<a routerLink="/simple">click me</a>

The test expression debugElement.triggerEventHandler('click', null); throws error Cannot read property 'button' of null

Traced the problem to a line in the generated component.ngfactory.js:

_View_RootComponent0.prototype._handle_click_1_0 = function($event) {
  var self = this;
  self.markPathToRootAsCheckOnce();
  self.debug(1,1,2);
  var pd_0 = (self._RouterLinkWithHref_1_3.onClick($event.button,$event.ctrlKey,$event.metaKey) !== false);
  return (true && pd_0);
};

Notice the reference to $event.button. In practice, the $event is null and wouldn’t be a button anyway.

See repro

Expected behavior Should be able to trigger button.

Workaround is to click the native element:

 // element.triggerEventHandler('click', null); // bug
    element.nativeElement.click(); // works in Chrome, fails in phantom

Angular version: 2.0.0-final

Reproduction of the problem

Paste this as a spec in any test harness and watch it fail:

import { Location } from '@angular/common';
import { Component } from '@angular/core';
import { ComponentFixture, TestBed, fakeAsync, inject, tick } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';

@Component({selector: 'root-cmp', template: `
  <a routerLink="/simple">click me</a>
  <router-outlet></router-outlet>
`})
class RootComponent {}

@Component({selector: 'blank-cmp', template: `<p>blank component</p>`})
class DefaultComponent {}


@Component({selector: 'simple-cmp', template: `simple`})
class FirstPageComponent {}

fdescribe('Integration', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule.withRoutes([
          {path: '', component: DefaultComponent},
          {path: 'simple', component: FirstPageComponent}
        ]),
      ],
      declarations: [
        RootComponent,
        DefaultComponent,
        FirstPageComponent
      ]
    });
  });

  // Fails when call triggerEventHandler
  it('should navigate when the link is clicked',
      fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
    const fixture = createRoot(router, RootComponent);
    let element = fixture.debugElement.query(By.css('a'));

    // element.triggerEventHandler('click', null); // bug!
    // element.nativeElement.dispatchEvent(newEvent('click')); // also fails by doing nothing
    element.nativeElement.click(); // works in Chrome, fails in phantom

    advance(fixture);
    expect(location.path()).toEqual('/simple');
  })));

});

function advance(fixture: ComponentFixture<any>): void {
  tick();
  fixture.detectChanges();
}

function createRoot(router: Router, type: any): ComponentFixture<any> {
  const f = TestBed.createComponent(type);
  advance(f);
  router.initialNavigation();
  advance(f);
  return f;
}

function newEvent(eventName: string, bubbles = false, cancelable = false) {
  let evt = document.createEvent('CustomEvent');  // MUST be 'CustomEvent'
  evt.initCustomEvent(eventName, bubbles, cancelable, null);
  return evt;
}

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
ishitatsuyukicommented, Mar 29, 2017

I don’t want to bump, but the docs mentions this usage without describing details of DebugElement. We should fix that for less misperception.

1reaction
ilkercatcommented, Nov 24, 2017

(Meanwhile) it is mentioned in the docs: https://angular.io/guide/testing#triggereventhandler

Other handlers are less forgiving. For example, the RouterLink directive expects an object with a button property that identifies which mouse button was pressed. This directive throws an error if the event object doesn’t do this correctly.

Read more comments on GitHub >

github_iconTop Results From Across the Web

submitEl.triggerEventHandler is not a function in Angular 5
try to use submitEl = fixture.debugElement.nativeElement.querySelector('button');. then submitEl.click();.
Read more >
Component testing scenarios - Angular
The test detects that event through its subscription to selected . triggerEventHandler link. The heroDe in the previous test is a DebugElement that...
Read more >
Testing Components with Spectator - Testing Angular
We have used Angular's testing tools to set up modules, render Components, query the DOM and more. These tools are TestBed , ComponentFixture ......
Read more >
Testing - Angular
This guide offers tips and techniques for unit and integration testing Angular applications. The guide presents tests of a sample application created with ......
Read more >
Testing Angular routing components with the ...
This target route must match the route passed to a router link directive or Router#navigateByUrl . We use the component fixture's debug element...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found