'Cannot read properties of null (reading 'parentElement') during Unit Test

I am trying to write a unit test for the following function:

    focusSkipButton(event: MouseEvent, isLoggedIn: boolean): void {
    if (isLoggedIn) {
      return;
    }
    const button: HTMLButtonElement = document.querySelector('.skip-btn');
    const overlay = document.querySelector('.story-viewer-login-container');
    const target = event.target as Element;
    if (event.target !== overlay &&
      (target.parentElement && target.parentElement !== overlay)) {
      button.focus();
    } 
   }

This is what I have come up with:

it('should set focus on skip buuton', fakeAsync(()=>{
    let button = document.createElement('button');
    spyOn(document, 'querySelector').and.returnValue(button);
    spyOn(button, 'focus');

    var event = new MouseEvent('click', {
      view: window,
      bubbles: true,
      cancelable: true
    });

    let parent = document.createElement('div');
    let child = document.createElement('div');
    parent.append(child);
    child.dispatchEvent(event);

    component.focusSkipButton(event, false);
    tick();

    expect(button.focus).toHaveBeenCalled();

    component.focusSkipButton(event, true);
    tick();

    expect(button.focus).not.toHaveBeenCalled();
  }));

However during running this test I am getting an error:

Cannot read properties of null (reading 'parentElement')

I'm not sure what I'm missing here. Any help would be greatly appreciated.



Solution 1:[1]

The element you dispatched the click event on isn't in the DOM. target property on MouseEvent is null in that case.

You could try adding the element to the DOM, but generally I would avoid doing DOM access within Angular without ViewChild and the other Angular ways of doing it.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Kevin Beal