How to compile Cypress e2e tests/files using Vite? - vue.js

By default, Cypress compiles e2e tests with a built-in webpack config, which used to be fine because Vue-CLI also used Webpack; however, now that I've upgraded to Vue 3 and Vite, no webpack.
I have two options:
Revive the old webpack config for my Vue 2 project and update it for Vue 3 just to run Cypress' e2e tests.
Figure out how to tell Cypress to compile the app with Vite and not Webpack
I can't figure out #2, and I don't want to do #1 because having two different compilation methods sounds like a really bad future headache.
So far, I have this for my Cypress config:
import { devServer } from '#cypress/vite-dev-server'
import { defineConfig } from 'cypress'
import * as path from 'path'
export default defineConfig({
chromeWebSecurity: false,
projectId: '5kusbh',
requestTimeout: 10000,
responseTimeout: 60000,
viewportHeight: 1080,
viewportWidth: 1920,
e2e: {
baseUrl: 'http://localhost:8080',
setupNodeEvents (on, config) {
on('dev-server:start', (options) => {
return devServer({
...options,
viteConfig: {
configFile: path.resolve(__dirname, 'vite.config.ts'),
},
})
})
return config
},
specPattern: 'cypress/e2e/**/**.spec.js',
},
})
However, when I run Cypress, I get a webpack compilation error, which is telling me Vite is not compiling the application for Cypress.
Note Otherwise, my application is working great - I just can't run Cypress, and we have hundreds of unit, integration, and e2e tests written in Cypress.
TL;DR; I need help configuring Cypress to use my app's Vite config to compile its e2e tests and run it's dev server.
EDIT:
I removed my config to see how it'd run just hitting localhost, but Cypress must be trying to compile my code, because it's struggling with the Vite env variable syntax, import.meta.env.[insert key name here] in non-Cypress JavaScript files because it's not process.env...

For e2e tests, the execution of tests is separate from running the app and you access the app using cy.visit(). #cypress/vite-dev-server was for running component tests prior to cypress 10. But with cypress-vite you can also compile e2e tests using vite and use the same configuration as your app, so you don't need to config the webpack anymore.

Related

Cannot configure Jest for WebStorm/IntelliJ

I have installed Jest using npm :
npm i jest --save-dev
At the package level I also have a Jest config file: jest.config.js which is very simple and just contains :
const config = {
verbose: true,
};
module.exports = config;
However if I look at a test that I wrote, the expect() cannot be compiled :
On closer inspection WebStorm/IntelliJ thinks that describe() and it() belong to mocha, and not jest.
How do I point IntelliJ/WebStorm to jest and not to mocha? I can't seem to find anything in the settings.

BDD with Cypress & Vite (Vue 3) & Cucumber

I've currently managed to implement Cucumber BDD tests within a Vitejs + Vue 3 as follows:
I start and run the development server with:
$ yarn dev
And then in a separate window I run the Cypress test runner:
$ yarn cy:run
Which corresponds to:
...,
"scripts": {
...
"cy:run": "cypress run -q",
...
},
...
In my package.json. The output of this, is 1 test passing.
So far, so good. I then came across the #cypress/vite-dev-server package, and implemented it with the cucumber preprocessor inside /cypress/plugins/index.ts as follows:
/// <reference types="cypress" />
const path = require('path')
const { startDevServer } = require('#cypress/vite-dev-server')
const browserify = require('#cypress/browserify-preprocessor')
const cucumber = require('cypress-cucumber-preprocessor').default
/**
* #type {Cypress.PluginConfig}
*/
module.exports = (on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) => {
on('dev-server:start', options => {
return startDevServer({
options,
viteConfig: {
configFile: path.resolve(__dirname, '..', '..', 'vite.config.ts')
}
})
})
const cucumberOptions = {
...browserify.defaultOptions,
typescript: require.resolve('typescript')
}
on('file:preprocessor', cucumber(cucumberOptions))
return config
}
So, it looks like the #cypress/vite-dev-server package doesn't accept what I am trying to do with Cypress & Cucumber.
Has anyone managed to get Cypress & Cucumber BDD working with Vite in a seamless fashion?
I've also looked at the wait-on module, running the following:
yarn dev & wait-on http://localhost:8099
But it doesn't seem to be waiting, only the Vite server runs? So I can't then run the cypress command I need ...
The #cypress/vite-dev-server is for component testing, not e2e testing. The cypress-cucumber-preprocessor on the other hand is for compiling e2e specs.
In e2e testing, the app runs independently from tests, so you can use vite for running the dev server, but it has nothing to do with tests. If you want to use vite config for compiling tests you can use cypress-vite instead of cypress-cucumber-preprocessor.

Global node-config variable undefined when testing with Jest

I am implementing Option 2 from the node-config docs.
This runs fine, and my global config variable is defined when running outside of a test environment.
However, when I run this with vue-cli and Jest unit testing (e.g. vue-cli-service test:unit), I get this error:
● Test suite failed to run
ReferenceError: APP_CONFIG is not defined
// vue.config.js
...
configureWebpack: {
plugins: [
new ConfigWebpackPlugin('APP_CONFIG')
]
},
...
What is a good way around this? Is it because Jest starts executing the JS files before the node-config can finish switching out all global variables with their values?
Jest does not run Webpack, so you would have to manually setup the config for your tests. As a workaround, you could declare the config as a Jest global.
To declare the global, add the globals property to the exported object in jest.config.js. The sub-property key would be the config-webpack's namespace (APP_CONFIG in your case), and the value would be the required config JSON files from config/:
// jest.config.js
module.exports = {
globals: {
APP_CONFIG: require('./config/default.json')
}
}

How to disable webpack minification for classes names

I use jasmine, karma and webpack to test my module. The webpack preprocesses my tests files before initiating tests.
In my tests I have the class Name{...} to be tested. I create new Name instance and then, in my tests I expect(myInstance.constructor.name).toBe("Name")
class Name{}
const myInstance = new Name();
describe("The object",function(){
it("should be the instance of Name class",function(){
expect(myInstance.constructor.name).toBe("Name"); // Expected 't' to be 'Name'.
})
});
But it returns failed tests. I figured out that my Name class is parsed by webpack to the t class in the bundled file and myInstance.constructor.name equals "t".
Can I prevent webpack to change the names of classes/constructors?
Have a build setup for development and production separately, whenever in development mode(which you can mention in the webpack config object), don't apply minification plugin(might be there in your webpack config).
Help links:
Bundling Modes
Minification pluin
You can use 'keep_classnames' option provided by the minification plugin to keep the class names intact.
Install Terser Plugin to customize Webpack optimization > minimizer options running:
npm i -D terser-webpack-plugin
...or in the case you use yarn:
yarn add -D terser-webpack-plugin
Then add this optimization option inside webpack.config.js:
module.exports = {
mode: ...,
resolve: ...,
target: ...,
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
keep_classnames: true,
},
}),
],
},
};

How can I add a custom reporter to Jasmine through karma?

I'm trying to call jasmine-fail-fast through karma. I have karma-jasmine installed.
[https://www.npmjs.com/package/jasmine-fail-fast][1]
All jasmine custom reporters appear to have a configuration like the one below to add it.
var failFast = require('jasmine-fail-fast');
jasmine.getEnv().addReporter(failFast.init());
The problem is that this does not work in my karma.conf:
module.exports = function(options) {
jasmine.getEnv().addReporter(failFast.init());
config.set({...});
};
The karma.conf file does not give me access to jasmine or window.jasmine through module.exports
The karma config itself can give a require in jasmine-fail-fast for me if I add it as a plugin:
plugins: ['karma-firefox-launcher', 'karma-jasmine', 'jasmine-fail-fast'],
But unfortunately it never calls the init():
jasmine.getEnv().addReporter(failFast.init());
Does anyone know how the hell I can add this reporter to jasmine with karma?
[1]: jasmine-fail-fast Causes Jasmine to stop after failing the first test