React-router: SecurityError while testing

Created on 25 Apr 2017  路  5Comments  路  Source: ReactTraining/react-router

I'm testing a react HOC which checks if there's a token present in localstorage or not. If there is, it redirects the user to the Home component else the user will be redirected to the Login component.

However, i'm getting this strange error in the last test where it tests for calling componentDidMount

SecurityError
at HistoryImpl._sharedPushAndReplaceState (node_modules/jsdom/lib/jsdom/living/window/History-impl.js:87:15)
at HistoryImpl.pushState (node_modules/jsdom/lib/jsdom/living/window/History-impl.js:69:10)
at History.pushState (node_modules/jsdom/lib/jsdom/living/generated/History.js:72:31)

app.test.js

import React from 'react'; 
import { shallow, mount } from 'enzyme';
import { expect } from 'chai';
import sinon from 'sinon';

import App from '../containers/App.jsx';

describe('<App />', () => {
  beforeAll(() => {
    global.localStorage = {
      i2x_token: 'someToken',
      getItem() {
        return 'someToken';
      }
    };
  });

  it('renders without exploding', () => {
    shallow(<App />);
  });

  it('renders children when passed in', () => {
    const wrapper = shallow(
      <App>
        <div className='unique' />
      </App>,
   );
    expect(wrapper.contains(<div className='unique' />)).to.equal(true);
  });

 it('calls componentDidMount', () => {
    sinon.spy(App.prototype, 'componentDidMount');
    const wrapper = mount(<App />);
    expect(App.prototype.componentDidMount).to.have.property('callCount', 1);
    App.prototype.componentDidMount.restore();
  });
});

`
app.jsx

import React, { Component } from 'react';
import { browserHistory } from 'react-router';

class App extends Component {
  componentWillMount() {
    if (localStorage.i2x_token) {
       browserHistory.push('/home');
    } else {
      browserHistory.push('/');
    }
  }

  render() {
    return (
      <main>
        {React.Children.toArray(this.props.children)}
      </main>
    );
  }
}

App.propTypes = {
  children: React.PropTypes.node,
};

export default App;

package.json

  "dependencies": {
    "express": "^4.15.2",
    "react": "^15.4.2",
    "react-dom": "^15.4.2",
    "react-router": "3.0.0",
    "whatwg-fetch": "^2.0.3"
  },
  "devDependencies": {
    "babel-core": "^6.24.1",
    "babel-jest": "^19.0.0",
    "babel-loader": "^7.0.0",
    "babel-polyfill": "^6.23.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "chai": "^3.5.0",
    "cross-env": "^3.1.3",
    "css-loader": "^0.28.0",
    "enzyme": "^2.8.2",
    "eslint": "^3.19.0",
    "eslint-config-airbnb": "^14.1.0",
    "eslint-plugin-import": "^2.2.0",
    "eslint-plugin-jsx-a11y": "^4.0.0",
    "eslint-plugin-react": "^6.10.3",
    "file-loader": "^0.11.1",
    "jest": "^19.0.2",
    "moment": "^2.18.1",
    "moment-timezone": "^0.5.13",
    "node-sass": "^4.5.2",
    "react-addons-test-utils": "^15.5.1",
    "sass-loader": "^3.2.0",
    "sinon": "^2.1.0",
    "style-loader": "^0.16.1",
    "webpack": "^2.2.1",
    "webpack-dev-server": "^2.4.2"
  }

Most helpful comment

The issue linked here leads to a long rabbit hole but I finally found the solution. If you're using jest with jsdom, the fix is to add this to your configuration:

{
  // This configures the jsdom document with a URL.
  testURL: 'http://localhost',
}

All 5 comments

The issue linked here leads to a long rabbit hole but I finally found the solution. If you're using jest with jsdom, the fix is to add this to your configuration:

{
  // This configures the jsdom document with a URL.
  testURL: 'http://localhost',
}

In my case I was using jsdom directly (without jest) and created jsdom like so:

const document = jsdom('', {
  url: 'http://localhost/',
});
global.document = document;

@kumar303 thanks so much for sharing, you've saved my sanity ! ;-)

I was facing the issue while executing this.props.history.push method:

(node:6392) UnhandledPromiseRejectionWarning: SecurityError: Could not parse url argument "../../ListMapView" to pushState against base URL "about:blank".
at HistoryImpl._sharedPushAndReplaceState (D:KD1KrossDeliveryWebAppnode_modulesjsdomlibjsdomlivingwindowHistory-impl.js:73:15)
at HistoryImpl.pushState (D:KD1KrossDeliveryWebAppnode_modulesjsdomlibjsdomlivingwindowHistory-impl.js:54:10)
at History.pushState (D:KD1KrossDeliveryWebAppnode_modulesjsdomlibjsdomlivinggeneratedHistory.js:88:21)
at D:KD1KrossDeliveryWebAppnode_moduleshistorycreateBrowserHistory.js:175:23
at Object.confirmTransitionTo (D:KD1KrossDeliveryWebAppnode_moduleshistorycreateTransitionManager.js:44:7)
at Object.push (D:KD1KrossDeliveryWebAppnode_moduleshistorycreateBrowserHistory.js:166:23)
at D:KD1KrossDeliveryWebAppsrcscenesaccountloginlogin.Container.js:149:50
at

I'm using HOC

import { connect } from 'react-redux';
import { withRouter } from 'react-router-dom';

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Login));

This is my react code

`

if (this.props.user && this.props.user.userRole !== "" && this.props.user.loggedIn)  {

        let url = loginUrl;
        Api.Get(url, this).then((responseData) => {   
            if (responseData.success) {
                if (this.props.user.userRole === Constants.Admin) {
                    this.props.history.push("../Notifications");
                } else if (responseData.status === "Confirmation Pending") {
                    this.props.history.push("../../Verification");
                } else if (this.props.user.userRole === Constants.CUSTOMER) {
                    this.props.history.push("../../Customer/CustomerLanding");
                }else if (this.props.user.partyRoleId > 0) {
                    this.props.history.push("../../ListMapView");
                }
            }
        });
    }

`

Solution :

I was missing to mention tesst url in package.json file

"jest": {
    "testURL" : "http://localhost"
  },

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wzup picture wzup  路  3Comments

imWildCat picture imWildCat  路  3Comments

Waquo picture Waquo  路  3Comments

andrewpillar picture andrewpillar  路  3Comments

winkler1 picture winkler1  路  3Comments