angular - Angular Jest Spectator - 焦点功能不起作用
问题描述
所以,我有看起来像这样的 Angular 组件
<div class="hello" (keydown.enter)="doSomething()"></div>
我正在尝试为案例编写测试 - 当用户专注于 div 时,按 enter 应该调用 doSomething()。不幸的是,我不能用 Spectator 来模拟这种情况。我已经尝试过:
spectator.focus(spectator.query('.hello'));
expect(spectator.query('.hello')).toBeFocused(); // test failed
spectator.keyboard.pressEnter();
还
spectator.query('.hello').dispatchEvent(new Event('focus'));
并且都与
spectator.detectChanges(); // without success
我想,这个问题出在我的 HTML 模板中,但这些功能也不适用于:
<div class="hello" tabindex="0">
甚至与
<input class="hello" type="text">
请给予一些支持,如何专注于 div 元素,然后按 Enter 键。
解决方案
首先,您需要了解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();
}
我们可以注意到,在触发原生element.focus()
方法之前,它还调用了这个方法patchElementFocus(element);
的代码:
export function patchElementFocus(element: HTMLElement): void {
element.focus = () => dispatchFakeEvent(element, 'focus');
element.blur = () => dispatchFakeEvent(element, 'blur');
}
where在引擎盖下dispatchFakeEvent
调用本机方法。node.dispatchEvent(event);
所以,spectator.focus(element)
触发器node.dispatchEvent(...)
。
现在,您需要了解可信事件和不可信事件之间的区别。
使用 node.dispatchEvent 触发的事件称为不可信事件,它们不会触发默认浏览器操作(w3.org 参考)
这意味着手动触发事件不会生成与该事件关联的默认操作。例如,手动触发焦点事件不会导致元素接收焦点,手动触发提交事件不会提交表单。
您只能通过事件处理程序收听手动创建的事件。这就是旁观者向我们展示的。(测试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();
推荐阅读
- arrays - 在 C 中传递混合的 const 整数 ASCII 值和 const char 数组,并在没有先前声明的情况下传递 const int
- bash - 从多个图像和声音文件创建叙述幻灯片
- django - user=User.objects.get_or_create(first_name=fk_first_name,last_name=fk_last_name,email=fk_email)[0] 为什么使用 [0]
- c++ - 我应该将 printf 与 std::cin 混合使用吗?
- laravel - 如何解决请求规则验证中的未知列“employment_type_id.0”
- linux - 将mpd重新流式传输到m3u8会加载CPU,有什么解决方案吗?
- visual-studio-code - 如何找到 VSCode 默认的 NodeJS 二进制位置?
- java - 为什么我无法从 tcp 服务器获得响应?
- laravel - 如何在 Laravel 中使用相同的请求来获取替代功能
- java - 如何在 datepicker Android 中仅启用特定日期?