diff --git a/Rakefile b/Rakefile index 59be55fc..b66d467b 100644 --- a/Rakefile +++ b/Rakefile @@ -27,12 +27,16 @@ ANGULAR_SCENARIO = [ 'src/scenario/Application.js', 'src/scenario/Describe.js', 'src/scenario/Future.js', - 'src/scenario/HtmlUI.js', + 'src/scenario/ObjectModel.js', 'src/scenario/Describe.js', 'src/scenario/Runner.js', 'src/scenario/SpecRunner.js', 'src/scenario/dsl.js', 'src/scenario/matchers.js', + 'src/scenario/output/Html.js', + 'src/scenario/output/Json.js', + 'src/scenario/output/Xml.js', + 'src/scenario/output/Object.js', ] BUILD_DIR = 'build' diff --git a/css/angular-scenario.css b/css/angular-scenario.css index adadebb0..f5cded7f 100644 --- a/css/angular-scenario.css +++ b/css/angular-scenario.css @@ -8,6 +8,10 @@ body { font-size: 14px; } +#json, #xml { + display: none; +} + #header { position: fixed; width: 100%; @@ -32,7 +36,7 @@ body { height: 30px; } -#frame h2, +#application h2, #specs h2 { margin: 0; padding: 0.5em; @@ -45,26 +49,26 @@ body { } #header, -#frame, +#application, .test-info, .test-actions li { overflow: hidden; } -#frame { +#application { margin: 10px; } -#frame iframe { +#application iframe { width: 100%; height: 758px; } -#frame .popout { +#application .popout { float: right; } -#frame iframe { +#application iframe { border: none; } @@ -154,6 +158,10 @@ body { margin-left: 6em; } +.test-describe { + padding-bottom: 0.5em; +} + .test-describe .test-describe { margin: 5px 5px 10px 2em; } @@ -178,11 +186,11 @@ body { } #specs h2, -#frame h2 { +#application h2 { background-color: #efefef; } -#frame { +#application { border: 1px solid #BABAD1; } diff --git a/jsTestDriver-jquery.conf b/jsTestDriver-jquery.conf index 7f0d6912..a2388662 100644 --- a/jsTestDriver-jquery.conf +++ b/jsTestDriver-jquery.conf @@ -10,9 +10,11 @@ load: - src/*.js - test/testabilityPatch.js - src/scenario/Scenario.js + - src/scenario/output/*.js - src/scenario/*.js - test/angular-mocks.js - test/scenario/*.js + - test/scenario/output/*.js - test/*.js exclude: @@ -20,6 +22,6 @@ exclude: - src/angular.suffix - src/angular-bootstrap.js - src/AngularPublic.js - - src/scenario/bootstrap.js + - src/scenario/angular-bootstrap.js - test/jquery_remove.js diff --git a/jsTestDriver.conf b/jsTestDriver.conf index 7d202d72..c8ced595 100644 --- a/jsTestDriver.conf +++ b/jsTestDriver.conf @@ -11,9 +11,11 @@ load: - example/personalLog/*.js - test/testabilityPatch.js - src/scenario/Scenario.js + - src/scenario/output/*.js - src/scenario/*.js - test/angular-mocks.js - test/scenario/*.js + - test/scenario/output/*.js - test/*.js - example/personalLog/test/*.js @@ -22,5 +24,5 @@ exclude: - src/angular.prefix - src/angular.suffix - src/angular-bootstrap.js - - src/scenario/bootstrap.js + - src/scenario/angular-bootstrap.js - src/AngularPublic.js diff --git a/scenario/Runner.html b/scenario/Runner.html index ffa08af9..f715b8e5 100644 --- a/scenario/Runner.html +++ b/scenario/Runner.html @@ -1,7 +1,7 @@ - + diff --git a/scenario/widgets-scenario.js b/scenario/widgets-scenario.js index 0d604fc9..ba3ef3cf 100644 --- a/scenario/widgets-scenario.js +++ b/scenario/widgets-scenario.js @@ -36,6 +36,9 @@ describe('widgets', function() { element('input[type="image"]').click(); expect(binding('button').fromJson()).toEqual({'count': 4}); + element('#navigate a').click(); + expect(binding('$location.hash')).toEqual('route'); + /** * Custom value parser for futures. */ diff --git a/scenario/widgets.html b/scenario/widgets.html index 8960f5f4..a520a326 100644 --- a/scenario/widgets.html +++ b/scenario/widgets.html @@ -2,7 +2,6 @@ - @@ -94,6 +93,11 @@ + + navigate + Go to #route + {{$location.hash}} + diff --git a/src/scenario/Application.js b/src/scenario/Application.js index 4ee0dd03..e2d34551 100644 --- a/src/scenario/Application.js +++ b/src/scenario/Application.js @@ -1,51 +1,84 @@ /** * Represents the application currently being tested and abstracts usage * of iframes or separate windows. + * + * @param {Object} context jQuery wrapper around HTML context. */ angular.scenario.Application = function(context) { this.context = context; - context.append('

Current URL: None

'); + context.append( + '

Current URL: None

' + + '
' + ); }; /** * Gets the jQuery collection of frames. Don't use this directly because * frames may go stale. * + * @private * @return {Object} jQuery collection */ -angular.scenario.Application.prototype.getFrame = function() { - return this.context.find('> iframe'); +angular.scenario.Application.prototype.getFrame_ = function() { + return this.context.find('#test-frames iframe:last'); }; /** - * Gets the window of the test runner frame. Always favor executeAction() + * Gets the window of the test runner frame. Always favor executeAction() * instead of this method since it prevents you from getting a stale window. * + * @private * @return {Object} the window of the frame */ -angular.scenario.Application.prototype.getWindow = function() { - var contentWindow = this.getFrame().attr('contentWindow'); +angular.scenario.Application.prototype.getWindow_ = function() { + var contentWindow = this.getFrame_().attr('contentWindow'); if (!contentWindow) - throw 'No window available because frame not loaded.'; + throw 'Frame window is not accessible.'; return contentWindow; }; /** * Changes the location of the frame. + * + * @param {string} url The URL. If it begins with a # then only the + * hash of the page is changed. + * @param {Function} onloadFn function($window, $document) */ angular.scenario.Application.prototype.navigateTo = function(url, onloadFn) { - this.getFrame().remove(); - this.context.append(''); + var self = this; + var frame = this.getFrame_(); + if (url.charAt(0) === '#') { + url = frame.attr('src').split('#')[0] + url; + frame.attr('src', url); + this.executeAction(onloadFn); + } else { + frame.css('display', 'none').attr('src', 'about:blank'); + this.context.find('#test-frames').append('