This post is stackoverflow repost from my issues at https://github.com/frankwallis/plugin-typescript/issues/64 and https://github.com/Workiva/karma-jspm/issues/112
We plan to upgrade our team stack for web ui so we decide:
1) use Karma as test launcher and jasmine as framework ( mocha and custom runners before)
2) use TypeScript for source code with UMD or system module out (pure Javascript before)
3) use SystemJS as module loader to allow use different module's types (CommonJS, AMD, system , ES6) without overheat ( RequireJS before)
And additionally:
1) we want to run tests directly from typescript code without precompilation and storing JS on disk
2) we want to have test environment layout very close to production layout
3) we have setup karma + jasmine + karma-typescript-preprocessor and it works well. BUT we want ot work with JSPM/SystemJS loader while in this case we will be sure that our test environment match production where SystemJS loader is used. Becuase for another hand we will require to write some custom bootstrap things for test-only.
But we have problems with karma + jspm + typescript-plugin (jspm).
In JSPM './config.js'
System.config({
baseURL: "/",
"transpiler": false,
"packages": {
"src": {
"main": "test.ts",
"defaultExtension": "ts",
"meta": {
"*.ts": {
"loader": "ts"
},
"*.js": {
"loader": "ts"
}
}
}
},
paths: {
"npm:*": "jspm/npm/*",
"github:*": "jspm/github/*"
},
map: {
"ts": "github:frankwallis/plugin-typescript#2.2.3",
"typescript": "npm:typescript#1.6.2",
"github:frankwallis/plugin-typescript#2.2.3": {
"typescript": "npm:typescript#1.6.2"
}
}
});
In Karma config:
// Karma configuration
// Generated on Mon Nov 30 2015 02:58:44 GMT+0500 (RTZ 4 (зима))
module.exports = function(config) {
config.set({
basePath: '',
frameworks: ['jspm','jasmine'],
plugins:[
"karma-jspm",
'karma-jasmine',
'karma-chrome-launcher'
],
jspm: {
loadFiles: ['src/test.ts'], //we just try to check one simple test
packages: "jspm/"
} ,
proxies : { // avoid Karma's ./base virtual directory
'/src/': '/base/src/',
'/jspm/': '/base/jspm/'
},
reporters: ['progress'],
port: 9876,
browsers: ['Chrome']
})
}
But something goes wrong:
30 11 2015 14:53:34.564:WARN [web-server]: 404: /jspm/github/frankwallis/pl
ugin-typescript#2.2.3
Chrome 46.0.2490 (Windows 10 0.0.0) ERROR: 'Potentially unhandled rejection [6]
Error: XHR error (404 Not Found) loading http://localhost:9876/jspm/github/frank
wallis/plugin-typescript#2.2.3
at error (http://localhost:9876/base/jspm/system.src.js?6536115be64e0ff966e0
5546f7767676fa7c03d6:1020:16)
at XMLHttpRequest.xhr.onreadystatechange (http://localhost:9876/base/jspm/sy
stem.src.js?6536115be64e0ff966e05546f7767676fa7c03d6:1028:13)'
And we checked that url is valid: for ex /jspm/github/frankwallis/plugin-typescript#2.2.3\utils.js is served well by Karma.
I don't understand why it trys to load whole typescript plugin directory.
So we have question:
1) Is it a bug or our fail in understanding/config
2) If it's our fail - how to fix it?
3) May be we choose not correct how to test with Karma + JSPM + Typescript?
Any advice will be helpful.
Have found mistake ourselves: "defaultJSExtensions": true, was not in .\config.js
I used karma-uiuxengineering-jspm instead of karma-jspm.
It's a fork which seemed to fix my problems at the time, and which supports JSPM 0.17-beta.
The repo also has some seed projects for angular2 and typescript (using JSPM) with a testing environment. It really helped me the set up my project.
Related
I'm making a website using Angular2 and I'm having what i suppose is an issue. On the first load of my angular page, SystemJS is making more than 500 hundred requests to retrieve every Angular2 file in angular2/src directory. In total, the first load downloads more than 4MB and it takes more than 14 seconds to start.
My index.html does the following scripts includes:
<script src="libs/angular2/bundles/angular2-polyfills.js"></script>
<script src="libs/systemjs/dist/system.src.js"></script>
<script src="libs/rxjs/bundles/Rx.js"></script>
<script src="libs/angular2/bundles/angular2.min.js"></script>
<script src="libs/angular2/bundles/http.dev.js"></script>
<script src="libs/jquery/jquery.js"></script>
<script src="libs/lodash/lodash.js"></script>
<script src="libs/bootstrap/js/bootstrap.js"></script>
And my systemJs initialization code looks like this:
<script>
System.config({
defaultJSExtensions: true,
paths: {
'*': 'libs/*',
'app/*': 'app/*'
},
packageConfigPaths: ['libs/*/package.json'],
packages: {
app: {
format: 'register',
defaultExtension: 'js'
}
}
});
System.import('app/main')
.then(null, console.error.bind(console));
</script>
My public folder has the following structure:
.
├── img
├── styles
├── app
├── libs
| └── angular2
| └── systemjs
| └── rxjs
| └── jquery
| └── lodash
| └── bootstrap
└── index.html
A couple of screenshots of some of the js files that are being requested:
Is there a way to avoid all of those requests?
I had the exact same problem, was actually looking at this post for an answer. Here is what I did to solve the problem.
Modify your project to use webpack. Follow this short tutorial:
Angular2 QuickStart SystemJS To Webpack
This method will give you a single javascript file however it is quite large (my project file was over 5MB) and needs to be minified. To do this I installed webpack globaly:npm install webpack -g. Once installed, run webpack -p from your apps root directory. This brought my file size down to about 700KB
From 20 seconds and 350 requests down to 3 seconds and 7 requests.
I see you already have a response, which is good of course.
BUT for those who want to use systemjs (like I also do), and not go to webpack, you can still bundle the files. However, it does involve using another tool also (I use gulp).
So... you would have the folowing systemjs config (not in the html, but in a separate file - let's call it "system.config.js"):
(function(global) {
// map tells the System loader where to look for things
var map = {
'app': 'dist/app', // this is where your transpiled files live
'rxjs': 'node_modules/rxjs',
'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api', // this is something new since angular2 rc.0, don't know what it does
'#angular': 'node_modules/#angular'
};
// packages tells the System loader how to load when no filename and/or no extension
var packages = {
'app': { main: 'boot.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
'angular2-in-memory-web-api': { defaultExtension: 'js' }
};
var packageNames = [
'#angular/common',
'#angular/compiler',
'#angular/core',
'#angular/http',
'#angular/platform-browser',
'#angular/platform-browser-dynamic',
//'#angular/router', // I still use "router-deprecated", haven't yet modified my code to use the new router that came with rc.0
'#angular/router-deprecated',
'#angular/http',
'#angular/testing',
'#angular/upgrade'
];
// add package entries for angular packages in the form '#angular/common': { main: 'index.js', defaultExtension: 'js' }
packageNames.forEach(function(pkgName) {
packages[pkgName] = { main: 'index.js', defaultExtension: 'js' };
});
var config = {
map: map,
packages: packages
};
// filterSystemConfig - index.html's chance to modify config before we register it.
if (global.filterSystemConfig) { global.filterSystemConfig(config); }
System.config(config);
})(this);
Then, in your gulpfile.js you would build a bundle like this (using the info from system.config.js and tsconfig.json files):
var gulp = require('gulp'),
path = require('path'),
Builder = require('systemjs-builder'),
ts = require('gulp-typescript'),
sourcemaps = require('gulp-sourcemaps');
var tsProject = ts.createProject('tsconfig.json');
var appDev = 'dev/app'; // where your ts files are, whatever the folder structure in this folder, it will be recreated in the below 'dist/app' folder
var appProd = 'dist/app';
/** first transpile your ts files */
gulp.task('ts', () => {
return gulp.src(appDev + '/**/*.ts')
.pipe(sourcemaps.init({
loadMaps: true
}))
.pipe(ts(tsProject))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(appProd));
});
/** then bundle */
gulp.task('bundle', function() {
// optional constructor options
// sets the baseURL and loads the configuration file
var builder = new Builder('', 'dist/system.config.js');
/*
the parameters of the below buildStatic() method are:
- your transcompiled application boot file (the one wich would contain the bootstrap(MyApp, [PROVIDERS]) function - in my case 'dist/app/boot.js'
- the output (file into which it would output the bundled code)
- options {}
*/
return builder
.buildStatic(appProd + '/boot.js', appProd + '/bundle.js', { minify: true, sourceMaps: true})
.then(function() {
console.log('Build complete');
})
.catch(function(err) {
console.log('Build error');
console.log(err);
});
});
/** this runs the above in order. uses gulp4 */
gulp.task('build', gulp.series(['ts', 'bundle']));
So, when running "gulp build", you will get the "bundle.js" file with everything you need.
Sure, you also need a few more packages for this gulp bundle task to work:
npm install --save-dev github:gulpjs/gulp#4.0 gulp-typescript gulp-sourcemaps path systemjs-builder
Also, make sure that in your tsconfig.json you have "module":"commonjs".
Here is my tsconfig.json which is used in my 'ts' gulp task:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false
},
"exclude": [
"node_modules",
"typings/main",
"typings/main.d.ts"
]
}
Then, in your html file you only need to include this:
<!-- Polyfill(s) for older browsers -->
<script src="node_modules/es6-shim/es6-shim.min.js"></script>
<script src="node_modules/zone.js/dist/zone.js"></script>
<script src="node_modules/reflect-metadata/Reflect.js"></script>
<script src="dist/app/bundle.js"></script>
And that's it... I got from 600 requests, 4mb in about 5 seconds... to 20 requests, 1.4mb in 1.6 seconds (local development machine). But these 20 requests ~1.4mb in 1.6 seconds also include some other js and css that the admin theme came with plus a few html templates that get required on the first load, I prefer to use external templates - templateUrl: '', instead of inline ones, written in my component.ts file.
Sure, for an app that would have millions of users, this still wouldn't be enough. Also server-side rendering for initial load and cache system should be implemented, I actually managed to do that with angular universal, but on Angular2 beta (took about 200-240 milliseconds to load the initial render of the same admin app that above takes 1.6 seconds - I know: WOW!). Now it's incompatible since Angular2 RC came out, but I'm sure the guys doing universal will get it up to speed soon, specially since ng-conf is coming up. Plus, they're also planing to make Angular Universal for PHP, ASP and a few other - right now it's only for Nodejs.
Edit:
Actually, I've just found out that on NG-CONF they said Angular Universal already supports ASP (but it doesn't support Angular2 > beta.15 :)) ... but let's give them some time, RC just came out a few days ago
I think that your question is related to this one:
My angular 2 app takes a long time to load for first time users, I need help to speed it up
To have something ready for production (and speed it up), you need to package it.
I mean transpiling all files into JavaScript ones and concat them the same way Angular2 does for example. This way you will have several modules contained into a single JS file. This way you will reduce the number of HTTP calls to load your application code into the browser.
I found a simple solution, using browserify & uglifyjs on mgechev's angular2-seed repository
Here's my version:
pacakge.json:
{
...
"scripts": {
"build_prod": "npm run clean && npm run browserify",
"clean": "del /S/Q public\\dist",
"browserify": "browserify -s main public/YourMainModule.js > public/dist/bundle.js && npm run minify",
"minify": "uglifyjs public/dist/bundle.js --screw-ie8 --compress --mangle --output public/dist/bundle.min.js"
},
...
"devDependencies": {
"browserify": "^13.0.1",
"typescript": "^1.9.0-dev.20160625-1.0",
"typings": "1.0.4",
"uglifyjs": "^2.4.10"
}
}
Build your project.
Run: npm run build_prod
It'll create bundle.js & bundle.min.js under public\dist directory.
Edit your index.html file:
Instead of running System.import('YourMainModule')... ,
add <script src="/dist/bundle.min.js"></script>
On the first load of my angular page, systemjs is making more than 500 hundred requests to retrieve every angular2 file in angular2/src directory. In total, the first load downloads more than 4mb and it takes more than 14s to start.
The SystemJs workflows are fairly new and don't have enough research in them for best deployment.
Suggest going back to commonjs + webpack. More : https://basarat.gitbooks.io/typescript/content/docs/quick/browser.html
Here is an example : https://github.com/AngularClass/angular2-webpack-starter
#FreeBird72 Your answer is awesome.
If you want to use SystemJS for development and speed up the production server like I do. Check this out.
NOTE: Only import the components that you use, DO NOT import from the whole package.
Eg: If you want to use Modal from ng2-bootstrap.
import {MODAL_DIRECTIVES} from "ng2-bootstrap/components/modal";
Instead of:
import {MODAL_DIRECTIVES} from "ng2-bootstrap/ng2-bootstrap";
This will import the modal component instead of the whole ng2-bootstrap
Then follow the answer from #FreeBird72
Add this package.json
{
...
"scripts": {
...
"prod": "npm run tsc && npm run browserify",
"browserify": "browserify -s main dist/main.js > dist/bundle.js && npm run minify",
"minify": "uglifyjs dist/bundle.js --screw-ie8 --compress --mangle --output dist/bundle.min.js",
...
},
"devDependencies": {
...
"browserify": "^13.0.1",
"uglifyjs": "^2.4.10",
...
}
...
}
Then you can npm run tsc on development and npm run prod on production server
Also remove System.import(.... from your index.html and change it to <script src="/dist/bundle.min.js"></script>
If you want to stick with SystemJS, you can bundle your app with JSPM. I've had good success with this so far, using JSPM's bundle-sfx command to make single JS files for Angular 2 apps.
There's some useful information in this Gist, and there's a seed project.
I am using AG2 RC version
While using MrCroft's solution with systemjs-builder, i was hitting a lot of issues like:
error TS2304: Cannot find name 'Map'
error TS2304: Cannot find name 'Promise'...
After many tries, i added:
///<reference path="../../typings/index.d.ts" />
into my boot.ts and now I got my bundle file compiled.
The Angular command line interface now supports bundling (with tree-shaking to strip out unused code from imports), minification, and ahead-of-time template compilation, which not only hugely minimises the number of requests made, but also makes the bundle very small. It uses WebPack underneath.
It's incredibly easy to make production builds with it:
ng build --prod --aot
https://github.com/angular/angular-cli
I set up grunt to run node.js jasmine tests. For some reason, with this config, the results always show double the tests.
Here is my config:
I'm using jasmine-node which plugs into grunt.
/spec/some-spec.js:
var myModule = require('../src/myModule.js');
describe('test', function(){
it('works', function(done){
setTimeout(function(){
expect(1).toBe(1);
done();
}, 100);
});
});
Gruntfile.js:
module.exports = function(grunt) {
grunt.initConfig({
jasmine_node: {
options: {
forceExit: true
},
all: ['spec/']
}
});
grunt.loadNpmTasks('grunt-jasmine-node');
grunt.registerTask('default', ['jasmine_node']);
};
This results in two tests running rather than one.
> grunt
Running "jasmine_node:all" (jasmine_node) task
..
Finished in 0.216 seconds
2 tests, 2 assertions, 0 failures, 0 skipped
I was able to reproduce the behavior. This is what seems to be happening:
The task looks in the specified folder (spec in your case) for files with spec in the name.
Then it looks again in every folder in the whole project for files with spec in the name.
What it ends up with is 2 overlapping sets of test files to run.
My first attempt at trying to coerce it into more logical behavior was to set specNameMatcher: null (default is 'spec'), and leave the folder set to 'spec/'. This results in no tests being run, since apparently both conditions (name and folder) must be met for files in the specified folder. You get the same problem if specNameMatcher is left at the default value, but the files in the folder don't have 'spec' in the name.
What does work is to set the folder (or 'test set' or whatever you want to call it) to []:
jasmine_node: {
options: {
forceExit: true
},
all: []
}
The catch is that if you have any other files somewhere else in the project with 'spec' in the name, they'll be mistaken for tests by jasmine.
I would consider this behavior a bug, and it should probably be reported via the project's github issues page.
This grunt plugin ( https://github.com/jasmine-contrib/grunt-jasmine-node ) seems to be dead ( https://github.com/jasmine-contrib/grunt-jasmine-node/issues/60 ).
Maybe it is a better to switch to https://github.com/onury/grunt-jasmine-nodejs ?
The jasmine-node project is pretty old. The latest commit is from July of 2014. The grunt-jasmine-node plugin appears to be active, but running against something that is going stale seems a little pointless IMHO.
To test CommonJS modules using Jasmine I'd recommend using Karma along with the
karma-jasmine and karma-commonjs plugins. I got your example working with the following files:
package.json
{
"private": "true",
"devDependencies": {
"grunt": "^0.4.5",
"grunt-jasmine-node": "^0.3.1",
"grunt-karma": "^0.10.1",
"jasmine-core": "^2.3.4",
"karma": "^0.12.31",
"karma-commonjs": "0.0.13",
"karma-jasmine": "^0.3.5",
"karma-phantomjs-launcher": "^0.1.4"
}
}
karma.conf.js
module.exports = function(config) {
config.set({
basePath: '.',
frameworks: ['jasmine', 'commonjs'],
files: [{
pattern: 'src/**/*.js'
}, {
pattern: 'spec/**/*.js'
}],
preprocessors: {
'src/**/*.js': ['commonjs'],
'spec/**/*.js': ['commonjs']
},
reporters: ['progress'],
browsers: ['PhantomJS']
});
};
Gruntfile.js (optional if you still want to use grunt)
module.exports = function(grunt) {
grunt.initConfig({
karma: {
unit: {
configFile: 'karma.conf.js',
options: {
singleRun: true
}
}
}
});
grunt.loadNpmTasks('grunt-karma');
grunt.registerTask('default', ['karma:unit']);
};
You should also install the karma command line runner globally, just like you probably did with grunt. npm install -g karma-cli
From your command line you can start karma by typing karma start. It will run the tests and then watch your files and re-run them on every save. (VERY NICE)
Alternatively you can run karma start --single-run to have it just run your tests once and exit. If you also updated your Gruntfile you can also just run grunt to run the tests once.
The current up voted answer isn't the solution. You simply modify the expression that's going to match your tests. The answer is as follows:
module.exports = function(grunt) {
grunt.initConfig({
jasmine_node: {
options: {
forceExit: true
},
all: ['spec/*spec.js']
}
});
grunt.loadNpmTasks('grunt-jasmine-node');
grunt.registerTask('default', ['jasmine_node']);
};
Here you can see that 'all' is set to *'spec/spec.js'. This will search for all tests.
Secondly, just because a project hasn't had a recently commit, doesn't mean it's "old". jasmine-node is simply stable.
I have the same issue using grunt-jasmine-node, and as aeryaguzov points out, that project is no longer maintained. Switching to grunt-jasmine-node-new solves the issue for me.
grunt-jasmine-node-new is a fork of grunt-jasmine-node that is actively maintained, and can be found here: https://www.npmjs.com/package/grunt-jasmine-node-new
I ma trying to add Karma & Jasmine+Require Js based Unit testing support for an AngularJS +Angular AMD & RequireJS Application that I have created. I have been wrecking my brain around this for two days now but I am still nowhere close to sealing the deal.
I keep getting the error :
INFO [karma]: Karma v0.12.21 server started at http://localhost:9876/
INFO [launcher]: Starting browser Chrome
INFO [Chrome 36.0.1985 (Mac OS X 10.9.4)]: Connected on socket 8oFHaa2hqJPs0ecgIXCa with id 31963369
Chrome 36.0.1985 (Mac OS X 10.9.4) ERROR: 'There is no timestamp for ../www/scripts/specs/UserControllerTest.js!'
WARN [web-server]: 404: /www/scripts/specs/UserControllerTest.js
Chrome 36.0.1985 (Mac OS X 10.9.4) ERROR
Uncaught Error: Script error for: specs/UserControllerTest
http://requirejs.org/docs/errors.html#scripterror
at /usr/local/lib/node_modules/requirejs/require.js:141
My Code is as follows :
The Karma Config file :
// Karma configuration
// Generated on Fri Aug 15 2014 20:49:40 GMT+1000 (EST)
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '.',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine', 'requirejs'],
// list of files / patterns to load in the browser
files: [
'test-main.js',
{pattern: 'specs/*.js', included: true}
],
// list of files to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false
});
};
My test-main.js file.
var allTestFiles = [];
var TEST_REGEXP = /(spec|test)\.js$/i;
var pathToModule = function(path) {
return path.replace(/^\/base\//, '').replace(/\.js$/, '');
};
Object.keys(window.__karma__.files).forEach(function(file) {
if (TEST_REGEXP.test(file)) {
// Normalize paths to RequireJS module names.
allTestFiles.push(pathToModule(file));
}
});
require.config({
// Karma serves files under /base, which is the basePath from your config file
baseUrl: '../www/scripts',
// alias libraries paths
paths: {
'angular': '../libs/angular',
'angular-route': '../libs/angular-route',
'angular-animate':'../libs/angular-animate',
'angular-mocks':'../libs/angular-mocks',
'angularAMD': '../libs/angularAMD.min',
'Framework7':'../libs/framework7',
'UserController':'controller/UserCtrl',
'WebCallManager':'services/WebCallManager'
},
// Add angular modules that does not support AMD out of the box, put it in a shim
shim: {
'angularAMD': ['angular'],
'angular-route': ['angular'],
'angular-animate':['angular'],
'angular-mocks':['angular'],
'Framework7':{exports: 'Framework7'}
},
//kick start application
//deps: ['app'],
// dynamically load all test files
deps: allTestFiles,
// we have to kickoff jasmine, as it is asynchronous
callback: window.__karma__.start
});
And My Unit Test is :
describe('UserController', function () {
var scope,controller;
//mock Application to allow us to inject our own dependencies
beforeEach(angular.mock.module('app'));
//mock the controller for the same reason and include $rootScope and $controller
beforeEach(angular.mock.inject(function($rootScope, $controller) {
//create an empty scope
scope = $rootScope.$new();
//declare the controller and inject our empty scope
$controller('UserController', {$scope: scope});
}));
it('checks the controller name', function () {
expect(scope.name).toBe('Superhero');
});
});
I have uploaded all my code of my project to link here. Anyone who can help me with this is highly appreciated. I think In am at the end of my tether with this.
marcoseu is right, the There is no timestamp for... error means karma cant find the the file, but there is more.
I'd recommend making karma's base path your project root. This avoids Karma making the file paths absolute instead of relative which keeps things simpler and avoids path reference problems (at least on my windows OS).
Your test should be a require module (i.e. using define) so it can be sure the objects it requires are fully loaded. See the example test at http://karma-runner.github.io/0.12/plus/requirejs.html
karma.config.js
basePath: "../",
files: [
'test/test-main.js',
{pattern: 'test/specs/*.js', included: false},
{pattern: 'www/**/*.js', included: false},
],
Now your files are all served by Karma under /base.
test-main.js
require.config({
baseUrl: "/base/www/scripts",
Debugging
But most importantly you can debug all of this. Run Karma, switch to the Karma created chrome instance, click the debug button, open the chrome developer tools. Check the console, and your source files. Especially the source of debug.html, as at the bottom it has the definition of all your karma served files.
You can also set breakpoints and then refresh the page to watch the tests being executed. You will be able to see for yourself why you are getting test errors. Win.
The error There is no timestamp for... means that karma is unable to access the file in question. You need to define the www directory so that is is accessible by karma. Try the following:
karma.config.js
files: [
'test-main.js',
{pattern: './specs/*.js', included: true},
{pattern: '../../www/**/*.js', included: false}
],
Take a look at karma.conf in the angularAMD project and the Karma documentation for files.
i have configured followung Gruntmodule for DalekJS:
module.exports = {
dalek: {
options: {
browser: ['phantomjs'],
reporter: ['html', 'junit', 'json'],--> I also tried without this line
dalekfile: true
},
files: {
src: ['tests/gui/dalekjs/dakektest.js']
}
}
};
I have a Dalekfile in the same folder as the configured module (i have a splitted gruntfile! see http://www.html5rocks.com/en/tutorials/tooling/supercharging-your-gruntfile/?redirect_from_locale=de):
Dalekfile.json:
{
"reporter": ["console", "junit", "html", "json"],--> I also tried without this line
"html-reporter": {
"dest": "C:/my/path/tests/gui/dalekjs/report"
},
"junit-reporter": {
"dest": "C:/my/path/tests/gui/dalekjs/report/report.xml"
},
"json-reporter": {
"dest": "C:/my/path/tests/gui/dalekjs/report/report.json"
}
}
After executing grunt my tests are executed successfully.
But if i check the custom path there is no report. It creates the report in the same folder of the Gruntfile.js so --> gruntfilefolder/report/dalek/
When executing the Dalektest over ther console with dalek dalektest.js the reports are created successfully. --> I installed the reporting plugins as described in the dalek docs!
Is there anyone who can tell me, why the custom path is not used?
Versions:
grunt-cli v0.1.13
grunt v0.4.4
grunt-dalek 0.2.0
Cheers izocan.
Solved in a google groups discussion here: How to configure reporting options when using dalekjs with grunt?
I have a fairly simple karma.config.js file
basePath = '../';
files = [
JASMINE,
JASMINE_ADAPTER,
'js/lib/angular*.js',
'test/lib/angular/angular-mocks.js',
'js/**/*.js',
'test/unit/**/*.js'
];
autoWatch = true;
browsers = ['PhantomJS'];
When I run karma start config/karma.conf.js --single-run I'm getting the following output
$ karma start config/karma.conf.js --single-run
[2013-06-24 23:47:08.750] [DEBUG] config - autoWatch set to false, because of singleRun
INFO [karma]: Karma server started at http://localhost:9876/
INFO [launcher]: Starting browser PhantomJS
INFO [PhantomJS 1.9 (Mac)]: Connected on socket id LwMoWxzIbSUuBsvIqB_m
PhantomJS 1.9 (Mac): Executed 6 of 6 SUCCESS (0.073 secs / 0.02 secs)
I've been searching for something to tell me how to get the output of the tests that get logged (e.g. SUCCESS Unit: services myService should behave)
The only way I can see the output of the tests is to open Chrome and click 'Debug', then show the developer tools console. I want the messages to be logged out to the terminal, but I cannot figure out how to get this working.
Fixed by installing the karma-spec-reporter
npm install karma-spec-reporter --save-dev
and adding this my karma.config.js
reporters: ['spec'],
According to karma documentation
By default, Karma loads all NPM modules that are siblings to it and their name matches karma-*.
but some users have had to add the following to their config
plugins: ['karma-spec-reporter']
Just another detail - if you keep the default reporter 'progress' in the karma.config.js, like below:
reporters: ["progress", "spec"]
or another console reporter, the "spec" reporter output won't work.
You should keep only the "spec" one, or the "spec" with other browser reporters. For example:
reporters: ["spec", "coverage"]
I wrote a reporter to make the output more readable: karma-helpful-reporter
Has some nice customization options: https://github.com/whyboris/karma-helpful-reporter
Instal instructions inside, basically npm install --save-dev karma-helpful-reporter and then add to the Karma configuration plugins section:
plugins: [
require('karma-helpful-reporter')
],
reporters: [ 'helpful' ],
You can also use the Karma-mocha-reporter
as reporter and you should have a clean report in your console.
npm i karma-mocha-reporter --save-dev
// karma.conf.js
module.exports = function(config) {
config.set({
frameworks: ['jasmine'],
// reporters configuration
reporters: ['mocha']
});
};
Sometimes, e.g in #angular/cli environment you should require this like:
plugins: [
...
require('karma-mocha-reporter'),
...
]
Here is my working (draft) configuration without the section 'plugins' (actually I don't fully understand why I should need to specify them ...):
package.json
"devDependencies": {
[...]
"grunt-karma": "~0.9.0",
"karma": "~0.12.24",
"karma-jasmine": "~0.2.3",
"karma-chrome-launcher": "~0.1.5",
"karma-phantomjs-launcher": "~0.1.4",
"karma-spec-reporter": "0.0.13"
}
karma.conf.js
module.exports = function (config) {
config.set({
frameworks: ['jasmine'],
reporters: ['spec'],
browsers: ['PhantomJS']
});
};
Gruntfile.js
karma: {
options: {
configFile: 'karma.conf.js',
files: [
'app/libs/angular.js',
'app/libs/angular-resource.js',
'app/libs/angular-route.js',
[...]
'app/modules/**/*-spec.js'
]
},
unit: {
singleRun: true
}
}
Now when I run grunt karma messages from the *-spec.js files (describe('message', function() ...)) are displayed nicely in the console.