|
1 | 1 | /** |
2 | 2 | * Represents the application currently being tested and abstracts usage |
3 | 3 | * of iframes or separate windows. |
| 4 | + * |
| 5 | + * @param {Object} context jQuery wrapper around HTML context. |
4 | 6 | */ |
5 | 7 | angular.scenario.Application = function(context) { |
6 | 8 | this.context = context; |
7 | | - context.append('<h2>Current URL: <a href="about:blank">None</a></h2>'); |
| 9 | + context.append( |
| 10 | + '<h2>Current URL: <a href="about:blank">None</a></h2>' + |
| 11 | + '<div id="test-frames"></div>' |
| 12 | + ); |
8 | 13 | }; |
9 | 14 |
|
10 | 15 | /** |
11 | 16 | * Gets the jQuery collection of frames. Don't use this directly because |
12 | 17 | * frames may go stale. |
13 | 18 | * |
| 19 | + * @private |
14 | 20 | * @return {Object} jQuery collection |
15 | 21 | */ |
16 | | -angular.scenario.Application.prototype.getFrame = function() { |
17 | | - return this.context.find('> iframe'); |
| 22 | +angular.scenario.Application.prototype.getFrame_ = function() { |
| 23 | + return this.context.find('#test-frames iframe:last'); |
18 | 24 | }; |
19 | 25 |
|
20 | 26 | /** |
21 | | - * Gets the window of the test runner frame. Always favor executeAction() |
| 27 | + * Gets the window of the test runner frame. Always favor executeAction() |
22 | 28 | * instead of this method since it prevents you from getting a stale window. |
23 | 29 | * |
| 30 | + * @private |
24 | 31 | * @return {Object} the window of the frame |
25 | 32 | */ |
26 | | -angular.scenario.Application.prototype.getWindow = function() { |
27 | | - var contentWindow = this.getFrame().attr('contentWindow'); |
| 33 | +angular.scenario.Application.prototype.getWindow_ = function() { |
| 34 | + var contentWindow = this.getFrame_().attr('contentWindow'); |
28 | 35 | if (!contentWindow) |
29 | | - throw 'No window available because frame not loaded.'; |
| 36 | + throw 'Frame window is not accessible.'; |
30 | 37 | return contentWindow; |
31 | 38 | }; |
32 | 39 |
|
33 | 40 | /** |
34 | 41 | * Changes the location of the frame. |
| 42 | + * |
| 43 | + * @param {string} url The URL. If it begins with a # then only the |
| 44 | + * hash of the page is changed. |
| 45 | + * @param {Function} onloadFn function($window, $document) |
35 | 46 | */ |
36 | 47 | angular.scenario.Application.prototype.navigateTo = function(url, onloadFn) { |
37 | | - this.getFrame().remove(); |
38 | | - this.context.append('<iframe src=""></iframe>'); |
| 48 | + var self = this; |
| 49 | + var frame = this.getFrame_(); |
| 50 | + if (url.charAt(0) === '#') { |
| 51 | + url = frame.attr('src').split('#')[0] + url; |
| 52 | + frame.attr('src', url); |
| 53 | + this.executeAction(onloadFn); |
| 54 | + } else { |
| 55 | + frame.css('display', 'none').attr('src', 'about:blank'); |
| 56 | + this.context.find('#test-frames').append('<iframe>'); |
| 57 | + frame = this.getFrame_(); |
| 58 | + frame.load(function() { |
| 59 | + self.executeAction(onloadFn); |
| 60 | + frame.unbind(); |
| 61 | + }).attr('src', url); |
| 62 | + } |
39 | 63 | this.context.find('> h2 a').attr('href', url).text(url); |
40 | | - this.getFrame().attr('src', url).load(onloadFn); |
41 | 64 | }; |
42 | 65 |
|
43 | 66 | /** |
44 | | - * Executes a function in the context of the tested application. |
| 67 | + * Executes a function in the context of the tested application. Will wait |
| 68 | + * for all pending angular xhr requests before executing. |
45 | 69 | * |
46 | | - * @param {Function} The callback to execute. function($window, $document) |
| 70 | + * @param {Function} action The callback to execute. function($window, $document) |
| 71 | + * $document is a jQuery wrapped document. |
47 | 72 | */ |
48 | 73 | angular.scenario.Application.prototype.executeAction = function(action) { |
49 | | - var $window = this.getWindow(); |
50 | | - return action.call(this, $window, _jQuery($window.document)); |
| 74 | + var self = this; |
| 75 | + var $window = this.getWindow_(); |
| 76 | + if (!$window.angular) { |
| 77 | + return action.call(this, $window, _jQuery($window.document)); |
| 78 | + } |
| 79 | + var $browser = $window.angular.service.$browser(); |
| 80 | + $browser.poll(); |
| 81 | + $browser.notifyWhenNoOutstandingRequests(function() { |
| 82 | + action.call(self, $window, _jQuery($window.document)); |
| 83 | + }); |
51 | 84 | }; |
0 commit comments