SyntaxError: Cannot use import statement outside a module
markocir opened this issue ยท 21 comments
Summary
I was trying to runt tests npm run test:ui
and it failed with: SyntaxError: Cannot use import statement outside a module
.
I have changed ChromeDriver version to latest and run npm install and it did not change the outcome: "chromedriver": "^107.0.3",
Salesforce Org Type
Scratch Org
Steps To Reproduce
- Installing E-Bikes using a Scratch Org
npm install
npm run test:ui:compile
npm run test:ui:generate:login
npm run test:ui
-> this fails- update
chromedriver
dependency version to^107.0.3
npm install
npm run test:ui
-> this still fails
Current Behavior
No response
Expected Behavior
No response
Relevant Log Output
Code of Conduct
- I agree to follow this project's Code of Conduct
Thank you for posting this issue. ๐๐ผโโ๏ธ
We will come back to you shortly.
Hi @markocir. Thanks for reporting this issue but I couldn't reproduce it.
Can you confirm that you're using node v16 or above?
I just updated the dependencies on the repo, just in case.
Hi,
I have node version v16.15.0. Also I am using wsl2 subsystem on windows if that could cause the issue...
Ah yes, I have suspicions on WSL and the Windows file system. It could be that there's an issue with the ways paths are represented vs Unix systems. I'll try to see if I can get my hands on a Windows machine to repro.
Sorry for the delay, I didn't get the chance to run the tests on a Windows machine. I'm glad that you could make it work but fixing code under pageObjects
is not future proof because it's auto-generated by the UTAM compiler.
There's definitely an issue with path resolution when working with Windows.
Out of curiosity, are the official JS UTAM recipes working for you?
No problem :)
Yes its working - the offical JS UTAM recipes.
But only in windows command line. On WSL it is not working due to chromedriver
Just adding my 2 cents on the issue:
The error Cannot use import statement outside a module
is a SyntaxError
. Indeed, the use of the import
keyword (which is part of the JS specification) is only allowed in the context of an ES Module. Using the import
keyword outside of that context is syntactically invalid. That error is actually thrown by node.js itself when trying to load a file.
Node.js uses some heuristics to determine the module system of a given file. There are a couple of things at play here:
First, we have to look at the root package.json
to see what the value of the type
property hold. If it's setup to commonjs
(or absent), node will use it's legacy CommonJS module format by default for the files that end up with the .js
file extension. That's the case for this project as we don't have a type
property in the package manifest.
Our tests, which have a .js
file extension, will be interpreted by node.js as being authored with the CommonJS module format.
Note: The commonJS module format isn't part of the JS specification and is using a
require
function that's actually backed into node.js.
So the error is actually what would node.js throw if we were to execute the file directly through it. However, there's a trick in that repo in the WDIO config. We register a helpers
script that will use Babel to transpile the content of the test file from ES Modules to CommonJS on the fly while running the test. So even if the test uses import it's actually being transpiled into a require call when passed to the node.js runtime.
My guess is that this helper doesn't resolve correctly on your system. Could you please provide the output of:
console.log(path.resolve(process.cwd(), 'wdioJasmineHelper.js'));
Just to double check if that's the issue you were having. I understood you solve the issue switching to require
calls but you shouldn't have to.
I tried to put the console log into wdioJasmineHelper._jasmineRegister() but nothing was printed out so I put it inside the tests and this is what I got, I think its ok?
I can successfully run tests with yarn test --spec force-app/test/record-create.spec.js
(https://github.com/salesforce/utam-js-recipes)
Yes that looks correct to me.
Can you try npm run test:ui --spec force-app/test/utam/page-explorer.spec.js
?
I would also just try to add a dummy console.log('something')
statement in the wdioJasmineHelper.js
file (in the top-level scope) and see if that prints when you start running the test.
Just adding that I see in the OP that @babel/register
is not loaded.
Instead of @wdio/config:utils: Found '@babel/register' package, auto-compiling files with Babel
it's showing @wdio/config:utils: Found 'ts-node' package, auto-compiling TypeScript files
.
Thanks @muenzpraeger! That's a good catch. It explains why babel doesn't transpile the files and hence why node.js interpret them as being ES Modules. @markocir do you have any changes in your local copy of the repository (such as typescript setup or dependencies)?
I did a quick investigation in the wdio
source code. The ts-node
message is very specific (see here).
After a quick test I can reproduce the error when adding ts-node
to the project (which confirms what @olivier-martin-sf mentioned).
Sorry for late reply.
@olivier-martin-sf No I have not changed anything.
This is the package.json:
{
"name": "ebikes-lwc",
"private": true,
"version": "1.0.0",
"description": "EBikes Sample App - Lightning Web Components",
"scripts": {
"lint": "eslint **/lwc/**/*.js",
"test": "npm run test:unit",
"test:unit": "sfdx-lwc-jest --skipApiVersionCheck",
"test:unit:watch": "sfdx-lwc-jest --watch --skipApiVersionCheck",
"test:unit:debug": "sfdx-lwc-jest --debug --skipApiVersionCheck",
"test:unit:coverage": "sfdx-lwc-jest --coverage --skipApiVersionCheck",
"test:ui": "wdio",
"test:ui:compile": "utam -c utam.config.js",
"test:ui:generate:login": "node scripts/generate-login-url.js",
"prettier": "prettier --write \"**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}\"",
"prettier:verify": "prettier --check \"**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}\"",
"postinstall": "husky install",
"precommit": "lint-staged"
},
"lint-staged": {
"**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}": [
"prettier --write"
],
"**/lwc/**/*.js": [
"eslint"
],
"**/lwc/**": [
"sfdx-lwc-jest --skipApiVersionCheck -- --bail --findRelatedTests --passWithNoTests"
]
},
"author": "salesforce.com",
"license": "CC0-1.0",
"repository": {
"type": "git",
"url": "git+https://github.com/trailheadapps/ebikes-lwc"
},
"devDependencies": {
"@babel/cli": "^7.19.3",
"@babel/core": "^7.20.2",
"@babel/preset-env": "^7.20.2",
"@babel/register": "^7.18.9",
"@lwc/eslint-plugin-lwc": "^1.5.0",
"@prettier/plugin-xml": "^2.2.0",
"@sa11y/jest": "^4.0.1",
"@salesforce/eslint-config-lwc": "^3.3.3",
"@salesforce/eslint-plugin-lightning": "^1.0.0",
"@salesforce/sfdx-lwc-jest": "^1.1.3",
"@wdio/cli": "^7.25.4",
"@wdio/jasmine-framework": "^7.25.4",
"@wdio/local-runner": "^7.25.4",
"@wdio/spec-reporter": "^7.25.4",
"chromedriver": "^107.0.3",
"dotenv": "^16.0.3",
"eslint": "^8.27.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jest": "^27.1.4",
"husky": "^8.0.1",
"lint-staged": "^13.0.3",
"prettier": "^2.7.1",
"prettier-plugin-apex": "^1.11.0",
"salesforce-pageobjects": "^2.2.0",
"utam": "^1.2.1",
"wdio-chromedriver-service": "^8.0.0",
"wdio-utam-service": "^1.2.1"
},
"workspaces": [
"./"
],
"volta": {
"node": "16.13.2",
"npm": "8.1.2"
}
}
How can I test from where ts-node is comming from? Nor bash or cmd recognize ts-node or typescript command.
npm explain ts-node
should give you some information about this!
I would try 2 things:
- First delete your
node_modules
folder and try to runnpm install && npm test:ui:compile
- Disable WDIO auto compile option by adding
autoCompileOpts: { autoCompile: false }
in theconfig
object that's exported bywdio.conf.js
Thank you everybody!
I discovered that I had node_module
in a
folder of folder structure: a/b/c/ebikes
When running npm explain ts-node
in ebikes
folder only ebikes/node_modules
folder is evaluated which in fact did not contain ts-node
module. When running npm explain ts-node
in c
folder ts-node
was detected.
So I just removed the a/node_modules
folder and reinstalled ebikes
and now it works.
Thanks again for your help!
Nice, thanks for sharing you investigations. We're glad that you were able to deploy.