Permalink
Browse files

fix(cucumber): correctly hanlde --strict and --no-color flags

affects: serenity-js
  • Loading branch information...
jan-molak committed Nov 14, 2017
1 parent d00ff0a commit 878a165f023fda58add2c2261380a0ca50ff25c9
@@ -3,7 +3,7 @@ import { BrowseTheWeb } from 'serenity-js/lib/serenity-protractor';
import { TodoList } from '../user_interface';
export class ItemStatus implements Question<string> {
export class ItemStatus implements Question<PromiseLike<string>> {
static of(itemName: string) {
return new ItemStatus(itemName);
}
@@ -7,7 +7,7 @@
"clean": "rimraf target",
"lint": "tslint --config ../../tslint.json --project ./tsconfig.json --format stylish",
"pretest": "serenity update",
"pree2e": "npm run lint && npm run webdriver:update -- --standalone",
"pree2e": "npm run lint && npm run webdriver:update -- --standalone --versions.standalone=3.0.1",
"e2e": "protractor ./protractor.conf.js",
"e2e-single": "protractor ./protractor.conf.js --cucumberOpts.name",
"report": "serenity run",
@@ -7,11 +7,7 @@ var _ = require('lodash'),
exports.config = {
seleniumServerJar: path.resolve(node_modules, 'protractor/node_modules/webdriver-manager/selenium/selenium-server-standalone-3.4.0.jar'),
localSeleniumStandaloneOpts: {
jvmArgs: [`-Dwebdriver.gecko.driver=${path.resolve(node_modules, 'protractor/node_modules/webdriver-manager/selenium')}/geckodriver-v0.18.0`]
},
seleniumServerJar: path.resolve(node_modules, 'protractor/node_modules/webdriver-manager/selenium/selenium-server-standalone-3.0.1.jar'),
baseUrl: 'http://todomvc.com',
@@ -22,12 +18,13 @@ exports.config = {
serenity: {
dialect: 'cucumber',
crew: [
crew.serenityBDDReporter(),
crew.consoleReporter(),
crew.Photographer.who(_ => _
.takesPhotosOf(_.Tasks_and_Interactions)
.takesPhotosWhen(_.Activity_Finishes)
)
crew.serenityBDDReporter()
// ,
// crew.consoleReporter(),
// crew.Photographer.who(_ => _
// .takesPhotosOf(_.Failures)
// .takesPhotosWhen(_.Activity_Finishes)
// )
]
},
@@ -42,16 +39,18 @@ exports.config = {
browserName: 'chrome',
chromeOptions: {
args: [
// 'incognito',
// 'disable-extensions',
// 'show-fps-counter=true'
'--disable-infobars'
// '--incognito',
// '--disable-extensions',
// '--show-fps-counter=true'
]
},
}
// ,
// execute tests using 2 browsers running in parallel
shardTestFiles: true,
maxInstances: 2
// shardTestFiles: true,
// maxInstances: 2
},
restartBrowserBetweenTests: true
restartBrowserBetweenTests: false
};
@@ -0,0 +1,47 @@
import { Result, SceneFinished } from '@serenity-js/core/lib/domain';
import { spawner } from '../../support/spawner';
import expect = require('../../expect');
describe('When working with Cucumber', function() {
this.timeout(30 * 1000); // it might take a while to start up the selenium server
const protractor = spawner(
process.cwd() + '/node_modules/.bin/protractor',
{ cwd: __dirname, silent: true },
);
describe('Serenity/JS', () => {
it('correctly sets the strict mode when required', () => {
const spawned = protractor('protractor.conf.js',
'--specs', '**/recognises_an_implicitly_pending_scenario.feature',
'--cucumberOpts.strict', 'true',
);
return expect(spawned.result).to.be.eventually.rejected.then(() => {
const lastMessage = spawned.messages.pop();
expect(lastMessage).to.be.instanceOf(SceneFinished);
expect(Result[lastMessage.value.result]).to.equal(Result[Result.PENDING]);
});
});
it('correctly disables the strict mode when required', () => {
const spawned = protractor('protractor.conf.js',
'--specs', '**/recognises_an_implicitly_pending_scenario.feature',
'--cucumberOpts.strict', 'false',
);
return expect(spawned.result).to.be.eventually.fulfilled.then(() => {
const lastMessage = spawned.messages.pop();
expect(lastMessage).to.be.instanceOf(SceneFinished);
expect(Result[lastMessage.value.result]).to.equal(Result[Result.PENDING]);
});
});
});
});
@@ -25,7 +25,7 @@ export class CucumberTestFramework implements TestFrameworkAdapter {
if (wasSuccessful) {
resolve(wasSuccessful);
} else {
reject(wasSuccessful);
reject(new Error('Cucumber test run has failed.'));
}
});
});
@@ -34,14 +34,25 @@ export class CucumberTestFramework implements TestFrameworkAdapter {
private serenityCucumberModule = () => glob.sync(path.resolve(__dirname, '../serenity-cucumber') + '/index.?s').pop();
private stageCue = () => glob.sync(path.resolve(__dirname, '../serenity-cucumber') + '/stage_cue.?s').pop();
private argumentsFrom(config: CucumberConfig): string[]{
private argumentsFrom(config: CucumberConfig): string[] {
const resolveGlobs = (path: string) => glob.sync(path, { cwd: this.requireRoot });
const resolvePaths = (globPath: string[]) => _.chain(globPath).map(resolveGlobs).flatten().value();
const resolvedConfig = Object.assign({}, config, { require: resolvePaths(config.require || []) } );
const cleanUpFlags = (option: [string, string]) => {
switch (option[1]) {
case 'true': return [option[0]];
case 'false': return [option[0], false];
default: return option;
}
};
const onlyApplicableOptions = (option: [string, any]) => option[1] !== false;
return _.chain(resolvedConfig).toPairs().
flatMap(option => _.castArray(option[1]).map(param => [`--${ option[0]}`, param])).
map(cleanUpFlags).filter(onlyApplicableOptions).
flatten().
value() as string[];
}
@@ -83,6 +94,13 @@ export interface CucumberConfig {
*/
tags?: string[];
/**
* @link https://github.com/angular/protractor/blob/e5a5d59fcabe15860b30944e714bbd8e81ceaeae/docs/frameworks.md#using-cucumber
*/
strict?: boolean;
'no-colors'?: boolean;
/**
* @link https://github.com/cucumber/cucumber-js/blob/master/docs/cli.md#world-parameters
*/
@@ -11,7 +11,6 @@ import { StandIns } from './stand_ins';
import { TestFrameworkAdapter } from './test_framework_adapter';
import { TestFrameworkDetector } from './test_framework_detector';
import _ = require('lodash');
import { ProtractorBrowserDetector } from '../reporting/protractor_browser_detector';
// spec: https://github.com/angular/protractor/blob/master/lib/frameworks/README.md
@@ -51,9 +50,17 @@ export class SerenityProtractorFramework {
run = (specs: string[]): PromiseLike<ProtractorReport> => this.runner.runTestPreparer(this.detect.supportedCLIParams()).
then(() => this.framework.run(specs).
then(noop, this.analyzeTheFailure).
then(() => this.serenity.stageManager().waitForNextCue()).
then(() => this.waitForOtherProtractorPlugins()).
then(() => this.reporter.finalResults()));
then(() => {
return this.waitForOthers().
then(() => this.reporter.finalResults());
}, error => {
console.error(error.message);
return this.waitForOthers().
then(() => this.reporter.finalResults()).
then(results => (results.failedCount++, results));
}),
)
private analyzeTheFailure = (issue: any) => new Promise((resolve, reject) => {
return issue instanceof Error
@@ -63,6 +70,11 @@ export class SerenityProtractorFramework {
// so we don't need any additional error handling here.
})
private waitForOthers = () => Promise.all([
this.serenity.stageManager().waitForNextCue(),
this.waitForOtherProtractorPlugins(),
]);
private waitForOtherProtractorPlugins = () => Promise.resolve(this.onComplete);
// tslint:disable-next-line:no-string-literal that's how, by design, you access custom properties in Protractor

0 comments on commit 878a165

Please sign in to comment.