Issue running karma task from gulp - node.js

I am trying to run karma tests from gulp task and I am getting this error:
Error: 1
at formatError (C:\Users\Tim\AppData\Roaming\npm\node_modules\gulp\bin\gulp.js:161:10)
at Gulp.<anonymous> (C:\Users\Tim\AppData\Roaming\npm\node_modules\gulp\bin\gulp.js:187:15)
at Gulp.emit (events.js:95:17)
at Gulp.Orchestrator._emitTaskDone (C:\path\to\project\node_modules\gulp\node_modules\orchestrator\index.js:264:8)
at C:\path\to\project\node_modules\gulp\node_modules\orchestrator\index.js:275:23
at finish (C:\path\to\project\node_modules\gulp\node_modules\orchestrator\lib\runTask.js:21:8)
at cb (C:\path\to\project\node_modules\gulp\node_modules\orchestrator\lib\runTask.js:29:3)
at removeAllListeners (C:\path\to\project\node_modules\karma\lib\server.js:216:7)
at Server.<anonymous> (C:\path\to\project\node_modules\karma\lib\server.js:227:9)
at Server.g (events.js:180:16)
My system is Windows 7, nodejs version is v0.10.32, gulp version:
[10:26:52] CLI version 3.8.8
[10:26:52] Local version 3.8.9
Also, the same error I am getting on Ubuntu 12.04 LTS while on newer Ubuntu (not sure what version) and mac os it is seems to be working ok. What can cause this error?
Update 5/11/2016: Before writing comment about the fact that accepted answer hide errors, please, see first two comments to that particular accepted answer. Use it only if know what you are doing. Related info: https://github.com/karma-runner/gulp-karma/pull/15

How are you running your tests with Gulp? I came up against this issue recently on OSX, running node v0.11.14 and gulp 3.8.10, whenever there were failing tests.
Changing from the recommended:
gulp.task('test', function(done) {
karma.start({
configFile: __dirname + '/karma.conf.js',
singleRun: true
}, done);
});
To:
gulp.task('test', function(done) {
karma.start({
configFile: __dirname + '/karma.conf.js',
singleRun: true
}, function() {
done();
});
});
...got rid of this error.
Seems to be down to how gulp handles error messages when an error is signalled in a callback. See Improve error messages on exit for more information.

None of these solutions worked correctly for me using gulp 3.9.1 and karma 1.1.1. Adding a reference to gulp-util npm install --save-dev gulp-util and updating the task to the below fix the error output very nicely, while maintaining exit status correctly.
var gutil = require('gulp-util');
gulp.task('test', function (done) {
new Server({
configFile: __dirname + '/karma.conf.js',
singleRun: true
}, function(err){
if(err === 0){
done();
} else {
done(new gutil.PluginError('karma', {
message: 'Karma Tests failed'
}));
}
}).start();
});

Below is a code snippet from gulp patterns on using Karma. It's a bit similar, but also uses the newer method how to start the karma.
/**
* Start the tests using karma.
* #param {boolean} singleRun - True means run once and end (CI), or keep running (dev)
* #param {Function} done - Callback to fire when karma is done
* #return {undefined}
*/
function startTests(singleRun, done) {
var child;
var excludeFiles = [];
var fork = require('child_process').fork;
var KarmaServer = require('karma').Server;
var serverSpecs = config.serverIntegrationSpecs;
if (args.startServers) {
log('Starting servers');
var savedEnv = process.env;
savedEnv.NODE_ENV = 'dev';
savedEnv.PORT = 8888;
child = fork(config.nodeServer);
} else {
if (serverSpecs && serverSpecs.length) {
excludeFiles = serverSpecs;
}
}
var server = new KarmaServer({
configFile: __dirname + '/karma.conf.js',
exclude: excludeFiles,
singleRun: singleRun
}, karmaCompleted);
server.start();
////////////////
function karmaCompleted(karmaResult) {
log('Karma completed');
if (child) {
log('shutting down the child process');
child.kill();
}
if (karmaResult === 1) {
done('karma: tests failed with code ' + karmaResult);
} else {
done();
}
}
}

What worked for me and gave a nice formatted error message is to provide an Error instance to the done callback.
gulp.task('test', function(done) {
karma.start({
configFile: __dirname + '/karma.conf.js',
singleRun: true
}, function(result) {
if (result > 0) {
return done(new Error(`Karma exited with status code ${result}`));
}
done();
});
});

If you want to return with an error code, and want to see Karma's error output but not Gulp's (probably unrelated) stack trace:
gulp.task('test', function() {
karma.start({
configFile: __dirname + '/karma.conf.js',
singleRun: true
}, function(karmaExitStatus) {
if (karmaExitStatus) {
process.exit(1);
}
});
});

Not sure about Ubuntu, but I was getting a similar error on Windows, and installing one version back fixed it right away like this:
npm install -g gulp#3.8.8
npm install gulp#3.8.8

this is gulp's way of telling your tests have failed and that karma exited with a return code of 1. Why you would want to call done yourself and not pass the error as a message baffles me.

The right way to solve this according to Karma's documentation and https://github.com/pkozlowski-opensource, is to rely on Karma's watch mechanism rather than Gulp's:
gulp.task('tdd', function (done) {
karma.start({
configFile: __dirname + '/karma.conf.js'
}, done);
});
Note the omission of singleRun: true.
#McDamon's workaround will work for gulp.watch, but you don't want to swallow exit codes like that when running on a CI server.
Gulp is also reworking how they handle exit codes in scenarios just like this one. See https://github.com/gulpjs/gulp/issues/71 and the other dozen or so related issues.

gulp.task('test', function(done) {
karma.start({
configFile: __dirname + '/karma.conf.js',
singleRun: false
}, done);
});
passing singleRun: false argument will prevent the process from returning a value different of 0 (which would signify an error and exit gulp).
Run with singleRun: true if you only launching your test from a command line, not part of a continuous integration suite.

In case anyone else comes here, do not use the accepted solution. It will hide failed tests. If you need a quick solution to modify your gulp test task, you can use the solution found in this comment in this github thread.
gulp.src(src)
// pipeline...
.on('error', function (error) {
console.error('' + error);
});

Related

Browsersync not reloading browser or injecting css

I've been trying to get this straight for a few days now but haven't been able to get it working the way I need to. I'm unable to find any examples of other people using Browsersync with .net core, that may even be the reason I'm experiencing all of these issues. But I can't find any evidence that proves that and wouldn't understand why exactly that would be the case.
Anyway... I've got everything working in my gulp file exactly how I want it to for sass/js for handling errors, etc. I'm not new to gulp otherwise I'd blame my lack of experience for my inability to get this working.
Here's my gulp file followed by what the output is when running gulp.
Default Task:
const gulp = require("gulp"),
uglify = require("gulp-uglify"),
sass = require("gulp-sass"),
rename = require('gulp-rename'),
sassGlob = require('gulp-sass-glob'),
postcss = require('gulp-postcss'),
autoprefixer = require('gulp-autoprefixer'),
sourcemaps = require('gulp-sourcemaps'),
cleanCSS = require('gulp-clean-css'),
concat = require('gulp-concat'),
msbuild = require('gulp-msbuild'),
through = require('through2'),
notifier = require('node-notifier'),
browserSync = require('browser-sync').create();
// Static Server + watching scss/html files
gulp.task('serve', ['sass', 'compileJS'], function() {
browserSync.init({
proxy : {
target: "https://localhost:3000",
},
files: ['./wwwroot/css/*'],
rewriteRules: [
{
match: new RegExp('/css/main.min.css'),
fn: function() {
return './wwwroot/css/main.min.css'
}
}
]
});
//Watch for any changes to the scss files.
gulp.watch('./wwwroot/sass/**/*.scss', ['sass']);
//Watch for any changes to the js files, reload after those changes are made.
gulp.watch('./wwwroot/js/source/*.js', ['compileJS']).on('change', browserSync.reload);
//Watch for any changes to a .cshtml file and reload the browser if/when that change happens.
gulp.watch("./**/*.cshtml").on('change', browserSync.reload);
});
gulp.task('default', ['serve']);
/**
* Compiles SASS files and stores the result into the public folder
*/
gulp.task('sass', function () {
return gulp.src('./wwwroot/sass/main.scss')
.pipe(sassGlob())
.pipe(sass().on('error', function (err) {
console.log('Sass Error:', err.toString());
notifier.notify({
'title': 'Gettin\' Sassy 💁‍♀️',
'message': 'You goofed. Check your terminal window for more information.'
});
this.emit("end");
}))
.pipe(postcss([require('autoprefixer')]))
.pipe(
autoprefixer({
browsers: ['last 2 versions'],
cascade: false
})
)
.pipe(
through.obj(function(chunk, enc, cb) {
cb(null, chunk)
})
)
.pipe(cleanCSS({compatibility: 'ie8',
level: 2}))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest('./wwwroot/css'))
.pipe(browserSync.stream());
});
/**
* Compiles the Javascript files and stores the result in the public folder
*/
gulp.task('compileJS', function (done) {
return gulp.src('./wwwroot/js/source/*.js')
.pipe(sourcemaps.init())
.pipe(concat('main.js'))
.pipe(uglify().on('error', function (err) {
console.log('JS Uglify Error:', err.toString());
notifier.notify({
'title': 'JS Compile Error',
'message': 'Something about your JS is a little off. Check yourself before you wreck yourself.'
});
this.emit("end");
}))
.pipe(rename({suffix: '.min'}))
.pipe(sourcemaps.write('../maps'))
.pipe(gulp.dest('./wwwroot/js/dist'));
});
Output:
$ gulp
[21:34:15] Using gulpfile
~/Repos/PROJECT_DIRECTORY/PROJECT_NAME/gulpfile.js
[21:34:15] Starting 'sass'...
[21:34:15] Starting 'compileJS'...
[21:34:15] Finished 'sass' after 437 ms
[21:34:15] Finished 'compileJS' after 426 ms
[21:34:15] Starting 'serve'...
[21:34:16] Finished 'serve' after 1 s
[21:34:16] Starting 'default'...
[21:34:16] Finished 'default' after 68 μs
[Browsersync] Proxying: https://localhost:3000
[Browsersync] Access URLs:
------------------------------------
Local: https://localhost:3000
External: https://10.0.0.137:3000
------------------------------------
UI: http://localhost:3001
UI External: http://localhost:3001
------------------------------------
[21:34:35] Starting 'sass'...
[Browsersync] 1 file changed (main.min.css)
[21:34:35] Finished 'sass' after 207 ms
[21:34:58] Starting 'compileJS'...
[21:34:58] Finished 'compileJS' after 154 ms
[Browsersync] Reloading Browsers...
So, looking at that output you would probably think to yourself, "This dude is an idiot... Browsersync states that it's reloading browsers..." Right, it does state that, but it is not reloading the browser. Browsersync also fails to inject my css into the browser as well.
As I mentioned, I've used gulp before, and this setup closely represents the gulp files that I use when doing Wordpress development as well. However, it won't work for this project (which has led me to my .net core / Visual Studio suspicions).
You could just do something like this
Create a env variable thats global to your application then above the closing tag in your view you can add the following code.
This code is how I do it in Laravel with my Blade templates but it should be exactly the same you just need to replace it with the way .NET does it, I think they use Razor templating engine :)
{{-- Live reload with browser sync --}}
#if (!empty(env('APP_ENV')) && env('APP_ENV') === 'local')
<script
async
defer
src="{{ URL::to('/') . ':3000/browser-sync/browser-sync-client.js?v=2.26.7'}}">
</script>
#endif
Hope this helps you.
Just for interest sake below is my gulp pipeline:
const browserSync = require("browser-sync");
const sass = require("gulp-sass");
const autoprefixer = require("gulp-autoprefixer");
const sourcemaps = require("gulp-sourcemaps");
const rename = require("gulp-rename");
const reviser = require("gulp-rev");
const runSequence = require("run-sequence");
gulp.task("browserSync", function() {
return browserSync.init({
open: false,
https: false,
notify: false,
injectChanges: true,
proxy: "http://{site-name-here}.local/",
});
});
gulp.task("compile:scss", function() {
return (
gulp
// Gets the main.scss file
.src("resources/assets/scss/main.scss")
// Passes it through a gulp-sass, log errors to console
.pipe(sass().on("error", sass.logError))
// Adds versioning
.pipe(reviser())
// Add vendor prefixes
.pipe(
autoprefixer({
browsers: ["last 2 versions"],
cascade: false
})
)
// Rename the file
.pipe(rename({ suffix: ".min" }))
// Outputs it in the css folder
.pipe(gulp.dest("public/css"))
// Add sourcemaps
.pipe(sourcemaps.write())
// Adds versioned file to manifest so we can access with the same name
.pipe(reviser.manifest("manifest/rev-manifest.json"), { merge: true })
// Outputs it in the css folder
.pipe(gulp.dest("public/css"))
.pipe(
browserSync.reload({
// Reloading with Browser Sync
stream: true
})
)
);
});
// Watchers
gulp.task("watch", function() {
gulp.watch(["./resources/assets/scss/**/*"], "compile:scss", browserSync.reload);
});
// Default task
gulp.task("start", function(callback) {
return runSequence(
"browserSync",
"compile:scss",
"watch",
callback
);
});
to use it I just run gulp start
Keep in mind that running gulp like this you will need to have gulp installed globally. to do this run npm install --global gulp-cli

Gulp task is causing my Node process to hang

I'm trying to run the 'rundev' task in the following gulp code but it keeps causing my Node/Gulp process to hang. I can't unhang them without restarting my computer so tracking down the problem has proven difficult.
const gulp = require("gulp");
const concat = require("gulp-concat");
const uglify = require("gulp-uglify");
const uglifycss = require("gulp-uglifycss");
const del = require("del");
const sass = require('gulp-sass');
const streamqueue = require('streamqueue');
const gzip = require('gulp-gzip');
const compression = require('compression');
const browserSync = require("browser-sync").create();
const scripts = require("./scripts");
const styles = require("./styles");
var devMode = false;
gulp.task("html", function() {
gulp.src("./src/html/**/*.html")
.pipe(gulp.dest("./dist/"))
/*.pipe(gzip({extension: 'gz'}))
.pipe(gulp.dest("./dist/"))*/
.pipe(browserSync.reload({
stream: true
}));
});
gulp.task("css", function() {
var cssRaw = gulp.src(styles["css"])
.pipe(uglifycss());
var cssFromSass = gulp.src(styles["scss"])
.pipe(sass({outputStyle: 'compressed'}));
return streamqueue({objectMode: true},
cssFromSass,
cssRaw)
.pipe(concat("allStyles.min.css"))
.pipe(gulp.dest("./dist/css"))
/*.pipe(gzip({extension: 'gz'}))
.pipe(gulp.dest("./dist/css"))*/
.pipe(browserSync.reload({
stream: true
}));
});
gulp.task("js", function() {
var jsMin = gulp.src(scripts["min"]);
var jsOther = gulp.src(scripts["other"])
.pipe(uglify());
return streamqueue({objectMode: true},
jsMin,
jsOther)
.pipe(concat("allScripts.min.js"))
.pipe(gulp.dest("./dist/js"))
/*.pipe(gzip({extension: 'gz'}))
.pipe(gulp.dest("./dist/js"))*/
.pipe(browserSync.reload({
stream: true
}));
});
gulp.task("fonts", function() {
gulp.src(["./src/fonts/**/*.eot",
"./src/fonts/**/*.svg",
"./src/fonts/**/*.ttf",
"./src/fonts/**/*.woff",
"./src/fonts/**/*.woff2"])
.pipe(gulp.dest("./dist/fonts"))
.pipe(browserSync.reload({
stream: true
}));
});
gulp.task("images", function() {
gulp.src(["./src/images/**/*.*"])
.pipe(gulp.dest("./dist/images"))
.pipe(browserSync.reload({
stream: true
}));
});
gulp.task("sounds", function() {
gulp.src(["./src/sounds/**/*.*"])
.pipe(gulp.dest("./dist/sounds"))
.pipe(browserSync.reload({
stream: true
}));
});
gulp.task("clean", function() {
return del('./dist/**', {read: false});
});
gulp.task("build", ['clean'], function() {
gulp.start(["css", "js", "html", "fonts", "images", "sounds"]);
});
gulp.task("browser-sync", function() {
browserSync.init(null, {
open: false,
server: {
baseDir: "dist",
middleware: compression()
}/*,
httpModule: 'http2',
https: true*/
});
});
gulp.task("rundev", function() {
devMode = true;
gulp.start(["build", "browser-sync"]);
gulp.watch(["./src/css/**/*.css", "./src/css/**/*.scss"], ["css"]);
gulp.watch(["./src/js/**/*.js"], ["js"]);
gulp.watch(["./src/html/**/*.html"], ["html"]);
gulp.watch(["./src/fonts/**/*.*"], ["fonts"]);
});
I recently picked this project back up after a month long break and haven't touched the code since, yet I've never had this issue before.
I have this problem when I try to run 'gulp rundev' in my Git Bash window. It appears to complete without errors but never actually serves the files and I can't use the Git Bash window or even close it afterwards (none of these work: clicking exit, Alt+F4, or killing the process in Task Manager). The only way to get rid of it is to restart the computer. I'm using Windows 10, Node v8.9.4, Gulp v3.9.1, Brackets, and Git Bash as my development environment in case that helps.
Here's a copy of the output:
MyName#MyComputer MINGW64 ~
$ cd Documents/GitHub/PoeFilterEditor
MyName#MyComputer MINGW64 ~/Documents/GitHub/PoeFilterEditor (Development)
$ gulp rundev
[12:11:27] Using gulpfile ~\Documents\GitHub\PoeFilterEditor\gulpfile.js
[12:11:27] Starting 'rundev'...
[12:11:27] Starting 'clean'...
[12:11:27] Starting 'browser-sync'...
[12:11:27] Finished 'browser-sync' after 114 ms
[12:11:28] Finished 'rundev' after 816 ms
[Browsersync] Access URLs:
--------------------------------------
Local: http://localhost:3000
External: http://192.168.1.142:3000
--------------------------------------
UI: http://localhost:3001
UI External: http://192.168.1.142:3001
--------------------------------------
[Browsersync] Serving files from: dist
I do remember getting more 'Starting' and 'Finished' lines in the output for the other tasks that are called by 'rundev' but otherwise the output looks normal.
Since the 'clean' task never reports as 'Finished' I assume the problem is somehow related to that and my research seems to indicate that the problem has something to do with permissions or the files being locked when it tries to operate on them. To this end, I've tried messing with the devMode, closing all programs except the Git Bash to call the task, and making sure everything is running with admin privileges, but it always hangs.
I'm a bit new to Node and Gulp so there may be something glaringly obvious that I don't even know to ask about, so hopefully someone here can help me learn my way through this.

How do I run Jest Tests

I have following hello World test to my __tests__ folder:
hello-test.js:
describe('hello world', function() {
it('basic test', function() {
expect(1).toBe(1);
});
});
My aim is to eventually write tests in es6 and run using a gulp task. I have tried running the above with the following gulp task:
gulp.task('jest', ['test-compile'], function(done){
jest.runCLI({
rootDir : __dirname,
//scriptPreprocessor : "../node_modules/babel-jest",
testFileExtensions : ["es6", "js"],
}, __dirname, function (result) {
if (result) {
console.log(result);
} else {
console.log('Tests Failed');
}
done();
});
});
I have also tried running jest using the globally install jest-cli and cannot get it to work, I also tried using the npm test way as shown on line but no matter which of these I try I just get Using Jest CLI v0.6.0 in the terminal, no errors no results.
I am very confused as I seem to be doing what all the doc's online say. I am using Node 4.2.1 if that has any bearing

Babel not working with Mocha and starting Node server

I am running sailsjs, mocha, and babel on sails and mocha. When I run, my before function to start the sails app before running tests, I get this:
> PORT=9999 NODE_ENV=test mocha --recursive --compilers js:babel/register
lifting sails
1) "before all" hook
0 passing (757ms)
1 failing
1) "before all" hook:
Uncaught Error: only one instance of babel/polyfill is allowed
For the life of me, I can't figure out how to make mocha running babel and sails running babel at the same time work.
My before() code looks like this:
import Sails from 'sails'
// Global before hook
before(function (done) {
console.log('lifting sails')
// Lift Sails with test database
Sails.lift({
log: {
level: 'error'
},
models: {
connection: 'testMongoServer',
migrate: 'drop'
},
hooks: {
// sails-hook-babel: false
babel: false
}
}, function(err) {
if (err) {
return done(err);
}
// Anything else you need to set up
// ...
console.log('successfully lifted sails')
done();
});
});
I use sails-hook-babel and it works like a charm. Here to do it:
Install npm install sails-hook-babel --save-dev
Edit your bootstrap.js/ before function to load babel, i.e.
var Sails = require('sails'),
sails;
var options = {
loose : "all",
stage : 2,
ignore : null,
only : null,
extensions: null
};
global.babel = require("sails-hook-babel/node_modules/babel/register")(options);
before(function (done) {
Sails.lift({
//put your test only config here
}, function (err, server) {
sails = server;
if (err) return done(err);
// here you can load fixtures, etc.
done(err, sails);
});
});
after(function (done) {
// here you can clear fixtures, etc.
sails.lower(done);
});
Now you are able to use ES6 within your tests.
Here is the reference:
Babel issue at GitHub
My Blog, sorry it written in Bahasa Indonesia, use Google translate if you want to.

How do I test grunt task callback with nodeunit?

I have a nodeunit test that tests my custom grunt task:
'use strict';
var grunt = require('grunt');
exports.when_executing_single_command = {
it_should_execute_successfully: function(test) {
test.expect(1);
grunt.initConfig({
mytask: {
success: function(data) {
test.strictEqual(data, '1');
test.done();
}
}
});
require('../src/mytask')(grunt);
grunt.registerTask('default', ['mytask']);
grunt.task.run('default');
}
};
Based on nodeunit documentation the test appears to be setup correctly, but the callback is never executed and test continues to run indefinitely.
I know that under the right conditions the callback is definitely executed, so this is not a bug in my task.
Exact same issue here.
It appears to me that grunt is queuing task calls. So if you launch your tests with a grunt nodeunit command you cannot launch another task inside your test, it will be queued and can only be run after your nodeunit task is done.
There is a solution but it doesn't fit for my case, it may apply for you :
grunt.util.spawn({
grunt: true,
args: ["your_task_name"],
opts:{
stdio: 'inherit'
}
}, function(){
// Do something
})
grunt.util.spawn

Resources