How to mock document.currentScript to return a valid script object with data attributes

Viewed 73

I'm trying to write some tests in jest for an API that is intended to be shared with third parties. The inclusion method used by the third parties is a script tag which initiates the script but also passes along some data attributes via document.currentScript.

Here is a very cut down version of the code with the relevant parts:

// clientLib.js
export const getCurrentScript = () => document.currentScript;

export const initLib = () => {
  const currentScript = getCurrentScript();
  const reference = currentScript.getAttribute('data-reference');
  const lang = currentScript.getAttribute('data-lang');

  return new clientLib(reference, lang);
}

export class clientLib {
  constructor(reference, lang) {
    this._brand = reference;
    this._market = lang;
  }
}

window.clientLib = initLib();



// html

<script src="clientLib.js" data-reference="12345" data-lang="en-GB"></script>

What I'd like to be able to do in my test is something like this, but I've been unable to get anything to work:

// clientLib.test.js

import {
  getCurrentScript,
  initLib,
  clientLib
} from './clientLib';

// here I want to mock the output of getCurrentScript() since document.currentScript does 
// not exist, and I need the mock to return a script object with the two data attributes
// (ideally I need to be able to recreate this mock with both, either or none of the attributes)
// to test other cases

describe('initLib', () => {
  it('returns a new instance of the library based on script attributes', () => {
    window.clientLib = initLib();
    // in here I should then be able to access properties on my lib on the window object
  });
});

I did manage to get this working using an external setup file but for logistical reasons I don't think I can use this approach. I've tried to mock it in the test file itself and keep coming back to an "Invalid variable access: document" error. Is there a way to do this that I'm missing?

0 Answers
Related