I'm pretty new to node. I built a sample express app and wrote some BDD tests for it using cucumber.js. I would like to automate the tests using gulp so that when I run my tests it will first start the express app and, once the server is up, run through the tests. However, currently the tests run before the server is up and therefore all fail. Is there a way to wait (using gulp) for the server to start and only then run the tests?
I'm using gulp-cucumber and gulp-express here (somewhat hidden by gulp-load-plugins).
My gulpfile (partial):
var gulp = require('gulp'),
plugins = require('gulp-load-plugins')();
gulp.task('server', function () {
plugins.express.run(['bin/www']);
});
gulp.task('cucumber', ['server'], function() {
return gulp.src('features/*').pipe(plugins.cucumber({
'steps': 'features/steps/*.steps.js',
'support': 'features/support/*.js'
}));
});
gulp.task('test', ['server', 'cucumber']);
I have to use this solution - https://www.npmjs.com/package/run-sequence
var gulp = require('gulp'),
plugins = require('gulp-load-plugins')(),
runSequence = require('run-sequence');
gulp.task('server', function () {
plugins.express.run(['bin/www']);
});
gulp.task('cucumber', function() {
return gulp.src('features/*').pipe(plugins.cucumber({
'steps': 'features/steps/*.steps.js',
'support': 'features/support/*.js'
}));
});
gulp.task('test', function(){
runSequence('server', 'cucumber');
});
Related
I checked out my project on a new machine and get an unsatisfying console output.
Console Output
gulp default
Using gulpfile ...\gulpfile.js
Task never defined: default
Please check the documentation for proper gulpfile formatting
gulp -v
CLI version 1.2.2
Local version 4.0.0-alpha.2
Settings
Node interpreter: nodejs-6.9.2\node.exe
Gulp package: node_modules\gulp-4.0.build
Gulp File Content
'use strict';
var gulp = require('gulp');
var del = require('del');
var path = require('path');
var sass = require('gulp-sass');
var ts = require('gulp-typescript');
var gulpPromise = require("gulp-promise");
var gulpPromiseAll = require('gulp-all');
var merge = require('merge-stream');
var through = require('through2');
var runSequence = require('run-sequence');
var async = require("async");
var Rx = require('rx');
var chok = require('chokidar');
var deleteEmpty = require('delete-empty');
var browserSync = require('browser-sync').create();
var webserver = require('gulp-webserver');
var historyApiFallback = require('connect-history-api-fallback');
/* A few functions like this */
var yadda1 = function() {
return yadda9("yadda", yaddayadda);
};
/* A few tasks like this */
gulp.task('build', function(){
return gulpPromiseAll(
yadda1(),
yadda2(),
yadda3()
).then(
function() {
console.log("yadda");
}, function(err) {
console.error("yadda:", err);
}
);
});
gulp.task('default', gulp.series('build', 'serve', function(done) {
console.log("Default task that cleans, builds and runs the application [END]");
done();
}));
What am I doing wrong?
I just had this problem.
We both are using browser-sync, and a task related to browser-sync is where the problem was in my code, so there's a good chance that you have the same problem (and possibly in your other gulp tasks as well), but can't say for sure because you didn't share the tasks' code.
The problem:
In gulp 3.x you could write code like this:
gulp.task('watch', () => {
gulp.watch('./dev/styles/**/*.scss', ['styles'];
...
});
You can't in gulp 4.x.
The solution:
You have to pass a function instead of the name of a task in these cases. You can do this by passing a gulp.series() function. The above code becomes:
gulp.task('watch', () => {
gulp.watch('./dev/styles/**/*.scss', gulp.series('styles'));
...
});
Try making this change wherever applicable. Worked for me.
I want to be able to send the browserSync external URL as a parameter for an external node script in my gulp file. How can I get at that external URL through the browserSync object (or some other way)?
var gulp = require('gulp');
var shell = require('gulp-shell');
var browserSync = require('browser-sync').create();
gulp.task('default', ['browser-sync', 'config']);
gulp.task('browser-sync', function() {
browserSync.init({
proxy: "localhost:8024",
open: "external"
});
});
gulp.task('config', shell.task([
"node scripts/someNodeScript.js browserSync.externalURL"
]));
UPDATE
Based on the excellent answer by #sven-shoenung below, I slightly tweaked his solution and am successfully using this:
var gulp = require('gulp');
var browserSync = require('browser-sync').create();
var spawn = require('child_process').spawn;
var externalUrl;
var browserSyncDone = function () {
spawn('node', ['scripts/someNodeScript.js', externalUrl], {stdio:'inherit'});
};
gulp.task('default', ['browser-sync']);
gulp.task('browser-sync', function() {
browserSync.init({
proxy: "localhost:8024",
open: "external"
}, function() {
externalUrl = browserSync.getOption('urls').get('external');
browserSyncDone();
});
});
You can use browserSync.getOptions('urls') to get a Map of all access URLs. It returns something like this:
Map {
"local": "http://localhost:3000",
"external": "http://192.168.0.125:3000",
"ui": "http://localhost:3001",
"ui-external": "http://192.168.0.125:3001"
}
Note that is only available after browser-sync is successfully initialized, so you need to pass a callback function to browserSync.init() or you'll try to get the value too soon.
You won't be able to use gulp-shell for the same reason. shell.task() will be set up before browser-sync has initialized, so browserSync.getOptions('urls') isn't available yet.
I recommend you use the standard nodejs child_process.spawn() instead.
var gulp = require('gulp');
var browserSync = require('browser-sync').create();
var spawn = require('child_process').spawn;
var externalUrl;
gulp.task('default', ['browser-sync', 'config']);
gulp.task('browser-sync', function(done) {
browserSync.init({
proxy: "localhost:8024",
open: "external"
}, function() {
externalUrl = browserSync.getOption('urls').get('external');
done();
});
});
gulp.task('config', ['browser-sync'], function(done) {
spawn('node', ['scripts/someNodeScript.js', externalUrl], {stdio:'inherit'}).on('close', done);
});
Hi I was following a tutorial to build an nodejs app. This tutorial is using gulp, to run my app I just do gulp dev to start all things. In my gulpfile I have:
var fs = require('fs')
var gulp = require('gulp')
fs.readdirSync(__dirname+'/gulp').forEach(function(task){
require('./gulp/' + task)
})
gulp.task('dev', ['watch:css', 'watch:js', 'dev:server'])
The code in ./gulp/server.js
var gulp = require('gulp')
var nodemon = require('gulp-nodemon')
gulp.task('dev:server', function(){
nodemon({
script: 'server.js',
ext:'js',
ignore: ['ng*', 'gulp*', 'assets*'],
env: { 'NODE_ENV': require('../config').ENV }
})
})
Is it possible somehow to use pm2 with this gulp setup, I saw some questions in stackoverflow and google, but cant get anything done. If someone can help me would be great. Thank you in advance.
It's available at http://pm2.keymetrics.io/docs/usage/pm2-api/
var gulp = require('gulp');
var pm2 = require('pm2');
gulp.task('dev:server', function () {
pm2.connect(true, function () {
pm2.start({
name: 'server',
script: 'server.js',
env: {
"NODE_ENV": require('../config').ENV
}
}, function () {
console.log('pm2 started');
pm2.streamLogs('all', 0);
});
});
});
Implementation from https://github.com/Unitech/PM2/issues/1525#issuecomment-134236549
I have this script that watches over files in a directory
// the_script.js
var fs = require('fs');
fs.watch('someDir', function() {
console.log('I see you');
});
I run it with
node the_script.js
and it correctly keeps running forever.
Now I'd like to make it a grunt task, but if I write the task as
// Gruntfile.js
module.exports = function(grunt) {
grunt.registerTask('default', function(grunt) {
console.log('loading task');
var fs = require('fs');
fs.watch('someDir', function() {
console.log('I see you');
});
});
};
when I run
grunt
I just see "loading task" and than the process exits.
I want to know how to make the grunt task run forever and understand what's happening.
I only have gulp experience and from what I recall gulp executes and then terminates and if grunt is similar and you need to force it to stay open then try reading from the console (example, via the readline npm module):
https://www.npmjs.com/package/readline
I have the below NodeJS script, which polls an address for web automation tasks and executes upon receipt. Polling and parsing response is fine, but I'm unsure how to synchronously fire the mocha test runner within the res.on() method:
var express = require('express');
//...
app.set('port', process.env.PORT || 3000);
//...
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
app.get('/users', user.list);
var getTestTaskFromQueue = {
host: 'remotehost',
port: 3000,
path: '/met/my/test',
method: 'GET'
};
setInterval(function() {
var reqGet = http.request(getTestTaskFromQueue, function (res) {
var content;
res.on('data', function (chunk){
content += chunk;
});
res.on('end', function () {
content = JSON.parse(content.substring(9, content.length));
console.info("\nReceived Task:\n");
//run one test via mocha here
});
});
reqGet.end();
reqGet.on('error', function (e) {
console.error(e);
});
}, 10000);
And the test runner currently runs fine from CLI as such:
mocha test/folders/test_script.js --browser "firefox" --param1 foo
I'm evisioning stopping the setInterval loop at mocha execution start time and restarting it from a callback, but how should I execute the actual mocha test - from within the same script or talk to the CLI via subprocess?
You can call mocha.run() to start your test once your environment is ready.
Though, what you search is probably stub and mock objects to prevent your test from interacting with external sources.