16

I cannot configure angular-cli + scss + karma to test my components together. Running ng test the kamra unit tests are only including the components' own scss styles.

In order to apply my main styles.scss in tests, I've tried to configure them in karma.conf.js:

files: [ 
  { pattern: './src/test.ts', watched: false },
  { pattern: './src/styles.scss' },   // main scss
  { pattern: './src/test.css' },      // just some test css to see if it is working
]
preprocessors: {
  './src/test.ts': ['@angular/cli'],
  './src/styles.scss': [ '@angular/cli' ]
}

Main scss is still not included during karma tests. But the components own scss and the global css are applied.

How can I make it work?

István Békési
  • 993
  • 4
  • 16
  • 27

5 Answers5

29

NO NPM PACKAGE: Angular Way

Add files in the angular.json-file within the stylePreprocessorOptions-property.

projects.your-project-name.architect.build.options and projects.your-project-name.architect.test.options should be the same:

{
  "projects": {
    "your-project-name": {
      "architect": {

        "build": {
          "options": {
            "stylePreprocessorOptions": {
              "includePaths": [
                "./src/styles"
              ]
            },
            ...
          },
          ...
        },

        "test": {
          "options": {
            "stylePreprocessorOptions": {
              "includePaths": [
                "./src/styles"
              ]
            },
            ...
          },
          ...
        },

        ...

      },
      ...
    },
    ...
  },
  ...
}

@istibekesi, Angular framework has an angular.json configuration file in which you can add your style paths, so it will be included into the Karma/test build. Therefore it is not needed to install the karma-scss-preprocessor.

I was running into the same problem when importing my variables.scss into the stylesheets of my components (@import 'variables').

Brampage
  • 6,014
  • 4
  • 33
  • 47
17

Summary

Angular CLI supports all major CSS preprocessors, including sass/scss. Simply generate the project like this and almost everything will work:

ng new sassy-project --style=sass

However, if Karma is also involved, during tests the global scss files are not included. It seems an additional prepocessor is required for karma to process these scss files.

It was very confusing for me, but note there are two similar preprocessors out there. I do not recommend 'karma-sass-preprocessor', it is still available via npm, but the project seems to be deprecated. Use 'karma-scss-preprocessor' instead (karma-scss-preprocessor)

Installation

npm install karma-scss-preprocessor node-sass --save-dev

If you installed karma-sass-prepocessor before, first uninstall it by removing from package.json

Configuration

karma.conf.js

module.exports = function (config) {
  config.set({

    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage-istanbul-reporter'),
      require('@angular/cli/plugins/karma'),
      require('karma-scss-preprocessor')
    ],

    files: [
      { pattern: './src/test.ts', watched: false },
      { pattern: './src/dummy.scss', watched: true,  included: true, served: true },
      { pattern: './src/styles.scss', watched: true,  included: true, served: true }
    ],
    preprocessors: {
      './src/test.ts': ['@angular/cli'],
      './src/dummy.scss': ['scss'],
      './src/styles.scss': ['scss']
    },

  });
};
István Békési
  • 993
  • 4
  • 16
  • 27
  • 2
    Note that if you are doing imports using `~` instead of `node_modules` you need to add the `node-sass-tilde-importer` library. – joshhunt Sep 03 '17 at 23:47
  • 1
    @GiftZwergrapper pretty sure I got it working. Make a question and I'll post my karma config – joshhunt Sep 13 '17 at 22:12
  • @joshhunt Apparently for me it can't find that ~@angular/material/_theming.scss I tried with the node-sass-tilde-importer, but it didn't work either – Deunz Dec 13 '17 at 09:37
  • 1
    @Deunz currently I'm using `@import '~@angular/material/theming';` which seems to work. Try removing the underscore? – joshhunt Dec 13 '17 at 22:15
  • Solved it by putting in karma config into files sections : ,{ pattern: './node_modules/@angular/material/prebuilt-themes/indigo-pink.css', included: true, watched: false } – Deunz Dec 15 '17 at 16:12
  • Thanks István and Josh Hunt (~clue) I've now got my global styles loading in Karma and angular 12 :-) btw had to npm install node-sass@5.0.0 aswell (latest version - 6+ - was not compatible). Surprised that styling in test mode for karma not configurable through angular.json. – Kieran Ryan Aug 08 '21 at 13:25
2

The configuration of scss in karma is done as following:

module.exports = function(config) {
  config.set({
    files: [
      {
        pattern: 'scss/**/*.scss',
        watched: true,
        included: false,
        served: true
      },
      'test/unit-sass.css'
    ],
    preprocessors: {
      'scss/**/*.scss': ['sass']
    },
    sassPreprocessor: {
      source: 'scss/*.scss',
      createSourceMaps: true,
      outputDir:  __dirname + '/test/',
      outputFile: 'unit-sass.css'
    }    
  });
};

  • The easiest way is to keep karma-sass-preprocessor as a devDependency in your package.json.

    { "devDependencies": { "karma": "~0.10", "karma-sass-preprocessor": "~0.0.1" } }

  • You can simple do it by:

    npm install karma-sass-preprocessor --save-dev

However sass-preprocessor isn't worth the time and really isn't best practice as the code in the question should work already, which will be explained below.


So at the end of the discussion in the chat we finally found out what was missing, which was quite silly:

require('karma-scss-preprocessor')

This was missing in the code itself and he finally managed to solve the problem! Hope it might help out any future users that look at this answer :)

King Reload
  • 2,780
  • 1
  • 17
  • 42
  • What is the difference between `'karma-sass-preprocessor'` and `'karma-scss-preprocessor'`? (Actually... both fails to install) – István Békési Jun 12 '17 at 09:09
  • `karma-sass-preprocessor`: Preprocessor to watch sass files changes and build css on the fly. `karma-scss-preprocessor`: Karma preprocessor to compile Sass files on the fly with node-sass. In contrast of karma-sass-preprocessor, it does not write any intermediate file to the disk, and does not use any Gulp plugin. – King Reload Jun 12 '17 at 09:12
  • what do you mean with `both fails to install`? you mean that you can't install them or that the solution didn't help out? because I would like to see the updated error or what goes wrong in the script, as this solution should work. – King Reload Jun 12 '17 at 09:15
  • karma-sass-preprocessor: faield to download a deprecated dependency of node-sass@2.1.1 – István Békési Jun 12 '17 at 09:17
  • karma-scss-prepocessor: failed to support node-sass@4.0.0 https://github.com/amercier/karma-scss-preprocessor/issues/62 – István Békési Jun 12 '17 at 09:19
  • you might want to look here: https://github.com/AngularClass/angular-starter/issues/582 for more information of how to make `karma` work with `sass`. – King Reload Jun 12 '17 at 09:21
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/146398/discussion-between-king-reload-and-istibekesi). – King Reload Jun 12 '17 at 09:21
1

Angular CLI already uses node-sass if you configure it to use sass. So there is no need to install it again:

npm install karma-scss-preprocessor --save-dev

should be sufficient. Plus you don't have multiple versions of node-sass in your project.

The rest of the solution of @istibekesi works like charm.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Friedrich
  • 1,292
  • 1
  • 18
  • 26
  • @theMayer: you are right, but at the time of writing I hadn't enough reputation to "comment everywhere". So this was the only option to provide that information. – Friedrich May 04 '18 at 05:38
-1

If you use Bootstrap-sass, You should describe karma.conf.js

preprocessors : {
  './src/test.ts': [ '@angular/cli' ],
  './node_modules/bootstrap-sass/assets/stylesheets/_bootstrap.scss': [ 'scss' ],
  './src/*.scss': [ 'scss' ]
},

It is important write order that bootstrap is faster than your file.

mitsu
  • 1
  • 2