How to simulate mouse events in Jasmine tests in Angular 2 or 4

I'm new to testing Jasmine and I'm trying to test a directive that handles mouse events like mouse down and up. My question is how can I pass the mouse coordinates from the Jasmine spec to my directive and simulate mouse events. I've searched a lot on this topic, but I couldn't find any examples other than this , which doesn't do anything like passing element coordinates.

Below is my attempt at writing a test using the TestBed configuration in Angular:

import { Component, Directive, DebugElement } from "@angular/core";
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
import { By } from '@angular/platform-browser';
import { TestDirective } from "./test";
import { MyService } from "./my-service";

@Component({
    template: `<div testDirec style="height:800px; width:500px; background-color:blue;"></div>`
})
class DummyComponent { }

export default function () {
    describe('Directive: Zoom', () => {
        let fixture: ComponentFixture<TestComponent>;
        let debugEle: DebugElement[];

        beforeAll(() => {
          TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());

        }

        beforeEach(() => {
            TestBed.configureTestingModule({
                declarations: [TestDirective, DummyComponent],
                providers: [MyService]
            });
            fixture = TestBed.createComponent(DummyComponent);
            fixture.detectChanges();
            debugEle = fixture.debugElement.queryAll(By.directive(TestDirective));
        });

        it('mousedown on the div', () => {
            debugEle[0].triggerEventHandler('mousedown', null);
            expect(debugEle[0].nativeElement.style.width).toBe('500px');
        });

        it('mousemove on the div', () => {
            debugEle[0].triggerEventHandler('mousemove', null);
          expect(debugEle[0].nativeElement.style.backgroundColor).toBe('blue');
        });

    });

}

      

My directive is this:

import { Directive, ElementRef, HostListener} from "@angular/core";
import { MyService } from "./my-service";
@Directive({
    selector: "[testDirec]"
})
export class Test {
  private initPointX: number;
  private initPointY: number;

  constructor(private ele: ElementRef,
        private serviceInstance: MyService) {
    }

    @HostListener('mousedown', ['$event'])
    onMouseDown(event: MouseEvent) {
        console.log("Entered mouse down");
        this.initPointX = event.PageX;
        this.initPointY = event.PageY;
        if (event.ctrlKey) {
            // do something
        }
    } 

    @HostListener('mousedown', ['$event'])
    onMouseMove(event: MouseEvent) {
        console.log("Entered mouse move");
        if (this.initPointX && this.initPointY) {
            // calculate the new mouse x and y coordinates and compute the difference to move the object.
        }
    } 
 //other functions.

}

      


As you can see inside my test spec, I am passing null as an event. This will execute and run my tests successfully, but instead I would like to simulate mouse events by passing the mouse coordinates here. Can anyone give me some resources or point me in the right direction on how to achieve this, or if it cannot be achieved what alternatives can I explore.

Any help would be greatly appreciated.

Thank.
Tammy Gonzalez

+3


source to share


3 answers


I don't understand why you are passing null

in yours triggerEventHandler

. Instead, you must traverse the object. According to your directive, the object must have a value pageX

, and pageY

for the events mousedown

and mousemove

.

The directive will receive these values ​​and execute the steps of your logic, and then you can expect values. expect's

which you currently have doesn't make any sense as they don't test anything related to mouse events.

I believe the following type of BOM is what you are looking for:



it('mousedown on the div', inject([MyService], service) => {
     debugEle[0].triggerEventHandler('mousedown',{pageX:50, pageY: 40});
     debugEle[0].triggerEventHandler('mousemove',{pageX:60, pageY: 50});
     // assuming you are calculating the difference between the second and first objects.
     expect(service.someObj).toBe({x:10, y:10});
 });

      

The above code is rough, but I hope it will be helpful.

Thank.

+2


source


It's one thing to make sure you're going to initiate a change to the DOM that you allow it to update. fixture.detectChanges () is your friend in this regard. In tests, I can see that you click on the item but check the change right away, preventing the discovery changes from propagating.



0


source


This should be more readable than the other answers:

const btn = btnDbg ? <HTMLButtonElement>btnDbg.nativeElement : new HTMLButtonElement();
btn.dispatchEvent(new Event('mousedown'));

      

0


source







All Articles