diff options
| author | Elliott Sprehn | 2010-10-08 16:43:40 -0700 |
|---|---|---|
| committer | Elliott Sprehn | 2010-10-14 09:47:39 -0700 |
| commit | 03df6cbddbb80186caf571e29957370b2ef9881c (patch) | |
| tree | d5a321c8b207b464a5c8a300c422186e20e8ae31 /src/scenario/HtmlUI.js | |
| parent | 0f104317dff5628765e26cc68df7dd1175b2aa5e (diff) | |
| download | angular.js-03df6cbddbb80186caf571e29957370b2ef9881c.tar.bz2 | |
New Angular Scenario runner and DSL system with redesigned HTML UI.
Uses the Jasmine syntax for tests, ex:
describe('widgets', function() {
it('should verify that basic widgets work', function(){
navigateTo('widgets.html');
input('text.basic').enter('Carlos');
expect(binding('text.basic')).toEqual('Carlos');
input('text.basic').enter('Carlos Santana');
expect(binding('text.basic')).not().toEqual('Carlos Boozer');
input('text.password').enter('secret');
expect(binding('text.password')).toEqual('secret');
expect(binding('text.hidden')).toEqual('hiddenValue');
expect(binding('gender')).toEqual('male');
input('gender').select('female');
expect(binding('gender')).toEqual('female');
});
});
Note: To create new UI's implement the interface shown in angular.scenario.ui.Html.
Diffstat (limited to 'src/scenario/HtmlUI.js')
| -rw-r--r-- | src/scenario/HtmlUI.js | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/src/scenario/HtmlUI.js b/src/scenario/HtmlUI.js new file mode 100644 index 00000000..46c88837 --- /dev/null +++ b/src/scenario/HtmlUI.js @@ -0,0 +1,204 @@ +/** + * User Interface for the Scenario Runner. + * + * @param {Object} The jQuery UI object for the UI. + */ +angular.scenario.ui.Html = function(context) { + this.context = context; + context.append( + '<div id="header">' + + ' <h1><span class="angular"><angular/></span>: Scenario Test Runner</h1>' + + ' <ul id="status-legend" class="status-display">' + + ' <li class="status-error">0 Errors</li>' + + ' <li class="status-failure">0 Failures</li>' + + ' <li class="status-success">0 Passed</li>' + + ' </ul>' + + '</div>' + + '<div id="specs">' + + ' <div class="test-children"></div>' + + '</div>' + ); +}; + +/** + * Adds a new spec to the UI. + * + * @param {Object} The spec object created by the Describe object. + */ +angular.scenario.ui.Html.prototype.addSpec = function(spec) { + var specContext = this.findContext(spec.definition); + specContext.find('> .tests').append( + '<li class="status-pending test-it"></li>' + ); + specContext = specContext.find('> .tests li:last'); + return new angular.scenario.ui.Html.Spec(specContext, spec.name, + angular.bind(this, function(status) { + var status = this.context.find('#status-legend .status-' + status); + var parts = status.text().split(' '); + var value = (parts[0] * 1) + 1; + status.text(value + ' ' + parts[1]); + }) + ); +}; + +/** + * Finds the context of a spec block defined by the passed definition. + * + * @param {Object} The definition created by the Describe object. + */ +angular.scenario.ui.Html.prototype.findContext = function(definition) { + var path = []; + var currentContext = this.context.find('#specs'); + var currentDefinition = definition; + while (currentDefinition && currentDefinition.name) { + path.unshift(currentDefinition); + currentDefinition = currentDefinition.parent; + } + angular.foreach(path, angular.bind(this, function(defn) { + var id = 'describe-' + defn.id; + if (!this.context.find('#' + id).length) { + currentContext.find('> .test-children').append( + '<div class="test-describe" id="' + id + '">' + + ' <h2></h2>' + + ' <div class="test-children"></div>' + + ' <ul class="tests"></ul>' + + '</div>' + ); + this.context.find('#' + id).find('> h2').text('describe: ' + defn.name); + } + currentContext = this.context.find('#' + id); + })); + return this.context.find('#describe-' + definition.id); +}; + +/** + * A spec block in the UI. + * + * @param {Object} The jQuery object for the context of the spec. + * @param {String} The name of the spec. + * @param {Function} Callback function(status) to call when complete. + */ +angular.scenario.ui.Html.Spec = function(context, name, doneFn) { + this.status = 'pending'; + this.context = context; + this.startTime = new Date().getTime(); + this.doneFn = doneFn; + context.append( + '<div class="test-info">' + + ' <p class="test-title">' + + ' <span class="timer-result"></span>' + + ' <span class="test-name"></span>' + + ' </p>' + + '</div>' + + '<ol class="test-actions">' + + '</ol>' + ); + context.find('> .test-info .test-name').text('it ' + name); +}; + +/** + * Adds a new Step to this spec and returns it. + * + * @param {String} The name of the step. + */ +angular.scenario.ui.Html.Spec.prototype.addStep = function(name) { + this.context.find('> .test-actions').append('<li class="status-pending"></li>'); + var stepContext = this.context.find('> .test-actions li:last'); + var self = this; + return new angular.scenario.ui.Html.Step(stepContext, name, function(status) { + self.status = status; + }); +}; + +/** + * Completes the spec and sets the timer value. + */ +angular.scenario.ui.Html.Spec.prototype.complete = function() { + this.context.removeClass('status-pending'); + var endTime = new Date().getTime(); + this.context.find("> .test-info .timer-result") + .text((endTime - this.startTime) + "ms"); +}; + +/** + * Finishes the spec, possibly with an error. + * + * @param {Object} An optional error + */ +angular.scenario.ui.Html.Spec.prototype.finish = function(error) { + this.complete(); + if (error) { + if (this.status !== 'failure') { + this.status = 'error'; + } + this.context.append('<pre></pre>'); + this.context.find('pre:first').text(error.stack || error.toString()); + } + this.context.addClass('status-' + this.status); + this.doneFn(this.status); +}; + +/** + * Finishes the spec, but with a Fatal Error. + * + * @param {Object} Required error + */ +angular.scenario.ui.Html.Spec.prototype.error = function(error) { + this.finish(error); +}; + +/** + * A single step inside an it block (or a before/after function). + * + * @param {Object} The jQuery object for the context of the step. + * @param {String} The name of the step. + * @param {Function} Callback function(status) to call when complete. + */ +angular.scenario.ui.Html.Step = function(context, name, doneFn) { + this.context = context; + this.name = name; + this.startTime = new Date().getTime(); + this.doneFn = doneFn; + context.append( + '<span class="timer-result"></span>' + + '<span class="test-title"></span>' + ); + context.find('> .test-title').text(name); +}; + +/** + * Completes the step and sets the timer value. + */ +angular.scenario.ui.Html.Step.prototype.complete = function() { + this.context.removeClass('status-pending'); + var endTime = new Date().getTime(); + this.context.find(".timer-result") + .text((endTime - this.startTime) + "ms"); +}; + +/** + * Finishes the step, possibly with an error. + * + * @param {Object} An optional error + */ +angular.scenario.ui.Html.Step.prototype.finish = function(error) { + this.complete(); + if (error) { + this.context.addClass('status-failure'); + this.doneFn('failure'); + } else { + this.context.addClass('status-success'); + this.doneFn('success'); + } +}; + +/** + * Finishes the step, but with a Fatal Error. + * + * @param {Object} Required error + */ +angular.scenario.ui.Html.Step.prototype.error = function(error) { + this.complete(); + this.context.addClass('status-error'); + this.doneFn('error'); +}; |
