Reputation: 941
I am getting the following error:
command: npx cucumber-js .\cucumber-e2e\
import { Given, When, Then } from '@cucumber/cucumber';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1032:15)
at Module._compile (node:internal/modules/cjs/loader:1067:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1157:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at C:\dev\FrontSystems.KeystonePortal\Keystone.Web\ClientApp\node_modules\@cucumber\cucumber\lib\cli\index.js:122:17
at Array.forEach (<anonymous>)
at Cli.getSupportCodeLibrary (C:\dev\xxxxx\xxxx.Web\ClientApp\node_modules\@cucumber\cucumber\lib\cli\index.js:120:26)
at Cli.run (C:\dev\xxxx\xxxx.Web\ClientApp\node_modules\@cucumber\cucumber\lib\cli\index.js:145:41)
at async Object.run [as default] (C:\dev\xxxxx\xxxx.Web\ClientApp\node_modules\@cucumber\cucumber\lib\cli\run.js:25:18)codepath: C:\dev\xxxxx\xxxx.Web\ClientApp\cucumber-e2e\step-definitions\catalog.steps.ts
steps file:
import { Given, When, Then } from '@cucumber/cucumber';
Given('A bank account with starting balance of {int}', (balance: number) => {
// Write code here that turns the phrase above into concrete actions
return 'pending';
});
My folder structure is the following:
cucumber.js:
var common = [
'--require ./cucumber-e2e/step-definitions/**/*.ts',
'--publish-quiet',
].join(' ');
module.exports = {
default: common,
};
tsconfig.json:
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/cucumber-e2e",
"module": "commonjs",
"target": "es5",
"types": [
"jasmine",
"jasminewd2",
"node"
]
}
}
inherited tsconfig.json:
{
"compileOnSave": false,
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"module": "esnext",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"target": "es2015",
"resolveJsonModule": true,
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2018",
"dom"
],
"paths": {
"jszip": [
"node_modules/jszip/dist/jszip.min.js"
]
},
"plugins": [
{
"name": "typescript-tslint-plugin",
"alwaysShowRuleFailuresAsWarnings": false,
"ignoreDefinitionFiles": true,
"configFile": "./tslint.json",
"suppressWhileTypeErrorsPresent": false
}
]
}
}
and I've added the following packages to package.json:
"@cucumber/cucumber": "^7.3.2",
"@types/chai": "^4.3.0",
"chai": "^4.3.6",
"chai-as-promised": "^7.1.1",
"protractor-cucumber-framework": "^8.4.0",
"webdriver-manager": "^12.1.8"
So, the feature files and the step definitions are being recognised, however it's throwing a syntax error when it shouldn't. I have a feeling it might be related to the package.json but I've tried multiple versions of the different packages with no positive result.
All tutorials out there seem to do it this way or very similar.
Any ideas?
Upvotes: 8
Views: 8216
Reputation: 698
The thing that helped me was the ts-node/register
and a dedicated tsconfig.json
file.
Cucumber
configuration placed under the playwright
folder, not in the root.// playwright/cucumber.config.js
/**
* @type {Record<string, import('@cucumber/cucumber/lib/configuration').IConfiguration>}
*/
module.exports = {
default: {
paths: ['playwright/features/**/*.{feature,features}'],
require: ['playwright/steps/**/*.{step,steps}.*'],
requireModule: ['ts-node/register'], // Transpiles the `.ts` steps
formatOptions: { snippetInterface: 'async-await' },
}
};
// playwright/tsconfig.json
{
"compilerOptions": {
"skipLibCheck": true,
"noErrorTruncation": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"lib": ["esnext", "dom"],
"moduleResolution": "node",
"target": "esnext",
"module": "commonjs"
},
"include": ["playwright/**/*.ts"]
}
TS_NODE_PROJECT='playwright/tsconfig.json'
option passed to the cucumber-js
executable:package.json
{
...
"scripts": {
...
"test-playwright-cucumber": "TS_NODE_PROJECT='playwright/tsconfig.json' cucumber-js --config playwright/cucumber.config.js"
}
Upvotes: 1
Reputation: 1371
If you haven't specified the type
of module in your package.json
, it will default to CommonJS. In this context, you cannot use the import
syntax, you have to rely on require
.
There are 2 ways to resolve this:
const { Given, When, Then } = require('@cucumber/cucumber');
// package.json
{
...
"type": "module",
...
}
Note that in this second case, if the module you are requesting is a CommonJS module, it may not support named exports and you will have to fallback to the following syntax:
import Cucumber from '@cucumber/cucumber';
const { Given, When, Then } = Cucumber;
Upvotes: 3