Skip to content
This repository was archived by the owner on Jul 29, 2024. It is now read-only.

Commit 3c76246

Browse files
colinmutterjuliemr
authored andcommitted
Added nested angular app capability via conf file. Copied some tests over to demonstrate
Changed option name to coincide with angular's $rootElement semantics
1 parent 422eab6 commit 3c76246

File tree

7 files changed

+116
-14
lines changed

7 files changed

+116
-14
lines changed

lib/cli.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ var config = {
1919
capabilities: {
2020
'browserName': 'chrome'
2121
},
22+
rootElement: 'body',
2223
jasmineNodeOpts: {
2324
specs: [],
2425
isVerbose: false,
@@ -138,7 +139,7 @@ var startJasmineTests = function() {
138139
driver.getSession().then(function(session) {
139140
id = session.getId();
140141

141-
protractor.setInstance(protractor.wrapDriver(driver, config.baseUrl));
142+
protractor.setInstance(protractor.wrapDriver(driver, config.baseUrl, config.rootElement));
142143

143144
// Export protractor to the global namespace to be used in tests.
144145
global.protractor = protractor;

lib/protractor.js

+11-8
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@ var clientSideScripts = {};
2525
* Wait until Angular has finished rendering and has
2626
* no outstanding $http calls before continuing.
2727
*
28-
* arguments none.
28+
* arguments[0] {string} The selector housing an ng-app
29+
* arguments[1] {function} callback
2930
*/
3031
clientSideScripts.waitForAngular = function() {
31-
var callback = arguments[arguments.length - 1];
32-
angular.element(document.body).injector().get('$browser').
32+
var el = document.querySelector(arguments[0]);
33+
var callback = arguments[1];
34+
angular.element(el).injector().get('$browser').
3335
notifyWhenNoOutstandingRequests(callback);
3436
};
3537

@@ -291,9 +293,10 @@ var mixin = function(to, from, fnName) {
291293
/**
292294
* @param {webdriver.WebDriver} webdriver
293295
* @param {string=} opt_baseUrl A base URL to run get requests against.
296+
* @param {string=body} opt_rootElement Selector el that has an ng-app in scope
294297
* @constructor
295298
*/
296-
var Protractor = function(webdriver, opt_baseUrl) {
299+
var Protractor = function(webdriver, opt_baseUrl, opt_rootElement) {
297300
// Mix all other driver functionality into Protractor.
298301
for (var foo in webdriver) {
299302
if(!this[foo] && typeof webdriver[foo] == 'function') {
@@ -303,7 +306,7 @@ var Protractor = function(webdriver, opt_baseUrl) {
303306

304307
this.driver = webdriver;
305308
this.baseUrl = opt_baseUrl || '';
306-
309+
this.rootEl = opt_rootElement || 'body';
307310
this.moduleNames_ = [];
308311

309312
this.moduleScripts_ = [];
@@ -317,7 +320,7 @@ var Protractor = function(webdriver, opt_baseUrl) {
317320
* scripts return value.
318321
*/
319322
Protractor.prototype.waitForAngular = function() {
320-
return this.driver.executeAsyncScript(clientSideScripts.waitForAngular);
323+
return this.driver.executeAsyncScript(clientSideScripts.waitForAngular, this.rootEl);
321324
};
322325

323326
/**
@@ -444,8 +447,8 @@ Protractor.prototype.debugger = function() {
444447
* @param {string=} opt_baseUrl A URL to prepend to relative gets.
445448
* @return {Protractor}
446449
*/
447-
exports.wrapDriver = function(webdriver, opt_baseUrl) {
448-
return new Protractor(webdriver, opt_baseUrl);
450+
exports.wrapDriver = function(webdriver, opt_baseUrl, opt_rootElement) {
451+
return new Protractor(webdriver, opt_baseUrl, opt_rootElement);
449452
};
450453

451454
var instance;

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"bin": "bin/protractor",
3232
"main": "lib/protractor.js",
3333
"scripts": {
34-
"test": "node lib/cli.js spec/basicConf.js"
34+
"test": "node lib/cli.js spec/basicConf.js; node lib/cli.js spec/altRootConf.js;"
3535
},
3636
"version": "0.7.0"
3737
}

spec/altRoot/findelements_spec.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
var util = require('util');
2+
3+
describe('finding elements when ng-app is nested', function() {
4+
var ptor;
5+
6+
describe('in forms', function() {
7+
ptor = protractor.getInstance();
8+
9+
beforeEach(function() {
10+
ptor.get('app/alt_root_index.html#/form');
11+
});
12+
13+
it('should find an element by binding', function() {
14+
var greeting = ptor.findElement(protractor.By.binding('{{greeting}}'));
15+
16+
expect(greeting.getText()).toEqual('Hiya');
17+
});
18+
19+
it('should find elements outside of angular', function() {
20+
var outside = ptor.findElement(protractor.By.id('outside-ng'));
21+
var inside = ptor.findElement(protractor.By.id('inside-ng'));
22+
23+
expect(outside.getText()).toEqual('{{1 + 2}}');
24+
expect(inside.getText()).toEqual('3');
25+
});
26+
});
27+
});

spec/altRootConf.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Tests for an Angular app where ng-app is not on the body.
2+
exports.config = {
3+
seleniumServerJar: './selenium/selenium-server-standalone-2.35.0.jar',
4+
chromeDriver: './selenium/chromedriver',
5+
6+
seleniumAddress: 'http://localhost:4444/wd/hub',
7+
8+
// Spec patterns are relative to the current working directly when
9+
// protractor is called.
10+
specs: [
11+
'spec/altRoot/*_spec.js',
12+
],
13+
14+
capabilities: {
15+
'browserName': 'chrome'
16+
},
17+
18+
// Selector for the element housing the angular app.
19+
rootElement: 'div#nested-ng-app',
20+
21+
baseUrl: 'http://localhost:8000',
22+
23+
jasmineNodeOpts: {
24+
onComplete: null,
25+
isVerbose: false,
26+
showColors: true,
27+
includeStackTrace: true,
28+
}
29+
};

spec/testapp_spec.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ var util = require('util');
22

33
describe('longer example', function() {
44
var ptor = protractor.getInstance();
5-
5+
66
describe('synchronizing with Angular', function() {
77
describe('http calls', function() {
88
beforeEach(function() {
@@ -29,11 +29,11 @@ describe('longer example', function() {
2929
// Would normally need ptor.sleep(2) or something.
3030
expect(ptor.findElement(protractor.By.id('statuscode')).getText()).
3131
toEqual('200');
32-
32+
3333
expect(ptor.findElement(protractor.By.id('data')).getText()).
3434
toEqual('finally done');
3535
});
36-
});
36+
});
3737

3838
describe('slow rendering', function() {
3939
beforeEach(function() {
@@ -59,4 +59,5 @@ describe('longer example', function() {
5959
});
6060
});
6161
});
62-
});
62+
63+
});

testapp/app/alt_root_index.html

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>My AngularJS App</title>
6+
<link rel="stylesheet" href="css/app.css"/>
7+
</head>
8+
<body>
9+
10+
<div id="outside-ng">
11+
{{1 + 2}}
12+
</div>
13+
14+
<div id="nested-ng-app" ng-app="myApp">
15+
<div id="inside-ng">
16+
{{1 + 2}}
17+
</div>
18+
19+
<ul class="menu">
20+
<li><a href="#/http">http</a></li>
21+
<li><a href="#/repeater">repeater</a></li>
22+
<li><a href="#/bindings">bindings</a></li>
23+
<li><a href="#/form">form</a></li>
24+
<li><a href="#/async">async</a></li>
25+
</ul>
26+
27+
<div ng-view></div>
28+
<div>Angular seed app: v<span app-version></span></div>
29+
</div>
30+
31+
<!-- In production use:
32+
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
33+
-->
34+
<script src="lib/angular_v1.0.6/angular.js"></script>
35+
<script src="js/app.js"></script>
36+
<script src="js/services.js"></script>
37+
<script src="js/controllers.js"></script>
38+
<script src="js/filters.js"></script>
39+
<script src="js/directives.js"></script>
40+
</body>
41+
</html>

0 commit comments

Comments
 (0)