angular / components

Component infrastructure and Material Design components for Angular
https://material.angular.io
MIT License
24.24k stars 6.7k forks source link

A "Testing with Material Components" guide to demonstrate including core theme in test suite #4056

Open willshowell opened 7 years ago

willshowell commented 7 years ago

Bug, feature request, or proposal:

Bug or missing docs

What is the expected behavior?

Tests shouldn't log warnings after following the Getting Started guide on a fresh cli generated app.

Current behavior / steps to reproduce

  1. Fresh cli app
  2. Follow the getting started guide
  3. Add an md-card component to AppComponent
  4. Run unit tests
  5. Resulting warning:
WARN: 'Could not find Angular Material core theme. Most Material components may not work as expected. For more info refer to the theming guide: https://material.angular.io/guide/theming'
Chrome 57.0.2987 (Mac OS X 10.12.4): Executed 0 of 3 SUCCESS (0 secs / 0 secs)
Chrome 57.0.2987 (Mac OS X 10.12.4): Executed 3 of 3 SUCCESS (0.226 secs / 0.199 secs)

Is there anything else we should know?

Modifying karma.conf.js to include a theme silenced the warning. This approach was borrowed from Material's karma config:

files: [
  { pattern: './src/test.ts', watched: false },
  { pattern: './node_modules/@angular/material/prebuilt-themes/indigo-pink.css' }
],
ChenReuven commented 7 years ago

@willshowell i have the same issue, i am with angular 4 and the newset beta 3 of angular material with a custom theme

kuncevic commented 7 years ago

I am using the custom theme with ng v4, material beta.3 and all good. Got my custom theme in file assets/theme.scss:

@import '~@angular/material/_theming';
@import './my-palette.scss';
@include mat-core();
$primary: mat-palette($mat-saphire, 500);
$accent:  mat-palette($mat-saphire, A100);
$warn:    mat-palette($mat-orange, A200);
$theme: mat-light-theme($primary, $accent, $warn);
@include angular-material-theme($theme);

Importing that in file styles.scss: (if you using rebuild just import that instead)

@import '/assets/theme';

As I am using Angular CLI then in .angular-cli.json just doing so:

 "styles": [
        "styles.scss"
      ], 

And I am on Windows 7 x64, running node 7.8.0, karma 1.4.1 if it is making any difference.

From package.json:

    "karma": "~1.4.1",
    "karma-chrome-launcher": "~2.0.0",
    "karma-cli": "~1.0.1",
    "karma-coverage-istanbul-reporter": "^1.1.0",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "karma-remap-istanbul": "0.2.2", 
ChenReuven commented 7 years ago

I have this configuration:

app-theme.scss @include mat-core(); $app-primary: mat-palette($mat-blue); $app-accent: mat-palette($mat-amber); $app-warn: mat-palette($mat-red); $app-theme: mat-light-theme($app-primary, $app-accent, $app-warn); @include angular-material-theme($app-theme);

angular-cli.json "styles": [ "styles.css", "app-theme.scss" ],

style.css i have all fonts application configuration

kuncevic commented 7 years ago

you are missing @import '~@angular/material/_theming'; in your app-theme.scss it is where mat-core(), and .mat-theme-loaded-marker, etc. is coming from

// Marker that is used to determine whether the user has added a theme to their page.
  .mat-theme-loaded-marker {
    display: none;
  }
ChenReuven commented 7 years ago

@kuncevic oops :), i just forgot to wrote it here in comment but it exist in code: @import '~@angular/material/theming'; on the top of the app-theme.scss

BTW i am not use the '_theming' but the 'theming'

Thanks 4 your help :)

kuncevic commented 7 years ago

actually I just run ng t and I notice same warning, whoops...

willshowell commented 7 years ago

From what I understand, karma does not inject any css into your tests by default, but including a material component without a theme will trigger the warning.

In my original comment I showed how to inject one of the prebuilt themes into the test suite. What I don't know is if this is the ideal solution. I figure there should either be something in the docs about it, or the warning should stay silent during unit tests that import material modules.

Maybe @DevVersion or @crisbeto can weigh in?

LilSebastian5000 commented 7 years ago

Another issue with receiving warnings- I've also noticed that the ".css.map" files seem to be missing in beta.3, so I keep getting thrown the following in Chrome:

DevTools failed to parse SourceMap: https://localhost:3000/@angular/material/indigo-pink.css.map

Is this the case, or am I just unable to find it? The ".css.map" files do not exist in the "/prebuilt-themes" directory.

jelbourn commented 7 years ago

I think the real solution here is that there should be guide specifically for testing w/ the Material components.

KostyaTretyak commented 7 years ago

Now in docs we have:

Angular Material comes prepackaged with several pre-built theme css files. These theme files also include all of the styles for core (styles common to all components), so you only have to include a single css file for Angular Material in your app.

I use:

When I import css-file in src/app/app.component.css:

@import '~@angular/material/prebuilt-themes/indigo-pink.css';

and run project via ng serve, I have same warn in console:

Could not find Angular Material core theme. Most Material components may not work as expected. For more info refer to the theming guide: https://material.angular.io/guide/theming

When I do

@import '~@angular/material/theming'
/* or @import '~@angular/material/_theming'*/

I have error "file not found".

When I include the style in src/index.html or in src/style.css all works without warn.

crisbeto commented 7 years ago

Sorry that I haven't been following the discussion here. If you're testing something that contains a Material component, you definitely need to include the theme, otherwise the positioning and a few other things won't be accurate. To do that, you need to add it to your Karma config. You can see how we're doing it for our own tests here.

gajdot commented 7 years ago

The problem with the way you do it it's Chinese for somebody who is just started to work with karma testing. If I put just the line you highlighted then it's not working, but the file is quite different to be able to figure out what's the problem.

TaylorPzreal commented 7 years ago

thanks @crisbeto , i changed my karma.conf.js

    files: [
      {pattern: './config/karma-test-shim.js', watched: false},
            // Include a Material theme in the test suite.
      {pattern: './node_modules/@angular/material/prebuilt-themes/indigo-pink.css', included: true, watched: true},
    ],

it workd.

elvirdolic commented 7 years ago

How we can add custom themes .scss files with angular-cli sass processing?

farley911 commented 7 years ago

custom themes being written in sass throw an error when including it in the files array of karma.conf.js

Invalid character: '@'

gajdot commented 7 years ago

Any update on this? I'm not able to properly test any component using material. The error is showing up and no material animation is working in the components.

willshowell commented 7 years ago

I think this document would be a good place to suggest reading the tests from the source for figuring out how to test different components. It would cut down on a number of issues like "how do I access x in my tests?" and "x works fine in my app, but my tests fail"

gajdot commented 7 years ago

Well it gives me no error, but I still couldn't figure out how to make the animations work in testing. It gives 0 error or warning, but no animation is happening in testing :(

herkulano commented 7 years ago

@crisbeto how do we target the sass file generated by angular-cli instead? I have all my theming files there, so I should use that instead.

vapits commented 7 years ago

Had the same issue here and manage to fix it by importing any of the themes in the karma.config file.

Though I'm getting those warnings even that my tests are passing: Chrome 59.0.3071 (Mac OS X 10.12.5) LOG: '>>>>>>', '', 'Error: STACKTRACE TRACKING' Chrome 59.0.3071 (Mac OS X 10.12.5) LOG: '>>>>>>', ' at SEP_TAG (http://localhost:9876/_karma_webpack_/vendor.bundle.js:7538:37) []', ' at captureStackTraces (http://localhost:9876/_karma_webpack_/vendor.bundle.js:7538:37) []' Chrome 59.0.3071 (Mac OS X 10.12.5) LOG: '>>>>>>', ' at SEP_TAG (http://localhost:9876/_karma_webpack_/vendor.bundle.js:7538:37) []', ' at captureStackTraces (http://localhost:9876/_karma_webpack_/vendor.bundle.js:7538:37) []' Chrome 59.0.3071 (Mac OS X 10.12.5): Executed 0 of 28 SUCCESS (0 secs / 0 secs) Chrome 59.0.3071 (Mac OS X 10.12.5): Executed 28 of 28 SUCCESS (2.446 secs / 2.525 secs)

hpawe01 commented 6 years ago

@herkulano @elvirdolic @farley911 To use scss files instead of css files, you have to tell Karma how to process them. I followed this solution (coming from https://github.com/angular/angular-cli/issues/6261):

But there was still the problem, that the import wasn't found when I ran ng test: File to import not found or unreadable: ~@angular/material/theming.

I fixed it by replacing @import '~@angular/material/theming' with @import '../node_modules/@angular/material/_theming.scss'; in ./src/theme.scss.

Now everything works as expected.

Does anyone has an idea how to tell Karma how to import the correct file without this workaround above?

msandeeprao38 commented 6 years ago

@hpawe01 I had to do the same workaround for importing material theming, but everything works. Thanks for sharing your answer

maiasmith commented 6 years ago

@hpawe01 's solution worked for me, although I did have to restart my 'npm test'.

zessu commented 6 years ago

Some Material Components require some default styles. When setting up an angular application, you need to either create your own custom theme or include one of the default themes in order for these components to work.

When testing, the whole application is not bootstrapped. Meaning the stylesheet(usually included in index.html of styles.(s)css) is not included, hence the warnings. When testing, we bootstrap our own Modules using TestBed. We need to find a way to load a stylesheet into the build. We can load any stylesheet into the files[] config section of our karma config. This is where we include files.

files: [ { pattern: './src/test.ts', watched: false }, { pattern: './node_modules/@angular/material/prebuilt-themes/indigo-pink.css', watched: false, included: true }, ],

This includes the stylesheet in the final build So it is not an issue with Angular, and not an issue with Karma (just a test runner) We just have to understand how our build works You should close this issue

LosD commented 6 years ago

@zessu IMHO, the issue is still valid, as it is not about the behavior being wrong, but about documenting it (I don't necessarily think that Getting Started should mention it, but it's not mentioned anywhere in the documentation, which seems to be an oversight to me).

joaopgrassi commented 6 years ago

@hpawe01 did you have any issues with karma loading the assets under the "base" path? I can't get this working because of this. [web-server]: 404: /base/node_modules/@angular/material/prebuilt-themes/indigo-pink.css

My styles.scss @import '../node_modules/@angular/material/prebuilt-themes/indigo-pink.css';

karma.conf files: [ { pattern: './src/test.ts', watched: false }, { pattern: './src/styles.scss', included: true, watched: true} ]

I can add the files directly as @zessu said but I'll miss my custom styles.. plus adding twice the material styles sucks.

hpawe01 commented 6 years ago

@joaopgrassi: No, unfortunately I get the same warning as you get. It seems, that you have to add the path to the prebuild theme twice: in styles.scss and in karma.conf as @zessu and @qaznine suggested. Why would you lose your custom styles if you add it to karma.conf?

joaopgrassi commented 6 years ago

Well, mainly because I didn't want to add the styles twice which sucks.

yoonjesung commented 6 years ago

@hpawe01

You can use the experimental importer feature for node-sass >= v2.0 with the custom node-sass-tilde-importer library.

  1. Download node-sass-tilde-importer as a dev-dependency

  2. Update karma.conf.js with the following:

plugins: [
  ...,
  require('karma-scss-preprocessor'),
],
files: [
  ...,
  { pattern: './src/theme.scss', included: true, watched: true},
],
preprocessors: {
  ...,
  './src/theme.scss': ['scss']
},
scssPreprocessor: {
  options: {
    includePaths: ['node_modules'],
    importer: require('node-sass-tilde-importer')
  }
}

I don't think includePaths is necessary here, but I've included it just to be safe.

hpawe01 commented 6 years ago

Thanks very much @yoonjesung - this is working. Now I can use the normal import in my ./src/theme.scss:

@import '~@angular/material/theming';

And it works without includePaths as you assumed.