Is it possible to run Grunt Karma locally? - node.js

Is it possible to run Grunt Karma locally?
Start the Karma server, assign a port to it and then open different browsers on my computer and run tests by inserting the localhost:port?
I have a Github project running Travis and have strange results in some Browsers. I can run the tests locally but only with "virtual" PhantomJS. Would be nice to check my Specs in a real browser.

I regularly use karma-chrome-launcher and know that there is also karma-firefox-launcher as well.
In your karma.conf.js file, or in your Gruntfile.js options area you can define:
browsers: ['Phantomjs', 'Chrome'],
and then in the plugins section include:
plugins: [
'karma-chrome-launcher',
'karma-firefox-launcher',
'karma-phantomjs-launcher'
]
https://github.com/karma-runner has a list of launcher plugins and other useful plugins. There is even a karma-browserstack-launcher, though that wouldn't be local.
Documentation on what you can configure either total in the Gruntfile.js or by referencing a karma.conf.js in your Gruntfile.js can be found:
https://github.com/karma-runner/grunt-karma
http://karma-runner.github.io/0.10/config/configuration-file.html
I like the functionality of using a karma.conf.js file to separate out the majority of my karma config, so in my Gruntfile.js I do the following:
karma: {
options: {
configFile: 'karma.conf.js'
},
unit: {
autoWatch: true,
singleRun: true
},
watch: { // still needs watch integration and testing
browsers: ['PhantomJS'],
background: true
}
},
Then in my karma.conf.js file I follow the base structure shown https://github.com/karma-runner/karma/blob/master/test/client/karma.conf.js

Related

Angular 6 and karma 'Can not load "#angular-devkit/build-angular", it is not registered'

I had to migrate to the newest angular version. After that, karma tests stopped working and just keep crushing with an error log:
14 04 2018 14:17:00.453:ERROR [preprocess]: Can not load "#angular-devkit/build-angular", it is not registered!
Perhaps you are missing some plugin?
...\parkandrest-ui\node_modules\#angular-devkit\build-angular\src\angular-cli-files\plugins\packages\angular_devkit\build_angular\src\angular-cli-files\plugins\karma.ts:52
const options = config.buildWebpack.options;
^ TypeError: Cannot read property 'options' of undefined
at init (...\parkandrest-ui\node_modules\#angular-devkit\build-angular\src\angular-cli-files\plugins\packages\angular_devkit\build_angular\src\angular-cli-files\plugins\karma.ts:52:39)
at Array.invoke (...\parkandrest-ui\node_modules\di\lib\injector.js:75:15)
at Injector.get (...\parkandrest-ui\node_modules\di\lib\injector.js:48:43)
at E:\Workspace\Training\spring-boot-tutorial\parkandrest-ui\node_modules\karma\lib\server.js:166:20
at Array.forEach ()
at Server._start (...\parkandrest-ui\node_modules\karma\lib\server.js:165:21)
at Injector.invoke (...\parkandrest-ui\node_modules\di\lib\injector.js:75:15)
at Server.start (...\parkandrest-ui\node_modules\karma\lib\server.js:126:18)
at Object.
My karma.conf.js file looks like this:
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '#angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('#angular-devkit/build-angular/plugins/karma')
],
client:{
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
files: [
{ pattern: './src/test.ts', watched: false }
],
preprocessors: {
'./src/test.ts': ['#angular-devkit/build-angular']
},
mime: {
'text/x-typescript': ['ts','tsx']
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true
},
angularCli: {
config: './angular.json',
environment: 'dev'
},
reporters: config.angularCli && config.angularCli.codeCoverage
? ['progress', 'coverage-istanbul']
: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false
});
};
#angular-devkit\build-angular is of course installed. I appreciate any help.
EDIT:
I have a solution which actually combines most of the user answers to my question with my own. Firstly I updated my whole project to stable angular 6 release. Next, I generated empty project like #R.Richards suggested and then I replaced almost every configuration in my old project with the new one. Finally, I have encountered a problem #Suvendu warn me about. I used his solution to resolve it. Unfortunately, I still have one problem with my environment (Intellij IDEA 2017.3.4 Ultimate) which disallows me to start karma tests directly from my IDE ( I've got the same error #Suvendu mentions about), however, it is a topic for the next question.
My solution was a little different, as I had to move the karma.conf.js.
Update all dependencies and make sure the app itself works as intented
If not done already: Replacing every occurrence of #angular/cli with #angular-devkit/build-angular in the karma.conf.js
Removing the files and the preprocessor configs from the karma.conf.js completely. This is all defined in the angular.json and should be handled automatically by the #anguler-devkit karma plugin.
Could not find module "#angular-devkit/build-angular"
here is what worked for my project:
npm install -g #angular/cli
npm install #angular/cli
ng update #angular/cli --migrate-only --from=1.7.0
ng update #angular/core
npm install rxjs-compat
ng serve
I hope this works for you!
I followed this guide to do a clean migration of the project, which solved the same issue for me.
Try installing karma-webpack with npm and then add it to the plugins array -
plugins: [
...
require('karma-webpack'),
...
],
and replace the preprocessors with this -
preprocessors: {
'./src/test.ts': ['webpack']
},
This worked in my case and will also work for the below anticipated future error-
Error: The '#angular-devkit/build-angular/plugins/karma' karma plugin is meant to be used from within Angular CLI and will not work correctly outside of it.
Hope this helps.
The solution for me was that my NODE_ENV environmental variable was set to "production". While trying to upgrade to Angular 6 I did not realize that #angular-devkit/build-angular was listed in my devDependencies, which are not installed in a production environment.
Running "unset NODE_ENV" and removing NODE_ENV from /etc/environment fixed my problem. (Note: Be careful changing this variable in an actual production environment).
In your karma.conf.js add following library, in plugins section. This is done in Angular8.
require('#angular-devkit/build-angular/plugins/karma')

Building Durandal with Grunt (R.js + Text)

I would like to use Grunt to build a Durandal project, because Weyland remains completely undocumented and isn't as standard as Grunt.
To do this, the grunt task needs to pull in all the js and html files during optimization, but I am unable to get RequireJS to inline the html files via the text module.
It looks like weyland copies the text files manually, but I can't figure out what it's doing to get requirejs (or almond, in this case), to actually use them. I have seeen this question, but it requires the text modules to be referenced in the define call, which isn't done in Durandal.
My gruntfile for require uses this config
requirejs: {
build: {
options: {
name: '../lib/require/almond-custom', //to deploy with require.js, use the build's name here instead
insertRequire: ['main'], //needed for almond, not require
baseUrl: 'src/client/app',
out: 'build/main-built.js',
mainConfigFile: 'src/client/app/main.js', //needed for almond, not require
wrap: true, //needed for almond, not require
paths: {
'text': '../lib/require/text',
'durandal':'../lib/durandal/js',
'plugins' : '../lib/durandal/js/plugins',
'transitions' : '../lib/durandal/js/transitions',
'knockout': '../lib/knockout-2.3.0',
'bootstrap': '../lib/bootstrap.min',
'jquery': '../lib/jquery-1.9.1',
'Q' : '../lib/q.min'
},
inlineText: true,
optimize: 'none',
stubModules: ['text']
}
}
}
You might want to give https://npmjs.org/package/grunt-durandal a try. I'm using this as part of a grunt based build process. See https://github.com/RainerAtSpirit/HTMLStarterKitPro for an example.
durandal: {
main: {
src: ['app/**/*.*', 'lib/durandal/**/*.js'],
options: {
name: '../lib/require/almond-custom',
baseUrl: requireConfig.baseUrl,
mainPath: 'app/main',
paths: mixIn({}, requireConfig.paths, { 'almond': '../lib/require/almond-custom.js' }),
exclude: [],
optimize: 'none',
out: 'build/app/main.js'
}
}
},
As a possible alternative to Grunt I would suggest looking at Mimosa. It's not as widely used as Grunt but is well documented and requires a good deal less configuration and if you start with the durandal skeleton everything is configured for you including inlining html.
Durandal also recommends it and tells you how to get started with it: http://durandaljs.com/pages/get-started/
You can run make start to start developing and make dist to have it package everything up for release.

karma error 'There is no timestamp for'

Trying to get karma working with requirejs. I don't understand why I am getting all of these errors when running Karma:
ERROR: 'There is no timestamp for /base/test/mainSpec.js?bust=1387739317116!'
ERROR: 'There is no timestamp for /base/app/main.js?bust=1387739317116!'
ERROR: 'There is no timestamp for /base/bower_components/jquery/jquery.js?bust=1387739317116!'
When I go to the network tab in inspector, all of the files are there with no 404s.
I'm a little confused because karma seems to be looking for a 'base' directory but there is no 'base' directory in my project. According to the karma docs:
Karma serves files under the /base directory. So, on the server
requests to files will be served up under
http://localhost:9876/base/*. The Require.js config for baseUrl gives
a starting context for modules that load with relative paths. When
setting this value for the Karma server it will need to start with
/base. We want the baseUrl for our tests to be the same folder as the
base url we have in src/main.js, so that relative requires in the
source won’t need to change. So, as we want our base url to be at
src/, we need to write /base/src.
This confusing to say the least. Am I supposed to have a baseUrl configuration in my main.js file that points to '/base'?
note: This post was valid by Karma in 2014 Jan 16. I am not certain of the current state of that lib, maybe they fixed their weird configuration logic and added meaningful error messages. If not, then this post can be probably very helpful by fixing configuration issues related to Karma.
These kind of errors occur by misconfiguration. You should add everything your test uses to the file patterns in your config file.
For example:
module.exports = function (config) {
config.set({
basePath: './',
frameworks: ['jasmine', 'requirejs'],
files: [
{pattern: 'test/bootstrap.js', included: true},
{pattern: 'test/**/*.js', included: false},
{pattern: 'src/**/*.js', included: false},
{pattern: 'vendor/**/*.js', included: false}
],
exclude: [
],
reporters: ['progress'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Firefox'],
captureTimeout: 6000,
singleRun: false
});
};
In this example the bootstrap.js is the only file included by Karma in the HTML, the other files are dependencies which are loaded by the code in the bootstrap.js. The pattern order is very important and sadly it is far from logical: the next pattern does not override the previous one. So if I'd give the test/**/*.js pattern as first and test/bootstrap.js as second, it would not work because the bootstrap would not be included. In these cases Karma sends you an "empty testsuite" message, which is useless if you don't know how to configure it...
If your tests try to use a file which is not covered by the patterns you gave in your Karma configuration file, then you will get the "There is no timestamp for xy" error message, which is very similar to the previously mentioned "empty testsuite". If you don't know the system you won't have a clue, what it means, or what you have to do in order to fix it ...
The exclude part of the configuration object is for files, which have been added to the file patterns for inclusion, but you don't want to include or use them in your tests. These can be for example requirejs configuration files for development and production environments, etc...
For me it was simply making the mistake of setting basePath: 'base' instead of baseUrl: '/base'.
baseUrl: '/base' ftw!
The basePath is to identify the root of your project relative to the configuration file (karma.conf.js). Take a look at this example: https://github.com/karma-runner/karma/blob/v0.8.5/test/client/karma.conf.js
In the browser, I also got this error about the timestamp but it doesn't affect anything. The tests are working properly. I guess it should be a warning more than an error :-)
Jeff's right, you should exclude the requirejs config file of your app, because "we don't want to actually start the application in our tests. [LINK]".
The test-main.js config file is a separate file from the requirejs config file your app uses, which in your case might be config.js or main.js, depending on where you config your requirejs.
They both configures path and dependencies (could be specifying about the same ones), but the former is to provide requirejs support for the tests you write. This whole requirejs setup is a separate one from the requirejs you use in your app. So don't include the latter, it confuses Karma.
And the link above is a working Karma with its requirejs demo, check it out.
After trying all the solutions posted on different sources, Finally I got it Fixed. Check it here: Make "no timestamp" error configurable #6 .
Example from the issue for the karma.conf.js file:
client: {
requireJsShowNoTimestampsError: '^(?!.*(^/base/app/node_modules/))'
}
in my karma.conf.js file, I simply excluded my file that contained my require.config function (in my case happened to be config.js) and the errors went away.
exclude: [
'app/config.js',
'bower_components/jasmine/**/*.js'
],
This error can also happen when the files in question don't actually exist!
So check to make sure that the file you're getting this error for actually exists in your project!
Once you find out what the files are, you can ignore them using a pattern like so in your karma.conf.js, if it turns out their existence should be ignored in some cases:
exclude: [
'path/to/files/to/ignore/**/*.js'
]
I had an exact same error in my project and I found that the best and fastest way to debug where is the problem is to list the files that our karma have loaded.
If you used karma init (if not, just do it) and respond YES to the question about the usage of RequireJS you probably have a file like this:
var tests = [];
var TEST_REGEXP = /(spec|test)\.js$/i;
var BASE_URL = '/base/build/js';
var BASE_URL_REGEXP = /^\/base\/build\/js\/|\.js$/g;
// Get a list of all the test files to include
Object.keys(window.__karma__.files).forEach(function (file) {
console.log(file;) // ADD THIS CONSOLE LOG TO LIST LOADED FILES
if (TEST_REGEXP.test(file)) {
var normalizedTestModule = file.replace(BASE_URL_REGEXP, '')
tests.push(normalizedTestModule)
}
})
require.config({
// Karma serves files under /base, which is the basePath from your config file
baseUrl: BASE_URL,
paths: {
},
shim: {
},
deps: tests,
// we have to kickoff jasmine, as it is asynchronous
callback: window.__karma__.start
})
Then you can play with your karam.conf.js file and load new files to check whats going on in karma local path.
Expanding from #Naruto Sempai's answer:
I resolved this issue by first setting the basePath attribute in my karma.conf.js file. This path contains the needed ../ (previous directory) strings until my path was at the root of my source/test files.
Then I modified my test-main.js file (containing my RequireJS configuration) and set the baseUrl to /base.
Now, no timestamp errors.
--
To illustrate my environment and paths I configured, heres a basic setup example:
Source file location:
/Users/ben/some-project/src/main/resources/var/www/project/js/app
Test file location:
/Users/ben/some-project/src/test/var/www/project/
Karma Config location:
/Users/ben/some-project/src/test/var/www/project/karma.conf.js
Test RequireJS Config location:
/Users/ben/some-project/src/test/var/www/project/test-main.js
My karma.conf.js:
module.exports = function (config) {
config.set({
basePath: '../../../../'
});
}
to make my "root" at /Users/ben/some-project/src/.
My test-main.js:
requirejs.config({
baseUrl: '/base'
});

watch doesn't refresh the page on file change (express site)

It would be nice to have the browser automatically reload the page when I change a project file. I have this node-express site with the server being defined in 'server.js'
However, I've tried different grunt configurations, but none of them caused the browser to reload on a file change although the 'watch' task prints a message that the file changed!
Here is the relevant grunt configuration:
watch: {
all: {
files: 'views/index.ejs', // for now only watch this file!
options: {
livereload: true
}
}
},
express: {
options: {
background: true,
error: function(err, result, code) {},
fallback: function() {},
port: 3000
delay: 0,
output: ".+",
debug: false
},
dev: {
options: {
script: './server.js',
node_env: 'development',
livereload: true
}
}
}
....
grunt.registerTask('server', [
'express:dev',
'open',
'watch'
])
};
And to run the task I do
$> grunt server
Can someone explain what is wrong with this configuration ?
thnx
You need to install the livereload browser plugin from http://livereload.com/
I am trying to use grunt livereload to reload css changes on my node.js pages. I am getting closer to solve my problem which is similar to yours. So from what i know so far and please correct me if i'm wrong you dont need to install "livereload browser plugin" right? I used grunt alone without node.js and i could just use livereload without installing "livereload browser plugin" i just had to add a line in my .html (the problem i run into with node is how to reload .ejs and i found this page/question on the way solving it) : so i dont know if installing the livereload thing is another way to do the script part or if this is the case like i mentioned in my problem if i want to live reload .ejs i have to install the plugin.

How to test nodejs backend code with Karma (testacular)

How do I setup Karma to run my backend unit tests (written with Mocha)? If I add my backend test script to the files = [], it fails stating that require is undefined.
You don't. Karma is only for testing browser-based code. If you have a project with mocha tests on the backend and karma/mocha on the front end, try editing your package.json under scripts to set test to: mocha -R spec && karma run karma.con
Then, if npm test returns true, you'll know it's safe to commit or deploy.
It seems like it cannot be done (thanks #dankohn). Here is my solution using Grunt:
Karma: update your karma.conf.js file
set autoWatch = false;
set singleRun = true;
set browsers = ['PhantomJS']; (to have inline results)
Grunt:
npm install grunt-contrib-watch grunt-simple-mocha grunt-karma
configure the two grunt tasks (see grunt file below)
Gruntfile.js:
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-simple-mocha');
grunt.loadNpmTasks('grunt-karma');
grunt.initConfig({
simplemocha: {
backend: {
src: 'test/server-tests.js'
}
},
karma: {
unit: {
configFile: 'karma.conf.js'
}
}
});
// Default task.
grunt.registerTask('default', ['simplemocha', 'karma']);
};
Grunt (optional): configure grunt-watch to run after changing spec files or files to be tested.
run all using grunt command.

Resources