Pranjal
Pranjal

Reputation: 463

How do I check if my element has been focused in a unit test in angular 4?

I have following function to unit test. I have taken element which is text box with view child in component and in testing I need to test whether my text box got focused or not after setTimeout() was called.

 @ViewChild('searchInput') searchInput: ElementRef;
function A(show) {
        const self = this;
        if (show) {
            this.xyz= true;
            setTimeout(function () {
                self.searchInput.nativeElement.focus();
            }, 0);
        } else {
            self.xyz= false;
            self.abc = '';
        }
    }

Here is my test case that I am trying:

it('textbox get focus toggleSearch', async(() => {
        let el: DebugElement;

        component.toggleSearch(true);
        el = fixture.debugElement.query(By.css('#search-input-theme'));
        let native: HTMLElement = el.nativeElement;
        spyOn(native,'focus');
        fixture.whenStable().then(() => {
            expect(native.focus).toHaveBeenCalled();
        });
    }));

Upvotes: 17

Views: 21719

Answers (3)

Luis Abreu
Luis Abreu

Reputation: 4570

maybe something like this:

const input = de.query(By.css("your_field_selector")).nativeElement;
const focusElement = de.query(By.css(":focus")).nativeElement;
expect(focusElement).toBe(input);

Luis

Upvotes: 15

Sergio Mazzoleni
Sergio Mazzoleni

Reputation: 1608

You can query directly on native element and use a unique selector

const input = fixture.nativeElement.querySelector('#your-input-id:focus');
expect(input).toBeTruthy();

Upvotes: 3

Edwin Vasquez
Edwin Vasquez

Reputation: 398

Luis Abreu's answer worked for me as not only I wanted to spy that the focus method was called but that the focus was set on the right element on the view. Here's an example:

describe('Email input focus', () => {
  beforeEach(() => {
    spyOn(comp.emailField.nativeElement, 'focus');
    comp.ngAfterViewInit();
  });

  it('Should call the focus event', () => {
    expect(comp.emailField.nativeElement.focus).toHaveBeenCalled();
  });

  it('Should be focused on the view', () => {
    fixture.detectChanges();
    const emailInput = de.query(By.css('#email')).nativeElement;
    const focusedElement = de.query(By.css(':focus')).nativeElement;
    expect(focusedElement).toBe(emailInput);
  });
});

Upvotes: 8

Related Questions