So, I have Angular component that looks like this
<div class="hello" (keydown.enter)="doSomething()"></div>
and I'm trying to write test for case - when user is focused in div, pressing enter should call doSomething(). Unfortunately, I cannot mock this situation with Spectator. I've already tried:
spectator.focus(spectator.query('.hello'));
expect(spectator.query('.hello')).toBeFocused(); // test failed
spectator.keyboard.pressEnter();
also
spectator.query('.hello').dispatchEvent(new Event('focus'));
and both also with
spectator.detectChanges(); // without success
I suppose, that problem is in my HTML template, but those functions does not work also with:
<div class="hello" tabindex="0">
and even with
<input class="hello" type="text">
Please gimmie some support, how to focus on div element and then press enter on this.
First, you need to understand what
spectator.focus()
method does.Let's take a look at this method in Spectator source code:
We can notice that before triggering native
element.focus()
method it also callspatchElementFocus(element);
Here's the code of this method:where
dispatchFakeEvent
callsnode.dispatchEvent(event);
native method under the hood.So,
spectator.focus(element)
triggersnode.dispatchEvent(...)
.Now, you need to understand difference between trusted and untrusted events.
Events fired by using node.dispatchEvent are called untrusted events and they do not trigger default browser actions (w3.org reference)
That means that manually firing an event does not generate the default action associated with that event. For example, manually firing a focus event does not cause the element to receive focus, manually firing a submit event does not submit a form.
You can only listen to that manually created events through events handlers. This is what Spectator demonstrates us. (Test https://github.com/ngneat/spectator/blob/fcdb6a809571706fac3d7b5d8da5bf2f7ba0e305/projects/spectator/test/events/events.component.spec.ts#L13) (Listener https://github.com/ngneat/spectator/blob/fcdb6a809571706fac3d7b5d8da5bf2f7ba0e305/projects/spectator/test/events/events.component.html#L2)
Finally, the solution here is to use native
element.focus()
method to be able to set focus on your div. Also,tabindex attribute
is required here.Stackblitz Example