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

14,250

Solution 1

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

Solution 2

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);
  });
});

Solution 3

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

const input = fixture.nativeElement.querySelector('#your-input-id:focus');
expect(input).toBeTruthy();
Share:
14,250
Pranjal
Author by

Pranjal

Updated on June 14, 2022

Comments

  • Pranjal
    Pranjal about 2 years

    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();
            });
        }));
    
  • Jamie Pate
    Jamie Pate over 4 years
    This only seems to work if the browser window has focus also, so it ends up a bit flakey.
  • Jamie Pate
    Jamie Pate over 4 years
    workaround to ignore focus issues in jasmine: const focused = () => fixture.nativeElement.querySelector(':focus'); button.nativeElement.focus(); if (focused() !== button.nativeElement) { pending('Requires browser focus'); return; }