API Docs for: 0.9.3
Show:

File: lib/task/client/cucumber.js

// Copyright 2014, Yahoo! Inc.
// Copyrights licensed under the Mit License. See the accompanying LICENSE file for terms.

var AbstractClient = require('../../abstractClient');
var Promise = require('promise');
var _ = require('underscore');
var utils = require('preceptor-core').utils;

/**
 * @class CucumberClient
 * @extends AbstractClient
 * @constructor
 */
var CucumberClient = AbstractClient.extend(

	{
		/**
		 * Initializes the instance
		 *
		 * @method initialize
		 */
		initialize: function () {

			var self = this;

			this.__super();

			this.getFunctions().push(function () {

				this.BeforeFeatures(function (event, callback) {
					self.processBefore().then(function () {
						callback();
					}, function (err) {
						console.error(err.stack);
						callback(err);
					});
				});
				this.AfterFeatures(function (event, callback) {
					self.processAfter().then(function () {
						callback();
					}, function (err) {
						console.error(err.stack);
						callback(err);
					});
				});

				this.BeforeStep(function (event, callback) {
					self.processBeforeTest().then(function () {
						callback();
					}, function (err) {
						console.error(err.stack);
						callback(err);
					});
				});
				this.AfterStep(function (event, callback) {
					self.processAfterTest().then(function () {
						callback();
					}, function (err) {
						console.error(err.stack);
						callback(err);
					});
				});
			});
		},


		/**
		 * Gets the cucumber configuration
		 * Overwrite this function if the cucumber configuration is found somewhere else.
		 *
		 * @method getCucumberConfiguration
		 * @return {object}
		 */
		getCucumberConfiguration: function () {
			return this.getOptions();
		},

		/**
		 * Sets the cucumber configuration
		 * Overwrite this function if the cucumber configuration is found somewhere else.
		 *
		 * @method setCucumberConfiguration
		 * @param {object} options
		 */
		setCucumberConfiguration: function (options) {
			this._options = options;
		},


		/**
		 * Gets the path to the text files
		 * Cucumber Option: <Last parameter>
		 *
		 * @method getPath
		 * @return {string}
		 */
		getPath: function () {
			return this.getCucumberConfiguration().path;
		},

		/**
		 * Gets the tags to include/exclude
		 * Cucumber Option: tags
		 *
		 * @method getTags
		 * @return {string[]}
		 */
		getTags: function () {
			return this.getCucumberConfiguration().tags;
		},

		/**
		 * Gets the required file before running the tests
		 * Cucumber Option: require
		 *
		 * @method getRequires
		 * @return {string[]}
		 */
		getRequires: function () {
			return this.getCucumberConfiguration().require;
		},

		/**
		 * Gets the functions to execute as part of files to execute
		 * Cucumber Option: <does not exist>
		 *
		 * @method getFunctions
		 * @return {function[]}
		 */
		getFunctions: function () {
			return this.getCucumberConfiguration().functions;
		},

		/**
		 * Should output in coffee-script?
		 * Cucumber Option: coffee
		 *
		 * @method shouldOutputCoffeeScript
		 * @return {boolean}
		 */
		shouldOutputCoffeeScript: function () {
			return this.getCucumberConfiguration().coffeeScript;
		},

		/**
		 * Gets the output format for cucumber
		 * Cucumber Option: format
		 *
		 * @method getFormat
		 * @return {string}
		 */
		getFormat: function () {
			return this.getCucumberConfiguration().format;
		},


		/**
		 * Execute client
		 *
		 * @method run
		 * @param {string} parentId
		 * @return {Promise}
		 */
		run: function (parentId) {

			return new Promise(function (resolve, reject) {

				var hook,
					options,
					done;

				hook = this.getReportManager().loadHook('cucumber', parentId);

				options = this.getCucumberConfiguration();
				options.functions.push(hook);

				this.getReportManager().message().start();
				done = function () {
					this.getReportManager().message().stop();
					this.getReportManager().message().complete();
				}.bind(this);

				this._runCucumber(options, function () {
					done();
					resolve.apply(this, arguments);
				}, function () {
					done();
					reject.apply(this, arguments);
				});

			}.bind(this));
		},

		/**
		 * Runs the cucumber tests, self-contained
		 *
		 * @method _runCucumber
		 * @param {object} options
		 * @param {string} options.path
		 * @param {string[]} [options.tags]
		 * @param {string[]} [options.require]
		 * @param {function[]} [options.functions]
		 * @param {string} [options.format]
		 * @param {boolean} [options.coffeeScript]
		 * @param {function} success
		 * @param {function} failure
		 * @private
		 */
		_runCucumber: function (options, success, failure) {

			var args = [],
				cli,
				Cucumber = require('cucumber');

			if (options.tags) {
				_.each(options.tags, function (tagList) {
					if (!_.isArray(tagList)) {
						tagList = tagList.split(',');
					}
					args.push('--tags');
					args.push(tagList.join(','));
				});
			}

			if (options.format) {
				args.push('--format');
				args.push(options.format);
			}

			if (options.require) {
				_.each(options.require, function (require) {
					args.push('--require');
					args.push(require);
				});
			}

			if (options.coffeeScript) {
				args.push('--coffee');
			}

			args.push(options.path);

			// Adds the "functions" feature to cucumber
			(function () {
				var originalSupportCodeLoader = Cucumber.Cli.SupportCodeLoader,
					firstTimeLoaded = false;

				// Overwrite the constructor
				Cucumber.Cli.SupportCodeLoader = function () {

					var result = originalSupportCodeLoader.apply(this, arguments),
						originalBuildSupportCodeInitializerFromPaths = result.buildSupportCodeInitializerFromPaths;

					// Overwrite the resulting functions since they are created for each object in the constructor
					result.buildSupportCodeInitializerFromPaths = function () {

						var wrapperFn = originalBuildSupportCodeInitializerFromPaths.apply(this, arguments);

						// Overwrite the wrapper returned from the builder function
						return function () {

							// Execute functions as if they were in files
							if (!firstTimeLoaded) {
								firstTimeLoaded = true;

								_.each(options.functions, function (fn) {
									fn.call(this);
								}, this);
							}

							wrapperFn.apply(this, arguments);
						}
					};

					return result;
				};
			}());

			// Add some standard arguments that will be cut out in cucumber anyways
			args.unshift('node');
			args.unshift('cucumber.js');

			// Run cucumber with options supplied
			cli = Cucumber.Cli(args);
			cli.run(function (succeeded) {
				if (succeeded) {
					success(succeeded);
				} else {
					failure(new Error('Failed'));
				}
			});

			return cli;
		}
	});

module.exports = CucumberClient;