I updated Cypress from 3.0.3
to 3.1.3
. Im using ES6 import/export modules which must be working related to docs. But Im getting a line with u
In case people are coming here for the message...
ParseError: 'import' and 'export' may appear only with 'sourceType: module'
... in a Cypress TypeScript project. Here is the answer:
Cypress does support TypeScript out of the box, as long as you have a tsconfig.json
file. However, imports don't work unless you preprocess your TypeScript files.
Here are the steps:
yarn add -D webpack
yarn add -D ts-loader
yarn add -D @cypress/webpack-preprocessor
Now, make sure you have these 3 files,tsconfig.json
, webpack.config.js
and plugins/index.js
on your Cypress folder.
plugins/index.js
:
const wp = require("@cypress/webpack-preprocessor");
module.exports = on => {
const options = {
webpackOptions: require("../webpack.config.js")
};
on("file:preprocessor", wp(options));
};
tsconfig.json
:
{
"compilerOptions": {
"strict": true,
"target": "es5",
"lib": ["es5", "dom"],
"types": ["cypress"]
},
"include": [
"**/*.ts"
]
}
webpack.config.js
:
module.exports = {
mode: 'development',
resolve: {
extensions: ['.ts', '.js']
},
module: {
rules: [
{
test: /\.ts$/,
exclude: [/node_modules/],
use: [
{
loader: 'ts-loader',
options: {
// skip typechecking for speed
transpileOnly: true
}
}
]
}
]
}
}
It should just work now.
When using @vue/cli you can simply do (which is commented in Cypress /plugins/index.js
):
const webpack = require('@cypress/webpack-preprocessor');
module.exports = (on, config) => {
on('file:preprocessor', webpack({
webpackOptions: require('@vue/cli-service/webpack.config'),
watchOptions: {},
}));
};
There is an official sample on github available at this address https://github.com/cypress-io/cypress-example-recipes/tree/master/examples/preprocessors__typescript-webpack
Note: if you are on windows and want to run localy the project, first update the path in the package.json.
// D:\path\cypress-example-recipes\examples\preprocessors__typescript-webpack\package.json
{
"name": "cypress-example-typescript-webpack",
"version": "1.0.0",
"description": "Example showing TypeScript tests with Cypress",
"scripts": {
// ...
"cypress:open": "..\\..\\node_modules\\.bin\\cypress open"
}
}
This error is caused by the presence of modern keywords like "import" and "export" when Cypress runs in the browser. Unlike Selenium or Protractor -- it actually runs inside the browser. Since browsers don't support modern JS yet, you'll need to use webpack or browserify to transpile your code.
https://docs.cypress.io/api/plugins/preprocessors-api.html#Examples
Here is a fantastic blog post on how to get Cypress to work with modern JS and Typescript using webpack: https://glebbahmutov.com/blog/use-typescript-with-cypress/
^^ The post is focused on TypeScript, but the configuration options for Javascript will be similar.
The following npm packages must be installed and in your package.json:
"@cypress/webpack-preprocessor": "^4.1.0",
"cypress": "^3.3.1",
"ts-loader": "^6.0.3",
"typescript": "^3.5.2",
"webpack": "^4.34.0"
Webpack should be installed using:
npm install --save-dev webpack typescript ts-loader
npm install --save-dev @cypress/webpack-preprocessor
The following should be present under the "compilerOptions" section of a file called tsconfig.json in your root directory, with "allowJs" set to true for non-typescript users:
"module": "es6",
"target": "es6",
"types": ["cypress"],
"allowJs": true
A file called "webpack.config.js" should be present in your root directory with the following:
const path = require('path')
module.exports = {
entry: './src/index.ts',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.tsx', '.ts', '.js']
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
}
And these exports should be present under cypress/plugins/index.js:
const webpack = require('@cypress/webpack-preprocessor')
module.exports = on => {
const options = {
// send in the options from your webpack.config.js, so it works the same
// as your app's code
webpackOptions: require('../../webpack.config'),
watchOptions: {}
}
on('file:preprocessor', webpack(options))
}
Note this final bit at the end of the Cypress plugins file,
on('file:preprocessor', webpack(options))
That is where Cypress is told to process your modern JS code in such a way as to make it Cypress-runnable.
I solved it, in my root folder was a babel.config.js
file which possibly overrode Cypress configs. After I deleted it, everything is working. ¯\_(ツ)_/¯
Update:
Maybe the magic was readd the babel.config.js
with this content based on this issue: https://github.com/cypress-io/cypress/issues/2945
module.exports = process.env.CYPRESS_ENV
? {}
: { presets: ['@vue/babel-preset-app'] }