From 40d7e66f408eaaa66efd8d7934ab2eb3324236a1 Mon Sep 17 00:00:00 2001 From: Elliott Sprehn Date: Sun, 24 Oct 2010 14:14:45 -0700 Subject: Lots of bug fixes in the scenario runner and a bunch of new features. - By default the runner now creates multiple output formats as it runs. Nodes are created in the DOM with ids: json, xml, and html. ex. $('#json').html() => json output of the runner ex. $('#xml').html() => json output of the runner $result is also an object tree result. The permitted formats are html,json,xml,object. If you don't want certain formats you can select specific ones with the new ng:scenario-output attribute on the script tag. '); + } + + function addCSS(path) { + document.write(''); + } + + window.onload = function(){ + try { + if (previousOnLoad) previousOnLoad(); + } catch(e) {} + angularScenarioInit($scenario, angularJsConfig(document)); + }; + + addCSS("../../css/angular-scenario.css"); + addScript("../../lib/jquery/jquery-1.4.2.js"); + document.write( + '' + ); + addScript("../angular-bootstrap.js"); + + addScript("Scenario.js"); + addScript("Application.js"); + addScript("Describe.js"); + addScript("Future.js"); + addScript("Runner.js"); + addScript("SpecRunner.js"); + addScript("dsl.js"); + addScript("matchers.js"); + addScript("ObjectModel.js"); + addScript("output/Html.js"); + addScript("output/Json.js"); + addScript("output/Object.js"); + addScript("output/Xml.js"); + + // Create the runner (which also sets up the global API) + document.write( + '' + ); + +})(window.onload); diff --git a/src/scenario/angular.prefix b/src/scenario/angular.prefix index d6660d61..fb9ae147 100644 --- a/src/scenario/angular.prefix +++ b/src/scenario/angular.prefix @@ -22,4 +22,4 @@ * THE SOFTWARE. */ (function(window, document, previousOnLoad){ - var _jQuery = window.jQuery.noConflict(true); \ No newline at end of file + var _jQuery = window.jQuery.noConflict(true); diff --git a/src/scenario/angular.suffix b/src/scenario/angular.suffix index c38f0ab5..66843013 100644 --- a/src/scenario/angular.suffix +++ b/src/scenario/angular.suffix @@ -4,25 +4,7 @@ try { if (previousOnLoad) previousOnLoad(); } catch(e) {} - _jQuery(document.body).append( - '
' + - '' - ); - var frame = _jQuery('#frame'); - var runner = _jQuery('#runner'); - var application = new angular.scenario.Application(frame); - var ui = new angular.scenario.ui.Html(runner); - $scenario.run(ui, application, angular.scenario.SpecRunner, function(error) { - frame.remove(); - if (error) { - if (window.console) { - console.log(error.stack || error); - } else { - // Do something for IE - alert(error); - } - } - }); + angularScenarioInit($scenario, angularJsConfig(document)); }; })(window, document, window.onload); diff --git a/src/scenario/bootstrap.js b/src/scenario/bootstrap.js deleted file mode 100644 index 4661bfb2..00000000 --- a/src/scenario/bootstrap.js +++ /dev/null @@ -1,73 +0,0 @@ -(function(previousOnLoad){ - var prefix = (function(){ - var filename = /(.*\/)bootstrap.js(#(.*))?/; - var scripts = document.getElementsByTagName("script"); - for(var j = 0; j < scripts.length; j++) { - var src = scripts[j].src; - if (src && src.match(filename)) { - var parts = src.match(filename); - return parts[1]; - } - } - })(); - - function addScript(path) { - document.write(''); - } - - function addCSS(path) { - document.write(''); - } - - window.onload = function(){ - try { - if (previousOnLoad) previousOnLoad(); - } catch(e) {} - _jQuery(document.body).append( - '' + - '' - ); - var frame = _jQuery('#frame'); - var runner = _jQuery('#runner'); - var application = new angular.scenario.Application(frame); - var ui = new angular.scenario.ui.Html(runner); - $scenario.run(ui, application, angular.scenario.SpecRunner, function(error) { - frame.remove(); - if (error) { - if (window.console) { - console.log(error.stack || error); - } else { - // Do something for IE - alert(error); - } - } - }); - }; - - addCSS("../../css/angular-scenario.css"); - addScript("../../lib/jquery/jquery-1.4.2.js"); - document.write( - '' - ); - addScript("../angular-bootstrap.js"); - - addScript("Scenario.js"); - addScript("Application.js"); - addScript("Describe.js"); - addScript("Future.js"); - addScript("HtmlUI.js"); - addScript("Runner.js"); - addScript("SpecRunner.js"); - addScript("dsl.js"); - addScript("matchers.js"); - - // Create the runner (which also sets up the global API) - document.write( - '' - ); - -})(window.onload); diff --git a/src/scenario/dsl.js b/src/scenario/dsl.js index f4484df8..1ae26db8 100644 --- a/src/scenario/dsl.js +++ b/src/scenario/dsl.js @@ -1,18 +1,19 @@ /** * Shared DSL statements that are useful to all scenarios. */ - + /** * Usage: * wait() waits until you call resume() in the console */ - angular.scenario.dsl('wait', function() { +angular.scenario.dsl('wait', function() { return function() { - return this.addFuture('waiting for you to call resume() in the console', function(done) { + return this.addFuture('waiting for you to resume', function(done) { + this.emit('InteractiveWait', this.spec, this.step); this.$window.resume = function() { done(); }; }); }; - }); +}); /** * Usage: @@ -21,7 +22,7 @@ angular.scenario.dsl('pause', function() { return function(time) { return this.addFuture('pause for ' + time + ' seconds', function(done) { - this.setTimeout(function() { done(null, time * 1000); }, time * 1000); + this.$window.setTimeout(function() { done(null, time * 1000); }, time * 1000); }); }; }); @@ -49,8 +50,8 @@ angular.scenario.dsl('expect', function() { /** * Usage: - * navigateTo(future|string) where url a string or future with a value - * of a URL to navigate to + * navigateTo(url) Loads the url into the frame + * navigateTo(url, fn) where fn(url) is called and returns the URL to navigate to */ angular.scenario.dsl('navigateTo', function() { return function(url, delegate) { @@ -60,17 +61,7 @@ angular.scenario.dsl('navigateTo', function() { url = delegate.call(this, url); } application.navigateTo(url, function() { - application.executeAction(function($window) { - if ($window.angular) { - var $browser = $window.angular.service.$browser(); - $browser.poll(); - $browser.notifyWhenNoOutstandingRequests(function() { - done(null, url); - }); - } else { - done(null, url); - } - }); + done(null, url); }); }); }; @@ -162,7 +153,11 @@ angular.scenario.dsl('repeater', function() { chain.count = function() { return this.addFutureAction('repeater ' + this.selector + ' count', function($window, $document, done) { - done(null, $document.elements().size()); + try { + done(null, $document.elements().length); + } catch (e) { + done(null, 0); + } }); }; @@ -238,6 +233,7 @@ angular.scenario.dsl('select', function() { /** * Usage: + * element(selector).count() get the number of elements that match selector * element(selector).click() clicks an element * element(selector).attr(name) gets the value of an attribute * element(selector).attr(name, value) sets the value of an attribute @@ -248,10 +244,28 @@ angular.scenario.dsl('select', function() { angular.scenario.dsl('element', function() { var chain = {}; + chain.count = function() { + return this.addFutureAction('element ' + this.selector + ' count', function($window, $document, done) { + try { + done(null, $document.elements().length); + } catch (e) { + done(null, 0); + } + }); + }; + chain.click = function() { return this.addFutureAction('element ' + this.selector + ' click', function($window, $document, done) { - $document.elements().trigger('click'); - done(); + var elements = $document.elements(); + var href = elements.attr('href'); + elements.trigger('click'); + if (href && elements[0].nodeName.toUpperCase() === 'A') { + this.application.navigateTo(href, function() { + done(); + }); + } else { + done(); + } }); }; diff --git a/src/scenario/matchers.js b/src/scenario/matchers.js index 0dfbc455..8ef154e9 100644 --- a/src/scenario/matchers.js +++ b/src/scenario/matchers.js @@ -6,6 +6,10 @@ angular.scenario.matcher('toEqual', function(expected) { return angular.equals(this.actual, expected); }); +angular.scenario.matcher('toBe', function(expected) { + return this.actual === expected; +}); + angular.scenario.matcher('toBeDefined', function() { return angular.isDefined(this.actual); }); diff --git a/src/scenario/output/Html.js b/src/scenario/output/Html.js new file mode 100644 index 00000000..4a682b9a --- /dev/null +++ b/src/scenario/output/Html.js @@ -0,0 +1,165 @@ +/** + * User Interface for the Scenario Runner. + * + * TODO(esprehn): This should be refactored now that ObjectModel exists + * to use angular bindings for the UI. + */ +angular.scenario.output('html', function(context, runner) { + var model = new angular.scenario.ObjectModel(runner); + + context.append( + '' + + ' ' + + ' ' + + '
' + + '