Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Triggering event listeners bound to document with custom events in tests #12518

Closed
wesleycho opened this issue Oct 25, 2016 · 4 comments
Closed
Assignees
Labels
area: testing Issues related to Angular testing features, such as TestBed

Comments

@wesleycho
Copy link
Contributor

wesleycho commented Oct 25, 2016

I'm submitting a ... (check one with "x")

[ ] bug report => search github for a similar issue or PR before submitting
[x] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

Currently triggering custom event listeners bound to document is awkward.
DebugElement.prototype.triggerEventHandler with 'myEvent' or 'document:myEvent' passed as the event name does not match any listener, so my listener is not fired in the test.

Expected behavior
I expect to be able to pass 'myEvent' or 'document:myEvent' to DebugElement.prototype.triggerEventHandler so that I can take advantage of passing custom objects into the event handler. Any other approaches to this that satisfies ease of testing with custom event property values would also be welcome.

Minimal reproduction of the problem with instructions
N/A - discussed situation with @robwormald about being able to trigger an event listener bound to document by a directive via @HostListener('document:myEvent', ['$event'])

What is the motivation / use case for changing the behavior?
I would like an easier way to test event listeners bound to document by directives with the ability to pass custom event objects. Currently there is DebugElement.prototype.triggerEventHandler, but passing 'myEvent' or 'document:myEvent' does not match any listener, so my listener is not fired in the test.

My use case is because I have a complex module for dragging & dropping built purely in Angular 2 that my company intends on open sourcing, so I need to test DOM positioning & logic involving the mouse cursor. I am trying to hook into a directive's listener bound to document:mousemove in order to test that it repositions my dragged element in the proper location.

I can currently hack around this by querying the directive, creating a fake mouse event object, and using the injector for the element to get the directive instance & firing the method directly, but this is awkward. This is necessary for me currently because our CI setup uses PhantomJS, and we don't have anything like headless Chrome yet, so creating a custom MouseEvent using new MouseEvent is not an option.

Please tell us about your environment: macOS Sierra

  • Angular version: 2.1.1
  • Browser: PhantomJS
  • Language: TypeScript 2.0.3
  • Node (for AoT issues): node --version = 4.5.0
@wesleycho wesleycho changed the title Triggering event listeners bound to document with custom events Triggering event listeners bound to document with custom events in tests Oct 25, 2016
@juliemr juliemr self-assigned this Oct 25, 2016
@vicb vicb added the area: testing Issues related to Angular testing features, such as TestBed label Oct 26, 2016
@deanproxy
Copy link

Just to show a workaround solution to help others...

@Component({
   template: '<div myDirective>'
})
class TestComponent implements OnInit {
   // Here is how to get access directly to your directive from your test component.
   @ViewChild(MyDirective) directive: MyDirective;

   constructor() { }
   ngOnInit() { }
}

describe('MyDirectiveTest', () => {
   let component: TestComponent;
   let fixture: ComponentFixture<TestComponent>;

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

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

   it('should organize the tabs', () => {
      // Now we can use that directive and call the method that was bound to document:mouseup
      component.directive.onMouseUp({ pageX: 10, pageY: 20 });

      // expect tests below...
   });
});    

@applecool
Copy link

@deanproxy Fabulous workaround! 🍻 cheers.

@vikerman
Copy link
Contributor

Closing this as there is a workaround.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: testing Issues related to Angular testing features, such as TestBed
Projects
None yet
Development

No branches or pull requests

6 participants