Protractor - SyntaxError: Unexpected identifier - javascript

I wrote some tests in Protractor, but sadly I have little problem with import/export files.
HomePage.js
export default class HomePage {
constructor() {
this.path = 'http://automationpractice.com/index.php';
this.searchQuery = element(by.css('.search_query'));
this.searchButton = element(by.name('submit_search'));
this.signInButtonHeader = element(by.css('.header_user_info'));
this.emailInput = element(by.id('email'));
this.passwordInput = element(by.id('passwd'));
this.logInButton = element(by.id('SubmitLogin'));
}
}
homepage-spec.js
import HomePage from '../page_objects/HomePage';
browser.waitForAngularEnabled(false);
const homePage = new HomePage();
beforeEach(async () => {
browser.get(homePage.path);
});
describe('Homepage', () => {
it('should have a title', () => {
expect(browser.getTitle()).toEqual('My Store');
});
it('Log into your account', () => {
homePage.signInButtonHeader.click();
homePage.emailInput.sendKeys('testprotractor#gmail.com');
homePage.passwordInput.sendKeys('xxxx');
homePage.logInButton.click();
});
it('Check categories', () => {
element(by.linkText('Women')).click();
});
});`
conf.js
const SpecReporter = require('jasmine-spec-reporter').SpecReporter;
require('#babel/register');
exports.config = {
framework: 'jasmine',
capabilities: {
browserName: 'chrome',
},
suites: {
homePage: 'specs/homepage-spec.js',
searchResults: 'specs/search-results-spec.js',
},
onPrepare: () => {
jasmine.getEnv().addReporter(new SpecReporter({
spec: {
displayStacktrace: true,
},
}));
},
};
package.json
{
"name": "protractorautomation",
"version": "1.0.0",
"description": "This is my test",
"main": "conf.js",
"dependencies": {
"babel-eslint": "^10.0.1",
"#babel/register": "^7.0.0",
"eslint": "^5.3.0",
"eslint-config-airbnb-base": "^13.1.0",
"eslint-plugin-import": "^2.14.0",
"jasmine-spec-reporter": "^4.2.1"
},
"devDependencies": {
"#babel/core": "^7.2.2",
"babel-preset-env": "^1.7.0",
"babel-register": "^6.26.0"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"Protractor"
],
"author": "Xxxx",
"license": "ISC"
}
Whenever I run tests, receive this error:
(function (exports, require, module, __filename, __dirname) { import
HomePage from '../page_objects/HomePage'; ^^^^^^^^
SyntaxError: Unexpected identifier
at new Script (vm.js:84:7)
at createScript (vm.js:264:10)
at Object.runInThisContext (vm.js:312:10)
at Module._compile (internal/modules/cjs/loader.js:694:28)
at Module._compile (C:\Users\X\Documents\protractorAutomation\node_modules\pirates\lib\index.js:83:24)
at Module._extensions..js (internal/modules/cjs/loader.js:745:10)
at Object.newLoader [as .js] (C:\Users\Mati\Documents\protractorAutomation\node_modules\pirates\lib\index.js:88:7)
at Module.load (internal/modules/cjs/loader.js:626:32)
at tryModuleLoad (internal/modules/cjs/loader.js:566:12)
at Function.Module._load (internal/modules/cjs/loader.js:558:3) [16:53:29] E/launcher - Process exited with error code 100
Anyone can help me fix this problem?

It appears that the es6 style of imports you are attempting to use are not supported natively in NodeJS.
According to this answer you have two options. I have created an example of the first for you to try.
module.exports = class HomePage {
constructor() {
this.path = 'http://automationpractice.com/index.php';
this.searchQuery = element(by.css('.search_query'));
this.searchButton = element(by.name('submit_search'));
this.signInButtonHeader = element(by.css('.header_user_info'));
this.emailInput = element(by.id('email'));
this.passwordInput = element(by.id('passwd'));
this.logInButton = element(by.id('SubmitLogin'));
}
}
Change Import to require
//Change import statement to standard require
let HomePage = require('../page_objects/HomePage');
browser.waitForAngularEnabled(false);
const homePage = new HomePage();
beforeEach(async () => {
browser.get(homePage.path);
});
describe('Homepage', () => {
it('should have a title', () => {
expect(browser.getTitle()).toEqual('My Store');
});
it('Log into your account', () => {
homePage.signInButtonHeader.click();
homePage.emailInput.sendKeys('testprotractor#gmail.com');
homePage.passwordInput.sendKeys('xxxx');
homePage.logInButton.click();
});
it('Check categories', () => {
element(by.linkText('Women')).click();
});
});

Related

Testing a smart contract using truffle ethereum, solidity, vue.js and VScode,on localhost 8080,i get a blanck page with only name and backround color

i'm trying to deploy a smart contract simple application "Hello World",every thing is running successfully ..when i run : npm run serve i get this warning :
( warning in ./node_modules/#truffle/contract/node_modules/ethers/dist/ethers.min.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted)
and when i open localhost8080 i just get the name of my application and the background-color!..no button no text or img! i try to fix it but i didn't find the error ..there are my codes if someone can help, thnx in advance:
App.vue:
<template>
<div id="app">
<img src="assets/images/logo.png" />
<horse></horse>
</div>
</template>
<script>
// # is an alias to /src
import horse from "./components/HelloHorse.vue";
export default {
name: "HelloHorse",
components: {
horse,
},
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
Package.json:
{
"name": "hello",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"start": "node server.js"
},
"dependencies": {
"#ensdomains/address-encoder": "^0.2.16",
"#truffle/contract": "^4.4.6",
"#truffle/hdwallet-provider": "^2.0.0",
"assert": "^2.0.0",
"core-js": "^3.8.3",
"crypto-browserify": "^3.12.0",
"crypto-js": "^3.1.9-1",
"crypto-random-string": "^3.3.0",
"dotenv": "^15.0.0",
"ethers": "^5.5.4",
"express": "^4.17.3",
"fs": "^0.0.1-security",
"http": "^0.0.1-security",
"http-browserify": "^1.7.0",
"https": "^1.0.0",
"https-browserify": "^1.0.0",
"jquery": "^3.6.0",
"lint": "^0.7.0",
"os": "^0.1.2",
"path": "^0.12.7",
"serve-static": "^1.14.2",
"stream": "^0.0.2",
"stream-browserify": "^3.0.0",
"stream-http": "^3.2.0",
"truffle-hdwallet-provider": "^1.0.0-web3one.5",
"url": "^0.11.0",
"vue": "^3.2.13",
"vue-router": "^4.0.3",
"vuex": "^4.0.0",
"web3": "^1.5.3"
},
"devDependencies": {
"#babel/core": "^7.12.16",
"#babel/eslint-parser": "^7.12.16",
"#vue/cli-plugin-babel": "~5.0.0",
"#vue/cli-plugin-eslint": "~5.0.0",
"#vue/cli-plugin-router": "~5.0.0",
"#vue/cli-plugin-vuex": "~5.0.0",
"#vue/cli-service": "~5.0.0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.0.3",
"path-browserify": "^1.0.1",
"prettier": "^2.4.1",
"resolve-url-loader": "^5.0.0"
},
"browser": {
"http": false,
"https": false,
"os": false
},
"engines": {
"node": "16.14.0",
"npm": "8.3.1"
}
}
router>index.js:
import { createRouter, createWebHistory } from "vue-router";
import HelloYouView from "../views/HelloYou.vue";
import store from "../store/index.js";
import ContractService from "../ContractService/ContractService.js";
const routes = [
{
path: "/",
name: "Hello",
component: HelloYouView,
beforeEnter: async (to, from, next) => {
if (store.state.currentAccount != "") {
next();
} else {
const contractService = new ContractService();
var initweb3 = await contractService.initWeb3();
if (!initweb3) {
alert(
"Install MetaMask, connect you to your account and refresh web page."
);
return;
}
var loadaccount = await contractService.loadAccount();
if (loadaccount) {
store.commit("setService", contractService);
store.commit("setCurrentAccount", contractService.currentAccount);
store.commit("setContract", contractService.contracts);
next();
}
}
},
},
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
export default router;
views< helloYou.vue:
import { createRouter, createWebHistory } from "vue-router";
import HelloYouView from "../views/HelloYou.vue";
import store from "../store/index.js";
import ContractService from "../ContractService/ContractService.js";
const routes = [
{
path: "/",
name: "Hello",
component: HelloYouView,
beforeEnter: async (to, from, next) => {
if (store.state.currentAccount != "") {
next();
} else {
const contractService = new ContractService();
var initweb3 = await contractService.initWeb3();
if (!initweb3) {
alert(
"Install MetaMask, connect you to your account and refresh web page."
);
return;
}
var loadaccount = await contractService.loadAccount();
if (loadaccount) {
store.commit("setService", contractService);
store.commit("setCurrentAccount", contractService.currentAccount);
store.commit("setContract", contractService.contracts);
next();
}
}
},
},
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
export default router;
contractService.js:
var Web3 = require("web3");
var TruffleContract = require("#truffle/contract");
var $ = require("jquery");
const HelloWorld = require("../../build/contracts/HelloWorld.json");
class ContractService {
web3Provider = null;
contracts = {};
currentAccount = {};
Web3 = Web3;
TruffleContract = TruffleContract;
$ = $;
initWeb3 = function () {
if (
process.env.VUE_APP_MODE == "development" &&
typeof window.ethereum === "undefined"
) {
this.web3Provider = new this.Web3.providers.HttpProvider(
process.env.VUE_APP_LOCAL_NODE
);
} else if (typeof window.ethereum != "undefined") {
this.web3Provider = this.Web3.givenProvider;
} else {
return false;
}
this.Web3 = new this.Web3(this.web3Provider);
return true;
};
initContract = async function () {
var HelloWorldArtifact = HelloWorld;
this.contracts.HelloWorld = TruffleContract(HelloWorldArtifact);
this.contracts.HelloWorld.setProvider(this.web3Provider);
return true;
};
loadAccount = async function () {
let v_accounts;
if (typeof window.ethereum === "undefined") {
v_accounts = await this.Web3.eth.getAccounts();
} else {
v_accounts = await window.ethereum.enable();
}
this.currentAccount = v_accounts[0];
return this.initContract();
};
init = async function () {
const res = await this.initWeb3();
if (res) {
await this.initContract();
return true;
}
return false;
};
}
export default ContractService;
this what i get :
enter image description here
this is the browser's console i didn't undrestund the error
enter image description here

Cannot find module 'react/lib/warning' - Error with React version

I'm trying to run the "gulp nodemon" to check an application made in REACT but I get the following error:
internal/modules/cjs/loader.js:638
throw err;
^
Error: Cannot find module 'react/lib/warning'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:636:15)
at Function.Module._load (internal/modules/cjs/loader.js:562:25)
at Module.require (internal/modules/cjs/loader.js:692:17)
at require (internal/modules/cjs/helpers.js:25:18)
at Object.<anonymous> (/home/kevin/hbtn/Fix_My_Code_Challenge/0x01-challenge/react-blog/node_modules/react-bootstrap/lib/BreadcrumbItem.js:23:24)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Object.require.extensions.(anonymous function) [as .js] (/home/kevin/hbtn/Fix_My_Code_Challenge/0x01-challenge/react-blog/node_modules/babel/lib/babel/api/register/node.js:130:7)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
It seems that the version of REACT with which it was developed is old and had a different distribution of its files.
This is the file where the error occurs:
'use strict';
var _objectWithoutProperties = require('babel-runtime/helpers/object-without-properties')['default'];
var _extends = require('babel-runtime/helpers/extends')['default'];
var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default'];
exports.__esModule = true;
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _classnames = require('classnames');
var _classnames2 = _interopRequireDefault(_classnames);
var _SafeAnchor = require('./SafeAnchor');
var _SafeAnchor2 = _interopRequireDefault(_SafeAnchor);
var _reactLibWarning = require('react/lib/warning');
var _reactLibWarning2 = _interopRequireDefault(_reactLibWarning);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var createReactClass = require('create-react-class');
var BreadcrumbItem = createReactClass({
displayName: 'BreadcrumbItem',
propTypes: {
/**
* If set to true, renders `span` instead of `a`
*/
active: _propTypes2['default'].bool,
/**
* HTML id for the wrapper `li` element
*/
id: _propTypes2['default'].oneOfType([_propTypes2['default'].string, _propTypes2['default'].number]),
/**
* HTML id for the inner `a` element
*/
linkId: _propTypes2['default'].oneOfType([_propTypes2['default'].string, _propTypes2['default'].number]),
/**
* `href` attribute for the inner `a` element
*/
href: _propTypes2['default'].string,
/**
* `title` attribute for the inner `a` element
*/
title: _propTypes2['default'].node,
/**
* `target` attribute for the inner `a` element
*/
target: _propTypes2['default'].string
},
getDefaultProps: function getDefaultProps() {
return {
active: false
};
},
render: function render() {
var _props = this.props;
var active = _props.active;
var className = _props.className;
var id = _props.id;
var linkId = _props.linkId;
var children = _props.children;
var href = _props.href;
var title = _props.title;
var target = _props.target;
var props = _objectWithoutProperties(_props, ['active', 'className', 'id', 'linkId', 'children', 'href', 'title', 'target']);
_reactLibWarning2['default'](!(href && active), '[react-bootstrap] `href` and `active` properties cannot be set at the same time');
var linkProps = {
href: href,
title: title,
target: target,
id: linkId
};
return _react2['default'].createElement(
'li',
{ id: id, className: _classnames2['default'](className, { active: active }) },
active ? _react2['default'].createElement(
'span',
props,
children
) : _react2['default'].createElement(
_SafeAnchor2['default'],
_extends({}, props, linkProps),
children
)
);
}
});
exports['default'] = BreadcrumbItem;
module.exports = exports['default'];
And this is the package.json file:
{
"name": "React-Isomorphic-Blog",
"version": "1.0.0",
"description": "React Isomorphic Blog",
"author": "Jonathan Rossi <jonathan.m.rossi#gmail.com>",
"license": "MIT",
"dependencies": {
"alt": "^0.14.5",
"babel": "^4.7.16",
"body-parser": "^1.12.3",
"cookie-parser": "^1.3.4",
"create-react-class": "^15.6.3",
"express": "^4.12.3",
"express-session": "^1.10.4",
"iso": "^4.0.2",
"jade": "^1.9.2",
"marked": "^1.1.0",
"moment": "^2.10.2",
"prop-types": "^15.7.2",
"react": "^16.13.1",
"react-bootstrap": "^0.26.2",
"react-ga": "^2.1.2",
"react-prop-types": "^0.4.0",
"react-router": "^3.2.6",
"superagent": "^5.2.2"
},
"devDependencies": {
"browserify": "^16.5.1",
"gulp": "^4.0.2",
"gulp-clean": "^0.3.2",
"gulp-concat": "^2.6.0",
"gulp-minify-css": "^1.2.4",
"gulp-nodemon": "^2.0.2",
"gulp-print": "^2.0.1",
"gulp-rename": "^1.2.2",
"gulp-sass": "^4.1.0",
"gulp-uglify": "^1.5.4",
"nodemon": "^1.3.7",
"reactify": "^1.1.0",
"vinyl-buffer": "^1.0.0",
"vinyl-source-stream": "^1.1.0"
},
"paths": {
"app": "./src/client.js"
},
"dest": {
"app": "bundle.js",
"dist": "public/scripts/react"
},
"main": "bin/www.js",
"scripts": {
"start": "node --use_strict bin/www.js"
}
}
I'm new to React, I've already solved many other mistakes that have come up, but for this one I couldn't find a solution. Can you help me? Thank you very much.

Getting an error: `ReferenceError: Cannot access 'imported const' before initialization` in react

Node v: "10.14.1"
React v: "^16.9.0"
After updating some packages locally by running npm update, I started getting this error when I start my react project.
ReferenceError: Cannot access 'USER_LOGIN_PENDING' before initialization
Module.USER_LOGIN_PENDING
http://localhost:3300/static/js/main.chunk.js:28487:110
push../src/state/reducers/auth.js.__webpack_exports__.default
src/state/reducers/auth.js:23
20 |
21 | export default (state = INITIAL_STATE, action) => {
22 | switch (action.type) {
> 23 | case USER_LOGIN_PENDING:
24 | return { ...state, isLoading: true, showLoginError: false };
25 | case USER_LOGIN_SUCCESS:
26 | return {
There is more stack frames but this is the top one.
I've tried reverting the local packages and running npm install after deleting node_modules and package-lock.json. That runs with no errors. No idea why it suddenly started giving me this error. A friend of mine has the master pulled down, and it works perfectly with the same versions.
Here is the reducers files where the error supposedly throws:
import {
USER_LOGIN_PENDING,
USER_LOGIN_SUCCESS,
USER_LOGIN_FAIL,
NOT_LOGGED_IN,
USER_LOGOUT_PENDING,
USER_LOGOUT_SUCCESS
} from '../actions/auth';
export const INITIAL_STATE = {
isLoading: false,
isLoggedIn: false,
showLoginError: false,
loginError: null,
access_token: null,
refresh_token: null,
expires_at: null
};
export default (state = INITIAL_STATE, action) => {
switch (action.type) {
case USER_LOGIN_PENDING:
return { ...state, isLoading: true, showLoginError: false };
case USER_LOGIN_SUCCESS:
return {
...state,
isLoading: false,
showLoginError: false,
isLoggedIn: true,
access_token: action.data.access_token,
expires_at: action.data.expires_at,
refresh_token: action.data.refresh_token
};
case USER_LOGIN_FAIL:
return {
...state, isLoading: false, showLoginError: true, loginError: action.payload
};
case NOT_LOGGED_IN:
return { ...state, isLoading: false, isLoggedIn: false };
case USER_LOGOUT_PENDING:
return { ...state, isLoading: true };
case USER_LOGOUT_SUCCESS:
return {
...state,
isLoading: false,
isLoggedIn: false,
access_token: null,
expires_at: null,
refresh_token: null
};
default:
return state;
}
};
Here is actions/auth just in case.
import userModel from '../../models/user';
export const USER_LOGIN_PENDING = "USER_LOGIN_PENDING";
export const USER_LOGIN_SUCCESS = "USER_LOGIN_SUCCESS";
export const USER_LOGIN_FAIL = "USER_LOGIN_FAIL";
export const NOT_LOGGED_IN = "NOT_LOGGED_IN";
export const USER_LOGOUT_PENDING = "USER_LOGOUT_PENDING";
export const USER_LOGOUT_SUCCESS = "USER_LOGOUT_SUCCESS";
export const checkLoggedIn = () => dispatch => {
dispatch({ type: USER_LOGIN_PENDING });
const access = JSON.parse(localStorage.getItem('access_token'));
const refresh = JSON.parse(localStorage.getItem('refresh_token'));
const exp = JSON.parse(localStorage.getItem('expires_at'));
if (access && refresh && exp) {
if (JSON.parse(exp) > new Date().getTime()) {
dispatch({ type: USER_LOGIN_SUCCESS, data: { access_token: access, refresh_token: refresh, expires_at: exp } });
return Promise.resolve(access);
}
dispatch({ type: NOT_LOGGED_IN });
return Promise.reject({ statusCode: 401 });
}
dispatch({ type: NOT_LOGGED_IN });
return Promise.reject({ statusCode: 401 });
};
export const login = body => async dispatch => {
const { email, password } = body;
try {
dispatch({ type: USER_LOGIN_PENDING });
const data = await userModel.login(email, password);
const {
access_token, refresh_token, expires_at, user
} = data;
localStorage.setItem('access_token', JSON.stringify(access_token));
localStorage.setItem('refresh_token', JSON.stringify(refresh_token));
localStorage.setItem('expires_at', JSON.stringify(expires_at));
dispatch({ type: USER_LOGIN_SUCCESS, data: { access_token, refresh_token, expires_at } });
return Promise.resolve(user);
} catch (err) {
dispatch({ type: USER_LOGIN_FAIL, payload: err });
return Promise.reject(err);
}
};
export const logout = () => dispatch => {
dispatch({ type: USER_LOGOUT_PENDING });
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
localStorage.removeItem('expires_at');
dispatch({ type: USER_LOGOUT_SUCCESS });
};
Also, my package.json just in case.
{
"name": "project",
"version": "0.1.0",
"private": true,
"engines": {
"node": "10.14.1"
},
"dependencies": {
"date-and-time": "^0.10.0",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.14.0",
"jest-junit": "^10.0.0",
"lodash": "^4.17.15",
"node-sass": "^4.12.0",
"react": "^16.9.0",
"react-beautiful-dnd": "^11.0.5",
"react-datepicker": "^2.9.6",
"react-dom": "^16.9.0",
"react-dropzone": "^10.2.2",
"react-redux": "^7.1.1",
"react-router-dom": "^5.1.0",
"react-scripts": "^3.1.2",
"react-toastify": "^5.4.0",
"redux": "^4.0.4",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.3.0",
"semantic-ui-react": "^0.88.1"
},
"devDependencies": {
"eslint": "^6.1.0",
"eslint-config-airbnb": "^18.0.1",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.14.3",
"eslint-plugin-react-hooks": "^1.7.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"jenkins-test": "CI=true react-scripts test --coverage --watchAll=false --coverageDirectory=coverage/cobertura --reporters=jest-junit --reporters=default",
"postbuild": "rm -rf ../build && mv build ../",
"lint": "eslint ./"
},
"jest": {
"coverageReporters": [
"text",
"cobertura"
]
},
"jest-junit": {
"outputDirectory": "./coverage",
"outputName": "report-jest.xml",
"suiteName": "Client jest tests",
"classNameTemplate": "Client jest tests.{classname}-{title}",
"titleTemplate": "Client jest tests.{classname}-{title}",
"ancestorSeparator": " > "
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"proxy": "http://localhost:8082/"
}
Help would be greatly appreciated.
The question is 7 years old but as I ran into the same issue I'll post an answer anyways, even if it might not help you anymore.
In our case this error was caused by a cyclic import (module A imports module B which imports module C which imports module A). This worked until a certain point but then broke after upgrading dependencies.
Found out what the problem was. Turns out things have been broken for a while (since last time I updated my packages a bit ago), and they only resurfaced after I deleted my node_modules and package-lock.json and reinstalled everything.
The culprit in my case was 'react-scripts'. After downgrading it to version "2.1.5" everything worked again.

updating ancient react stack - Element type is invalid

I'm updating a long-departed colleague's React project, moving it from node 2/react 0.13/babel 5 to something slightly more modern with node 10/react 16/babel 7. I am relatively inexperienced with React. I am attempting to do this in a minimalist fashion, as the budget is tiny. After updating all of the libraries and dependencies to close security holes, I updated code piece by piece to correct resulting errors in the code - but I have arrived at one that is a bit inscrutable.
ReactDOM.render(<Interface />, document.getElementById('main'));
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.
My understanding here is that the Interface component is of the wrong type (typeof shows it as a function). However, Interface is a component made up of a bunch of other components, so I don't know at what level the problem lies.
frontend.js
"use strict";
var React = require('react');
var ReactDOM = require('react-dom');
var Interface = require('./Interface.jsx');
ReactDOM.render(<Interface />, document.getElementById('main'));
Interface.jsx
/* jslint node: true, esnext: true, browser: true */
'use strict';
require('#babel/polyfill');
var React = require('react'), { Row, Alert } = require('react-bootstrap'), io = require('socket.io-client'), _ = require('lodash'), createReactClass = require('create-react-class');
var Submitter = require('./Submitter.jsx'),
Destination = require('./Destination.jsx'),
Options = require('./Options.jsx'),
Trace = require('./Trace.jsx'),
Finished = require('./Finished.jsx'),
DefaultOptions = require('../../lib/default-options.js');
var socket = io();
module.exports = createReactClass({
connected: function() {
console.log('connected');
this.setState({disconnected: false});
},
ack: function() {
this.state.ack = new Date().getTime();
if (this.state.disconnected) {
this.setState({disconnected: false});
}
},
stale: function(g) {
this.setState({stale: true});
clearInterval(this.state.ackInterval);
},
preferences: function(prefs) {
let options = _.assign({}, this.state.options, {submitter: prefs.submitter, postal_code: prefs.postal_code});
this.setState({options});
},
geoip: function(geoip) {
let options = _.assign({}, this.state.options, {geoip});
this.setState({options});
},
trsets: function(trsets) {
this.setState(...this.state, {trsets});
},
disconnected: function() {
console.log('disconnect');
},
update: function(incoming) {
let { type, message, content } = incoming, messages = [...this.state.messages];
// program information
if (content) {
if (content.status) {
this.state.currentStatus = content.status;
this.state.statusMessage = message;
this.state.progress = incoming.content;
}
if (content.submitted) {
this.state.submitted = content.submitted;
}
}
messages.push({ date: new Date(), type, message, content });
this.setState(...this.state, {messages});
},
submitTrace: function(options) {
this.state.currentStatus = null;
socket.emit('submitTrace', options);
},
cancelTrace: function() {
socket.emit('cancelTrace');
},
componentDidMount: function() {
socket.on('update', this.update);
socket.on('trsets', this.trsets);
socket.on('connect', this.connected);
socket.on('pong', this.ack);
socket.on('stale', this.stale);
socket.on('disconnect', this.disconnected);
socket.on('preferences', this.preferences);
socket.on('geoip', this.geoip);
let gen = new Date().getTime();
this.state.ackInterval = setInterval(() => {
if (this.state.ack) {
if (new Date().getTime() - this.state.ack > 20000) {
this.setState({disconnected: true});
}
}
socket.emit('ping', gen, this.state.ack > 0);
}, 500);
},
getInitialState: function() {
return {
options: DefaultOptions(),
messages: [],
step: 'Submitter',
currentStatus: null,
statusMessage: null,
trsets: null,
ack: 0,
lastPage: 'Submitter',
submitted : 0
};
},
render: function() {
let message;
if (this.state.stale) {
message = (
<Alert bsStyle='danger'>
<h1>Stale client</h1>
<p>This window should be closed since an active window is open. Check your other browser windows or refresh this window.</p>
</Alert>
);
} else if (this.state.disconnected) {
message = (
<Alert bsStyle='danger'>
<h1>Server disconnected</h1>
<p>The server is not responding to ping requests. It may be necessary to restart it.</p>
</Alert>
);
}
let step;
switch (this.state.step) {
case 'Destination':
step = <Destination caller={this} options={this.state.options} trsets={this.state.trsets}/>;
break;
case 'Options':
step = <Options caller={this} defaultOptions={DefaultOptions()} options={this.state.options}/>;
break;
case 'Trace':
step = <Trace caller={this} currentStatus={this.state.currentStatus} statusMessage={this.state.statusMessage} messages={this.state.messages} options={this.state.options} progress={this.state.progress} />;
break;
case 'Finished':
step = <Finished submitted={this.state.submitted} caller={this} lastPage={this.state.lastPage} />
break;
default:
step = <Submitter caller={this} options={this.state.options} />;
}
return (
<div className="container">
{message}
<Row className="col-md-12">
<form className='form-horizontal'>
{step}
</form>
</Row>
</div>
);
},
stepCall: function(to, opts, fields) {
if (fields) {
fields.forEach(i => {
this.state.options[i] = opts[i];
});
} else if (to === 'Finished') {
this.state.lastPage = opts;
}
// don't default to these anymore
delete this.state.options.geoip;
this.setState({
step: to
});
if (to === 'Trace') {
this.submitTrace(this.state.options);
}
},
savePrefs: function(prefs) {
socket.emit('savePreferences', prefs);
}
});
Submitter.jsx
/* jslint node: true, esnext: true */
var React = require('react'), {Input, Button, Panel} = require('react-bootstrap'),
createReactClass = require('create-react-class');
module.exports = createReactClass({
fields : ['submitter', 'city', 'postal_code', 'isp'],
render: function() {
var {caller} = this.props, {submitter, city, postal_code, isp, geoip} = this.state;
return (
<div>
<p>To get started, please provide your name, or pseudonym if you prefer. This is not required, but will help you find your own traceroutes later:
<input type='text' placeholder='Name or pseudonym (25 chars max)' onChange={this.change.bind(null, 'submitter')} value={submitter} className='input submitter' /></p>
<p>You appear to be near
<input type='text' placeholder='city' onChange={this.change.bind(null, 'city')} value={city} className='input city' />
<input type='text' placeholder='postal_code' onChange={this.change.bind(null, 'postal_code')} value={postal_code} className='input postal_code' /> <br />
with
<input type='text' placeholder='Internet Service Provider' onChange={this.change.bind(null, 'isp')} value={isp} className='input isp' />
as your internet service provider (ISP).</p>
<p>Please correct these if appropriate. This too is optional, but will assist in more accurately positioning the origin of the traceroutes you contribute.</p>
<Input ref='savePrefs' className='text-right' defaultChecked={true} type='checkbox' label='Store this information on your computer' />
<Button bsStyle='primary' className='pull-right' onClick={this.use}>Continue</Button>
<Button className='pull-right' onClick={this.cancel}>Cancel</Button>
</div>
);
},
change: function(field, e) {
this.setState({[field]: e.target.value});
},
getInitialState: function() {
return this.optionsWithGeoip(this.props.options, this.props.geoip);
},
componentWillReceiveProps(p) {
this.setState(this.optionsWithGeoip(p.options, p.geoip));
},
use: function() {
let options = {};
this.fields.forEach(i => {
options[i] = this.state[i];
});
if (this.refs.savePrefs.getChecked()) {
this.props.caller.savePrefs(options);
}
this.props.caller.stepCall('Destination', options, this.fields);
},
cancel: function() {
this.props.caller.stepCall('Finished', 'Submitter');
},
optionsWithGeoip: function(options) {
let geoip = options.geoip || {};
return {
submitter: options.submitter,
city: options.city || geoip.city,
postal_code: options.postal_code || geoip.postal_code,
isp: options.isp || geoip.isp
}
}
});
package.json
{
...
"scripts": {
"webpack-production": "webpack -p --config production.config.js",
"webpack": "webpack-dev-server --progress --colors --config dev.config.js --port 2050",
"dev": "NODE_ENV=development node server.js",
"public": "NODE_ENV=public node server.js",
"publicdev": "NODE_ENV=publicdev node server.js",
"start": "node server.js",
"test": "node test/*/*",
"build-macos": "pkg -t node10-macos-x64 server.js -o dist/macos/app --config package.json"
},
"pkg": {
"scripts": "lib/*.js",
"assets": "web/**/*"
},
"keywords": [
"internet mapping tool personal data traceroute surveillance"
],
"dependencies": {
"#babel/core": "^7.7.4",
"async": "^3.1.0",
"babel-core": "^7.0.0-bridge.0",
"babel-loader": "8.0.6",
"babel-preset-react": "^6.24.1",
"bootstrap": "^4.4.1",
"cheerio": "^0.22.0",
"create-react-class": "^15.6.3",
"express": "^4.17.1",
"lodash": "^4.17.15",
"lodash.template": "^4.5.0",
"moment": "^2.24.0",
"node-libs-browser": "^2.2.1",
"open": "^7.0.0",
"raw-socket": "^1.7.0",
"react": "^16.12.0",
"react-bootstrap": "^0.33.1",
"react-dom": "^16.12.0",
"request": "^2.88.0",
"socket.io": "^2.3.0",
"socket.io-client": "^2.3.0",
"webpack": "^4.41.2"
},
"devDependencies": {
"#babel/polyfill": "^7.7.0",
"#babel/preset-env": "^7.7.4",
"#babel/preset-react": "^7.0.0",
"gulp": "^4.0.2",
"gulp-less": "^4.0.1",
"gulp-notify": "^3.2.0",
"gulp-shell": "^0.7.1",
"gulp-streamify": "1.0.2",
"gulp-uglify": "^3.0.2",
"gulp-util": "^3.0.8",
"http-proxy": "^1.18.0",
"mkdirp": "^0.5.1",
"react-hot-loader": "^4.12.18",
"tape": "^4.11.0",
"vinyl-source-stream": "^2.0.0",
"watchify": "^3.11.1",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.9.0"
}
}

Jest Enzyme test throws unexpected token error

When I run the test, it thorws "unexpected token error at the code:
const wrapper = shallow(<WelcomeMessage/>");
The error is thrown at "(<". I have looked at a number of answers from stackoverflow and github but somehow I still cannot get it to work.
I have written jest tests. This is my first time writing a test case using enzyme and react. So I am not familar with the setup. I have installed: babel jest, react-dom, babel-plugin-transform-export-extensions, enzyme-adapter-react-16, react-test-renderer, #babel/preset-env, and #babel/core
package.json:
{
"private": true,
"version": "0.0.0",
"name": "example-jquery",
"devDependencies": {
"#babel/core": "*",
"#babel/preset-env": "^7.4.4",
"babel-jest": "^24.8.0",
"babel-plugin-transform-export-extensions": "^6.22.0",
"enzyme": "^3.9.0",
"enzyme-adapter-react-16": "^1.12.1",
"jest": "^24.8.0",
"jest-dom": "^3.1.4",
"jest-useragent-mock": "0.0.3"
},
"dependencies": {
"jest-puppeteer": "^4.1.1",
"jquery": "^3.4.1",
"jsdom": "^15.0.0",
"puppeteer": "^1.15.0",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-test-renderer": "^16.8.6"
},
"scripts": {
"test": "jest --verbose"
},
"jest": {
"transform": {
"^.+\\.jsx?$": "babel-jest"
}
}
}
jest.config.js:
module.exports = {
preset: 'jest-puppeteer',
"bail": 0,
setupFiles: ['<rootDir>/enzyme.config.js'],
moduleFileExtensions: ['js', 'json', 'jsx'],
transformIgnorePatterns: ['<rootDir>/node_modules/']
}
enzyme.config.js:
const Enzyme = require('enzyme');
const Adapter = require('enzyme-adapter-react-16');
Enzyme.configure({ adapter: new Adapter() });
.babelrc:
{
"presets": ["#babel/preset-env"],
"plugins": ["transform-export-extensions"],
"only": [
"./**/*.js",
"node_modules/jest-runtime"
]
}
WelcomeMessage.test.js:
import React from 'react';
import { shallow } from 'enzyme';
// Components
import WelcomeMessage from './WelcomeMessage';
function setup() {
const props = {
imgPath: 'some/image/path/to/a/mock/image',
};
const wrapper = shallow(<WelcomeMessage />);
return { wrapper, props };
}
describe('WelcomeMessage Test Suite', () => {
it('Should have an image', () => {
const { wrapper } = setup();
expect(wrapper.find('img').exists()).toBe(true);
});
});
This line:
<WelcomeMessage />
is JSX which "just provides syntactic sugar for the React.createElement function".
Since JSX isn't actually valid JavaScript code it must be compiled into React.createElement calls.
This is done by the Babel plugin #babel/plugin-transform-react-jsx which is included as part of #babel/preset-react.
Add #babel/preset-react to your Babel config and that should resolve the issue.

Categories

Resources