2

With the following command:

./node_modules/babel-core/register.js ./node_modules/jsdom-global/register.js **/*_spec.jsx

I am running the following test file:

"use strict";

import React from 'react';
import {expect} from 'chai';
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import {Home} from '../../../src/home/home.jsx';

Enzyme.configure({adapter: new Adapter()});

describe('<Home />', () => {
    const setup = () => {
        const props = {
            isButtonOn: true,
            toggleButton: () => null,
        };
        return Enzyme.shallow(<Home {...props}/>);
    };

    it('should a title and a button', () => {
        const wrapper = setup();
        expect(wrapper.find('.title').length).to.equal(1);
        expect(wrapper.find('button').length).to.equal(1);
    });
});

Which tests the following component:

"use strict";

import React from 'react';
import PropTypes from 'prop-types';
import {connect} from 'react-redux';
import {toggleButton} from '../store/home/actions.js';
import swal from 'sweetalert2';

export class Home extends React.Component {
    constructor() {
        super();
        this._toggleButton = this._toggleButton.bind(this);
    }

    _toggleButton() {
        // Invoke swal() here
    }

    render() {
        return (
            <div className="home">
                <div className="title">
                    <u>Frontend Template</u>
                </div>
                <div>
                    <button onClick={this._toggleButton}/>
                </div>
            </div>
        );
    }
}

However, even if the test cases fail, I get the following error message as well as (omitted below) the contents of the css file that cannot be parsed:

Error: Could not parse CSS stylesheet
    at exports.createStylesheet (/home/jbunker/IdeaProjects/frontend-template/node_modules/jsdom/lib/jsdom/living/helpers/stylesheets.js:35:21)
    at HTMLStyleElementImpl._updateAStyleBlock (/home/jbunker/IdeaProjects/frontend-template/node_modules/jsdom/lib/jsdom/living/nodes/HTMLStyleElement-impl.js:68:5)
    at HTMLStyleElementImpl._childTextContentChangeSteps (/home/jbunker/IdeaProjects/frontend-template/node_modules/jsdom/lib/jsdom/living/nodes/HTMLStyleElement-impl.js:37:12)
    at HTMLStyleElementImpl.insertBefore (/home/jbunker/IdeaProjects/frontend-template/node_modules/jsdom/lib/jsdom/living/nodes/Node-impl.js:225:14)
    at HTMLStyleElementImpl.appendChild (/home/jbunker/IdeaProjects/frontend-template/node_modules/jsdom/lib/jsdom/living/nodes/Node-impl.js:327:17)
    at HTMLStyleElement.appendChild (/home/jbunker/IdeaProjects/frontend-template/node_modules/jsdom/lib/jsdom/living/generated/Node.js:192:45)
    at injectCSS (/home/jbunker/IdeaProjects/frontend-template/node_modules/sweetalert2/dist/sweetalert2.all.js:2053:11)
    at /home/jbunker/IdeaProjects/frontend-template/node_modules/sweetalert2/dist/sweetalert2.all.js:2057:1
    at styles (/home/jbunker/IdeaProjects/frontend-template/node_modules/sweetalert2/dist/sweetalert2.all.js:6:82)
    at Object.<anonymous> (/home/jbunker/IdeaProjects/frontend-template/node_modules/sweetalert2/dist/sweetalert2.all.js:9:2)
    at Module._compile (module.js:569:30)
    at Module._extensions..js (module.js:580:10)
    at Object.require.extensions.(anonymous function) [as .js] (/home/jbunker/IdeaProjects/frontend-template/node_modules/babel-register/lib/node.js:152:7)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Module.require (module.js:513:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/home/jbunker/IdeaProjects/frontend-template/src/home/home.jsx:7:1)
    at Module._compile (module.js:569:30)
    at loader (/home/jbunker/IdeaProjects/frontend-template/node_modules/babel-register/lib/node.js:144:5)
    at Object.require.extensions.(anonymous function) [as .jsx] (/home/jbunker/IdeaProjects/frontend-template/node_modules/babel-register/lib/node.js:154:7)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Module.require (module.js:513:17)
    at require (internal/module.js:11:18)
    at Object.<anonymous> (/home/jbunker/IdeaProjects/frontend-template/test/test_react/home/home_spec.jsx:7:1)
    at Module._compile (module.js:569:30)
    at loader (/home/jbunker/IdeaProjects/frontend-template/node_modules/babel-register/lib/node.js:144:5)
    at Object.require.extensions.(anonymous function) [as .jsx] (/home/jbunker/IdeaProjects/frontend-template/node_modules/babel-register/lib/node.js:154:7)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Module.require (module.js:513:17)
    at require (internal/module.js:11:18)
    at /home/jbunker/IdeaProjects/frontend-template/node_modules/mocha/lib/mocha.js:231:27
    at Array.forEach (native)
    at Mocha.loadFiles (/home/jbunker/IdeaProjects/frontend-template/node_modules/mocha/lib/mocha.js:228:14)
    at Mocha.run (/home/jbunker/IdeaProjects/frontend-template/node_modules/mocha/lib/mocha.js:536:10)
    at Object.<anonymous> (/home/jbunker/IdeaProjects/frontend-template/node_modules/mocha/bin/_mocha:582:18)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Function.Module.runMain (module.js:605:10)
    at startup (bootstrap_node.js:158:16)
    at bootstrap_node.js:575:3

When I remove the following line from my component:

import swal from 'sweetalert2';

The error message disappears. This leads me to believe that the css used in sweetalert2 is not properly being parsed by JSDOM. A potential solution seems to be to use virtual consoles:

const virtualConsole = new jsdom.VirtualConsole();
const dom = new JSDOM(``, { virtualConsole });

or to send to a console while omitting errors:

virtualConsole.sendTo(console, {omitJSDOMErrors: true});

However, I have not had success with these approaches.

What can I do to avoid polluting my console with this error?

EDIT: I was able to solve this by placing my JSDOM logic in a separate file:

"use strict";

process.env.NODE_ENV = 'test';

require('babel-register')();

const jsdom = require('jsdom');
const {JSDOM} = jsdom;
const virtualConsole = new jsdom.VirtualConsole();
const dom = new JSDOM('<!DOCTYPE html><html><head></head><body></body></html>', {virtualConsole});

global.document = dom.window.document;
global.window = dom.window.document.defaultView;
global.navigator = {userAgent: 'node.js'};
global.requestAnimationFrame = () => null;

const exposedProperties = ['window', 'navigator', 'document'];
Object.keys(document.defaultView).forEach((property) => {
    if (typeof global[property] === 'undefined') {
        exposedProperties.push(property);
        global[property] = document.defaultView[property];
    }
});

Then, I added the following line in my package.json under scripts:

"test": "mocha --reporter progress tools/testSetup.js \"**/*_spec.jsx\""

By running npm test, I get the test results without any console pollution.

2 Answers 2

4

As @JKB mentioned, using this code fixes the error.

const virtualConsole = new jsdom.VirtualConsole();
const dom = new JSDOM(``, { virtualConsole });
Sign up to request clarification or add additional context in comments.

Comments

1

I can indeed confirm that using that code helped and fixed it. Basically, I stop seeing the error on my console.

const fs = require("fs");
const got = require("got");
const jsdom = require("jsdom");
const { JSDOM } = jsdom;

async function newsCatcher(option) {
  const virtualConsole = new jsdom.VirtualConsole();
  const website = 'website here';

  const TEST = await got(website)
  .then((response) => {
    const dom = new JSDOM(response.body, {virtualConsole});
    const info = Array.from(
      dom.window.document.querySelectorAll(
        "li.stack__slice__item > article > div.card__inner > div.card__content > div > h3 > a"
      )
    )
    .map((e) => e.innerHTML);
    return info
  })
  .catch((err) => {
    console.log(err);
  });
}

2 Comments

please be more descriotive
What do you mean? I was replying to the person. Stating that indeed that workaround worked and my code,

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.