Add Cypress and Cucumber to your Angular project
Posted on: 22-2-2024
To add Cypress 13 to your Angular 17 project and use Cucumber to write feature files you have to follow the following steps.
- Add Cypress
- Add dependencies
- Extend Cypress config
- Add section to package.json
- Write feature files
- Write step definitions
- Run test
1. Add Cypress
Use the Angular CLI to automatically add cypress to your project by running the following command.ng e2e
If you run this command for the first time you get asked to choose between different packages that offer e2e capabilities.
Choose Cypress and select all the default options during setup. This will add cypress and makes it possible to run e2e tests and component tests.
Now you can run the created default test by running
ng e2e
and using the cypress UI.
OR
don't use the Angular CLI and add cypress manually.
npm install cypress --save-dev
Create a tsconfig.json inside the cypress folder and give it the following content:
{
"compilerOptions": {
"target": "es5",
"lib": ["es5", "dom"],
"types": ["cypress", "node"]
},
"include": ["**/*.ts"]
}
You can run cypress using the following command:
npx cypress open
(make sure your application is running before running this command).
Now that cypress works, let's add the cucumber preprocessor to make it possible to write feature files in the Gherkin DSL.
2. Add dependencies
Add the Cucumber preprocessor by installing it using a package manager.npm install --save-dev @badeball/cypress-cucumber-preprocessor
Also add the following dependency:
npm install --save-dev @bahmutov/cypress-esbuild-preprocessor
3. Extend Cypress config
We have got to extend our Cypress config to make sure the Cucumber preprocessor and Cypress can work together.Add the following key-value pair to your config to make sure future .feature files get found when running cypress:
specPattern: '**/*.feature',
Add the following snippet to your config to add the Cucumber preprocessor and make sure it works together with Cypress:
async setupNodeEvents(
on: Cypress.PluginEvents,
config: Cypress.PluginConfigOptions
): Promise<Cypress.PluginConfigOptions> {
await addCucumberPreprocessorPlugin(on, config);
on(
"file:preprocessor",
createBundler({
plugins: [createEsbuildPlugin(config)],
})
);
// Make sure to return the config object as it might have been modified by the plugin.
return config;
}
This is what your cypress.config file should look like:
import { defineConfig } from 'cypress'
import {addCucumberPreprocessorPlugin} from "@badeball/cypress-cucumber-preprocessor";
import createBundler from "@bahmutov/cypress-esbuild-preprocessor";
import { createEsbuildPlugin } from "@badeball/cypress-cucumber-preprocessor/esbuild";
export default defineConfig({
e2e: {
specPattern: '**/*.feature',
baseUrl: 'http://localhost:4200',
async setupNodeEvents(
on: Cypress.PluginEvents,
config: Cypress.PluginConfigOptions
): Promise<Cypress.PluginConfigOptions> {
await addCucumberPreprocessorPlugin(on, config);
on(
"file:preprocessor",
createBundler({
plugins: [createEsbuildPlugin(config)],
})
);
// Make sure to return the config object as it might have been modified by the plugin.
return config;
}
},
component: {
devServer: {
framework: 'angular',
bundler: 'webpack',
},
}
})
4. Add section to package.json
Add the following to your package.json so your step definitions can get found:"cypress-cucumber-preprocessor": {
"stepDefinitions": [
"cypress/support/step_definitions/**/*.{js,ts}"
]
}
5. Write feature files
Write a feature file and place it in cypress/e2e/features.Feature: App
Scenario: some scenario
Given some given
When some when
Then some then
6. Write step definitions
Write step definitions for the steps you created in your feature file.Create a folder called cypress/support/step_definitions. This is where your step definitions will live.
Note that this folder needs to have the same name as the one provided in package.json.
Create a file and give it a name, e.g. app.ts and give it the following content:
import {Given, Then, When} from "@badeball/cypress-cucumber-preprocessor";
Given('some given', () => {
cy.visit('/');
});
When('some when', () => {
cy.contains('congratulations');
});
Then('some then', () => {
cy.contains('app is running');
});
7. Run test
Runng e2e
again to run your tests and see that the feature files work!