Invoke cucumber cli programatically through index.js of node - javascript

I have been given an automation framework in CucumberJS and node with selenium. But it has an older version of cucumber which relies on promises. In an attempt to avail latest synchronous step feature, I decided to upgrade the cucumberJS version (1.3.3 to 4.2.1)
Now the problem is the code that was used to invoke cucumber cli programmatically in index.js isnt working anymore. I made all the other changes in step definitions and world.js, but I am not able to figure out how do I run this thing via node, something like
node index.js --tags #SampleFeature
This used to work before with the older version but not anymore.
Code that was working before -
// execute cucumber
let cucumberCli = Cucumber.Cli(process.argv);
cucumberCli.run(succeeded => {
var code = succeeded ? 0 : 1;
function exitNow() {
process.exit(code);
}
if (process.stdout.write('')) {
exitNow();
} else {
process.stdout.on('drain', exitNow);
}
});
Now it throws the error like this after version update
/Users/../node_modules/babel-runtime/helpers/classCallCheck.js:7
throw new TypeError("Cannot call a class as a function");
^
TypeError: Cannot call a class as a function
at exports.default (/Users/../node_modules/babel-runtime/helpers/classCallCheck.js:7:11)
at Object.Cli (/Users/../node_modules/cucumber/lib/cli/index.js:78:34)
at Object.<anonymous> (/Users/../index.js:90:10)
at Module._compile (internal/modules/cjs/loader.js:678:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)
at Module.load (internal/modules/cjs/loader.js:589:32)
at tryModuleLoad (internal/modules/cjs/loader.js:528:12)
at Function.Module._load (internal/modules/cjs/loader.js:520:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:719:10)
at startup (internal/bootstrap/node.js:228:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:576:3)
I googled a lot but did not find an alternative. Tried multiple things as calling Cli as class with new keyword, didn't work. Tried removing it and running via plain cucumber cli runner, didn't work.
PS. I come from a Cucumber with Java background where things were simpler :)

You need to create a new CLI object, then use it's .run method:
let runArgs = ['The cucumber args array here'];
let cliArgs = {argv : runArgs, cwd: process.cwd(), stdout: process.stdout};
let cli = (new require('cucumber').Cli)(cliArgs);
cli.run(); //Returns a promise

For reference I've employed the same approach with Typescript and cucumber 7.3.2
import { Cli } from '#cucumber/cucumber';
const runArgs = ['-p', argv['profile'], '--tags', argv['tags'], '--fail-fast'];
const cliArgs = { argv: runArgs, cwd: process.cwd(), stdout: process.stdout };
const cli = new Cli(cliArgs);
await cli.run();

Related

node js discord bot is not works

/home/discord/project/bloodmoon/node_modules/discord.js/src/client/Client.js:42
} catch {
^
SyntaxError: Unexpected token {
at createScript (vm.js:80:10)
at Object.runInThisContext (vm.js:139:10)
at Module._compile (module.js:616:28)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/home/discord/project/bloodmoon/node_modules/discord.js/src/index.js:8:11)
i'm interested in developing discord bot. so i tried it. first, it works.
but, i moved the server and i setted it. and it not works! please give advise to me.
(please understand i can't write a English essay well. sorry)
If you check the discord.js source code, you can see that they're trying to silently ignore if there is an error when their code requires the worker_threads module. They simply omit the usual (error) part after catch:
try {
// Test if worker threads module is present and used
data = require('worker_threads').workerData || data;
} catch {
// Do nothing
}
However, it only works in newer versions of JavaScript and older ones will throw a SyntaxError. So, you must be using an older version of Node, because optional catch binding is only available in Node.js v10+.
The following is an example in Node v8:
// using Node v8
try { error } catch { console.log('oops') }
⬇⬇ result ⬇⬇
try { error } catch { console.log('oops') }
^
SyntaxError: Unexpected token {
While it just works fine in Node v10+:
// using Node v16
try { error } catch { console.log('oops') }
⬇⬇ result ⬇⬇
oops
To solve this, you need to update your Node version to at least v12, as mentioned in the discord.js docs:
v12 requires Node 12.x or higher, so make sure you're up-to-date. To
check your Node version, use node -v in your terminal or command
prompt, and if it's not high enough, update it! There are many
resources online to help you with this step based on your host system.

Getting error TypeError: Promise.any is not a function

I am learning Promise.any from the following site.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any
The IDE does not show any error, but while running using yarn command , I am getting the following error.
E:\typescript-2020-1\promise-usages-1\lib\basics1\promise-any.service.js:18
Promise.any([
^
TypeError: Promise.any is not a function
at PromiseAnyService.validateAll_Type1 (E:\typescript-2020-1\promise-usages-1\lib\basics1\promise-any.service.js:18:17)
at Object.<anonymous> (E:\typescript-2020-1\promise-usages-1\lib\test.js:35:7)
at Module._compile (internal/modules/cjs/loader.js:1137:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
at Module.load (internal/modules/cjs/loader.js:985:32)
at Function.Module._load (internal/modules/cjs/loader.js:878:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47
 ERROR  Command failed with exit code 1.
I have written the simple code to test. Please help where I am doing wrong in a Typescript class.
const promise1 = Promise.reject(0);
const promise2 = new Promise((resolve) => setTimeout(resolve, 100, 'quick'));
const promise3 = new Promise((resolve) => setTimeout(resolve, 500, 'slow'));
const proms = [promise1, promise2, promise3];
Promise.any(proms).then((result) => console.log(result));
Currently I am using NodeJs 12 and Typescript 3.8.3
The method Promise.any was supported in node.js 15.0.0, your node.js version is old, so you could update it and try again.
Imho it's better to stick with whatever is supported in your current setup, and it seems like esnext.promise is not there yet, but:
I'm in a situation where I'm porting a sizeable live codebase away from Bluebird, and this npm module did it for me (I'm on node v12.12.0):
https://www.npmjs.com/package/promise.any

Plain text SASL authentication in gremlin-javascript

I'm trying to connect to a Gremlin server with the JavaScript driver variant.
Up to package version 2.7.0, this is done easily by passing options to Gremlin.createClient() as in this example for Azure Cosmos DB:
const client = Gremlin.createClient(
config.port,
config.endpoint,
{
"session": false,
"ssl": true,
"user": `/dbs/${config.database}/colls/${config.collection}`,
"password": config.primaryKey
}
);
In newer versions of the package I can't get it done. The official docs suggest using gremlin.driver.auth.PlainTextSaslAuthenticator. However, that method seems to be not implemented in the package and returns TypeError: Cannot read property 'PlainTextSaslAuthenticator' of undefined
My test code (same config.js as in the working example):
const gremlin = require("gremlin");
const config = require("./config");
const Graph = gremlin.structure.Graph;
const DriverRemoteConnection = gremlin.driver.DriverRemoteConnection;
const graph = new Graph();
const authenticator = new gremlin.driver.auth.PlainTextSaslAuthenticator(
`/dbs/${config.database}/colls/${config.collection}`,
config.primaryKey
);
const g = graph.traversal().withRemote(new DriverRemoteConnection(`ws://${config.endpoint}:${config.port}`, { authenticator });
Return:
C:\repos\gremlin-test\index.js:9
const authenticator = new gremlin.driver.auth.PlainTextSaslAuthenticator(
^
TypeError: Cannot read property 'PlainTextSaslAuthenticator' of undefined
at Object.<anonymous> (C:\repos\gremlin-test\index.js:9:47)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:191:16)
at bootstrap_node.js:612:3
Anyone know a solution to this?
I've not got too much experience with Gremlin.js, but I just downloaded it and have manually searched through all of its files - I can't find any trace of a PlainTextSaslAuthenticator function or its declaration.
This could mean one of two three -
Its function has been (accidentally) removed
It uses a third party package that has been (accidentally) removed
It has not been added to the package yet
Upon a swift Google search, I found this link which seems to show it being added to /lib/driver/auth, but that directory doesn't seem to exist in the package I got through npm install gremlin. Perhaps it is yet to be released?
I would therefore suggest you raise an issue on Github, but it seems that repository you linked doesn't allow for issues to be raised. So perhaps email/contact the author?
EDIT:
Thanks to Stephen for the link - the code hasn't been merged to the package yet. Keep track of it here.

Node.js readline: Unexpected token =>

I am learning node.js and need to use readline for a project. I have the following code directly from the readline module example.
const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question('What do you think of Node.js? ', (answer) => {
// TODO: Log the answer in a database
console.log('Thank you for your valuable feedback:', answer);
rl.close();
});
But when I run the code via
node try.js command, it keeps giving out the errors like below:
rl.question('What is your favorite food?', (answer) => {
^^
SyntaxError: Unexpected token =>
at exports.runInThisContext (vm.js:73:16)
at Module._compile (module.js:443:25)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)
at startup (node.js:129:16)
at node.js:814:3
Arrow functions, one of the new features of the ECMAScript 6 standard, were introduced to node.js (as stable feature) only in version 4.0.0.
You can either upgrade your node.js version or use the old syntax, which would look like this:
rl.question('What do you think of Node.js? ', function(answer) {
// TODO: Log the answer in a database
console.log('Thank you for your valuable feedback:', answer);
rl.close();
});
(Note that there is one more difference between those syntaxes: The this variable behaves differently. It doesn't matter for this example, but it may in others.)
Upgrade your node version.
Arrow functions now work in node (version 4.0.0) see here: ECMAScript 2015 (ES6) in Node.js
Check to see which version you are running with node -v
You likely need to upgrade check out the compatibility table here to see what else is available:
Node Compatibility Table
For people who already upgraded node and are running into the same error: For me, this error was coming from eslint. I was using node 14 in my package.json:
"engines": {
"node": "14"
},
But only got rid of the error after updating the linter .eslintrc.js config to the following:
"parserOptions": {
"ecmaVersion": 8,
"ecmaFeatures": {
"experimentalObjectRestSpread": true,
"jsx": true,
},
"sourceType": "module",
},
The => syntax, known as an Arrow Function, is a relatively new feature of JavaScript. You'll need a similarly new version of Node to take advantage of it.
Change your "es" version from 6 to 7.
For this go to your functions**>**.eslintrc.js file.
Change "es6:true" to "es7:true".
Actually, "=>" is an element of es7 and therefore throws error on es6.

Not able to access another module's function in NodeJS

To break it down and simplify it a bit: Imagine I have three files in my project. One main.js, and two modules: moduleA.js and moduleB.js.
main.js accesses moduleA.js which calls a function from moduleB.js. Now moduleB.js finds out that it needs an information that is only available in moduleA.js. Of course moduleB.js tries to access a function in moduleA.js which is technically able to give this information to moduleB.js but there is an error.
Here is the simplified code.
main.js
var a = require("./moduleA.js");
console.log(a.respond());
moduleA.js
var b = require("./moduleB.js");
module.exports = {
respond: function(){
return b.returnAnswerForModuleA();
},
getSomeInformationOnlyAvailableInA: function(){
return "This is the information we need!";
}
};
moduleB.js
var a = require("./moduleA.js");
module.exports = {
returnAnswerForModuleA: function(){
return a.getSomeInformationOnlyAvailableInA()
}
};
Here is the error message:
/Users/Tim/Code/ChatBot/test/moduleB.js:5
return a.getSomeInformationOnlyAvailableInA()
^
TypeError: a.getSomeInformationOnlyAvailableInA is not a function
at Object.module.exports.returnAnswerForModuleA (/Users/Tim/Code/ChatBot/test/moduleB.js:5:16)
at Object.module.exports.respond (/Users/Tim/Code/ChatBot/test/moduleA.js:5:18)
at Object.<anonymous> (/Users/Tim/Code/ChatBot/test/main.js:3:15)
at Module._compile (module.js:425:26)
at Object.Module._extensions..js (module.js:432:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:311:12)
at Function.Module.runMain (module.js:457:10)
at startup (node.js:136:18)
at node.js:972:3
Why cannot I access moduleA.js from moduleB.js?
To restructure my code is not really an option!
Thanks for help!
This looks like an issue with circular dependencies in node.js where a circular dependency causes one module to be resolved as an empty object (thus causing the error you see). See these articles which explain:
Node.js and circular dependencies
Circular dependencies in Node.js
The first article offers two possible solutions: "delaying invocation of dependency until runtime" and "replace circular dependency with dependency injection".
I think you can work around the circular issue by changing module B to this:
var moduleA;
module.exports = {
returnAnswerForModuleA: function(){
if (!moduleA) {
moduleA = require("./moduleA.js");
}
return moduleA.getSomeInformationOnlyAvailableInA()
}
};
This delays the loading of module A in module B until runtime by which time, it is already successfully loaded and in the module cache, thus avoiding the circular dependency.

Categories