JSDOM:无法解析CSS样式表

时间:2018-02-16 15:31:58

标签: reactjs mocha enzyme jsdom

使用以下命令:

Dim getAns As OleDbCommand = New OleDbCommand("SELECT MCAnswer FROM tblMultipleChoiceAnswers WHERE ChoiceID = ?", DatabaseConnection)
getAns.Parameters.Add(New OleDbParameter("?", sqlID))
getAns.ExecuteNonQuery().ToString()

我正在运行以下测试文件:

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

测试以下组件:

"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);
    });
});

但是,即使测试用例失败,我也会收到以下错误消息以及(在下面省略)无法解析的css文件的内容:

"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>
        );
    }
}

当我从组件中删除以下行时:

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

错误消息消失。这让我相信在sweetalert2中使用的css没有被JSDOM正确解析。一个潜在的解决方案似乎是使用虚拟控制台:

import swal from 'sweetalert2';

或在省略错误时发送到控制台:

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

然而,我对这些方法并没有取得成功。

我可以做些什么来避免因此错误而污染我的控制台?

编辑:我能够通过将我的JSDOM逻辑放在一个单独的文件中来解决这个问题:

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

然后,我在package.json中的脚本下添加了以下行:

"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];
    }
});

通过运行"test": "mocha --reporter progress tools/testSetup.js \"**/*_spec.jsx\"" ,我得到的测试结果没有任何控制台污染。

2 个答案:

答案 0 :(得分:1)

如@JKB所述,使用此代码可修复错误。

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

答案 1 :(得分:0)

我确实可以确认使用该代码有助于并修复它。 基本上,我不再在控制台上看到错误。

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);
  });
}