Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jest mock document.activeElement

I have a function that uses the DOM

const trap = {
  // ...
  init() {
    if (document.activeElement === this.firstTabStop) {
      return this.lastTabStop.focus();
    }
  }
}

module.exports = trap.init;

I try to mock document.activeElement but it throws an error.

global.document.activeElement = mockFirstTabStop;

mockFirstTabStop is just function mock, but whatever I put there, the error is the same.

TypeError: Cannot set property activeElement of [object Object] which has only a getter

So, how can I test that conditional to expect this.lastTabStop.focus() was called?

like image 245
sandrina-p Avatar asked Sep 20 '25 08:09

sandrina-p


2 Answers

The solution is to create a mocked DOM and use it as scenario:

trap.js

const trap = {
  // ...
  init() {
    if (document.activeElement === this.firstTabStop) {
      return this.lastTabStop.focus();
    }
  }
}

module.exports = trap.init;

trap.test.js

const trap = require('./trap.js');

// Mock a DOM to play around
document.body.innerHTML = `
    <div>
        <button id="btn1">btn 1 </button>
        <button id="btn2">btn 2 </button>
        <button id="btn3">btn 3 </button>
    </div>
`;

// Mock Jest function
const mockBtnFocus = jest.fn();
const mockBtnFirst = document.getElementById('btn1');
const mockBtnLast = document.getElementById('btn3');


it('should focus this.lastTabStop when activeElement is this.firstTabStop', () => {
    mockBtnFirst.focus(); // <<< this is what sets document.activeElement
    mockBtnLast.focus = mockBtnFocus;

    // Mock trap context to access `this`
    trap.bind({
        firstTabStop: mockBtnFirst,
        lastTabStop: mockBtnLast,
    });

    expect(mockBtnLast.focus).toHaveBeenCalledTimes(1);
});
like image 50
sandrina-p Avatar answered Sep 22 '25 01:09

sandrina-p


An alternative solution:

const element = document.createElement('div');

Object.defineProperty(document, 'activeElement', { value: element, writable: false });
like image 33
whitezo Avatar answered Sep 22 '25 00:09

whitezo