{
  "doc": {
    "id": "app/component-testing/angular/overview",
    "title": "Angular component testing",
    "description": "Learn how to set up component tests in Angular and configure Cypress for Angular projects.",
    "section": "app",
    "source_path": "/llm/markdown/app/component-testing/angular/overview.md",
    "version": "fbc9225067c51c52ee13224e3b702cf8a025ec12",
    "updated_at": "2026-08-14T12:36:26.878Z",
    "headings": [
      {
        "id": "app/component-testing/angular/overview#angular-component-testing",
        "text": "Angular Component Testing",
        "level": 1
      },
      {
        "id": "app/component-testing/angular/overview#framework-support",
        "text": "Framework Support",
        "level": 2
      },
      {
        "id": "app/component-testing/angular/overview#tutorial",
        "text": "Tutorial",
        "level": 2
      },
      {
        "id": "app/component-testing/angular/overview#installation",
        "text": "Installation",
        "level": 2
      },
      {
        "id": "app/component-testing/angular/overview#framework-configuration",
        "text": "Framework Configuration",
        "level": 2
      },
      {
        "id": "app/component-testing/angular/overview#angular-cli-configuration",
        "text": "Angular CLI Configuration",
        "level": 3
      },
      {
        "id": "app/component-testing/angular/overview#options-api",
        "text": "Options API",
        "level": 4
      },
      {
        "id": "app/component-testing/angular/overview#sample-angular-apps",
        "text": "Sample Angular Apps",
        "level": 4
      },
      {
        "id": "app/component-testing/angular/overview#styling",
        "text": "Styling",
        "level": 2
      },
      {
        "id": "app/component-testing/angular/overview#sass-use-import-cant-find-a-stylesheet",
        "text": "Sass @use / @import can't find a stylesheet",
        "level": 3
      },
      {
        "id": "app/component-testing/angular/overview#tailwind-css-v4-utility-classes-arent-applied",
        "text": "Tailwind CSS v4 utility classes aren't applied",
        "level": 3
      },
      {
        "id": "app/component-testing/angular/overview#see-also",
        "text": "See also",
        "level": 2
      }
    ]
  },
  "content": {
    "type": "root",
    "children": [
      {
        "type": "heading",
        "depth": 1,
        "children": [
          {
            "type": "text",
            "value": "Angular Component Testing"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "What you'll learn"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "How to set up component tests in Angular"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "How to configure Cypress for Angular projects"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Framework Support"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress Component Testing supports Angular `^18.0.0`, `^19.0.0`, `^20.0.0`, and `^21.0.0`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Our testing harness, `cypress/angular`, still requires `zone.js` and `@angular-devkit/build-angular` to be installed in your project, even if your project is zoneless or is built with `@angular/build`. If you wish to use the zoneless configuration, which is the default in Angular 21, you can use `cypress/angular-zoneless` testing harness instead as of Cypress `15.8.0`."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Tutorial"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Visit the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/component-testing/get-started.md",
            "children": [
              {
                "type": "text",
                "value": "Getting Started Guide"
              }
            ]
          },
          {
            "type": "text",
            "value": " for a step-by-step tutorial on adding component testing to any project and how to write your first tests."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Installation"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To get up and running with Cypress Component Testing in Angular, install Cypress into your project:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "npm"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Yarn"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "pnpm"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Bun"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "npm install cypress --save-dev"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "yarn add cypress --dev"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "pnpm add --save-dev cypress"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "bun add --dev cypress"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Open Cypress:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "npm"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Yarn"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "pnpm"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Bun"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "npx cypress open"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "yarn cypress open"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "pnpm cypress open"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "bunx cypress open"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Choose Component Testing"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The Cypress App will guide you through configuring your project."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For a step-by-step guide on how to create a component test, refer to the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/component-testing/get-started.md",
            "children": [
              {
                "type": "text",
                "value": "Getting Started"
              }
            ]
          },
          {
            "type": "text",
            "value": " guide."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For usage and examples, visit the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/component-testing/angular/examples.md",
            "children": [
              {
                "type": "text",
                "value": "Angular Examples"
              }
            ]
          },
          {
            "type": "text",
            "value": " guide."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Framework Configuration"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress Component Testing works out of the box with `@angular/cli` projects. Cypress will automatically detect your project is Angular during setup and configure it properly."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For a full explanation of how the dev server and bundler work — including automatic config detection and override options — see "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/component-testing/component-framework-configuration.md#Dev-Server-and-Bundler",
            "children": [
              {
                "type": "text",
                "value": "Component Testing Configuration — Dev Server and Bundler"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The examples below are for quick reference."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Angular CLI Configuration"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "cypress.config.js"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "cypress.config.ts"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "const { defineConfig } = require('cypress')module.exports = defineConfig({  component: {    devServer: {      framework: 'angular',      bundler: 'webpack',    },    specPattern: '**/*.cy.ts',  },})"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "import { defineConfig } from 'cypress'export default defineConfig({  component: {    devServer: {      framework: 'angular',      bundler: 'webpack',    },    specPattern: '**/*.cy.ts',  },})"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Options API"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You can also use the `options` API to provide your own project specific configuration to your `devServer`. The `devServer` configuration receives an `options` property:"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "import { defineConfig } from 'cypress'export default {  component: {    devServer: {      framework: 'angular',      bundler: 'webpack',      options: {        projectConfig: {          root: '',          sourceRoot: 'apps/my-app',          buildOptions: {            outputPath: 'dist/my-app',            index: 'apps/my-app/src/index.html',            main: 'apps/my-app/src/main.ts',            polyfills: 'apps/my-app/src/polyfills.ts',            tsConfig: 'apps/my-app/tsconfig.app.json',            inlineStyleLanguage: 'scss',            assets: ['apps/my-app/src/favicon.ico', 'apps/my-app/src/assets'],            styles: ['apps/my-app/src/styles.scss'],            scripts: [],            buildOptimizer: false,            optimization: false,            vendorChunk: true,            extractLicenses: false,            sourceMap: true,            namedChunks: true,          },        },      },    },  },}"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Sample Angular Apps"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://github.com/cypress-io/cypress-component-testing-apps/tree/main/angular-standalone",
                    "children": [
                      {
                        "type": "text",
                        "value": "Angular 20 Standalone"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://github.com/cypress-io/cypress-component-testing-apps/tree/main/angular-zoneless",
                    "children": [
                      {
                        "type": "text",
                        "value": "Angular 21 Zoneless"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Styling"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress builds your component specs with the Angular build pipeline. When you do not provide an `options.projectConfig`, Cypress reads the build options (including `assets`, `styles`, and `stylePreprocessorOptions`) from the default application project in your `angular.json`. When you do provide your own "
          },
          {
            "type": "link",
            "title": null,
            "url": "#Options-API",
            "children": [
              {
                "type": "text",
                "value": "`projectConfig`"
              }
            ]
          },
          {
            "type": "text",
            "value": ", it replaces the configuration Cypress detects from `angular.json`, so any build options your styles rely on must be repeated in your `buildOptions`. The two issues below are usually a result of this."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Sass `@use` / `@import` can't find a stylesheet"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If your Sass resolves imports through paths configured in `angular.json` under `stylePreprocessorOptions.includePaths`, you may see an error during component testing like:"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "❌ Can't find stylesheet to import.@use 'mixins'"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This happens when a custom `projectConfig` omits those include paths. Add the same `stylePreprocessorOptions` to your `buildOptions` so the Sass compiler can resolve the imports:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "cypress.config.js"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "cypress.config.ts"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "const { defineConfig } = require('cypress')module.exports = defineConfig({  component: {    devServer: {      framework: 'angular',      bundler: 'webpack',      options: {        projectConfig: {          root: '',          sourceRoot: 'src',          buildOptions: {            styles: ['src/styles.scss'],            stylePreprocessorOptions: {              includePaths: ['src/styles'],            },          },        },      },    },    specPattern: '**/*.cy.ts',  },})"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "import { defineConfig } from 'cypress'export default defineConfig({  component: {    devServer: {      framework: 'angular',      bundler: 'webpack',      options: {        projectConfig: {          root: '',          sourceRoot: 'src',          buildOptions: {            styles: ['src/styles.scss'],            stylePreprocessorOptions: {              includePaths: ['src/styles'],            },          },        },      },    },    specPattern: '**/*.cy.ts',  },})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Tailwind CSS v4 utility classes aren't applied"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "With Tailwind CSS v4, you may find that your own styles load correctly but Tailwind utility classes such as `bg-red-500` have no effect. The class is present on the element in the DevTools inspector, but no rule is generated for it. This is because Tailwind v4 generates utilities through its own build plugin, which is not part of the Angular build pipeline Cypress uses to compile your `styles`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "A reliable workaround is to precompile your Tailwind stylesheet into a plain CSS file with the "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://tailwindcss.com/docs/installation/tailwind-cli",
            "children": [
              {
                "type": "text",
                "value": "Tailwind CLI"
              }
            ]
          },
          {
            "type": "text",
            "value": " and load that compiled file through `buildOptions.styles`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Install the CLI:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "npm"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "yarn"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "pnpm"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "bun"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "npm install -D @tailwindcss/cli"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "yarn add -D @tailwindcss/cli"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "pnpm add -D @tailwindcss/cli"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "bun add -d @tailwindcss/cli"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Compile your stylesheet before opening or running Cypress, then point `buildOptions.styles` at the compiled output:"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "{  \"scripts\": {    \"build:ct-styles\": \"npx @tailwindcss/cli -i ./src/styles.scss -o ./cypress/support/compiled-styles.css\",    \"cypress:open\": \"npm run build:ct-styles && cypress open --component\",    \"cypress:run\": \"npm run build:ct-styles && cypress run --component\"  }}"
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "cypress.config.js"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "cypress.config.ts"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "const { defineConfig } = require('cypress')module.exports = defineConfig({  component: {    devServer: {      framework: 'angular',      bundler: 'webpack',      options: {        projectConfig: {          buildOptions: {            styles: ['cypress/support/compiled-styles.css'],          },        },      },    },    specPattern: '**/*.cy.ts',  },})"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "import { defineConfig } from 'cypress'export default defineConfig({  component: {    devServer: {      framework: 'angular',      bundler: 'webpack',      options: {        projectConfig: {          buildOptions: {            styles: ['cypress/support/compiled-styles.css'],          },        },      },    },    specPattern: '**/*.cy.ts',  },})"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "See also"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/tooling/code-coverage.md#component-testing-code-coverage",
                    "children": [
                      {
                        "type": "text",
                        "value": "Component Testing code coverage"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  "token_estimate": 1252
}