4

We have custom assets brought in via <script> tags that find html tags and render the component. For example, we have <customABC />. When the page loads the scripts find <customABC /> and return what that component should be.

I'm trying to add scripts to my document via the following, before calling render.

  describe('DisclaimerContainer render tests', () => {
  test('simple Disclaimer renders disclaimer content', () => {

    const moduleScript = document.createElement('script');
    moduleScript.src = "https://www.example.com/assets/foo/bar/5.7.0/components.js";
    moduleScript.type = "module";
    moduleScript.async = true;
    document.body.appendChild(moduleScript); //I've also tried document.head.appendChild(moduleScript);
    const {debug} = render(<ContextDisclaimerContainer history={history}/>);
    debug();
  });

Debug() is still showing <customABC /> and not the html it should show.

When you do not have an npm package, and need to include custom scripts, how do you configure these to run in your react-testing-library jest test?

3 Answers 3

3

I had success loading a script by customizing the JSDOM in a jest setup file:

// jest.config.js
module.exports = {
  setupFilesAfterEnv: [
    './jest-setup.js',
  ],
};


// jest-setup.js
import { JSDOM } from 'jsdom';
    
const dom = new JSDOM(<!DOCTYPE html><body></body>, {
  resources: 'usable',
  runScripts: 'dangerously',
});

global.window = dom.window;
global.document = dom.window.document;

The key is to configure JSDOM with { resources: 'usable', runScripts: 'dangerously' }. See the jsdom documentation on executing scripts.

Sign up to request clarification or add additional context in comments.

Comments

3

You can set these options in your jest config (assuming jsdom environment):

    testEnvironment: 'jsdom',
    testEnvironmentOptions: {
        resources: 'usable',
        runScripts: 'dangerously',
    },

See jsdom docs about executing scripts and jest docs on configuring the test environment.

1 Comment

But then where do you load the actual script??
0

Turns out I was close but needed a combination of two things to get this to work.

  1. Like the others mentioned, allowing jsdom to execute scripts.

    // In "jest.react.config.json"
    {
      "testEnvironment": "jsdom",
      "testEnvironmentOptions": {
        "resources": "usable",
        "runScripts": "dangerously"
      },
    }
    
  2. Having my component actually load the script and I had to wait for the expected change to be accessible for my test.

    // In your component file
    const ComponentBeingTested = ({}) => {
      ...
    
      useEffect(() => {
        const script = document.createElement("script");
        script.src = "https://accounts.google.com/gsi/client";
        script.onerror = e => console.log('error :>> ', e);
        document.head.appendChild(script);
    
        return () => {
          document.head.removeChild(script); // Clean up on unmount
        };
      }, []);
    
      ...
    });
    
    // In your test file
    ...
    
    test('Google SSO script loads', async() => {
      const {
        getByText,
      } = render(<>
        <ComponentBeingTested />
      </>);
    
      // This line is critical so we can make sure the script actually executed
      await waitFor(() => expect(window.google).toBeTruthy());
      console.log('window.google or global.google :>> ', window.google);
    
      // The rest of your test
      ...
    });
    
    ...
    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.