Home

Awesome

cypress-angular-unit-test

npm version renovate-app badge cypress version ci status cypress-angular-unit-test

Installation

npm install -D cypress cypress-angular-unit-test

Add to your support file

// cypress/support/index.js
// core-js 3.*
require('core-js/es/reflect');
// core-js 2.*
require('core-js/es7/reflect');
require('cypress-angular-unit-test/support');

Webpack config

Create a new file webpack.config.ts in cypress/plugins folder. You can find the file content here :

Cypress >= v7

npm install -D @cypress/webpack-dev-server html-webpack-plugin

Enable component testing in cypress.json.

{
  "component": {
    "componentFolder": "src/app",
    "testFiles": "**/*cy-spec.ts"
  }
}

Configure cypress/plugins/index.js to transpile Angular code.

const webpackConfig = require('./webpack.config');
const { startDevServer } = require('@cypress/webpack-dev-server');

module.exports = (on, config) => {
  on('dev-server:start', (options) =>
    startDevServer({
      options,
      webpackConfig,
    }),
  );
  return config;
};

Run npx cypress open-ct

Cypress < v7

npm install -D @cypress/webpack-preprocessor

Enable experimental component testing mode in cypress.json and point at the spec files. Usually they are alongside your application files in src folder.

{
  "experimentalComponentTesting": true,
  "componentFolder": "src",
  "testFiles": "**/*cy-spec.*"
}

Configure cypress/plugins/index.js to transpile Angular code.

const wp = require('@cypress/webpack-preprocessor');
const webpackConfig = require('./webpack.config');
module.exports = (on, config) => {
  const options = {
    webpackConfig,
  };
  on('file:preprocessor', wp(options));
  return config;
};

Run npx cypress open

Use

import { mount } from 'cypress-angular-unit-test';
import { AppComponent } from './app.component';

describe('AppComponent', () => {
  it('shows the input', () => {
    // Init Angular stuff
    initEnv(AppComponent);
    // You can also :
    // initEnv({declarations: [AppComponent]});
    // initEnv({imports: [MyModule]});

    // component + any inputs object
    mount(AppComponent, { title: 'World' });
    // use any Cypress command afterwards
    cy.contains('Welcome to World!');
  });
});

Demo

Examples

Use caseDescription
InputTest inject @Input() value
OutputTest catching @Output()
BootstrapBootstrap integration with style : setConfig({ stylesheet: 'https://...});
Add styleAdd custom style for testing : setConfig({ style: 'p {background-color: blue;}' });
HTML mountMount a component with html, don't forget to call detectChanges() after
Image SnapshotMount a component and visual asserting
MaterialMaterial integration
Prime NGPrimeNG integration
OnPush strategyComponent with changeDetection: ChangeDetectionStrategy.OnPush need call detectChanges()
DirectiveTest directive with mountHtml
PipeTest pipe with mountHtml
Stub serviceStub a service with Observable
Only serviceTest a service without a component
Web ComponentTest a custom element with shadow dom
Assetsassets folder accessible by Cypress
AsyncAsync test with cy.tick
RoutingTest routing link
NetworkTest with http calls
NGRXNGRX store

Code coverage

Integration test

npm i -D ngx-build-plus

module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|ts)$/,
        loader: 'istanbul-instrumenter-loader',
        options: { esModules: true },
        enforce: 'post',
        include: require('path').join(__dirname, '..', 'src'),
        exclude: [
          /\.(e2e|spec)\.ts$/,
          /node_modules/,
          /(ngfactory|ngstyle)\.js/,
        ],
      },
    ],
  },
};
"serve": {
  "builder": "ngx-build-plus:dev-server",
  "options": {
    "browserTarget": "cypress-angular-coverage-example:build",
    "extraWebpackConfig": "./cypress/coverage.webpack.js"
  },
}

npm i -D istanbul-instrumenter-loader

npm install -D @cypress/code-coverage

// cypress/support/index.js
import '@cypress/code-coverage/support';
// cypress/plugins/index.js
module.exports = (on, config) => {
  require('@cypress/code-coverage/task')(on, config);
  return config;
};

source : https://github.com/skylock/cypress-angular-coverage-example

Unit test

npm i -D istanbul-instrumenter-loader

rules: [
  {
    test: /\.(js|ts)$/,
    loader: 'istanbul-instrumenter-loader',
    options: { esModules: true },
    enforce: 'post',
    include: path.join(__dirname, '../..', 'src'),
    exclude: [/\.(e2e|spec)\.ts$/, /node_modules/, /(ngfactory|ngstyle)\.js/],
  },
];

Report

You can find the HTML report at coverage/lcov-report/index.html

Working

I have successfully used this mounting approach to test components in other frameworks.

Debugging

You can turn on debugging log by setting environment variable :

// Unix
export DEBUG="cypress-angular-unit-test,cypress:webpack:stats"

// PowerShell
$env:DEBUG="cypress-angular-unit-test,cypress:webpack:stats"

Development

This project only transpiles the library, to see it in action:

Pick any component test spec file to run