Working on Windows I have installed Ruby and the Ruby DevKit to get things working with Cucumber. Now I have the following basic setup:
/app
/features
example.feature
/step_definitions
example.steps.js
In the example.feature file I have:
Feature: This is an example feature
In order to learn Cucumber
As a developer
I want to make this feature pass
Scenario: wrote my first scenario
Given a variable set to 1
When I increment the variable by 2
Then the variable should contain 3
And in the example.step.js file I have:
'use strict';
module.exports = function () {
this.givenNumber = 0;
this.Given(/^a variable set to (\d+)$/, function(number, next) {
this.givenNumber = parseInt(number);
next();
});
this.When(/^I increment the variable by (\d+)$/, function (number, next) {
this.givenNumber = this.givenNumber + parseInt(number);
next();
});
this.Then(/^the variable should contain (\d+)$/, function (number, next) {
if (this.givenNumber != number)
throw(new Error("This test didn't pass, givenNumber is " + this.givenNumber + " expected 0"));
next();
});
};
Now, when I run 'cucumber' from the /app dir I keep getting the folowing output:
1 scenario (1 undefined)
3 steps (3 undefined)
0m0.004s
I tried moving around the files, adding the --require option, etc. but nothing seems to be helping.
Any ideas?
Apparently this cannot be executed directly using the 'cucumber' command.
Settings things up using grunt and the grunt-cucumber task seems to be working as expected:
My Gruntfile.js
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
cucumberjs: {
src: 'features',
options: {
steps: 'features/step_definitions',
format: 'pretty'
}
}
});
grunt.loadNpmTasks('grunt-cucumber');
grunt.registerTask('default', ['cucumberjs']);
};
Additionally: if you are using protractor. It has cucumber build in. Just create the right config for protractor (protractor.conf.js):
exports.config = {
specs: [
//'e2e/features/*.feature'
'**/*.feature'
],
capabilities: {
'browserName': 'chrome'
},
baseUrl: 'http://localhost:9000/',
framework: 'cucumber'
}
Related
I have been trying to get this to work maybe I'm missing something. I am using ng-constant and setting up different environments end point as mentioned in the ng-constants issue
However I am using gulp and the configuration looks like
gulp.task('environmentsapi', function () {
return ngConstant({
stream: true,
development: {
constants: {
"ENV": {"api": "http://1.1.1.1:8082/"}
}
},
production: {
constants: {
"ENV": {"api": "https://productionapplink/"}
}
}
})
// Writes config.js to dist/ folder
.pipe(gulp.dest('dist/scripts/config'));
});
I cant figure out how to call the different end points in the different gulp tasks like the example in the link ngconstant:development etc. How can i run this within the task environmentsapi, since this task is shared in all environment builds. Please let me know how to do this.
gulp.task('build', function () {
runSequence('clean', ['sass', 'scripts', 'bower_components', 'environmentsapi' //How can I run ngconstant:development here? ], 'wiredep')
});
Simply create new tasks that set flags!
Here I'm using the development flag that defaults to true.
var development = true;
gulp.task('prod', function () {
development = false;
});
gulp.task('environmentsapi', function () {
const apiEndpoint = development ? 'http://1.1.1.1:8082/' : 'https://productionapplink/';
return ngConstant({
stream: true,
constants: {
'ENV': {api: apiEndpoint}
}
});
});
Now, using gulp build will build your application with the ENV.api set to 'http://1.1.1.1:8082/', your development endpoint.
And calling gulp prod build will make your output use an ENV.api set to 'https://productionapplink/'.
As discussed in the comments section, the solution above is quite perfect when you only have two environments, but it quickly gets out of hand when the number of environment grows.
In that case, I suggest using a different approach, the Pirate way, using yargs.
Here would be your new gulpfile.js:
const argv = require('yargs').argv;
const endpoints = {
'dev': 'http://1.1.1.1:8082/',
'prod-org': 'https://productionapplink.org/',
'prod-com': 'https://productionapplink.com/',
'prod-gov': 'https://productionapplink.gov/'
};
gulp.task('enviornmentsapi', function () {
const apiEnpdoint = typeof argv.env === 'undefined' ? endpoints.dev : endpoints[argv.env];
return ngConstant({
stream: true,
constants: {
ENV: { api: apiEnpdoint }
}
}).pipe(gulp.dest('dist/scripts/config'));
});
Use it like follows:
gulp build uses the default api URL: 'http://1.1.1.1:8082/'
gulp build --env=prod-org uses 'https://productionapplink.org/'
gulp build --env=prod-com uses 'https://productionapplink.com/'
I hope this could work for you this time!
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have gulp file set up to watch for changes. I'm developing an application in ReactJS using Redux architecture. What I've noticed is that the gulp does not watch for any changes in the SCSS files.
/*eslint-disable */
var path = require('path');
var runSequence = require('run-sequence');
var install = require('gulp-install');
var spawn = require('child_process').spawn;
var $ = require('gulp-load-plugins')({
pattern: [
'gulp',
'gulp-*',
'gulp.*',
'merge-stream',
'del',
'browserify',
'watchify',
'vinyl-source-stream',
'vinyl-transform',
'vinyl-buffer',
'glob',
'lodash',
'less-plugin-*',
'mochify'
],
replaceString: /^gulp(-|\.)/,
rename: {
'merge-stream': 'mergeStream',
'del': 'delete'
}
});
var env = require('env-manager')({
argv: process.argv,
dir: path.join(__dirname, 'environments'),
base: 'base.js',
pattern: '{env}.js',
defaults: {
'env': 'development'
}
});
$.util.log($.util.colors.magenta('Running in ' + env.name + ' environment'));
require('gulp-tasks-registrator')({
gulp: $.gulp,
dir: path.join(__dirname, 'tasks'),
args: [$, env],
verbose: true,
panic: true,
group: true
});
$.gulp.task('clean', ['clean:server', 'clean:client'], function task(done) {
done();
});
$.gulp.task('install', function () {
return $.gulp.src([ './package.json']).pipe(install());
});
$.gulp.task('build', function task(done) {
return runSequence(
//'lint',
// 'install',
'clean',
'build:server',
'build:client:images',
'build:client:fonts',
[
'build:client:scripts',
'build:client:styles'
],
'build:client:html',
done
);
});
$.gulp.task('run-wrapper', function(done) {
var server = spawn('node', ['serviceWrapper.js'], {stdio: ['inherit']});
server.stderr.on('data', function(data){
process.stderr.write(data);
});
server.stdout.on('data', function(data) {
process.stdout.write(data);
});
server.unref();
});
$.gulp.task('default', function task(done) {
runSequence('build', ['serve', 'run-wrapper','watch'], done);
});
$.gulp.task('run', function task(done) {
runSequence('serve', done);
});
/*eslint-enable */
In what you've provided, there's no watch task or Sass task (though you do call a task named watch so if running gulp (the default task) isn't giving you an error you must have defined the task named watch somewhere).
There are two Sass plugins for gulp, one using Ruby Sass (gulp-ruby-sass) and one using LibSass (gulp-sass). You can read about the difference here, but in short gulp-sass will probably be faste. The best way to find out is to try one and then the other and compare gulp's console logs (where it says "finished task after x ms").
Here's a SASS-watching example, edited very slightly from the example in the gulp-sass readme (assumes that gulp-sass is in your package.json, in which case it will have been imported by your gulp-load-plugins call). $.s added to match the code you provided
$.gulp.task('sass', function () {
return gulp.src('yourstylespath/*.scss') // grab the .scss files
.pipe(sass().on('error', sass.logError)) // compile them into css, loggin any errors
.pipe(gulp.dest('yourcompiledcsspath')); // save them in yourcompiledcsspath
});
$.gulp.task('sass:watch', function () {
gulp.watch('yourstylespath/*.scss', ['sass']); // "run the task 'sass' when there's a change to any .scss file in yourstylespath
});
Side notes:
Considering all the packages you're using that don't follow the "gulp-packagename" naming scheme, it might be more efficient to just write them out individually like this (of course depends on how many packages you're using)
var delete = require('del'),
mergeStream = require('merge-stream'),
...;
Looks like your run task could just be this? $.gulp.task('run', ['serve']);
Short version:
I am unable to see the code coverage from my tests that I have written using nightmare.js and mocha. I have already tried to use istanbul and _mocha with no luck so far.
Big version:
I have a little project:
/public/index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Website</title>
<script src="./js/hello.js"></script>
</head>
<body>
<h1>My Website</h1>
</body>
</html>
/public/js/hello.js
window.hello = function hello(){
return 'world';
};
The site is running using express and forever.
When I am trying to test it using nightmare.js.
/test/test.js
var path = require('path');
var Nightmare = require('nightmare');
var should = require('should');
/*global describe */
/*global it */
describe('Simple demo', function () {
this.timeout(15000);
var url = 'http://localhost:9000';
it('check hello world result', function (done) {
new Nightmare()
.goto(url)
.evaluate(function () {
/*global hello */
return hello();
}, function (value) {
var expected = "world";
if (value === null) {
false.should.equal(true);
return done();
}
value.should.equal(expected);
return done();
})
.run();
});
it('should get the index title', function (done) {
var expected = 'My Website';
new Nightmare()
.goto(url)
.title(function (title) {
title.should.equal(expected);
done();
})
.run();
});
});
The tests are passing
$ mocha
Simple demo
✓ check hello world result (2089ms)
title = Alexandria
✓ should get the index title (1947ms)
2 passing (4s)
But, I am unable to get code coverage reports from my tests.
I have already tried some commands like:
$ istanbul cover _mocha -- test/test.js -u exports -R spec
No coverage information was collected, exit without writing coverage information
$ istanbul cover --hook-run-in-context _mocha -- -R spec
No coverage information was collected, exit without writing coverage information
So, someone was able to create code coverage reports of nightmare.js tests? If no, there is something close to that using another tools?
I had exactly this same problem in my project. I couldn't find any libraries or configurations which solve this problem in simply way but with some implementation and Grunt configuration you can get code coverage from Grunt process.
Dependencies which I used in my project:
"chai": "^3.5.0",
"grunt": "^0.4.5",
"grunt-contrib-clean": "^0.7.0",
"grunt-contrib-copy": "^0.8.2",
"grunt-express-server": "^0.5.3",
"grunt-istanbul": "^0.7.1",
"grunt-mocha-test": "^0.12.7",
"istanbul": "^0.4.4",
"nightmare": "^2.2.0"
My project structure:
public/ -- public folder for index.html
src/ -- source folder for hello.js
test/ -- mocha tests implementation
server/ -- express implementation for server.js
coverage/ -- HTML report from code coverage
report/ -- HTML report from mocha tests
dist/ -- folder which is used by express server to get content, generated by Grunt
Steps which you have to run from Grunt:
grunt.registerTask('test_hello', [
'clean', // clean dist/ folder
'copy:public', // copy public files from public/ (ex. index.html) to dist/
'instrument', // generate instruments (ex. hello.js) for code coverage from src/ by istanbul
'express', // run express server from dist/ folder
'mochaTest', // run mocha tests with nightmare and generate HTML report to report/ folder
'report_coverage' // generate HTML report from code coverage to coverage/ folder
]);
Grunt configurations:
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-express-server');
grunt.loadNpmTasks('grunt-istanbul');
grunt.loadNpmTasks('grunt-mocha-test');
grunt.initConfig({
clean: {
dist: ['dist/', 'report/', 'coverage/']
},
copy: {
public: {
expand: true,
cwd: 'public/',
src: ['**'],
dest: 'dist/'
}
},
instrument: {
files: ['**/*.js'],
options: {
cwd: 'src/',
lazy: true,
basePath: 'dist/'
}
},
express: {
dev: {
options: {
port: 9000,
script: 'server/server.js',
background: true
}
}
},
mochaTest: {
hello: {
options: {
timeout: 10000,
captureFile: 'report/results.txt', // Optionally capture the reporter output to a file
quiet: false, // Optionally suppress output to standard out (defaults to false)
clearRequireCache: false // Optionally clear the require cache before running tests (defaults to false)
},
src: ['test/*.js']
},
}
});
grunt.registerTask('report_coverage', function () {
var coverage = require('./test/utils/coverage');
coverage.generateReport();
});
grunt.registerTask('test_hello', [
'clean', // clean dist/ folder
'copy:public', // copy public files from public/ (ex. index.html) to dist/
'instrument', // generate instruments (ex. hello.js) for code coverage from src/ by istanbul
'express', // run express server from dist/ folder
'mochaTest:hello', // run mocha tests with nightmare and generate HTML report to report/ folder
'report_coverage' // generate HTML report from code coverage to coverage/ folder
]);
}
I created also class which allows me collect code coverage from each Nightmare instance:
var istanbul = require('istanbul');
var reporter = new istanbul.Reporter(),
sync = true;
var Coverage = function () {
this.loadCodeCoverage = function (dom, done) {
dom
.evaluate(function () {
return window.__coverage__; // this variable store all information about code coverage
})
.then(function (coverageDate) {
if (coverageDate) {
this.getCollector().add(coverageDate);
}
done();
}.bind(this))
.catch(function (error) {
done(error);
});
}
// load page by nightmare
this.getCollector = function () {
if (!this.collector) {
this.collector = new istanbul.Collector();
}
return this.collector;
}
this.generateReport = function () {
reporter.add('text');
reporter.addAll(['lcov', 'clover']);
reporter.write(this.collector, sync, function () {
console.log('All reports generated');
});
}
}
module.exports = new Coverage();
For the above configuration file test/test.js should has the below structure:
var should = require('should');
var coverage = require('./utils/coverage');
/*global describe */
/*global it */
describe('Simple demo', function () {
this.timeout(15000);
var url = 'http://localhost:9000';
before(function (done) {
global.dom = new Nightmare()
.goto(url)
.evaluate(function () {
return 'test';
})
.then(function(result) {
done();
})
.catch(function(error) {
done(error);
});
});
after(function (done) {
coverage.loadCodeCoverage(dom, done);
});
it('check hello world result', function (done) {
dom.evaluate(function () {
/*global hello */
return hello();
})
.then(function(value) {
var expected = "world";
if (value === null) {
false.should.equal(true);
return done();
}
value.should.equal(expected);
return done();
})
.catch(function(error) {
done(error);
});
});
it('should get the index title', function (done) {
var expected = 'My Website';
dom.title(function (title) {
title.should.equal(expected);
done();
});
});
});
If everything works fine you should get on the console information and report from code coverage in HTML form should be generated in folder coverage/
Running "report_coverage" task
------------------------------------|----------|----------|----------|----------|----------------|
File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |
------------------------------------|----------|----------|----------|----------|----------------|
js/ | 100 | 100 | 100 | 100 | |
hello.js | 100 | 100 | 100 | 100 | |
------------------------------------|----------|----------|----------|----------|----------------|
All files | 100 | 100 | 100 | 100 | |
------------------------------------|----------|----------|----------|----------|----------------|
Problem which I still have is that for each test description I have to add method before and after. Could be nice to have these implementations only in one place, example somewhere in Grunt configuration that i needn't remember about them when I'm doing new test description.
It will be very appreciated if someone find more general solution for before and after methods.
I want to propose another approach. It basically boils down to
Instrument the application code with Istanbul
Fetch the coverage data from the browser and pass it to the test process (so we can extract it)
Run the reports
Here's a code snippet that does this
nightmare
.evaluate(() => window.__coverage__) // this executes in browser scope
.end() // terminate the Electron (browser) process
.then((cov) => {
// this executes in Node scope
// handle the data passed back to us from browser scope
const strCoverage = JSON.stringify(cov);
const hash = require('crypto').createHmac('sha256', '')
.update(strCoverage)
.digest('hex');
const fileName = `/tmp/coverage-${hash}.json`;
require('fs').writeFileSync(fileName, strCoverage);
done(); // the callback from the test
})
.catch(err => console.log(err));
for detailed information and links to actual commits please check my blog:
http://atodorov.org/blog/2017/08/12/code-coverage-from-nightmarejs-tests/
I have a set of gulp.js targets for running my mocha tests that work like a charm running through gulp-mocha. Question: how do I debug my mocha tests running through gulp? I would like to use something like node-inspector to set break points in my src and test files to see what's going on. I am already able to accomplish this by calling node directly:
node --debug-brk node_modules/gulp/bin/gulp.js test
But I'd prefer a gulp target that wraps this for me, e.g.:
gulp.task('test-debug', 'Run unit tests in debug mode', function (cb) {
// todo?
});
Ideas? I want to avoid a bash script or some other separate file since I'm trying to create a reusable gulpfile with targets that are usable by someone who doesn't know gulp.
Here is my current gulpfile.js
// gulpfile.js
var gulp = require('gulp'),
mocha = require('gulp-mocha'),
gutil = require('gulp-util'),
help = require('gulp-help');
help(gulp); // add help messages to targets
var exitCode = 0;
// kill process on failure
process.on('exit', function () {
process.nextTick(function () {
var msg = "gulp '" + gulp.seq + "' failed";
console.log(gutil.colors.red(msg));
process.exit(exitCode);
});
});
function testErrorHandler(err) {
gutil.beep();
gutil.log(err.message);
exitCode = 1;
}
gulp.task('test', 'Run unit tests and exit on failure', function () {
return gulp.src('./lib/*/test/**/*.js')
.pipe(mocha({
reporter: 'dot'
}))
.on('error', function (err) {
testErrorHandler(err);
process.emit('exit');
});
});
gulp.task('test-watch', 'Run unit tests', function (cb) {
return gulp.src('./lib/*/test/**/*.js')
.pipe(mocha({
reporter: 'min',
G: true
}))
.on('error', testErrorHandler);
});
gulp.task('watch', 'Watch files and run tests on change', function () {
gulp.watch('./lib/**/*.js', ['test-watch']);
});
With some guidance from #BrianGlaz I came up with the following task. Ends up being rather simple. Plus it pipes all output to the parent's stdout so I don't have to handle stdout.on manually:
// Run all unit tests in debug mode
gulp.task('test-debug', function () {
var spawn = require('child_process').spawn;
spawn('node', [
'--debug-brk',
path.join(__dirname, 'node_modules/gulp/bin/gulp.js'),
'test'
], { stdio: 'inherit' });
});
You can use Node's Child Process class to run command line commands from within a node app. In your case I would recommend childprocess.spawn(). It acts as an event emitter so you can subscribe to data to retrieve output from stdout. In terms of using this from within gulp, some work would probably need to be done to return a stream that could be piped to another gulp task.
I have a couple grunt tasks and I am trying to share global variables across those tasks and I am running into issues.
I have written a some custom tasks which set the proper output path depending on the build type. This seems to be setting things correctly.
// Set Mode (local or build)
grunt.registerTask("setBuildType", "Set the build type. Either build or local", function (val) {
// grunt.log.writeln(val + " :setBuildType val");
global.buildType = val;
});
// SetOutput location
grunt.registerTask("setOutput", "Set the output folder for the build.", function () {
if (global.buildType === "tfs") {
global.outputPath = MACHINE_PATH;
}
if (global.buildType === "local") {
global.outputPath = LOCAL_PATH;
}
if (global.buildType === "release") {
global.outputPath = RELEASE_PATH;
}
if (grunt.option("target")) {
global.outputPath = grunt.option("target");
}
grunt.log.writeln("Output folder: " + global.outputPath);
});
grunt.registerTask("globalReadout", function () {
grunt.log.writeln(global.outputPath);
});
So, I'm trying to then reference global.outputPath in a subsequent task, and running into errors.
If I call grunt test from the command line, it outputs the correct path no problem.
However, if I have a task like this:
clean: {
release: {
src: global.outputPath
}
}
It throws the following error:
Warning: Cannot call method 'indexOf' of undefined Use --force to continue.
Also, my constants in the setOutput task are set at the top of my Gruntfile.js
Any thoughts? Am I doing something wrong here?
So, I was on the right path. The issue is that the module exports before those global variables get set, so they are all undefined in subsequent tasks defined within the initConfig() task.
The solution I came up with, although, there may be better, is to overwrite a grunt.option value.
I have an optional option for my task --target
working solution looks like this:
grunt.registerTask("setOutput", "Set the output folder for the build.", function () {
if (global.buildType === "tfs") {
global.outputPath = MACHINE_PATH;
}
if (global.buildType === "local") {
global.outputPath = LOCAL_PATH;
}
if (global.buildType === "release") {
global.outputPath = RELEASE_PATH;
}
if (grunt.option("target")) {
global.outputPath = grunt.option("target");
}
grunt.option("target", global.outputPath);
grunt.log.writeln("Output path: " + grunt.option("target"));
});
And the task defined in initConfig() looked like this:
clean: {
build: {
src: ["<%= grunt.option(\"target\") %>"]
}
}
Feel free to chime in if you have a better solution. Otherwise, perhaps this may help someone else.
I have a way to do this that allows you to specify the output path using values like --dev. So far it's working very well, I quite like it. Thought I'd share it, as someone else may like it, too.
# Enum for target switching behavior
TARGETS =
dev: 'dev'
dist: 'dist'
# Configurable paths and globs
buildConfig =
dist: "dist"
dev: '.devServer'
timestamp: grunt.template.today('mm-dd_HHMM')
grunt.initConfig
cfg: buildConfig
cssmin:
crunch:
options: report: 'min'
files: "<%= grunt.option('target') %>/all-min.css": "/**/*.css"
# Set the output path for built files.
# Most tasks will key off this so it is a prerequisite
setPath = ->
if grunt.option 'dev'
grunt.option 'target', buildConfig.dev
else if grunt.option 'dist'
grunt.option 'target', "#{buildConfig.dist}/#{buildConfig.timestamp}"
else # Default path
grunt.option 'target', buildConfig.dev
grunt.log.writeln "Output path set to: `#{grunt.option 'target'}`"
grunt.log.writeln "Possible targets:"
grunt.log.writeln target for target of TARGETS
setPath()
With this setup, you can run commands like:
grunt cssmin --dist #sent to dist target
grunt cssmin --dev #sent to dev target
grunt cssmin --dev #sent to default target (dev)
This is an older question, I just thought to throw in my 5 cents.
If you need config variable to be accessible from any task, just define it in your main (the one that you'll always load) config file like this:
module.exports = function(grunt)
{
//
// Common project configuration
//
var config =
{
pkg: grunt.file.readJSON('package.json'),
options: // for 'project'
{
dist:
{
outputPath: '<%= process.cwd() %>/lib',
},
dev:
{
outputPath: '<%= process.cwd() %>/build',
},
},
}
grunt.config.merge( config )
}
Then you can simply access value like this:
in config file(s)
...
my_thingie:
[
ends_up_here: '<%= options.dev.outputPath %>/bundle',
],
...
in tasks
// as raw value
grunt.config.data.options.dist.outputPath
// after (eventual) templates have been processed
grunt.config('options.dist.outputPath')
I used key options here just to be in line with convention, but you can use anything as long as you remember not to register a task named 'options' or whatever you used for the key :)