使用angular和jasmine测试时,如何模拟浏览器焦点? [英] How can i simulate browser focus when testing using angular and jasmine?

查看:123
本文介绍了使用angular和jasmine测试时,如何模拟浏览器焦点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个单元测试,以检查是否发生了焦点事件.我的实际测试用例更加复杂,但是我使用以下代码创建了最小的复制品:

I am trying to write a unit test that checks whether or not the effect of a focus event takes place. My actual test case is more complicated, but I have created a minimal reproduction with the following code:

it('testing input focus', async(() => {
  let showDiv = false;
  const template = `<div *ngIf="shouldShow" class='hidden-div'>
                       SHOW ME WHAT YOU GOT
                    </div>
                    <input (focus)="shouldShow = !shouldShow" name="input">`;
  buildTestComponent(template, {shouldShow: showDiv}).then((fixture) => {
    fixture.detectChanges();
    const inputEl: HTMLInputElement = fixture.nativeElement.querySelector('input');

    expect(fixture.nativeElement.querySelector('.hidden-div')).toBe(null);

    inputEl.focus();
    fixture.detectChanges();

    expect(fixture.nativeElement.querySelector('.hidden-div')).not.toBe(null);
  });
}));

当我使用业力运行此测试时,只要我专注于运行业力目标的chrome选项卡,该测试就会通过.但是,如果浏览器没有聚焦,则测试失败(即使浏览器可见,但我单击了另一个窗口),并显示错误消息:

When I run this test with karma the test passes as long as I have focus on the chrome tab that is running the karma target. However, if the browser does not have focus the test fails (even if the browser is visible, but I click on another window) with error message:

Expected null not to be null.

我假设当Chrome选项卡没有焦点时,inputEl.focus()调用实际上没有被调用,但是我不知道如何解决.我编写的所有其他单元测试都通过了,无论浏览器如何侧重.有没有人碰到这个或有任何想法?

I assume that when the Chrome tab doesn't have focus, the inputEl.focus() call doesn't actually get called but I don't know how to fix it. All other unit tests I have written pass regardless of browser focus. Has anyone run into this or have any ideas?

推荐答案

要在Angular元素上触发事件,可以使用内置的JavaScript ES6方法

To trigger an event on an Angular element, you can use the built-in JavaScript ES6 method dispatchEvent with a subsequent call of Angular's change detection mechanism to get your DOM updated:

inputElement.dispatchEvent(new Event('focus'));
fixture.detectChanges();

实现同一目标的一种更优雅的方法是使用angular的wrapper方法:

A more elegant way to achieve the same thing is to use angular's wrapper method:

import { dispatchEvent } from '@angular/platform-browser/testing/src/browser_util'

dispatchEvent(inputElement, 'focus');
fixture.detectChanges();

一个有趣的是,当您想为输入元素设置一个值时.您需要先为输入的value属性分配一个字符串,然后触发输入"更改事件:

An interesting one is when you want to set a value to your input element. You will need to first assign a string to the input's value property and then trigger an 'input' change event:

inputElement.value = 'abcd';
dispatchEvent(inputElement, 'input');
fixture.detectChanges();

注意::某些事件并不像您期望的那样起作用.例如,调度一个'click'事件不会把焦点放在您的输入元素上!一种解决方法可能是先触发焦点"事件,然后触发点击"事件,如下所示:

Note: There are events that do not act the way you may expect. For example, dispatching a 'click' event will NOT give the focus to your input element! A workaround could be to first trigger a 'focus' event and then a 'click' event as follows:

dispatchEvent(inputElement, 'focus');
dispatchEvent(inputElement, 'input');
fixture.detectChanges();

所有可用的JavaScript事件均在此处.

All the available JavaScript events are here.

这篇关于使用angular和jasmine测试时,如何模拟浏览器焦点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆