X Tutup
Skip to content

Commit 40d7e66

Browse files
esprehnIgorMinar
authored andcommitted
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. <script src="angular-scenario.js" ng:scenario-output="xml,json"> - Added element(...).count() that returns the number of matching elements for the selector. - repeater(...).count() now returns 0 if no elements matched which can be used to check if a repeater is empty. - Added toBe() matcher that does strict equality with === - Implement iit and ddescribe. If iit() is used instead of it() then only that test will run. If ddescribe() is used instead of describe() them only it() statements inside of it will run. Several iit/ddescribe() blocks can be used to run isolated tests. - Implement new event based model for SpecRunner. You can now listen for events in the runner. This is useful for writing your own UI or connecting a remote process (ex. WebDriver). Event callbacks execute on the Runner instance. Events, if fired, will always be in the below order. All events always happen except for Failure and Error events which only happen in error conditions. Events: RunnerBegin SpecBegin(spec) StepBegin(spec, step) StepError(spec, step, error) StepFailure(spec, step, error) StepEnd(spec, step) SpecError(spec, step, error) SpecEnd(spec) RunnerEnd - Only allow the browser to repaint every 10 steps. Cuts 700ms off Firefox in benchmark, 200ms off Chrome. - Bug Fix: Manually navigate anchors on click since trigger wont work in Firefox.
1 parent 1d52349 commit 40d7e66

37 files changed

+1362
-648
lines changed

Rakefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,16 @@ ANGULAR_SCENARIO = [
2727
'src/scenario/Application.js',
2828
'src/scenario/Describe.js',
2929
'src/scenario/Future.js',
30-
'src/scenario/HtmlUI.js',
30+
'src/scenario/ObjectModel.js',
3131
'src/scenario/Describe.js',
3232
'src/scenario/Runner.js',
3333
'src/scenario/SpecRunner.js',
3434
'src/scenario/dsl.js',
3535
'src/scenario/matchers.js',
36+
'src/scenario/output/Html.js',
37+
'src/scenario/output/Json.js',
38+
'src/scenario/output/Xml.js',
39+
'src/scenario/output/Object.js',
3640
]
3741

3842
BUILD_DIR = 'build'

css/angular-scenario.css

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ body {
88
font-size: 14px;
99
}
1010

11+
#json, #xml {
12+
display: none;
13+
}
14+
1115
#header {
1216
position: fixed;
1317
width: 100%;
@@ -32,7 +36,7 @@ body {
3236
height: 30px;
3337
}
3438

35-
#frame h2,
39+
#application h2,
3640
#specs h2 {
3741
margin: 0;
3842
padding: 0.5em;
@@ -45,26 +49,26 @@ body {
4549
}
4650

4751
#header,
48-
#frame,
52+
#application,
4953
.test-info,
5054
.test-actions li {
5155
overflow: hidden;
5256
}
5357

54-
#frame {
58+
#application {
5559
margin: 10px;
5660
}
5761

58-
#frame iframe {
62+
#application iframe {
5963
width: 100%;
6064
height: 758px;
6165
}
6266

63-
#frame .popout {
67+
#application .popout {
6468
float: right;
6569
}
6670

67-
#frame iframe {
71+
#application iframe {
6872
border: none;
6973
}
7074

@@ -154,6 +158,10 @@ body {
154158
margin-left: 6em;
155159
}
156160

161+
.test-describe {
162+
padding-bottom: 0.5em;
163+
}
164+
157165
.test-describe .test-describe {
158166
margin: 5px 5px 10px 2em;
159167
}
@@ -178,11 +186,11 @@ body {
178186
}
179187

180188
#specs h2,
181-
#frame h2 {
189+
#application h2 {
182190
background-color: #efefef;
183191
}
184192

185-
#frame {
193+
#application {
186194
border: 1px solid #BABAD1;
187195
}
188196

jsTestDriver-jquery.conf

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,18 @@ load:
1010
- src/*.js
1111
- test/testabilityPatch.js
1212
- src/scenario/Scenario.js
13+
- src/scenario/output/*.js
1314
- src/scenario/*.js
1415
- test/angular-mocks.js
1516
- test/scenario/*.js
17+
- test/scenario/output/*.js
1618
- test/*.js
1719

1820
exclude:
1921
- src/angular.prefix
2022
- src/angular.suffix
2123
- src/angular-bootstrap.js
2224
- src/AngularPublic.js
23-
- src/scenario/bootstrap.js
25+
- src/scenario/angular-bootstrap.js
2426
- test/jquery_remove.js
2527

jsTestDriver.conf

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@ load:
1111
- example/personalLog/*.js
1212
- test/testabilityPatch.js
1313
- src/scenario/Scenario.js
14+
- src/scenario/output/*.js
1415
- src/scenario/*.js
1516
- test/angular-mocks.js
1617
- test/scenario/*.js
18+
- test/scenario/output/*.js
1719
- test/*.js
1820
- example/personalLog/test/*.js
1921

@@ -22,5 +24,5 @@ exclude:
2224
- src/angular.prefix
2325
- src/angular.suffix
2426
- src/angular-bootstrap.js
25-
- src/scenario/bootstrap.js
27+
- src/scenario/angular-bootstrap.js
2628
- src/AngularPublic.js

scenario/Runner.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
22
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
33
<head>
4-
<script type="text/javascript" src="../src/scenario/bootstrap.js"></script>
4+
<script type="text/javascript" src="../src/scenario/angular-bootstrap.js"></script>
55
<script type="text/javascript" src="widgets-scenario.js"></script>
66
</head>
77
<body>

scenario/widgets-scenario.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ describe('widgets', function() {
3636
element('input[type="image"]').click();
3737
expect(binding('button').fromJson()).toEqual({'count': 4});
3838

39+
element('#navigate a').click();
40+
expect(binding('$location.hash')).toEqual('route');
41+
3942
/**
4043
* Custom value parser for futures.
4144
*/

scenario/widgets.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
<html xmlns:ng="http://angularjs.org">
33
<head>
44
<link rel="stylesheet" type="text/css" href="style.css"/>
5-
<script type="text/javascript" src="../libs/jquery/jquery-1.4.2.js"></script>
65
<script type="text/javascript" src="../src/angular-bootstrap.js" ng:autobind></script>
76
</head>
87
<body ng:init="$window.$scope = this">
@@ -94,6 +93,11 @@
9493
</td>
9594
<td></td>
9695
</tr>
96+
<tr id="navigate">
97+
<td>navigate</td>
98+
<td><a href="#route">Go to #route</td>
99+
<td>{{$location.hash}}</td>
100+
</tr>
97101
</table>
98102
</body>
99103
</html>

src/scenario/Application.js

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,84 @@
11
/**
22
* Represents the application currently being tested and abstracts usage
33
* of iframes or separate windows.
4+
*
5+
* @param {Object} context jQuery wrapper around HTML context.
46
*/
57
angular.scenario.Application = function(context) {
68
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+
);
813
};
914

1015
/**
1116
* Gets the jQuery collection of frames. Don't use this directly because
1217
* frames may go stale.
1318
*
19+
* @private
1420
* @return {Object} jQuery collection
1521
*/
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');
1824
};
1925

2026
/**
21-
* Gets the window of the test runner frame. Always favor executeAction()
27+
* Gets the window of the test runner frame. Always favor executeAction()
2228
* instead of this method since it prevents you from getting a stale window.
2329
*
30+
* @private
2431
* @return {Object} the window of the frame
2532
*/
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');
2835
if (!contentWindow)
29-
throw 'No window available because frame not loaded.';
36+
throw 'Frame window is not accessible.';
3037
return contentWindow;
3138
};
3239

3340
/**
3441
* 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)
3546
*/
3647
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+
}
3963
this.context.find('> h2 a').attr('href', url).text(url);
40-
this.getFrame().attr('src', url).load(onloadFn);
4164
};
4265

4366
/**
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.
4569
*
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.
4772
*/
4873
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+
});
5184
};

0 commit comments

Comments
 (0)
X Tutup