I just cannot make it up why cucumber does not see the steps.
Here is my structure. Currently only test.feature matters, as i tried to simplify everything:
Here is my test.feature:
Here is my test.steps:
Here is my very much simplified now world.js:
As you can see the steps are not seen by the feature.
Here is the test result:
I tried manipulations with regexps, file names, folder moves, etc. Maybe somebody can give me a hint what else I can try.
EDITED: I added cucumber version used and cucumberOpts:
The root cause is for different Cucumber version, it has different pattern to write step defintion.
You used Cucumber 4, but your step definition pattern is for Cucumber 1.
For Cucumber 3 and 4, step definition should look like:
var {Given, Then, When} = require('cucumber');
When(/^i load the app$/, function(){
...
});
More detail
For Cucumber 2, step definition should look like:
var {defineSupportCode} = require('cucumber');
defineSupportCode(function ({ Given, When, Then }) {
When(/^i load the app$/, function () {
...;
});
}
More detail
For Cucumber 1, step definition should look like:
module.exports = function() {
this.When(/^i load the app$/, function() {
...;
});
};
More detail
FYI, pretty format removed in Cucumber 4, so you can't config it in cucumberOpts:
cucumberOpts: {
format: ['pretty']
}
If you want the pretty back, please install another package: cucumber-pretty, and add it in cucumberOptions:
cucumberOpts: {
format: ['node_modules/cucumber-pretty']
}
More detail
I believe your folder structure is little off. Can you try something like below. I believe you need to have features and step_definitions folders in the same directory for cucumber to find step definitions. If not, you can provide --require parameter and tell cucumber explicitly where your step_definitions are like below
cucumber.js test/features/paypalreg.feature --require test/features/step_definitions/ --format=pretty
Related
How can I configure the random option using grunt-contrib-jasmine? I can do it directly with jasmine's command line, but running jasmine's task by grunt-cli I didn't find the random option. Then the output of command line always shows the specs' randomic output.
I found the answer to my question. At least I've tested and it worked.
On the each describe declaration's top, you can configure the random option of your Suit Test. It can be with the following statement:
describe('My suite', function(){
jasmine.getEnv().configure({random:false});
// There are several tests here...
afterAll(function(){
jasmine.getEnv().configure({random:true});
});
...
If you use jasmine.d.ts and your tests are in typescript, you could also add to the Env interface in jasmine.d.ts a funtion like:
interface Env {
// some code
// add function:
configure(b: any): void;
}
Then in your tests you could write something like:
/// <reference path="../../../../typings/jasmine/jasmine.d.ts" />
jasmine.getEnv().configure({ random: false });
I tested this approach and in the end I didn't have to set the random option to false in each describe function. I added it right after the reference paths and it worked for all tests.
Edit: You could also include the jasmine configuration in the options/helpers part of your grunt-contrib-jasmine task as a separate file. Something like:
jasmine: {
src: [some source files],
options: {
specs: [some spec files],
helpers: 'helpers.js'
}
}
I have some complex Mocha code which I would like to statically check with FlowType because why not?
Below is a minimal repro:
/* #flow */
describe('it', function () {
it('fails', function() {
const s: number = 'flow spots this error';
});
});
When I run Flow on this, Flow does indeed spot the problem with the assignment of string to number which shows that the approach is working to some extend.
However, I also get:
test/test.js:4
4: describe('it', function () {
^^^^^^^^ identifier `describe`. Could not resolve name
test/test.js:5
5: it('fails', function() {
^^ identifier `it`. Could not resolve name
… apparently the Mocha test definitions run in an environment where these functions are globally available but looking at the test file there's nothing that would allow Flow to detect that.
I am not sure these problems are specific to Mocha but I don't feel I can confidently frame the question in broader terms, so my questions are:
how can I have Flow type check Mocha test code without suppressing every line that contains describe or it ?
is this is an instance of a broader class of situations and, if so, what would the latter be?
Third-party libraries usually need definition files, i.e. files containing all the type information for a given library.
In this case, you need a definition file for mocha, which fortunately is provided by flow-typed.
Install it with
npm install -g flow-typed
then run
flow-typed install
It will automatically install all the available definition files for your dependencies, including mocha.
You can simply declare the flow describe, it variables.
/* #flow */
declare var describe: any;
declare var it: any;
describe('it', function () {
it('fails', function() {
const s: number = 'flow spots this error';
});
});
So I'm having a slight problem with producing production ready scripts for my project. I'm using gulp to concatenate and minify my css and js, and while the css is working fine the gulp js function isn't generating my final file. Please refer to my code below:
gulp.task('js', function() {
return gulp.src([source + 'js/app/**/*.js'])
.pipe(concat('development.js'))
.pipe(gulp.dest(source + 'js'))
.pipe(rename({
basename: 'production',
suffix: '-min',
}))
.pipe(uglify())
.pipe(gulp.dest(source + 'js/'))
.pipe(notify({ message: 'Scripts task complete', onLast: true }));
});
If anyone has encountered a similar problem or has any tips it would be much appreciated :)
There is nothing wrong with your gulpfile. I tested it and it works perfectly.
The only thing I can guess is that your source is not set correctly. Did you forget the trailing slash '/' ?
I would suggest 2 things to figure it out. Include node path library to check where source is actually pointing to like this:
var path = require('path');
// in gulp task ...
path.resolve(path.resolve(source + 'js/app'));
Make sure it points where you think it does.
Secondly, you could use gulp-debug to establish that any files are found:
npm install gulp-debug
Then
var debug = require('gulp-debug');
// in gulp task ...
return gulp.src([source + 'js/app/**/*.js'])
.pipe(concat('development.js'))
.pipe(debug())
.pipe(gulp.dest(source + 'js'))
.pipe(debug())
// etc.
Good luck!
Based on additional infomation in the comments I realise you are generating JS files in a separate process ...
gulp is asynchronous by default. What this boils down to is that all functions try to run at the same time - if you want a specific order it must be by design. This is great because it's very fast but can be a headache to work with.
Problem
Here is what's basically happening:
// SOME TASK THAT SHOULD BE RUN FIRST
gulp.task('copy-vendor-files-to-tempfolder', function (done) {
// copy files to vendor folder
done()
})
// SOME TASKS THAT DEPEND ON FIRST TASK
gulp.task('complile-styles', function () { /* independent task */ })
gulp.task('concat-vendor-files', function () { /* concat files in vendor folder. depends on vendor files existing */ })
// GENERAL TASK WHICH STARTS OTHERS
gulp.task('ready', ['copy-vendor-files-to-tempfolder', 'compile-styles', 'concat-vendor-files])
When you try to run:
$ gulp ready
GULP TASK WILL FAIL! Folder is being created at the same time!!
NOWHERE TO COPY FILES!
Solution
There are many solutions but the following module has come in handy for me again and again:
npm install run-sequence
Then in your gulpfile.js:
var runSequence = require('run-sequence')
gulp.task('ready', function (done) {
runSequence(
'create-folders', // do this first,
[
'copy-css-files',
'copy-html-files'
], // do these AFTER but in parallel
done // callback when ready
)
})
This will guarantee the folder exists when you try to run the other functions.
In your specific case, you should make sure the task that concatenates the JS files is run after the task that copies them out of vendor.
Note: I'm leaving other answer because it contains useful help for debugging similar issues.
HTH!
I setup CucumberJS with Protractor and Gulp. I followed the documentation available here:
https://github.com/cucumber/cucumber-js
I have my feature file and step definition file. I also created world.js file in support folder and it is loaded in my step definition file with:
this.World = require("../support/world.js").World;
So the same way as it is presented in the documentation.
Everything works till this moment.
I tried to add some cucumber hooks to my case. I created hooks.js file in the support folder as it is proposed in the documentation, so:
// features/support/hooks.js (this path is just a suggestion)
var myHooks = function () {
this.Before(function (callback) {
// Just like inside step definitions, "this" is set to a World instance.
// It's actually the same instance the current scenario step definitions
// will receive.
// Let's say we have a bunch of "maintenance" methods available on our World
// instance, we can fire some to prepare the application for the next
// scenario:
console.log("Before hook");
// Don't forget to tell Cucumber when you're done:
callback();
});
};
module.exports = myHooks;
The documentation does not say how this hook.js file should be loaded in my step definitions so I assume that it is somehow loaded with the "convention over configuration" approach. Unfortunately, the file is not loaded and the Before method is not executed.
Any ideas?
If hooks are NOT in the same folder as your step_definitions, you would need to explicitly specify where your hooks are using --require. For example,
cucumber.js test/functional/features/xyz.feature
--require test/functional/step_definitions/
--require features/support/ --format=pretty
To avoid this, I usually keep my hooks under step_definitions folder. Since you need to specify require for step_definitions anyways, you don't need to explicitly specify require for hooks. So lets say if your hooks are in test/functional/step_definitions/, with following your hooks should get invoked.
cucumber.js test/functional/features/xyz.feature
--require test/functional/step_definitions/
--format=pretty
Once you have your hooks.js file, go to your cucumberOpts inside of your protractor.conf.js file and add the path to your hooks.js file there, that's it, your hooks.js file will be loaded.
cucumberOpts: {
require: [
conf.paths.e2e + '/steps/**/*Steps.js',
conf.paths.e2e + '/utilities/hooks.js',
],
tags: ['~#wip', '~#manual'],
format: 'pretty'
}
You can also include console.log('Was my hook loaded') in your hooks.js file and search for that log text later to ensure your hook was properly loaded.
Is there a way to exclude a folder from a build in a Brocfile (or any other place).
The use case is packaging, where I have an app made of sub-apps within pods. eg.
/app/modules/components
/app/modules/app1
/app/modules/app2
/app/modules/app3
I'd like to build them all when environment is set to 'development' or only eg. 'app1' when environment is 'app1'. Any suggestions?
I have tried different combinations of broccoli-file-remover, broccoli-funnel and broccoli-merge-trees to no avail.
var removeFile = require('broccoli-file-remover');
module.exports = removeFile(app.toTree(), {
paths: ['app/modules/pod1/', 'app/modules/pod2/']
});
Ah, so after actually thinking about this clearly, everything is actually working exactly as expected in my previous example.
I clearly wasn't paying enough attention. app.toTree() is far too late to perform this operation, as everything has already been built and concated.
Luckily, ember-cli does enable addons to modify the appropriate trees at various life cycle milestones.
See: https://github.com/ember-cli/ember-cli/blob/master/ADDON_HOOKS.md for more details on which hooks are currently available.
The hook that should do the trick is Addon.prototype.postprocessTree. Now we have two choices, we can build a standalone addon, via ember addon or we can create a light-weight in-repo addon via ember g in-repo-addon. Typically for these types of situations, I prefer in-repo-addons as they don't require a second project, but otherwise they are the same.
ember g in-repo-addon remove
we need to install broccoli-stew via npm install --save broccoli-stew
include it var stew = require('broccoli-stew');
add hook postprocessTree to the add-on
when the postprocessTree is for the type we care about, use broccoli-stew to remove the directories we no longer care care.
The resulting pull request: https://github.com/WooDzu/ember-exclude-pod/pull/1
Note: I noticed template wasn't one of the types available in postprocess, so I added it: https://github.com/ember-cli/ember-cli/pull/4263 (should be part of the next ember-cli release)
Note: we really do want an additional hook
Addon.prototype.preprocessTree, as to ignore the files before we
even build them. I have opened a related issue:
https://github.com/ember-cli/ember-cli/issues/4262
output of the above steps
var stew = require('broccoli-stew');
module.exports = {
name: 'remove',
isDevelopingAddon: function() {
return true;
},
postprocessTree: function(type, tree){
if (type === 'js' || type === 'template') {
return stew.rm(tree, '*/modules/pod{1,2}/**/*');
} else {
return tree;
}
}
};
I am pretty confident broccoli-stew's rm will handle this correctly.
https://github.com/stefanpenner/broccoli-stew/blob/master/lib/rm.js#L4-L40 there are even tests that test a very similar scenario: https://github.com/stefanpenner/broccoli-stew/blob/master/tests/rm-test.js#L48-L57
var stew = require('broccoli-stew');
module.exports = stew.rm(app.tree(), 'app/modules/{pod1,pod2}');
If this doesn't work, feel free to open an issue on broccoli-stew. Be sure to provide a running example though
This is really late, but I created a Broccoli plugin to do just this. It's available at https://www.npmjs.com/package/broccoli-rm.
(The trick is to detect whether an excluded path is a folder, and then use a glob match to make sure that none of the children of the folder get symlinked during copying.)
var rm = require('broccoli-rm');
var input = app.toTree();
module.exports = output = rm([input], {
paths: ['app/modules/pod1', 'app/modules/pod2']
});