Skip to content

Commit 02b17d0

Browse files
committed
Add ability to pick protractor framework to allow cucumber as an e2e framework.
1 parent 3e109e8 commit 02b17d0

22 files changed

+163
-47
lines changed

CONTRIBUTING.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ Because we create a generator you should be specific as possible in your request
2525

2626
Before you submit your pull request consider the following guidelines:
2727

28-
**Test**
28+
**Test**
2929
Please add unit tests for every new feature or bug fix and make sure all tests pass before submitting pull requests. Generator tests are written in [Mocha](http://mochajs.org). [Karma](http://karma-runner.github.io/0.12/index.html) and [Protractor](http://angular.github.io/protractor) are used to run unit tests and e2e tests on generated app.
30-
* Run `./node_modules/mocha/bin/_mocha ./test/*.js` to execute all tests instead of `npm test`. Currently all protractor tests in (2) are excluded from `npm test` due to Travis issue.
30+
* Run `./node_modules/mocha/bin/_mocha ./test/**/*.js` to execute all tests instead of `npm test`. Currently all protractor tests in (2) are excluded from `npm test` due to Travis issue. You will need to have the ruby sass gem installed to run the full suite of tests.
3131
* Add tests into (1) and (2) if there are changes in generated project's structure.
3232
* Feel free to create new test file for new generator features.
3333

@@ -39,13 +39,13 @@ Please add unit tests for every new feature or bug fix and make sure all tests p
3939
| (4) `test-import-gen.js` | Test generator directory.
4040
| (5) `test-utils.js` | Unit tests for utils.js.
4141

42-
**Style Guide**
42+
**Style Guide**
4343
Please brief yourself on [Idiomatic.js](https://github.com/rwldrn/idiomatic.js) style guide with two space indent.
4444

45-
**Documentation**
45+
**Documentation**
4646
Add documentation for every new feature, directory structure change. Feel free to send corrections or better docs!
4747

48-
**Branch**
48+
**Branch**
4949
Must be one of the following:
5050

5151
* feat: A new feature

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ yo gulp-angular
6464
![Logo](docs/assets/bower.png)
6565
![Logo](docs/assets/webpack.png)
6666
![Logo](docs/assets/karma.png)
67+
![Logo](docs/assets/cucumber.png)
6768
![Logo](docs/assets/istanbul.png)
6869
![Logo](docs/assets/browsersync.png)
6970
![Logo](docs/assets/jasmine.png)

docs/assets/cucmber.png

2.36 KB
Loading

docs/assets/original/cucumber.png

6.06 KB
Loading

docs/usage.md

+1
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,6 @@ There is none at the generation but you can add `.jade`, `.haml` or `.hbs` (depe
139139
* *CSS pre-processor*: Less, Sass with Ruby and Node, Stylus, none
140140
* *JS preprocessor*: CoffeeScript, TypeScript, ECMAScript 6 (Traceur and Babel), none
141141
* *HTML preprocessor*: Jade, Haml, Handlebars, none
142+
* *Protractor framework*: Jasmine, Cucumber
142143
* **TODO** Script loader: Require, Webpack, none
143144
* **TODO** Test framework: Jasmine, Mocha, Qunit

docs/user-guide.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Its usage is described in the chapters [Development server](#development-server)
1414

1515
### `test`
1616

17-
For testing, a fully working test environment is shipped with some examples. It uses Karma (with `gulp test`) for the unit tests, and Protractor for the end-to-end tests (with `gulp protractor`).
17+
For testing, a fully working test environment is shipped with some examples. It uses Karma (with `gulp test`) for the unit tests, and Protractor for the [end-to-end tests](#end-to-end-tests) (with `gulp protractor`).
1818

1919
More information in the [Test environment configured](#test-environment-configured) chapter.
2020

@@ -147,6 +147,12 @@ To allow tests to load HTML partials especially for the directives tests, we use
147147

148148
Other than that, we try to use as less Karma plugins as possible because they often duplicate process we already have inside Gulp. For sake of coherence and stability we're searching for a process centralized in Gulp and not duplicated in Karma or other tools like perhaps Webpack.
149149

150+
## End to end tests
151+
152+
The generator provides end to end testing using [Protractor](https://angular.github.io/protractor/#/). By default, Protractor uses the Jasmine test framework for its testing interface. There is an option to change the testing framework to [Cucumber](https://cucumber.io/), a BBD testing framework that uses human readable feature tests to drive assertions.
153+
154+
When the Cucumber options is selected, the [Chai](http://chaijs.com/) library loaded for assertions in your end-to-end tests.
155+
150156
## Optimization process
151157

152158
The central piece of the optimization process is the use of the [gulp-useref](https://github.com/jonkemp/gulp-useref). Its task is to concat files and rewriting the `index.html` file to points on the concat versions of the files. All works with HTML comments block starting with `<!-- build:(...) ->` and ending with `<!-- endbuild -->`.

generators/app/files.json

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,12 @@
44
".editorconfig",
55

66
"tsconfig.json",
7-
"protractor.conf.js",
87

98
"e2e/.eslintrc",
10-
"e2e/main.spec.js",
9+
"e2e/main.feature",
1110

1211
"gulpfile.js",
1312
"gulp/.eslintrc",
14-
"gulp/e2e-tests.js",
1513

1614
"src/favicon.ico",
1715
"src/assets/images/yeoman.png"
@@ -25,10 +23,13 @@
2523
"typings.json",
2624

2725
"karma.conf.js",
26+
"protractor.conf.js",
2827

28+
"e2e/main.spec.js",
2929
"e2e/main.po.js",
3030

3131
"gulp/conf.js",
32+
"gulp/e2e-tests.js",
3233
"gulp/build.js",
3334
"gulp/inject.js",
3435
"gulp/markups.js",

generators/app/prompts.json

+21
Original file line numberDiff line numberDiff line change
@@ -391,5 +391,26 @@
391391
"name": "Handlebars (*.hbs)"
392392
}
393393
]
394+
},
395+
{
396+
"type": "list",
397+
"name": "protractorFramework",
398+
"message": "Which Protractor test framework do you want?",
399+
"choices": [
400+
{
401+
"value": {
402+
"key": "jasmine",
403+
"extension": "js"
404+
},
405+
"name": "None, Use the default protractor framework (Jasmine)."
406+
},
407+
{
408+
"value": {
409+
"key": "cucumber",
410+
"extension": "feature"
411+
},
412+
"name": "Cucumber, a BDD testing framework that uses feature tests."
413+
}
414+
]
394415
}
395416
]

generators/app/src/mock-prompts.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ var questions = [
2424
'foundationComponents',
2525
'cssPreprocessor',
2626
'jsPreprocessor',
27-
'htmlPreprocessor'
27+
'htmlPreprocessor',
28+
'protractorFramework'
2829
];
2930

3031
var model = {};
@@ -81,6 +82,10 @@ model.htmlPreprocessor.choices.forEach(function (choice) {
8182
model.htmlPreprocessor.values[choice.value.key] = choice.value;
8283
});
8384

85+
model.protractorFramework.choices.forEach(function (choice) {
86+
model.protractorFramework.values[choice.value.key] = choice.value;
87+
});
88+
8489
module.exports = {
8590
prompts: model,
8691
defaults: {
@@ -94,6 +99,7 @@ module.exports = {
9499
foundationComponents: model.foundationComponents.values.noFoundationComponents,
95100
cssPreprocessor: model.cssPreprocessor.values['node-sass'],
96101
jsPreprocessor: model.jsPreprocessor.values.noJsPrepro,
97-
htmlPreprocessor: model.htmlPreprocessor.values.noHtmlPrepro
102+
htmlPreprocessor: model.htmlPreprocessor.values.noHtmlPrepro,
103+
protractorFramework: model.protractorFramework.values.jasmine,
98104
}
99105
};

generators/app/src/preprocessors.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ module.exports = function (GulpAngularGenerator) {
2020
'js',
2121
this.props.cssPreprocessor.extension,
2222
this.props.jsPreprocessor.extension,
23-
this.props.htmlPreprocessor.extension
23+
this.props.htmlPreprocessor.extension,
24+
this.props.protractorFramework.extension
2425
];
2526
if (this.imageMin) {
2627
this.processedFileExtension = this.processedFileExtension.concat(['jpg', 'png', 'gif', 'svg']);
@@ -75,6 +76,11 @@ module.exports = function (GulpAngularGenerator) {
7576
if (this.props.jsPreprocessor.key !== 'noJsPrepro') {
7677
rejectWithRegexp.call(this, /^(?!^e2e\/).*spec\.js/);
7778
}
79+
80+
if (this.props.protractorFramework.key !== 'cucumber') {
81+
rejectWithRegexp.call(this, /main\.feature/);
82+
}
83+
7884
};
7985

8086
/**

generators/app/src/techs.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ module.exports = function (GulpAngularGenerator) {
1919
this.props.foundationComponents.key,
2020
this.props.cssPreprocessor.key,
2121
this.props.jsPreprocessor.key,
22-
this.props.htmlPreprocessor.key
22+
this.props.htmlPreprocessor.key,
23+
this.props.protractorFramework.key
2324
])
2425
.filter(_.isString)
2526
.filter(function (tech) {

generators/app/techs.json

+6
Original file line numberDiff line numberDiff line change
@@ -157,5 +157,11 @@
157157
"url": "http://handlebarsjs.com/",
158158
"description": "Handlebars provides the power necessary to let you build semantic templates effectively with no frustration.",
159159
"logo": "handlebars.png"
160+
},
161+
"cucumber": {
162+
"title": "Cucumber",
163+
"url": "https://cucumber.io/",
164+
"description": "Cucumber, the popular Behaviour-Driven Development tool, brought to your JavaScript stack.",
165+
"logo": "cucumber.png"
160166
}
161167
}

generators/app/templates/_package.json

+6
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@
7878
"wiredep": "~2.2.2",
7979
"karma": "~0.13.10",
8080
"karma-jasmine": "~0.3.6",
81+
<% if (props.protractorFramework.key === 'cucumber') { -%>
82+
"cucumber": "~0.10.2",
83+
"protractor-cucumber-framework": "~0.5.0",
84+
"chai": "~3.5.0",
85+
"chai-as-promised": "~5.3.0",
86+
<% } -%>
8187
<% if(props.jsPreprocessor.key === 'traceur') { -%>
8288
"karma-chrome-launcher": "~0.2.1",
8389
<% } else { -%>

generators/app/templates/protractor.conf.js generators/app/templates/_protractor.conf.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,25 @@ exports.config = {
1717

1818
// Spec patterns are relative to the current working directory when
1919
// protractor is called.
20-
specs: [paths.e2e + '/**/*.js'],
20+
specs: [paths.e2e + '/**/*.<%- props.protractorFramework.extension %>'],
2121

22+
<% if (props.protractorFramework.key === 'cucumber') { -%>
23+
framework: 'custom',
24+
// path relative to the current config file
25+
frameworkPath: require.resolve('protractor-cucumber-framework'),
26+
27+
// relevant cucumber command line options
28+
cucumberOpts: {
29+
require: [
30+
paths.e2e + '/**/*.js'
31+
],
32+
format: "pretty"
33+
}
34+
<% } else { -%>
2235
// Options to be passed to Jasmine-node.
2336
jasmineNodeOpts: {
2437
showColors: true,
2538
defaultTimeoutInterval: 30000
2639
}
40+
<% } -%>
2741
};
+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
'use strict';
2+
3+
<% if (props.protractorFramework.key === 'cucumber') { -%>
4+
var chai = require('chai');
5+
var chaiAsPromised = require('chai-as-promised');
6+
var expect = chai.expect;
7+
var page = require('./main.po');
8+
9+
chai.use(chaiAsPromised);
10+
11+
module.exports = function () {
12+
this.Given('a demo app', function (done) {
13+
done();
14+
});
15+
16+
this.When('I load the page', function (done) {
17+
browser.get('/index.html');
18+
done();
19+
});
20+
21+
this.Then(/^I should see the jumbotron with correct data$/, function (done) {
22+
expect(page.h1El.getText()).to.eventually.equal('\'Allo, \'Allo!');
23+
expect(page.imgEl.getAttribute('src')).to.eventually.have.string('assets/images/yeoman.png');
24+
expect(page.imgEl.getAttribute('alt')).to.eventually.equal('I\'m Yeoman');
25+
done();
26+
});
27+
28+
this.Then(/^I should see a list of more than (\d+) awesome things$/, function (itemNumber, done) {
29+
expect(page.thumbnailEls.count()).to.eventually.be.at.least(itemNumber);
30+
done();
31+
});
32+
};
33+
<% } else { -%>
34+
describe('The main view', function () {
35+
var page;
36+
37+
beforeEach(function () {
38+
browser.get('/index.html');
39+
page = require('./main.po');
40+
});
41+
42+
it('should include jumbotron with correct data', function() {
43+
expect(page.h1El.getText()).toBe('\'Allo, \'Allo!');
44+
expect(page.imgEl.getAttribute('src')).toMatch(/assets\/images\/yeoman.png$/);
45+
expect(page.imgEl.getAttribute('alt')).toBe('I\'m Yeoman');
46+
});
47+
48+
it('should list more than 5 awesome things', function () {
49+
expect(page.thumbnailEls.count()).toBeGreaterThan(5);
50+
});
51+
52+
});
53+
<% } -%>
54+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Feature: The project introduction page
2+
3+
Scenario: The main view
4+
Given a demo app
5+
When I load the page
6+
Then I should see the jumbotron with correct data
7+
And I should see a list of more than 5 awesome things

generators/app/templates/e2e/main.spec.js

-21
This file was deleted.

generators/app/templates/gulp/e2e-tests.js generators/app/templates/gulp/_e2e-tests.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function runProtractor (done) {
1717
var params = process.argv;
1818
var args = params.length > 3 ? [params[3], params[4]] : [];
1919

20-
gulp.src(path.join(conf.paths.e2e, '/**/*.js'))
20+
gulp.src(path.join(conf.paths.e2e, '/**/*.<%- props.protractorFramework.extension %>'))
2121
.pipe($.protractor.protractor({
2222
configFile: 'protractor.conf.js',
2323
args: args
Loading

test/inception/test-inception.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe('gulp-angular generator inception tests', function () {
3535
});
3636
});
3737

38-
describe('with [angular 1.3.x, jQuery 2.x.x, Restangular, UI-Router, Foundation, angular-foundation, CSS, Coffee, Jade]', function () {
38+
describe('with [angular 1.3.x, jQuery 2.x.x, Restangular, UI-Router, Foundation, angular-foundation, CSS, Coffee, Jade, cucmber]', function () {
3939
before(function () {
4040
return inception.prepare({}, {
4141
angularVersion: prompts.angularVersion.values['1.3'],
@@ -46,7 +46,8 @@ describe('gulp-angular generator inception tests', function () {
4646
foundationComponents: prompts.foundationComponents.values['angular-foundation'],
4747
cssPreprocessor: prompts.cssPreprocessor.values.noCssPrepro,
4848
jsPreprocessor: prompts.jsPreprocessor.values.coffee,
49-
htmlPreprocessor: prompts.htmlPreprocessor.values.jade
49+
htmlPreprocessor: prompts.htmlPreprocessor.values.jade,
50+
protractorFramework: prompts.protractorFramework.values.cucumber
5051
}).then(function (generator) {
5152
gulpAngular = generator;
5253
});

0 commit comments

Comments
 (0)