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

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

wesleycho opened this issue Oct 25, 2016 · 4 comments
Assignees
Labels

Comments

@wesleycho
Copy link
Contributor

@wesleycho 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 comp: testing label Oct 26, 2016
@deanproxy
Copy link

@deanproxy deanproxy commented Apr 21, 2017

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

@applecool applecool commented Aug 21, 2017

@deanproxy Fabulous workaround! 🍻 cheers.

@vikerman
Copy link
Contributor

@vikerman vikerman commented Jan 26, 2018

Closing this as there is a workaround.

@vikerman vikerman closed this Jan 26, 2018
@angular-automatic-lock-bot
Copy link

@angular-automatic-lock-bot angular-automatic-lock-bot bot commented Sep 13, 2019

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.
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
6 participants
You can’t perform that action at this time.