I'm a beginner with Node and Javascript and Puppeteer. Given the following code, in which I'm simply trying to use one function from a different file:
const waitForFrame = require ("../../lib/frames");
const screenshotFolder = 'test/screenshots';
module.exports = async(page) => {
try {
const iframe = await waitForFrame(page);
await iframe.waitForSelector('.competition-response__copy');
await page.waitForSelector({
visible: '.competition-response__copy'
});
const confirmationMessageText = await frame.$eval('.competition-response__copy > p', e => e.textContent);
return confirmationMessageText;
} catch (err) {
await page.screenshot({
path: screenshotFolder + '/saveYourEntryButton.png',
fullPage: true
});
}
And a helper file called:
module.exports = async function waitForFrame(page) { export async
function waitForFrame(page) {
let fulfill;
const promise = new Promise(x => fulfill = x);
checkFrame();
return promise;
function checkFrame() {
const frame = page.frames().find(f => f.name() === 'iframe');
if (frame) {
fulfill(frame)
} else
page.once('frameattached', checkFrame);
}
};
And my package json is as follows:
"engines": {
"node": ">=6"
},
"dependencies": {
"chai": "^4.1.2",
"chai-as-promised": "^7.1.1",
"lodash": "^4.17.10",
"mocha": "^5.2.0",
"puppeteer": "^1.6.2",
"yargs": "^12.0.1",
"express": "^4.16.4",
"supertest": "^3.3.0"
},
"devDependencies": {
"chai": "^4.2.0",
"chai-dom": "^1.8.1",
"mocha": "^5.2.0",
"js-comments": "^0.5.4",
"chai-as-promised": "^7.1.1",
"express": "^4.16.4",
"supertest": "^3.3.0",
}
}
I am receving an error as follows:
import {waitForFrame} from "../../lib/frames";
^
SyntaxError: Unexpected token {
at new Script (vm.js:79:7)
I'm sure this has a beginners error but grateful for a quick pointer. I'm aware there are a number of different methods to import depending on which standards of Javascript you are adhering too.
Thanks
You're trying to use import as native, but this's no still supported on ES6, the problem is not related with async functions but import as an unexpected token, you have some alternatives:
Don't use import orexport and instead use:
const waitForFrame = require("../../lib/frames");
This works very well and is supported in Node 6.
Migrate to Node 10, in that version is supported and you can use it.
Use a Compiler, like babel or any other that works for you, this involve include more dependencies, but then you can use modern APIs on oldest Node versions.
All depends on what you prefer.
Hope this helps you!
Related
I have read the docs which introduces on working fs (file-system) in Node js, but I can not manage it to work in my Quasar js application in Electron app. There are the some codes:
<script>
import fs from 'fs';
export default {
// some another codes here
methods: {
save() {
console.log(fs.copyFile) // gives undefined
fs.copyFile("source.jpg", ("destination.jpg" , (err) => {
console.log(err)
});
},
},
};
</script>
The code gives that error:
Map.vue?108f:119 Uncaught (in promise) TypeError: fs__WEBPACK_IMPORTED_MODULE_1___default.a.copyFile is not a function
at eval (Map.vue?108f:119)
Additional quasar (vue) js files:
package.json
{
"dependencies": {
"#quasar/extras": "^1.0.0",
"axios": "^0.18.1",
"core-js": "^3.6.5",
"pg-hstore": "^2.3.3",
"quasar": "^1.0.0",
"sequelize": "^6.6.2",
"sequelize-file": "^0.3.0",
"sqlite3": "^5.0.2",
"vue-i18n": "^8.0.0",
"vue2-editor": "^2.10.2"
},
"devDependencies": {
"#quasar/app": "^2.0.0",
"devtron": "^1.4.0",
"electron": "^9.4.4",
"electron-debug": "^3.2.0",
"electron-devtools-installer": "^3.1.1",
"electron-packager": "^14.2.1",
"electron-rebuild": "^2.3.5"
},
}
After some trial and error attempts I have found the solution for the problem, it was enough easy to use fs in Electron app with Quasar js. In Quasar js, there are some its own configurations which are ready to use. In my case, just must import fs looks like following:
var remote = window.electron.remote;
var fs = remote.require("fs");
Trying to create SharedWorker with worker-loader
It doesnt create it, just Worker is created. Seems like it ignores options.
Usage in parent code
import SharedWorker from "worker-loader!./workers/get-nth-fibonacci-number.shared-worker.js";
import "./styles/style.scss";
const btn = document.getElementById("calc-btn");
const input = document.getElementById("nth-input");
const result = document.getElementById("result-el");
const worker = new SharedWorker();
console.log("worker", worker);
worker.port.addEventListener("message", (e) => {
result.innerHTML = e.data;
});
worker.port.addEventListener("error", (e) => {
result.innerHTML = `message: ${e.message}; filename: ${e.filename}; line: ${e.lineno}`;
console.error(e);
});
//...
worker code
import { getNthFobonacciNumber } from "../helpers/get-nth-fibonacci-number.js";
console.log("hello from worker");
self.addEventListener("connect", function (e) {
const port = e.ports[0];
console.log("port", port);
port.addEventListener("message", function (e) {
const num = e.data;
if (Number.isInteger(parseInt(num))) {
const result = getNthFobonacciNumber(num);
port.postMessage({ result, port });
} else {
throw new Error("Is not a number");
}
});
port.start();
});
webpack rule
{
test: /\.shared-worker\.(c|m)?js$/i,
loader: "worker-loader",
options: {
worker: "SharedWorker",
},
},
But in console it is shown as Worker class. What is wrong with it?
dependencies
"#babel/core": "^7.7.7",
"#babel/plugin-syntax-dynamic-import": "^7.2.0",
"#babel/preset-env": "^7.7.7",
"babel-loader": "^8.0.6",
"brotli-webpack-plugin": "^1.1.0",
"clean-webpack-plugin": "^3.0.0",
"compression-webpack-plugin": "^3.0.1",
"css-loader": "^3.4.1",
"cssnano": "^4.1.0",
"file-loader": "^5.0.2",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.9.0",
"node-sass": "^4.13.0",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"postcss-loader": "^3.0.0",
"postcss-preset-env": "^6.7.0",
"purgecss-webpack-plugin": "^1.6.0",
"sass-loader": "^8.0.0",
"style-loader": "^1.1.2",
"terser-webpack-plugin": "^2.3.1",
"webpack": "^4.41.5",
"webpack-cli": "^3.3.10",
"webpack-dev-server": "^3.10.1",
"worker-loader": "^3.0.5"
This thing asks me to add some more details: "It looks like your post is mostly code; please add some more details." This is just a stub text. I'm sorry.
Solved by using alternative plugin https://github.com/GoogleChromeLabs/worker-plugin
with worker-loader you can, create the file with the extension .sharedworker.js and in webpack rules you do this
{
test: /\.sharedworker\.js$/,
use: [
{
loader: 'worker-loader',
options: {
filename: '[name].[hash:8].js',
inline: 'fallback',
worker: {
type: 'SharedWorker',
options: {
credentials: 'omit',
name: 'mySharedWorker' // for debbuging
}
}
}
},
{
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env']
}
}
]
}
you can delete worker-loader! in your import code.
worker-loader! will change options to {}
just use webpack config only.
I have same question, and sovled it
Hy there,
I try to make a custom navigation guard with vue using vuex actions.
The code for the router guard is looking like this:
router.js
{
path: '/authusersonly',
name: 'authusersonly',
component: loadView('authusersonly'),
async beforeEnter (to, from, next) {
try {
let authStatus = await store.dispatch('pingAuth', 'checkAuth')
if (authStatus) next()
else next('/login')
} catch (error) {
console.log(error)
next('/')
}
}
}
The code from store.js file is looking like this
actions: {
async pingAuth ({ commit, state, getters, dispatch }, action) {
let pingStatus = getters.pingStatus
if (!pingStatus) {
// here i do the user check using axios with await axios.......
}
// here i return the results true or false
return false
}
}
The code work perfect but when the pingAuth action return false i get weird console error the user is redirected correctly even when the error appear.
If the pingAuth return true no error is present in the console.
The error is different in firefox and chrome.
Firefox Error
Chrome Error
I have tried to reproduce the issue in a codesandbox but the error doesn't apper. I have also tried the code with a new clean vue project (all dependencies to latest versions) and have the same error.
Can anyone explain why i get this error ?
Thanks a lot in advance.
#vue/cli 4.0.5 on ubuntu 19
package.js
"dependencies": {
"axios": "^0.19.0",
"core-js": "^2.6.5",
"date-fns": "1.29.0",
"register-service-worker": "^1.6.2",
"vue": "^2.6.10",
"vue-i18n": "^8.14.1",
"vue-router": "^3.0.3",
"vuex": "^3.0.1"
},
"devDependencies": {
"#vue/cli-plugin-babel": "^3.12.0",
"#vue/cli-plugin-eslint": "^3.12.0",
"#vue/cli-plugin-pwa": "^3.12.0",
"#vue/cli-service": "^3.12.0",
"#vue/eslint-config-standard": "^4.0.0",
"babel-eslint": "^10.0.1",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"node-sass": "^4.12.0",
"sass-loader": "^8.0.0",
"vue-cli-plugin-vueth": "file:../plugin/",
"vue-template-compiler": "^2.6.10"
}
Edit:
I tried to isolate the problem.
The problem came from router navigation.
I have created a repo for my problem.
git clone https://github.com/thenutz/vue-router-error.git
yarn install
yarn serve
Another interesting thing is if i'm using router-link for navigation no error is present.
I found a fix for this error.
If i use #click="$router.push({ path: '/protected' }).catch((err) => {})" instead of #click="$router.push({ path: '/protected' })" no error is present.
Please check if it's the case. You are visiting the 'login' page and you use next('login') to the same page. So need to determine whether the same page, if so just use 'next()'.
The React Context API allows me to place the logic for the app state in one place (and avoid redux). Right now it looks like this
// Using the Context API used in react 16.3 - https://www.youtube.com/watch?v=XLJN4JfniH4
const { Provider, Consumer: ContextConsumer } = React.createContext()
class ContextProvider extends Component {
...// lot of functions ...
render() {
return (
<Provider
value={{
...this.state,
getDose: this.getDose,
getDoseRange: this.getDoseRange,
setDose: this.setDose,
checkIN: this.checkIN,
checkOUT: this.checkOUT,
getFalsifiedDrug: this.getDefaultproductData,
updatePrescriptionDose: this.updatePrescriptionDose,
}}
>
{this.props.children}
</Provider>
)
}
}
module.exports = { ContextConsumer, ContextProvider }
Entire code can be found here.
What's the best practice to build jest tests that allows me to test the functions and don't mess up the state?
(Would like to avoid using Enzyme (developed by AirBnB) - since AirBnB officially gave up using React Native)
Example
How do I make a test that confirms that when I call setDose(2) that the productData.dose was changed from "5 mg" and now equals "2 mg. But then set the state back to "5 mg" for the other test.
BONUS INFO
I'm having some trouble getting jest to work with me (so I can try out the suggested solutions)
package.json
{
"main": "node_modules/expo/AppEntry.js",
"private": true,
"scripts": {
"test": "jest --watchAll"
},
"dependencies": {
"#expo/samples": "2.1.1",
"crypto-js": "^3.1.9-1",
"date-fns": "^1.29.0",
"expo": "^28.0.0",
"invert-color": "^1.2.3",
"lodash": "^4.17.10",
"react": "16.3.1",
"react-native": "https://github.com/expo/react-native/archive/sdk-28.0.0.tar.gz",
"react-native-qrcode": "^0.2.6",
"react-native-slider": "^0.11.0",
"react-native-switch": "^1.5.0",
"react-navigation": "2.3.1",
"whatwg-fetch": "^2.0.4"
},
"devDependencies": {
"babel-eslint": "^10.0.1",
"babel-preset-expo": "^5.0.0",
"eslint": "^5.16.0",
"eslint-config-codingitwrong": "^0.1.4",
"eslint-plugin-import": "^2.17.2",
"eslint-plugin-jest": "^22.5.1",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-react": "^7.13.0",
"jest-expo": "^32.0.0",
"react-native-testing-library": "^1.7.0",
"react-test-renderer": "^16.8.6"
},
"jest": {
"preset": "jest-expo"
}
}
It just throws this at me
> # test /Users/norfeldt/Desktop/React-Native/MedBlockChain
> jest --watchAll
● Validation Error:
Module react-native/jest/hasteImpl.js in the haste.hasteImplModulePath option was not found.
<rootDir> is: /Users/norfeldt/Desktop/React-Native/MedBlockChain
Configuration Documentation:
https://jestjs.io/docs/configuration.html
npm ERR! Test failed. See above for more details.
I have tried things like
rm -rf node_modules/ yarn.lock package-lock.json && npm install
You could make use of react-test-renderer which you're already using in your project specs. What you need is to call testRenderer.getInstance() => check current state => invoke some methods you need to test => check updated state:
import React from "react";
import { create } from "react-test-renderer";
import { ContextProvider } from "../Context";
describe("ContextProvider", () => {
test("it updates dose correctly", () => {
const component = create(<ContextProvider />);
const instance = component.getInstance();
expect(instance.getDose()).toBe(5);
expect(instance.state.productData.dose).toBe("5 mg");
instance.setDose(2);
expect(instance.getDose()).toBe(2);
expect(instance.state.productData.dose).toBe("2 mg");
});
test("it updates something else correctly", () => {
// ...
});
});
State for other tests won't be affected.
The only thing I needed to make this work with your repo is to npm install whatwg-fetch#2.0.4 --save as described here. Hope this helps.
UPDATE
Even though this is supposed to be another question and the obvious solution is to create a new rn project and copy you code in it, but here is what I've done to fix jest errors on your code:
1) Make versions match (as described in the comments...):
"expo": "^32.0.0",
"jest-expo": "^32.0.0",
// and maybe even
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",
2) To fix an error
api.caller is not a function
use babel.config.js as described here:
module.exports = function(api) {
api.cache(true);
return {
presets: ["babel-preset-expo"],
env: {
development: {
plugins: ["transform-react-jsx-source"]
}
}
};
};
3) Use yarn due to this
If you are looking for a replacement for Enzyme, I think you should look here: https://callstack.github.io/react-native-testing-library/
That library will allow you to use the update function provided to change the values you are testing, then change them back.
Great library for React Native - the getting started page says it all. If you are interested in some code to help you get started I can work something up as well.
I suggest that you only unit-test your logic and consider avoiding component tests altogether in this case.
You can extract your methods into a "Presenter" to process your data and only test this logic. With this approach it's easy to test the presenter which has a pure input/output logic.
The presenter, for example, can look like this:
// DosePresenter.js
const processDose = (value, productData) => {
productData.dose = value.toFixed(0) + productData.dose.replace(/[\d\.]*/g, '')
productData.productionTime = Conventions.datetimeStr();
productData.hashSalt = this.makeHashSalt();
return {productData, productDataHash: getHashOfproductData(productData)};
};
module.exports = {
processDose
};
The usage:
// Context.js
import * as DosePresenter from './DosePresenter';
const setDose = (value) => this.setState(DosePresenter.processDose(value, {...this.state}));
Now it should be easier to test the logic:
// DosePresenter.test.js
describe('DosePresenter tests', () => {
let uut;
beforeEach(() => {
uut = require('./DosePresenter');
});
it('should process a dose', () => {
const value = 10;
const productData = {};
expect(uut.processDose(value, productData)).toEqual(...);
});
};
I have written a code in node.js(ES6) and below is my problem with steps i followed to run my code:
-Step1:
ES6 code==>(babel)==>successfully transpiled code when run (npm run build)
-Step2:
run command (npm start) throws error "SyntaxError: Unexpected token import"
But if i run "nodemon ./src/index.js --exec babel-node" it runs successfully.
I have also tried to understand the reason for failure by searching similar questions on stackoverflow before posting this question here but not able to make my code work.
I really appreciate your help guys i do not know how to proceed from here, our whole production deployment is stuck due to this issue:(.
Below you will find my code files which shows i have already used babel and .babelrc in my code:
Package.json-
"dependencies": {
"babel-preset-es2015": "^6.24.1",
"body-parser": "^1.16.0",
"connect-timeout": "^1.8.0",
"core-js": "^2.4.1",
"cors": "^2.8.1",
"express": "^4.14.1",
"joi": "^10.2.2",
"jsonapi-serializer": "^3.5.3",
"mongoose": "^4.10.4",
"mongoose-rename-id": "^1.0.2",
"nedb": "^1.8.0",
"path": "^0.12.7",
"randomstring": "^1.1.5",
"request": "^2.79.0",
"request-promise": "^4.1.1",
"swagger-express-mw": "^0.1.0",
"swagger-ui": "^2.2.10",
"yamljs": "^0.2.8"
},
"devDependencies": {
"babel-cli": "^6.22.2",
"babel-core": "^6.22.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-es2015-node": "^6.1.1",
"babel-preset-es2016-node4": "^6.0.1",
"babel-preset-es2017": "^6.22.0",
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
"husky": "^0.13.1",
"mocha": "^3.2.0",
"mocha-duplicate-reporter": "^0.2.1",
"mocha-multi": "^0.9.0",
"mocha-sonar-generic-test-coverage": "0.0.1",
"nock": "^9.0.2",
"node-mocks-http": "^1.6.1",
"nodemon": "^1.11.0",
"nyc": "^10.1.2",
"pact": "^1.0.0",
"rimraf": "^2.5.4",
"sinon": "^1.17.7",
"sinon-chai": "^2.8.0",
"snazzy": "^6.0.0",
"standard": "^8.6.0",
"unit.js": "^2.0.0"
},
.babelrc-
{
"presets": [
"es2016-node4",
"es2017",
"es2015"
]
}
code for index.js:
'use strict'
import * as path from 'path'
import {PORT} from 'config'
// config module loads the configuration from the folder the process is run
process.env[ 'NODE_CONFIG_DIR' ] = path.resolve(__dirname, '/config')
import server from './server'
// Start the server
server(PORT)
code for server.js:
import cors from 'cors'
import SwaggerExpress from 'swagger-express-mw'
import bodyParser from 'body-parser'
import timeout from 'connect-timeout'
import * as YAML from 'yamljs'
import * as path from 'path'
import account from '../src/api/controllers/accounts.js'
const version = {
file: YAML.load(path.join(__dirname, 'version.yml'))
}
var config = {
appRoot: __dirname,
swaggerFile: path.resolve(__dirname, 'api', 'swagger', 'swagger.json'),
basePath: '/api/v1',
swaggerSecurityHandlers:{
basicAuth :async function(req, authOrSecDef, scopesOrApiKey, callback){
try{
//let data = true
console.log(req.headers.authorization)
let data = await account.authenticate(req.headers.authorization)
if(data.statusCode==200){
console.log(data)
callback(null,true);
}
else
callback(new Error("Access denied"))
}catch(err){
callback(new Error("Access denied"))
}
console.log("response ...."+data)
}
}
}
export default function start (serverPort) {
SwaggerExpress.create(config, function (err, swaggerExpress) {
if (err) {
throw err
}
var app = require('express')()
// Hack to override the host and port
app.get(path.resolve(config.basePath, '/api-docs'), function (req, res) {
swaggerExpress.runner.swagger.host = req.get('host')
// Set correct version for the API
swaggerExpress.runner.swagger.info.version = version.file.build.name
res.json(swaggerExpress.runner.swagger)
})
// Customize SwaggerUI
var swaggerUIParams = {
swaggerUi: config.basePath + '/docs',
apiDocs: config.basePath + '/api-docs'
}
// Add for version
app.get('/version', function (req, res) {
// Load yaml file using YAML.load
res.json(version.file.build)
})
// serves the Swagger documents and Swagger UI
app.use(swaggerExpress.runner.swaggerTools.swaggerUi(swaggerUIParams))
app.use(cors())
app.use(bodyParser.json())
app.use(timeout('6s'))
// install middleware
swaggerExpress.register(app)
app.listen(serverPort)
})
}
code for Accounts.js(here it actually throws the error at import statement first line):
import request from 'request-promise'
export default account()
function account() {
return {
authenticate: async function authenticate (authheader) {
console.log("Sending call for Account")
let temp = (authheader).split(" ")
console.log(temp[1])
let buf = new Buffer(temp[1], 'base64'); // create a buffer and tell it the
data coming in is base64
let plain_auth = buf.toString(); // read it back out as a string
console.log("Decoded Authorization ", plain_auth);
const cred = plain_auth.split(':')
const options={
uri: `http://localhost:3000/api/account/${cred[0]}`,
json: true,
resolveWithFullResponse: true,
headers: {
'Content-Type': 'application/json; charset=utf-8',
'Accept': 'application/json; charset=utf-8'
// 'Authorization':authheader
},
method: 'GET'
}
return request(options).then((response) => {
console.log(response.statusCode)
return {
"statusCode":response.statusCode,
"body":response.body
}
}).catch((err) => {
console.log(err);
console.log('errorstatuscode:' + err.statusCode)
});
}
}
}
scripts in package.json:
"scripts": {
"build:transpile": "babel src/ -d dist",
"build:copy-resources": "cp -r config dist && cp -r src/api/swagger dist/api
&& cp src/version.yml dist",
"build": "rimraf dist && npm run build:transpile && npm run build:copy-
resources",
"devstart": "nodemon ./src/index.js --exec babel-node",
"start": "node dist/index.js",
}
Dear all the issue is resolved now, the error is in the path defined at server.js at the below line:
-import account from '../src/api/controllers/accounts.js'
There is no issue with the babel or transpiled code, its due to the wrong path definition which tells the code to pick file accounts.js from src folder not from the transpiled code present in dist folder as a result it failed and throws the error of unexpected token import.
Now i have corrected the relative path and its working fine with npm run start as well.
Thanks you all too for your support.
require babel-register module start of your index.js
require('babel-register');
I think it will solve your problem.
Your npm run build work when you are bundling code, that time babel transpile your code as per your configuration provided to webpack/gulp.
But when you start server then babel does not transpile it because babel does not aware about it.