Angular Jest Spectator - 焦点功能不起作用

Kam*_*aja 1 jestjs angular spectator

所以,我的 Angular 组件看起来像这样

<div class="hello" (keydown.enter)="doSomething()"></div>
Run Code Online (Sandbox Code Playgroud)

我正在尝试编写案例测试 - 当用户专注于 div 时,按 Enter 应该调用 doSomething()。不幸的是,我无法用旁观者来嘲笑这种情况。我已经尝试过:

spectator.focus(spectator.query('.hello'));
expect(spectator.query('.hello')).toBeFocused(); // test failed
spectator.keyboard.pressEnter();
Run Code Online (Sandbox Code Playgroud)

spectator.query('.hello').dispatchEvent(new Event('focus'));
Run Code Online (Sandbox Code Playgroud)

并且两者都还与

spectator.detectChanges(); // without success
Run Code Online (Sandbox Code Playgroud)

我想,这个问题出在我的 HTML 模板中,但这些函数也不适用于:

<div class="hello" tabindex="0">
Run Code Online (Sandbox Code Playgroud)

甚至与

<input class="hello" type="text">
Run Code Online (Sandbox Code Playgroud)

请给予一些支持,如何关注 div 元素,然后按 Enter 键。

yur*_*zui 5

首先,您需要了解spectator.focus()方法的作用。

我们来看看Spectator源代码中这个方法:

public focus(selector: SpectatorElement = this.element): void {
    const element = this.getNativeElement(selector);

    if (!(element instanceof HTMLElement)) {
        throw new Error(`Cannot focus: ${selector} is not a HTMLElement`);
    }

    patchElementFocus(element);
    element.focus();
    this.detectChanges();
}
Run Code Online (Sandbox Code Playgroud)

我们可以注意到,在触发本机element.focus()方法之前,它还会调用patchElementFocus(element);以下方法的代码

export function patchElementFocus(element: HTMLElement): void {
  element.focus = () => dispatchFakeEvent(element, 'focus');
  element.blur = () => dispatchFakeEvent(element, 'blur');
}
Run Code Online (Sandbox Code Playgroud)

其中在底层dispatchFakeEvent调用本机方法。node.dispatchEvent(event);

所以,spectator.focus(element)触发node.dispatchEvent(...)

现在,您需要了解可信事件和不可信事件之间的区别。

使用 node.dispatchEvent 触发的事件称为不受信任事件,它们不会触发默认浏览器操作w3.org 参考

这意味着手动触发事件不会生成与该事件关联的默认操作。例如,手动触发 focus 事件不会导致元素接收 focus,手动触发 Submit 事件不会提交表单。

您只能通过事件处理程序监听手动创建的事件。这就是《观众》向我们展示的内容。(测试https://github.com/ngneat/spectator/blob/fcdb6a809571706fac3d7b5d8da5bf2f7ba0e305/projects/spectator/test/events/events.component.spec.ts#L13)(监听器https://github.com/ngneat/spectator/ blob/fcdb6a809571706fac3d7b5d8da5bf2f7ba0e305/projects/spectator/test/events/events.component.html#L2 )

最后,这里的解决方案是使用本机element.focus()方法将焦点设置在您的 div 上。另外,tabindex attribute这里也是需要的。

spectator.query<HTMLDivElement>('.hello').focus();
expect(spectator.query('.hello')).toBeFocused();
Run Code Online (Sandbox Code Playgroud)

堆栈闪电战示例