Commit f1f976e2 authored by Pascal Hartig's avatar Pascal Hartig

AngularJS: Upgrade to 1.2.12

parent 1b1d90e6
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
"name": "todomvc-angular", "name": "todomvc-angular",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"angular": "1.2.10", "angular": "1.2.12",
"todomvc-common": "~0.1.4" "todomvc-common": "~0.1.4"
}, },
"devDependencies": { "devDependencies": {
"angular-mocks": "1.2.10", "angular-mocks": "1.2.12",
"angular-route": "1.2.10" "angular-route": "1.2.12"
} }
} }
/** /**
* @license AngularJS v1.2.10 * @license AngularJS v1.2.12
* (c) 2010-2014 Google, Inc. http://angularjs.org * (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT * License: MIT
*/ */
...@@ -350,17 +350,17 @@ function $RouteProvider(){ ...@@ -350,17 +350,17 @@ function $RouteProvider(){
} }
</file> </file>
<file name="scenario.js"> <file name="protractorTest.js">
it('should load and compile correct template', function() { it('should load and compile correct template', function() {
element('a:contains("Moby: Ch1")').click(); element(by.linkText('Moby: Ch1')).click();
var content = element('.doc-example-live [ng-view]').text(); var content = element(by.css('.doc-example-live [ng-view]')).getText();
expect(content).toMatch(/controller\: ChapterCntl/); expect(content).toMatch(/controller\: ChapterCntl/);
expect(content).toMatch(/Book Id\: Moby/); expect(content).toMatch(/Book Id\: Moby/);
expect(content).toMatch(/Chapter Id\: 1/); expect(content).toMatch(/Chapter Id\: 1/);
element('a:contains("Scarlet")').click(); element(by.partialLinkText('Scarlet')).click();
sleep(2); // promises are not part of scenario waiting
content = element('.doc-example-live [ng-view]').text(); content = element(by.css('.doc-example-live [ng-view]')).getText();
expect(content).toMatch(/controller\: BookCntl/); expect(content).toMatch(/controller\: BookCntl/);
expect(content).toMatch(/Book Id\: Scarlet/); expect(content).toMatch(/Book Id\: Scarlet/);
}); });
...@@ -794,16 +794,17 @@ ngRouteModule.directive('ngView', ngViewFillContentFactory); ...@@ -794,16 +794,17 @@ ngRouteModule.directive('ngView', ngViewFillContentFactory);
} }
</file> </file>
<file name="scenario.js"> <file name="protractorTest.js">
it('should load and compile correct template', function() { it('should load and compile correct template', function() {
element('a:contains("Moby: Ch1")').click(); element(by.linkText('Moby: Ch1')).click();
var content = element('.doc-example-live [ng-view]').text(); var content = element(by.css('.doc-example-live [ng-view]')).getText();
expect(content).toMatch(/controller\: ChapterCntl/); expect(content).toMatch(/controller\: ChapterCntl/);
expect(content).toMatch(/Book Id\: Moby/); expect(content).toMatch(/Book Id\: Moby/);
expect(content).toMatch(/Chapter Id\: 1/); expect(content).toMatch(/Chapter Id\: 1/);
element('a:contains("Scarlet")').click(); element(by.partialLinkText('Scarlet')).click();
content = element('.doc-example-live [ng-view]').text();
content = element(by.css('.doc-example-live [ng-view]')).getText();
expect(content).toMatch(/controller\: BookCntl/); expect(content).toMatch(/controller\: BookCntl/);
expect(content).toMatch(/Book Id\: Scarlet/); expect(content).toMatch(/Book Id\: Scarlet/);
}); });
......
/** /**
* @license AngularJS v1.2.10 * @license AngularJS v1.2.12
* (c) 2010-2014 Google, Inc. http://angularjs.org * (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT * License: MIT
*/ */
...@@ -68,7 +68,7 @@ function minErr(module) { ...@@ -68,7 +68,7 @@ function minErr(module) {
return match; return match;
}); });
message = message + '\nhttp://errors.angularjs.org/1.2.10/' + message = message + '\nhttp://errors.angularjs.org/1.2.12/' +
(module ? module + '/' : '') + code; (module ? module + '/' : '') + code;
for (i = 2; i < arguments.length; i++) { for (i = 2; i < arguments.length; i++) {
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' + message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
...@@ -271,7 +271,7 @@ function isArrayLike(obj) { ...@@ -271,7 +271,7 @@ function isArrayLike(obj) {
* is the value of an object property or an array element and `key` is the object property key or * is the value of an object property or an array element and `key` is the object property key or
* array element index. Specifying a `context` for the function is optional. * array element index. Specifying a `context` for the function is optional.
* *
* It is worth nothing that `.forEach` does not iterate over inherited properties because it filters * It is worth noting that `.forEach` does not iterate over inherited properties because it filters
* using the `hasOwnProperty` method. * using the `hasOwnProperty` method.
* *
<pre> <pre>
...@@ -280,7 +280,7 @@ function isArrayLike(obj) { ...@@ -280,7 +280,7 @@ function isArrayLike(obj) {
angular.forEach(values, function(value, key){ angular.forEach(values, function(value, key){
this.push(key + ': ' + value); this.push(key + ': ' + value);
}, log); }, log);
expect(log).toEqual(['name: misko', 'gender:male']); expect(log).toEqual(['name: misko', 'gender: male']);
</pre> </pre>
* *
* @param {Object|Array} obj Object to iterate over. * @param {Object|Array} obj Object to iterate over.
...@@ -851,7 +851,7 @@ function shallowCopy(src, dst) { ...@@ -851,7 +851,7 @@ function shallowCopy(src, dst) {
for(var key in src) { for(var key in src) {
// shallowCopy is only ever called by $compile nodeLinkFn, which has control over src // shallowCopy is only ever called by $compile nodeLinkFn, which has control over src
// so we don't need to worry about using our custom hasOwnProperty here // so we don't need to worry about using our custom hasOwnProperty here
if (src.hasOwnProperty(key) && key.charAt(0) !== '$' && key.charAt(1) !== '$') { if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
dst[key] = src[key]; dst[key] = src[key];
} }
} }
...@@ -1834,11 +1834,11 @@ function setupModuleLoader(window) { ...@@ -1834,11 +1834,11 @@ function setupModuleLoader(window) {
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat". * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
*/ */
var version = { var version = {
full: '1.2.10', // all of these placeholder strings will be replaced by grunt's full: '1.2.12', // all of these placeholder strings will be replaced by grunt's
major: 1, // package task major: 1, // package task
minor: 2, minor: 2,
dot: 10, dot: 12,
codeName: 'augmented-serendipity' codeName: 'cauliflower-eradication'
}; };
...@@ -2135,6 +2135,9 @@ function JQLite(element) { ...@@ -2135,6 +2135,9 @@ function JQLite(element) {
if (element instanceof JQLite) { if (element instanceof JQLite) {
return element; return element;
} }
if (isString(element)) {
element = trim(element);
}
if (!(this instanceof JQLite)) { if (!(this instanceof JQLite)) {
if (isString(element) && element.charAt(0) != '<') { if (isString(element) && element.charAt(0) != '<') {
throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element'); throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
...@@ -3408,17 +3411,16 @@ function annotate(fn) { ...@@ -3408,17 +3411,16 @@ function annotate(fn) {
* Here is an example of registering a service using * Here is an example of registering a service using
* {@link AUTO.$provide#methods_service $provide.service(class)}. * {@link AUTO.$provide#methods_service $provide.service(class)}.
* <pre> * <pre>
* $provide.service('ping', ['$http', function($http) { * var Ping = function($http) {
* var Ping = function() { * this.$http = $http;
* this.$http = $http; * };
* }; *
* * Ping.$inject = ['$http'];
* Ping.prototype.send = function() {
* return this.$http.get('/ping');
* };
* *
* return Ping; * Ping.prototype.send = function() {
* }]); * return this.$http.get('/ping');
* };
* $provide.service('ping', Ping);
* </pre> * </pre>
* You would then inject and use this service like this: * You would then inject and use this service like this:
* <pre> * <pre>
...@@ -3516,7 +3518,7 @@ function annotate(fn) { ...@@ -3516,7 +3518,7 @@ function annotate(fn) {
* Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting * Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting
* calls to {@link ng.$log#error $log.warn()}. * calls to {@link ng.$log#error $log.warn()}.
* <pre> * <pre>
* $provider.decorator('$log', ['$delegate', function($delegate) { * $provide.decorator('$log', ['$delegate', function($delegate) {
* $delegate.warn = $delegate.error; * $delegate.warn = $delegate.error;
* return $delegate; * return $delegate;
* }]); * }]);
...@@ -5119,13 +5121,17 @@ function $TemplateCacheProvider() { ...@@ -5119,13 +5121,17 @@ function $TemplateCacheProvider() {
<div compile="html"></div> <div compile="html"></div>
</div> </div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should auto compile', function() { it('should auto compile', function() {
expect(element('div[compile]').text()).toBe('Hello Angular'); var textarea = $('textarea');
input('html').enter('{{name}}!'); var output = $('div[compile]');
expect(element('div[compile]').text()).toBe('Angular!'); // The initial state reads 'Hello Angular'.
expect(output.getText()).toBe('Hello Angular');
textarea.clear();
textarea.sendKeys('{{name}}!');
expect(output.getText()).toBe('Angular!');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
* *
...@@ -5887,7 +5893,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { ...@@ -5887,7 +5893,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
hasTranscludeDirective = true; hasTranscludeDirective = true;
// Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion. // Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion.
// This option should only be used by directives that know how to how to safely handle element transclusion, // This option should only be used by directives that know how to safely handle element transclusion,
// where the transcluded nodes are added or replaced after linking. // where the transcluded nodes are added or replaced after linking.
if (!directive.$$tlb) { if (!directive.$$tlb) {
assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode); assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode);
...@@ -6402,9 +6408,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) { ...@@ -6402,9 +6408,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
linkNode = $compileNode[0]; linkNode = $compileNode[0];
if (beforeTemplateLinkNode !== beforeTemplateCompileNode) { if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {
var oldClasses = beforeTemplateLinkNode.className;
// it was cloned therefore we have to clone as well. // it was cloned therefore we have to clone as well.
linkNode = jqLiteClone(compileNode); linkNode = jqLiteClone(compileNode);
replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode); replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);
// Copy in CSS classes from original node
safeAddClass(jqLite(linkNode), oldClasses);
} }
if (afterTemplateNodeLinkFn.transclude) { if (afterTemplateNodeLinkFn.transclude) {
childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude); childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude);
...@@ -7425,14 +7435,14 @@ function $HttpProvider() { ...@@ -7425,14 +7435,14 @@ function $HttpProvider() {
<option>JSONP</option> <option>JSONP</option>
</select> </select>
<input type="text" ng-model="url" size="80"/> <input type="text" ng-model="url" size="80"/>
<button ng-click="fetch()">fetch</button><br> <button id="fetchbtn" ng-click="fetch()">fetch</button><br>
<button ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button> <button id="samplegetbtn" ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button>
<button <button id="samplejsonpbtn"
ng-click="updateModel('JSONP', ng-click="updateModel('JSONP',
'http://angularjs.org/greet.php?callback=JSON_CALLBACK&name=Super%20Hero')"> 'http://angularjs.org/greet.php?callback=JSON_CALLBACK&name=Super%20Hero')">
Sample JSONP Sample JSONP
</button> </button>
<button <button id="invalidjsonpbtn"
ng-click="updateModel('JSONP', 'http://angularjs.org/doesntexist&callback=JSON_CALLBACK')"> ng-click="updateModel('JSONP', 'http://angularjs.org/doesntexist&callback=JSON_CALLBACK')">
Invalid JSONP Invalid JSONP
</button> </button>
...@@ -7469,27 +7479,34 @@ function $HttpProvider() { ...@@ -7469,27 +7479,34 @@ function $HttpProvider() {
<file name="http-hello.html"> <file name="http-hello.html">
Hello, $http! Hello, $http!
</file> </file>
<file name="scenario.js"> <file name="protractorTest.js">
var status = element(by.binding('status'));
var data = element(by.binding('data'));
var fetchBtn = element(by.id('fetchbtn'));
var sampleGetBtn = element(by.id('samplegetbtn'));
var sampleJsonpBtn = element(by.id('samplejsonpbtn'));
var invalidJsonpBtn = element(by.id('invalidjsonpbtn'));
it('should make an xhr GET request', function() { it('should make an xhr GET request', function() {
element(':button:contains("Sample GET")').click(); sampleGetBtn.click();
element(':button:contains("fetch")').click(); fetchBtn.click();
expect(binding('status')).toBe('200'); expect(status.getText()).toMatch('200');
expect(binding('data')).toMatch(/Hello, \$http!/); expect(data.getText()).toMatch(/Hello, \$http!/)
}); });
it('should make a JSONP request to angularjs.org', function() { it('should make a JSONP request to angularjs.org', function() {
element(':button:contains("Sample JSONP")').click(); sampleJsonpBtn.click();
element(':button:contains("fetch")').click(); fetchBtn.click();
expect(binding('status')).toBe('200'); expect(status.getText()).toMatch('200');
expect(binding('data')).toMatch(/Super Hero!/); expect(data.getText()).toMatch(/Super Hero!/);
}); });
it('should make JSONP request to invalid URL and invoke the error handler', it('should make JSONP request to invalid URL and invoke the error handler',
function() { function() {
element(':button:contains("Invalid JSONP")').click(); invalidJsonpBtn.click();
element(':button:contains("fetch")').click(); fetchBtn.click();
expect(binding('status')).toBe('0'); expect(status.getText()).toMatch('0');
expect(binding('data')).toBe('Request failed'); expect(data.getText()).toMatch('Request failed');
}); });
</file> </file>
</example> </example>
...@@ -7871,13 +7888,18 @@ function $HttpProvider() { ...@@ -7871,13 +7888,18 @@ function $HttpProvider() {
} }
function createXhr(method) { function createXhr(method) {
// IE8 doesn't support PATCH method, but the ActiveX object does //if IE and the method is not RFC2616 compliant, or if XMLHttpRequest
/* global ActiveXObject */ //is not available, try getting an ActiveXObject. Otherwise, use XMLHttpRequest
return (msie <= 8 && lowercase(method) === 'patch') //if it is available
? new ActiveXObject('Microsoft.XMLHTTP') if (msie <= 8 && (!method.match(/^(get|post|head|put|delete|options)$/i) ||
: new window.XMLHttpRequest(); !window.XMLHttpRequest)) {
} return new window.ActiveXObject("Microsoft.XMLHTTP");
} else if (window.XMLHttpRequest) {
return new window.XMLHttpRequest();
}
throw minErr('$httpBackend')('noxhr', "This browser does not support XMLHttpRequest.");
}
/** /**
* @ngdoc object * @ngdoc object
...@@ -7972,7 +7994,20 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc ...@@ -7972,7 +7994,20 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
} }
if (responseType) { if (responseType) {
xhr.responseType = responseType; try {
xhr.responseType = responseType;
} catch (e) {
// WebKit added support for the json responseType value on 09/03/2013
// https://bugs.webkit.org/show_bug.cgi?id=73648. Versions of Safari prior to 7 are
// known to throw when setting the value "json" as the response type. Other older
// browsers implementing the responseType
//
// The json response type can be ignored if not supported, because JSON payloads are
// parsed on the client-side regardless.
if (responseType !== 'json') {
throw e;
}
}
} }
xhr.send(post || null); xhr.send(post || null);
...@@ -8071,11 +8106,11 @@ var $interpolateMinErr = minErr('$interpolate'); ...@@ -8071,11 +8106,11 @@ var $interpolateMinErr = minErr('$interpolate');
//demo.label// //demo.label//
</div> </div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should interpolate binding with custom symbols', function() { it('should interpolate binding with custom symbols', function() {
expect(binding('demo.label')).toBe('This binding is brought you by // interpolation symbols.'); expect(element(by.binding('demo.label')).getText()).toBe('This binding is brought you by // interpolation symbols.');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
function $InterpolateProvider() { function $InterpolateProvider() {
...@@ -9294,7 +9329,7 @@ function $LogProvider(){ ...@@ -9294,7 +9329,7 @@ function $LogProvider(){
* @name ng.$logProvider#debugEnabled * @name ng.$logProvider#debugEnabled
* @methodOf ng.$logProvider * @methodOf ng.$logProvider
* @description * @description
* @param {string=} flag enable or disable debug level messages * @param {boolean=} flag enable or disable debug level messages
* @returns {*} current value if used as getter or itself (chaining) if used as setter * @returns {*} current value if used as getter or itself (chaining) if used as setter
*/ */
this.debugEnabled = function(flag) { this.debugEnabled = function(flag) {
...@@ -10750,7 +10785,7 @@ function $ParseProvider() { ...@@ -10750,7 +10785,7 @@ function $ParseProvider() {
* constructed via `$q.reject`, the promise will be rejected instead. * constructed via `$q.reject`, the promise will be rejected instead.
* - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to * - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to
* resolving it with a rejection constructed via `$q.reject`. * resolving it with a rejection constructed via `$q.reject`.
* - `notify(value)` - provides updates on the status of the promises execution. This may be called * - `notify(value)` - provides updates on the status of the promise's execution. This may be called
* multiple times before the promise is either resolved or rejected. * multiple times before the promise is either resolved or rejected.
* *
* **Properties** * **Properties**
...@@ -10900,7 +10935,7 @@ function qFactory(nextTick, exceptionHandler) { ...@@ -10900,7 +10935,7 @@ function qFactory(nextTick, exceptionHandler) {
reject: function(reason) { reject: function(reason) {
deferred.resolve(reject(reason)); deferred.resolve(createInternalRejectedPromise(reason));
}, },
...@@ -11057,6 +11092,12 @@ function qFactory(nextTick, exceptionHandler) { ...@@ -11057,6 +11092,12 @@ function qFactory(nextTick, exceptionHandler) {
* @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`. * @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`.
*/ */
var reject = function(reason) { var reject = function(reason) {
var result = defer();
result.reject(reason);
return result.promise;
};
var createInternalRejectedPromise = function(reason) {
return { return {
then: function(callback, errback) { then: function(callback, errback) {
var result = defer(); var result = defer();
...@@ -12117,7 +12158,7 @@ function $RootScopeProvider(){ ...@@ -12117,7 +12158,7 @@ function $RootScopeProvider(){
* onto the {@link ng.$exceptionHandler $exceptionHandler} service. * onto the {@link ng.$exceptionHandler $exceptionHandler} service.
* *
* @param {string} name Event name to emit. * @param {string} name Event name to emit.
* @param {...*} args Optional set of arguments which will be passed onto the event listeners. * @param {...*} args Optional one or more arguments which will be passed onto the event listeners.
* @return {Object} Event object (see {@link ng.$rootScope.Scope#methods_$on}). * @return {Object} Event object (see {@link ng.$rootScope.Scope#methods_$on}).
*/ */
$emit: function(name, args) { $emit: function(name, args) {
...@@ -12185,7 +12226,7 @@ function $RootScopeProvider(){ ...@@ -12185,7 +12226,7 @@ function $RootScopeProvider(){
* onto the {@link ng.$exceptionHandler $exceptionHandler} service. * onto the {@link ng.$exceptionHandler $exceptionHandler} service.
* *
* @param {string} name Event name to broadcast. * @param {string} name Event name to broadcast.
* @param {...*} args Optional set of arguments which will be passed onto the event listeners. * @param {...*} args Optional one or more arguments which will be passed onto the event listeners.
* @return {Object} Event object, see {@link ng.$rootScope.Scope#methods_$on} * @return {Object} Event object, see {@link ng.$rootScope.Scope#methods_$on}
*/ */
$broadcast: function(name, args) { $broadcast: function(name, args) {
...@@ -12977,13 +13018,15 @@ function $SceDelegateProvider() { ...@@ -12977,13 +13018,15 @@ function $SceDelegateProvider() {
] ]
</file> </file>
<file name="scenario.js"> <file name="protractorTest.js">
describe('SCE doc demo', function() { describe('SCE doc demo', function() {
it('should sanitize untrusted values', function() { it('should sanitize untrusted values', function() {
expect(element('.htmlComment').html()).toBe('<span>Is <i>anyone</i> reading this?</span>'); expect(element(by.css('.htmlComment')).getInnerHtml())
.toBe('<span>Is <i>anyone</i> reading this?</span>');
}); });
it('should NOT sanitize explicitly trusted values', function() { it('should NOT sanitize explicitly trusted values', function() {
expect(element('#explicitlyTrustedHtml').html()).toBe( expect(element(by.id('explicitlyTrustedHtml')).getInnerHtml()).toBe(
'<span onmouseover="this.textContent=&quot;Explicitly trusted HTML bypasses ' + '<span onmouseover="this.textContent=&quot;Explicitly trusted HTML bypasses ' +
'sanitization.&quot;">Hover over this text.</span>'); 'sanitization.&quot;">Hover over this text.</span>');
}); });
...@@ -13742,13 +13785,13 @@ function urlIsSameOrigin(requestUrl) { ...@@ -13742,13 +13785,13 @@ function urlIsSameOrigin(requestUrl) {
<button ng-click="doGreeting(greeting)">ALERT</button> <button ng-click="doGreeting(greeting)">ALERT</button>
</div> </div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should display the greeting in the input box', function() { it('should display the greeting in the input box', function() {
input('greeting').enter('Hello, E2E Tests'); element(by.model('greeting')).sendKeys('Hello, E2E Tests');
// If we click the button it will block the test runner // If we click the button it will block the test runner
// element(':button').click(); // element(':button').click();
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
function $WindowProvider(){ function $WindowProvider(){
...@@ -13957,35 +14000,47 @@ function $FilterProvider($provide) { ...@@ -13957,35 +14000,47 @@ function $FilterProvider($provide) {
Equality <input type="checkbox" ng-model="strict"><br> Equality <input type="checkbox" ng-model="strict"><br>
<table id="searchObjResults"> <table id="searchObjResults">
<tr><th>Name</th><th>Phone</th></tr> <tr><th>Name</th><th>Phone</th></tr>
<tr ng-repeat="friend in friends | filter:search:strict"> <tr ng-repeat="friendObj in friends | filter:search:strict">
<td>{{friend.name}}</td> <td>{{friendObj.name}}</td>
<td>{{friend.phone}}</td> <td>{{friendObj.phone}}</td>
</tr> </tr>
</table> </table>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should search across all fields when filtering with a string', function() { var expectFriendNames = function(expectedNames, key) {
input('searchText').enter('m'); element.all(by.repeater(key + ' in friends').column(key + '.name')).then(function(arr) {
expect(repeater('#searchTextResults tr', 'friend in friends').column('friend.name')). arr.forEach(function(wd, i) {
toEqual(['Mary', 'Mike', 'Adam']); expect(wd.getText()).toMatch(expectedNames[i]);
});
});
};
input('searchText').enter('76'); it('should search across all fields when filtering with a string', function() {
expect(repeater('#searchTextResults tr', 'friend in friends').column('friend.name')). var searchText = element(by.model('searchText'));
toEqual(['John', 'Julie']); searchText.clear();
searchText.sendKeys('m');
expectFriendNames(['Mary', 'Mike', 'Adam'], 'friend');
searchText.clear();
searchText.sendKeys('76');
expectFriendNames(['John', 'Julie'], 'friend');
}); });
it('should search in specific fields when filtering with a predicate object', function() { it('should search in specific fields when filtering with a predicate object', function() {
input('search.$').enter('i'); var searchAny = element(by.model('search.$'));
expect(repeater('#searchObjResults tr', 'friend in friends').column('friend.name')). searchAny.clear();
toEqual(['Mary', 'Mike', 'Julie', 'Juliette']); searchAny.sendKeys('i');
expectFriendNames(['Mary', 'Mike', 'Julie', 'Juliette'], 'friendObj');
}); });
it('should use a equal comparison when comparator is true', function() { it('should use a equal comparison when comparator is true', function() {
input('search.name').enter('Julie'); var searchName = element(by.model('search.name'));
input('strict').check(); var strict = element(by.model('strict'));
expect(repeater('#searchObjResults tr', 'friend in friends').column('friend.name')). searchName.clear();
toEqual(['Julie']); searchName.sendKeys('Julie');
strict.click();
expectFriendNames(['Julie'], 'friendObj');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
function filterFilter() { function filterFilter() {
...@@ -14063,7 +14118,7 @@ function filterFilter() { ...@@ -14063,7 +14118,7 @@ function filterFilter() {
(function(path) { (function(path) {
if (typeof expression[path] == 'undefined') return; if (typeof expression[path] == 'undefined') return;
predicates.push(function(value) { predicates.push(function(value) {
return search(path == '$' ? value : getter(value, path), expression[path]); return search(path == '$' ? value : (value && value[path]), expression[path]);
}); });
})(key); })(key);
} }
...@@ -14109,21 +14164,26 @@ function filterFilter() { ...@@ -14109,21 +14164,26 @@ function filterFilter() {
</script> </script>
<div ng-controller="Ctrl"> <div ng-controller="Ctrl">
<input type="number" ng-model="amount"> <br> <input type="number" ng-model="amount"> <br>
default currency symbol ($): {{amount | currency}}<br> default currency symbol ($): <span id="currency-default">{{amount | currency}}</span><br>
custom currency identifier (USD$): {{amount | currency:"USD$"}} custom currency identifier (USD$): <span>{{amount | currency:"USD$"}}</span>
</div> </div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should init with 1234.56', function() { it('should init with 1234.56', function() {
expect(binding('amount | currency')).toBe('$1,234.56'); expect(element(by.id('currency-default')).getText()).toBe('$1,234.56');
expect(binding('amount | currency:"USD$"')).toBe('USD$1,234.56'); expect(element(by.binding('amount | currency:"USD$"')).getText()).toBe('USD$1,234.56');
}); });
it('should update', function() { it('should update', function() {
input('amount').enter('-1234'); if (browser.params.browser == 'safari') {
expect(binding('amount | currency')).toBe('($1,234.00)'); // Safari does not understand the minus key. See
expect(binding('amount | currency:"USD$"')).toBe('(USD$1,234.00)'); // https://github.com/angular/protractor/issues/481
return;
}
element(by.model('amount')).clear();
element(by.model('amount')).sendKeys('-1234'); expect(element(by.id('currency-default')).getText()).toBe('($1,234.00)');
expect(element(by.binding('amount | currency:"USD$"')).getText()).toBe('(USD$1,234.00)');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
currencyFilter.$inject = ['$locale']; currencyFilter.$inject = ['$locale'];
...@@ -14162,25 +14222,26 @@ function currencyFilter($locale) { ...@@ -14162,25 +14222,26 @@ function currencyFilter($locale) {
</script> </script>
<div ng-controller="Ctrl"> <div ng-controller="Ctrl">
Enter number: <input ng-model='val'><br> Enter number: <input ng-model='val'><br>
Default formatting: {{val | number}}<br> Default formatting: <span id='number-default'>{{val | number}}</span><br>
No fractions: {{val | number:0}}<br> No fractions: <span>{{val | number:0}}</span><br>
Negative number: {{-val | number:4}} Negative number: <span>{{-val | number:4}}</span>
</div> </div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should format numbers', function() { it('should format numbers', function() {
expect(binding('val | number')).toBe('1,234.568'); expect(element(by.id('number-default')).getText()).toBe('1,234.568');
expect(binding('val | number:0')).toBe('1,235'); expect(element(by.binding('val | number:0')).getText()).toBe('1,235');
expect(binding('-val | number:4')).toBe('-1,234.5679'); expect(element(by.binding('-val | number:4')).getText()).toBe('-1,234.5679');
}); });
it('should update', function() { it('should update', function() {
input('val').enter('3374.333'); element(by.model('val')).clear();
expect(binding('val | number')).toBe('3,374.333'); element(by.model('val')).sendKeys('3374.333');
expect(binding('val | number:0')).toBe('3,374'); expect(element(by.id('number-default')).getText()).toBe('3,374.333');
expect(binding('-val | number:4')).toBe('-3,374.3330'); expect(element(by.binding('val | number:0')).getText()).toBe('3,374');
}); expect(element(by.binding('-val | number:4')).getText()).toBe('-3,374.3330');
</doc:scenario> });
</doc:protractor>
</doc:example> </doc:example>
*/ */
...@@ -14410,22 +14471,22 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+ ...@@ -14410,22 +14471,22 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
<doc:example> <doc:example>
<doc:source> <doc:source>
<span ng-non-bindable>{{1288323623006 | date:'medium'}}</span>: <span ng-non-bindable>{{1288323623006 | date:'medium'}}</span>:
{{1288323623006 | date:'medium'}}<br> <span>{{1288323623006 | date:'medium'}}</span><br>
<span ng-non-bindable>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span>: <span ng-non-bindable>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span>:
{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}<br> <span>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span><br>
<span ng-non-bindable>{{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}</span>: <span ng-non-bindable>{{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}</span>:
{{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}<br> <span>{{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}</span><br>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should format date', function() { it('should format date', function() {
expect(binding("1288323623006 | date:'medium'")). expect(element(by.binding("1288323623006 | date:'medium'")).getText()).
toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} (AM|PM)/); toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} (AM|PM)/);
expect(binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")). expect(element(by.binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).getText()).
toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} (\-|\+)?\d{4}/); toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} (\-|\+)?\d{4}/);
expect(binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")). expect(element(by.binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).getText()).
toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/); toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/);
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
dateFilter.$inject = ['$locale']; dateFilter.$inject = ['$locale'];
...@@ -14524,11 +14585,11 @@ function dateFilter($locale) { ...@@ -14524,11 +14585,11 @@ function dateFilter($locale) {
<doc:source> <doc:source>
<pre>{{ {'name':'value'} | json }}</pre> <pre>{{ {'name':'value'} | json }}</pre>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should jsonify filtered objects', function() { it('should jsonify filtered objects', function() {
expect(binding("{'name':'value'}")).toMatch(/\{\n "name": ?"value"\n}/); expect(element(by.binding("{'name':'value'}")).getText()).toMatch(/\{\n "name": ?"value"\n}/);
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
* *
*/ */
...@@ -14596,28 +14657,37 @@ var uppercaseFilter = valueFn(uppercase); ...@@ -14596,28 +14657,37 @@ var uppercaseFilter = valueFn(uppercase);
<p>Output letters: {{ letters | limitTo:letterLimit }}</p> <p>Output letters: {{ letters | limitTo:letterLimit }}</p>
</div> </div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
var numLimitInput = element(by.model('numLimit'));
var letterLimitInput = element(by.model('letterLimit'));
var limitedNumbers = element(by.binding('numbers | limitTo:numLimit'));
var limitedLetters = element(by.binding('letters | limitTo:letterLimit'));
it('should limit the number array to first three items', function() { it('should limit the number array to first three items', function() {
expect(element('.doc-example-live input[ng-model=numLimit]').val()).toBe('3'); expect(numLimitInput.getAttribute('value')).toBe('3');
expect(element('.doc-example-live input[ng-model=letterLimit]').val()).toBe('3'); expect(letterLimitInput.getAttribute('value')).toBe('3');
expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3]'); expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3]');
expect(binding('letters | limitTo:letterLimit')).toEqual('abc'); expect(limitedLetters.getText()).toEqual('Output letters: abc');
}); });
it('should update the output when -3 is entered', function() { it('should update the output when -3 is entered', function() {
input('numLimit').enter(-3); numLimitInput.clear();
input('letterLimit').enter(-3); numLimitInput.sendKeys('-3');
expect(binding('numbers | limitTo:numLimit')).toEqual('[7,8,9]'); letterLimitInput.clear();
expect(binding('letters | limitTo:letterLimit')).toEqual('ghi'); letterLimitInput.sendKeys('-3');
expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]');
expect(limitedLetters.getText()).toEqual('Output letters: ghi');
}); });
it('should not exceed the maximum size of input array', function() { it('should not exceed the maximum size of input array', function() {
input('numLimit').enter(100); numLimitInput.clear();
input('letterLimit').enter(100); numLimitInput.sendKeys('100');
expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3,4,5,6,7,8,9]'); letterLimitInput.clear();
expect(binding('letters | limitTo:letterLimit')).toEqual('abcdefghi'); letterLimitInput.sendKeys('100');
expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3,4,5,6,7,8,9]');
expect(limitedLetters.getText()).toEqual('Output letters: abcdefghi');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
function limitToFilter(){ function limitToFilter(){
...@@ -14718,29 +14788,6 @@ function limitToFilter(){ ...@@ -14718,29 +14788,6 @@ function limitToFilter(){
</table> </table>
</div> </div>
</doc:source> </doc:source>
<doc:scenario>
it('should be reverse ordered by aged', function() {
expect(binding('predicate')).toBe('-age');
expect(repeater('table.friend', 'friend in friends').column('friend.age')).
toEqual(['35', '29', '21', '19', '10']);
expect(repeater('table.friend', 'friend in friends').column('friend.name')).
toEqual(['Adam', 'Julie', 'Mike', 'Mary', 'John']);
});
it('should reorder the table when user selects different predicate', function() {
element('.doc-example-live a:contains("Name")').click();
expect(repeater('table.friend', 'friend in friends').column('friend.name')).
toEqual(['Adam', 'John', 'Julie', 'Mary', 'Mike']);
expect(repeater('table.friend', 'friend in friends').column('friend.age')).
toEqual(['35', '10', '29', '19', '21']);
element('.doc-example-live a:contains("Phone")').click();
expect(repeater('table.friend', 'friend in friends').column('friend.phone')).
toEqual(['555-9876', '555-8765', '555-5678', '555-4321', '555-1212']);
expect(repeater('table.friend', 'friend in friends').column('friend.name')).
toEqual(['Mary', 'Julie', 'Adam', 'Mike', 'John']);
});
</doc:scenario>
</doc:example> </doc:example>
*/ */
orderByFilter.$inject = ['$parse']; orderByFilter.$inject = ['$parse'];
...@@ -14894,46 +14941,55 @@ var htmlAnchorDirective = valueFn({ ...@@ -14894,46 +14941,55 @@ var htmlAnchorDirective = valueFn({
<a id="link-5" name="xxx" ng-click="value = 5">anchor</a> (no link)<br /> <a id="link-5" name="xxx" ng-click="value = 5">anchor</a> (no link)<br />
<a id="link-6" ng-href="{{value}}">link</a> (link, change location) <a id="link-6" ng-href="{{value}}">link</a> (link, change location)
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should execute ng-click but not reload when href without value', function() { it('should execute ng-click but not reload when href without value', function() {
element('#link-1').click(); element(by.id('link-1')).click();
expect(input('value').val()).toEqual('1'); expect(element(by.model('value')).getAttribute('value')).toEqual('1');
expect(element('#link-1').attr('href')).toBe(""); expect(element(by.id('link-1')).getAttribute('href')).toBe('');
}); });
it('should execute ng-click but not reload when href empty string', function() { it('should execute ng-click but not reload when href empty string', function() {
element('#link-2').click(); element(by.id('link-2')).click();
expect(input('value').val()).toEqual('2'); expect(element(by.model('value')).getAttribute('value')).toEqual('2');
expect(element('#link-2').attr('href')).toBe(""); expect(element(by.id('link-2')).getAttribute('href')).toBe('');
}); });
it('should execute ng-click and change url when ng-href specified', function() { it('should execute ng-click and change url when ng-href specified', function() {
expect(element('#link-3').attr('href')).toBe("/123"); expect(element(by.id('link-3')).getAttribute('href')).toMatch(/\/123$/);
element(by.id('link-3')).click();
element('#link-3').click(); // At this point, we navigate away from an Angular page, so we need
expect(browser().window().path()).toEqual('/123'); // to use browser.driver to get the base webdriver.
browser.wait(function() {
return browser.driver.getCurrentUrl().then(function(url) {
return url.match(/\/123$/);
});
}, 1000, 'page should navigate to /123');
}); });
it('should execute ng-click but not reload when href empty string and name specified', function() { it('should execute ng-click but not reload when href empty string and name specified', function() {
element('#link-4').click(); element(by.id('link-4')).click();
expect(input('value').val()).toEqual('4'); expect(element(by.model('value')).getAttribute('value')).toEqual('4');
expect(element('#link-4').attr('href')).toBe(''); expect(element(by.id('link-4')).getAttribute('href')).toBe('');
}); });
it('should execute ng-click but not reload when no href but name specified', function() { it('should execute ng-click but not reload when no href but name specified', function() {
element('#link-5').click(); element(by.id('link-5')).click();
expect(input('value').val()).toEqual('5'); expect(element(by.model('value')).getAttribute('value')).toEqual('5');
expect(element('#link-5').attr('href')).toBe(undefined); expect(element(by.id('link-5')).getAttribute('href')).toBe(null);
}); });
it('should only change url when only ng-href', function() { it('should only change url when only ng-href', function() {
input('value').enter('6'); element(by.model('value')).clear();
expect(element('#link-6').attr('href')).toBe('6'); element(by.model('value')).sendKeys('6');
expect(element(by.id('link-6')).getAttribute('href')).toMatch(/\/6$/);
element('#link-6').click(); element(by.id('link-6')).click();
expect(browser().location().url()).toEqual('/6'); expect(browser.getCurrentUrl()).toMatch(/\/6$/);
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
...@@ -15018,13 +15074,13 @@ var htmlAnchorDirective = valueFn({ ...@@ -15018,13 +15074,13 @@ var htmlAnchorDirective = valueFn({
Click me to toggle: <input type="checkbox" ng-model="checked"><br/> Click me to toggle: <input type="checkbox" ng-model="checked"><br/>
<button ng-model="button" ng-disabled="checked">Button</button> <button ng-model="button" ng-disabled="checked">Button</button>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should toggle button', function() { it('should toggle button', function() {
expect(element('.doc-example-live :button').prop('disabled')).toBeFalsy(); expect(element(by.css('.doc-example-live button')).getAttribute('disabled')).toBeFalsy();
input('checked').check(); element(by.model('checked')).click();
expect(element('.doc-example-live :button').prop('disabled')).toBeTruthy(); expect(element(by.css('.doc-example-live button')).getAttribute('disabled')).toBeTruthy();
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
* *
* @element INPUT * @element INPUT
...@@ -15053,13 +15109,13 @@ var htmlAnchorDirective = valueFn({ ...@@ -15053,13 +15109,13 @@ var htmlAnchorDirective = valueFn({
Check me to check both: <input type="checkbox" ng-model="master"><br/> Check me to check both: <input type="checkbox" ng-model="master"><br/>
<input id="checkSlave" type="checkbox" ng-checked="master"> <input id="checkSlave" type="checkbox" ng-checked="master">
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should check both checkBoxes', function() { it('should check both checkBoxes', function() {
expect(element('.doc-example-live #checkSlave').prop('checked')).toBeFalsy(); expect(element(by.id('checkSlave')).getAttribute('checked')).toBeFalsy();
input('master').check(); element(by.model('master')).click();
expect(element('.doc-example-live #checkSlave').prop('checked')).toBeTruthy(); expect(element(by.id('checkSlave')).getAttribute('checked')).toBeTruthy();
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
* *
* @element INPUT * @element INPUT
...@@ -15088,13 +15144,13 @@ var htmlAnchorDirective = valueFn({ ...@@ -15088,13 +15144,13 @@ var htmlAnchorDirective = valueFn({
Check me to make text readonly: <input type="checkbox" ng-model="checked"><br/> Check me to make text readonly: <input type="checkbox" ng-model="checked"><br/>
<input type="text" ng-readonly="checked" value="I'm Angular"/> <input type="text" ng-readonly="checked" value="I'm Angular"/>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should toggle readonly attr', function() { it('should toggle readonly attr', function() {
expect(element('.doc-example-live :text').prop('readonly')).toBeFalsy(); expect(element(by.css('.doc-example-live [type="text"]')).getAttribute('readonly')).toBeFalsy();
input('checked').check(); element(by.model('checked')).click();
expect(element('.doc-example-live :text').prop('readonly')).toBeTruthy(); expect(element(by.css('.doc-example-live [type="text"]')).getAttribute('readonly')).toBeTruthy();
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
* *
* @element INPUT * @element INPUT
...@@ -15127,13 +15183,13 @@ var htmlAnchorDirective = valueFn({ ...@@ -15127,13 +15183,13 @@ var htmlAnchorDirective = valueFn({
<option id="greet" ng-selected="selected">Greetings!</option> <option id="greet" ng-selected="selected">Greetings!</option>
</select> </select>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should select Greetings!', function() { it('should select Greetings!', function() {
expect(element('.doc-example-live #greet').prop('selected')).toBeFalsy(); expect(element(by.id('greet')).getAttribute('selected')).toBeFalsy();
input('selected').check(); element(by.model('selected')).click();
expect(element('.doc-example-live #greet').prop('selected')).toBeTruthy(); expect(element(by.id('greet')).getAttribute('selected')).toBeTruthy();
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
* *
* @element OPTION * @element OPTION
...@@ -15163,13 +15219,13 @@ var htmlAnchorDirective = valueFn({ ...@@ -15163,13 +15219,13 @@ var htmlAnchorDirective = valueFn({
<summary>Show/Hide me</summary> <summary>Show/Hide me</summary>
</details> </details>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should toggle open', function() { it('should toggle open', function() {
expect(element('#details').prop('open')).toBeFalsy(); expect(element(by.id('details')).getAttribute('open')).toBeFalsy();
input('open').check(); element(by.model('open')).click();
expect(element('#details').prop('open')).toBeTruthy(); expect(element(by.id('details')).getAttribute('open')).toBeTruthy();
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
* *
* @element DETAILS * @element DETAILS
...@@ -15528,18 +15584,27 @@ function FormController(element, attrs) { ...@@ -15528,18 +15584,27 @@ function FormController(element, attrs) {
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br> <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>
</form> </form>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should initialize to model', function() { it('should initialize to model', function() {
expect(binding('userType')).toEqual('guest'); var userType = element(by.binding('userType'));
expect(binding('myForm.input.$valid')).toEqual('true'); var valid = element(by.binding('myForm.input.$valid'));
expect(userType.getText()).toContain('guest');
expect(valid.getText()).toContain('true');
}); });
it('should be invalid if empty', function() { it('should be invalid if empty', function() {
input('userType').enter(''); var userType = element(by.binding('userType'));
expect(binding('userType')).toEqual(''); var valid = element(by.binding('myForm.input.$valid'));
expect(binding('myForm.input.$valid')).toEqual('false'); var userInput = element(by.model('userType'));
userInput.clear();
userInput.sendKeys('');
expect(userType.getText()).toEqual('userType =');
expect(valid.getText()).toContain('false');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
var formDirectiveFactory = function(isNgForm) { var formDirectiveFactory = function(isNgForm) {
...@@ -15664,29 +15729,31 @@ var inputType = { ...@@ -15664,29 +15729,31 @@ var inputType = {
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/> <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
</form> </form>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
var text = element(by.binding('text'));
var valid = element(by.binding('myForm.input.$valid'));
var input = element(by.model('text'));
it('should initialize to model', function() { it('should initialize to model', function() {
expect(binding('text')).toEqual('guest'); expect(text.getText()).toContain('guest');
expect(binding('myForm.input.$valid')).toEqual('true'); expect(valid.getText()).toContain('true');
}); });
it('should be invalid if empty', function() { it('should be invalid if empty', function() {
input('text').enter(''); input.clear();
expect(binding('text')).toEqual(''); input.sendKeys('');
expect(binding('myForm.input.$valid')).toEqual('false');
expect(text.getText()).toEqual('text =');
expect(valid.getText()).toContain('false');
}); });
it('should be invalid if multi word', function() { it('should be invalid if multi word', function() {
input('text').enter('hello world'); input.clear();
expect(binding('myForm.input.$valid')).toEqual('false'); input.sendKeys('hello world');
});
it('should not be trimmed', function() { expect(valid.getText()).toContain('false');
input('text').enter('untrimmed ');
expect(binding('text')).toEqual('untrimmed ');
expect(binding('myForm.input.$valid')).toEqual('true');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
'text': textInputType, 'text': textInputType,
...@@ -15740,24 +15807,30 @@ var inputType = { ...@@ -15740,24 +15807,30 @@ var inputType = {
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/> <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
</form> </form>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
var value = element(by.binding('value'));
var valid = element(by.binding('myForm.input.$valid'));
var input = element(by.model('value'));
it('should initialize to model', function() { it('should initialize to model', function() {
expect(binding('value')).toEqual('12'); expect(value.getText()).toContain('12');
expect(binding('myForm.input.$valid')).toEqual('true'); expect(valid.getText()).toContain('true');
}); });
it('should be invalid if empty', function() { it('should be invalid if empty', function() {
input('value').enter(''); input.clear();
expect(binding('value')).toEqual(''); input.sendKeys('');
expect(binding('myForm.input.$valid')).toEqual('false'); expect(value.getText()).toEqual('value =');
expect(valid.getText()).toContain('false');
}); });
it('should be invalid if over max', function() { it('should be invalid if over max', function() {
input('value').enter('123'); input.clear();
expect(binding('value')).toEqual(''); input.sendKeys('123');
expect(binding('myForm.input.$valid')).toEqual('false'); expect(value.getText()).toEqual('value =');
expect(valid.getText()).toContain('false');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
'number': numberInputType, 'number': numberInputType,
...@@ -15809,23 +15882,31 @@ var inputType = { ...@@ -15809,23 +15882,31 @@ var inputType = {
<tt>myForm.$error.url = {{!!myForm.$error.url}}</tt><br/> <tt>myForm.$error.url = {{!!myForm.$error.url}}</tt><br/>
</form> </form>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
var text = element(by.binding('text'));
var valid = element(by.binding('myForm.input.$valid'));
var input = element(by.model('text'));
it('should initialize to model', function() { it('should initialize to model', function() {
expect(binding('text')).toEqual('http://google.com'); expect(text.getText()).toContain('http://google.com');
expect(binding('myForm.input.$valid')).toEqual('true'); expect(valid.getText()).toContain('true');
}); });
it('should be invalid if empty', function() { it('should be invalid if empty', function() {
input('text').enter(''); input.clear();
expect(binding('text')).toEqual(''); input.sendKeys('');
expect(binding('myForm.input.$valid')).toEqual('false');
expect(text.getText()).toEqual('text =');
expect(valid.getText()).toContain('false');
}); });
it('should be invalid if not url', function() { it('should be invalid if not url', function() {
input('text').enter('xxx'); input.clear();
expect(binding('myForm.input.$valid')).toEqual('false'); input.sendKeys('box');
expect(valid.getText()).toContain('false');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
'url': urlInputType, 'url': urlInputType,
...@@ -15877,23 +15958,30 @@ var inputType = { ...@@ -15877,23 +15958,30 @@ var inputType = {
<tt>myForm.$error.email = {{!!myForm.$error.email}}</tt><br/> <tt>myForm.$error.email = {{!!myForm.$error.email}}</tt><br/>
</form> </form>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
var text = element(by.binding('text'));
var valid = element(by.binding('myForm.input.$valid'));
var input = element(by.model('text'));
it('should initialize to model', function() { it('should initialize to model', function() {
expect(binding('text')).toEqual('me@example.com'); expect(text.getText()).toContain('me@example.com');
expect(binding('myForm.input.$valid')).toEqual('true'); expect(valid.getText()).toContain('true');
}); });
it('should be invalid if empty', function() { it('should be invalid if empty', function() {
input('text').enter(''); input.clear();
expect(binding('text')).toEqual(''); input.sendKeys('');
expect(binding('myForm.input.$valid')).toEqual('false'); expect(text.getText()).toEqual('text =');
expect(valid.getText()).toContain('false');
}); });
it('should be invalid if not email', function() { it('should be invalid if not email', function() {
input('text').enter('xxx'); input.clear();
expect(binding('myForm.input.$valid')).toEqual('false'); input.sendKeys('xxx');
expect(valid.getText()).toContain('false');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
'email': emailInputType, 'email': emailInputType,
...@@ -15934,14 +16022,17 @@ var inputType = { ...@@ -15934,14 +16022,17 @@ var inputType = {
</form> </form>
Note that `ng-value="specialValue"` sets radio item's value to be the value of `$scope.specialValue`. Note that `ng-value="specialValue"` sets radio item's value to be the value of `$scope.specialValue`.
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should change state', function() { it('should change state', function() {
expect(binding('color')).toEqual('"blue"'); var color = element(by.binding('color'));
expect(color.getText()).toContain('blue');
input('color').select('red'); element.all(by.model('color')).get(0).click();
expect(binding('color')).toEqual('"red"');
expect(color.getText()).toContain('red');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
'radio': radioInputType, 'radio': radioInputType,
...@@ -15978,17 +16069,21 @@ var inputType = { ...@@ -15978,17 +16069,21 @@ var inputType = {
<tt>value2 = {{value2}}</tt><br/> <tt>value2 = {{value2}}</tt><br/>
</form> </form>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should change state', function() { it('should change state', function() {
expect(binding('value1')).toEqual('true'); var value1 = element(by.binding('value1'));
expect(binding('value2')).toEqual('YES'); var value2 = element(by.binding('value2'));
expect(value1.getText()).toContain('true');
expect(value2.getText()).toContain('YES');
element(by.model('value1')).click();
element(by.model('value2')).click();
input('value1').check(); expect(value1.getText()).toContain('false');
input('value2').check(); expect(value2.getText()).toContain('NO');
expect(binding('value1')).toEqual('false');
expect(binding('value2')).toEqual('NO');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
'checkbox': checkboxInputType, 'checkbox': checkboxInputType,
...@@ -16341,44 +16436,59 @@ function checkboxInputType(scope, element, attr, ctrl) { ...@@ -16341,44 +16436,59 @@ function checkboxInputType(scope, element, attr, ctrl) {
<tt>myForm.$error.maxlength = {{!!myForm.$error.maxlength}}</tt><br> <tt>myForm.$error.maxlength = {{!!myForm.$error.maxlength}}</tt><br>
</div> </div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
var user = element(by.binding('{{user}}'));
var userNameValid = element(by.binding('myForm.userName.$valid'));
var lastNameValid = element(by.binding('myForm.lastName.$valid'));
var lastNameError = element(by.binding('myForm.lastName.$error'));
var formValid = element(by.binding('myForm.$valid'));
var userNameInput = element(by.model('user.name'));
var userLastInput = element(by.model('user.last'));
it('should initialize to model', function() { it('should initialize to model', function() {
expect(binding('user')).toEqual('{"name":"guest","last":"visitor"}'); expect(user.getText()).toContain('{"name":"guest","last":"visitor"}');
expect(binding('myForm.userName.$valid')).toEqual('true'); expect(userNameValid.getText()).toContain('true');
expect(binding('myForm.$valid')).toEqual('true'); expect(formValid.getText()).toContain('true');
}); });
it('should be invalid if empty when required', function() { it('should be invalid if empty when required', function() {
input('user.name').enter(''); userNameInput.clear();
expect(binding('user')).toEqual('{"last":"visitor"}'); userNameInput.sendKeys('');
expect(binding('myForm.userName.$valid')).toEqual('false');
expect(binding('myForm.$valid')).toEqual('false'); expect(user.getText()).toContain('{"last":"visitor"}');
expect(userNameValid.getText()).toContain('false');
expect(formValid.getText()).toContain('false');
}); });
it('should be valid if empty when min length is set', function() { it('should be valid if empty when min length is set', function() {
input('user.last').enter(''); userLastInput.clear();
expect(binding('user')).toEqual('{"name":"guest","last":""}'); userLastInput.sendKeys('');
expect(binding('myForm.lastName.$valid')).toEqual('true');
expect(binding('myForm.$valid')).toEqual('true'); expect(user.getText()).toContain('{"name":"guest","last":""}');
expect(lastNameValid.getText()).toContain('true');
expect(formValid.getText()).toContain('true');
}); });
it('should be invalid if less than required min length', function() { it('should be invalid if less than required min length', function() {
input('user.last').enter('xx'); userLastInput.clear();
expect(binding('user')).toEqual('{"name":"guest"}'); userLastInput.sendKeys('xx');
expect(binding('myForm.lastName.$valid')).toEqual('false');
expect(binding('myForm.lastName.$error')).toMatch(/minlength/); expect(user.getText()).toContain('{"name":"guest"}');
expect(binding('myForm.$valid')).toEqual('false'); expect(lastNameValid.getText()).toContain('false');
expect(lastNameError.getText()).toContain('minlength');
expect(formValid.getText()).toContain('false');
}); });
it('should be invalid if longer than max length', function() { it('should be invalid if longer than max length', function() {
input('user.last').enter('some ridiculously long name'); userLastInput.clear();
expect(binding('user')) userLastInput.sendKeys('some ridiculously long name');
.toEqual('{"name":"guest"}');
expect(binding('myForm.lastName.$valid')).toEqual('false'); expect(user.getText()).toContain('{"name":"guest"}');
expect(binding('myForm.lastName.$error')).toMatch(/maxlength/); expect(lastNameValid.getText()).toContain('false');
expect(binding('myForm.$valid')).toEqual('false'); expect(lastNameError.getText()).toContain('maxlength');
expect(formValid.getText()).toContain('false');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
var inputDirective = ['$browser', '$sniffer', function($browser, $sniffer) { var inputDirective = ['$browser', '$sniffer', function($browser, $sniffer) {
...@@ -16510,14 +16620,23 @@ var VALID_CLASS = 'ng-valid', ...@@ -16510,14 +16620,23 @@ var VALID_CLASS = 'ng-valid',
<textarea ng-model="userContent"></textarea> <textarea ng-model="userContent"></textarea>
</form> </form>
</file> </file>
<file name="scenario.js"> <file name="protractorTest.js">
it('should data-bind and become invalid', function() { it('should data-bind and become invalid', function() {
var contentEditable = element('[contenteditable]'); if (browser.params.browser = 'safari') {
// SafariDriver can't handle contenteditable.
return;
};
var contentEditable = element(by.css('.doc-example-live [contenteditable]'));
expect(contentEditable.getText()).toEqual('Change me!');
// Firefox driver doesn't trigger the proper events on 'clear', so do this hack
contentEditable.click();
contentEditable.sendKeys(protractor.Key.chord(protractor.Key.COMMAND, "a"));
contentEditable.sendKeys(protractor.Key.BACK_SPACE);
expect(contentEditable.text()).toEqual('Change me!'); expect(contentEditable.getText()).toEqual('');
input('userContent').enter(''); expect(contentEditable.getAttribute('class')).toMatch(/ng-invalid-required/);
expect(contentEditable.text()).toEqual('');
expect(contentEditable.prop('className')).toMatch(/ng-invalid-required/);
}); });
</file> </file>
* </example> * </example>
...@@ -16824,24 +16943,30 @@ var ngModelDirective = function() { ...@@ -16824,24 +16943,30 @@ var ngModelDirective = function() {
* <input type="checkbox" ng-model="confirmed" ng-change="change()" id="ng-change-example1" /> * <input type="checkbox" ng-model="confirmed" ng-change="change()" id="ng-change-example1" />
* <input type="checkbox" ng-model="confirmed" id="ng-change-example2" /> * <input type="checkbox" ng-model="confirmed" id="ng-change-example2" />
* <label for="ng-change-example2">Confirmed</label><br /> * <label for="ng-change-example2">Confirmed</label><br />
* debug = {{confirmed}}<br /> * <tt>debug = {{confirmed}}</tt><br/>
* counter = {{counter}} * <tt>counter = {{counter}}</tt><br/>
* </div> * </div>
* </doc:source> * </doc:source>
* <doc:scenario> * <doc:protractor>
* var counter = element(by.binding('counter'));
* var debug = element(by.binding('confirmed'));
*
* it('should evaluate the expression if changing from view', function() { * it('should evaluate the expression if changing from view', function() {
* expect(binding('counter')).toEqual('0'); * expect(counter.getText()).toContain('0');
* element('#ng-change-example1').click(); *
* expect(binding('counter')).toEqual('1'); * element(by.id('ng-change-example1')).click();
* expect(binding('confirmed')).toEqual('true'); *
* expect(counter.getText()).toContain('1');
* expect(debug.getText()).toContain('true');
* }); * });
* *
* it('should not evaluate the expression if changing from model', function() { * it('should not evaluate the expression if changing from model', function() {
* element('#ng-change-example2').click(); * element(by.id('ng-change-example2')).click();
* expect(binding('counter')).toEqual('0');
* expect(binding('confirmed')).toEqual('true'); * expect(counter.getText()).toContain('0');
* expect(debug.getText()).toContain('true');
* }); * });
* </doc:scenario> * </doc:protractor>
* </doc:example> * </doc:example>
*/ */
var ngChangeDirective = valueFn({ var ngChangeDirective = valueFn({
...@@ -16914,20 +17039,26 @@ var requiredDirective = function() { ...@@ -16914,20 +17039,26 @@ var requiredDirective = function() {
<tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/> <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
</form> </form>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
var listInput = element(by.model('names'));
var names = element(by.binding('{{names}}'));
var valid = element(by.binding('myForm.namesInput.$valid'));
var error = element(by.css('span.error'));
it('should initialize to model', function() { it('should initialize to model', function() {
expect(binding('names')).toEqual('["igor","misko","vojta"]'); expect(names.getText()).toContain('["igor","misko","vojta"]');
expect(binding('myForm.namesInput.$valid')).toEqual('true'); expect(valid.getText()).toContain('true');
expect(element('span.error').css('display')).toBe('none'); expect(error.getCssValue('display')).toBe('none');
}); });
it('should be invalid if empty', function() { it('should be invalid if empty', function() {
input('names').enter(''); listInput.clear();
expect(binding('names')).toEqual(''); listInput.sendKeys('');
expect(binding('myForm.namesInput.$valid')).toEqual('false');
expect(element('span.error').css('display')).not().toBe('none'); expect(names.getText()).toContain('');
}); expect(valid.getText()).toContain('false');
</doc:scenario> expect(error.getCssValue('display')).not.toBe('none'); });
</doc:protractor>
</doc:example> </doc:example>
*/ */
var ngListDirective = function() { var ngListDirective = function() {
...@@ -17009,15 +17140,17 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/; ...@@ -17009,15 +17140,17 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
<div>You chose {{my.favorite}}</div> <div>You chose {{my.favorite}}</div>
</form> </form>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
var favorite = element(by.binding('my.favorite'));
it('should initialize to model', function() { it('should initialize to model', function() {
expect(binding('my.favorite')).toEqual('unicorns'); expect(favorite.getText()).toContain('unicorns');
}); });
it('should bind the values to the inputs', function() { it('should bind the values to the inputs', function() {
input('my.favorite').select('pizza'); element.all(by.model('my.favorite')).get(0).click();
expect(binding('my.favorite')).toEqual('pizza'); expect(favorite.getText()).toContain('pizza');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
var ngValueDirective = function() { var ngValueDirective = function() {
...@@ -17077,13 +17210,17 @@ var ngValueDirective = function() { ...@@ -17077,13 +17210,17 @@ var ngValueDirective = function() {
Hello <span ng-bind="name"></span>! Hello <span ng-bind="name"></span>!
</div> </div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should check ng-bind', function() { it('should check ng-bind', function() {
expect(using('.doc-example-live').binding('name')).toBe('Whirled'); var exampleContainer = $('.doc-example-live');
using('.doc-example-live').input('name').enter('world'); var nameInput = element(by.model('name'));
expect(using('.doc-example-live').binding('name')).toBe('world');
expect(exampleContainer.findElement(by.binding('name')).getText()).toBe('Whirled');
nameInput.clear();
nameInput.sendKeys('world');
expect(exampleContainer.findElement(by.binding('name')).getText()).toBe('world');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
var ngBindDirective = ngDirective(function(scope, element, attr) { var ngBindDirective = ngDirective(function(scope, element, attr) {
...@@ -17129,20 +17266,22 @@ var ngBindDirective = ngDirective(function(scope, element, attr) { ...@@ -17129,20 +17266,22 @@ var ngBindDirective = ngDirective(function(scope, element, attr) {
<pre ng-bind-template="{{salutation}} {{name}}!"></pre> <pre ng-bind-template="{{salutation}} {{name}}!"></pre>
</div> </div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should check ng-bind', function() { it('should check ng-bind', function() {
expect(using('.doc-example-live').binding('salutation')). var salutationElem = element(by.binding('salutation'));
toBe('Hello'); var salutationInput = element(by.model('salutation'));
expect(using('.doc-example-live').binding('name')). var nameInput = element(by.model('name'));
toBe('World');
using('.doc-example-live').input('salutation').enter('Greetings'); expect(salutationElem.getText()).toBe('Hello World!');
using('.doc-example-live').input('name').enter('user');
expect(using('.doc-example-live').binding('salutation')). salutationInput.clear();
toBe('Greetings'); salutationInput.sendKeys('Greetings');
expect(using('.doc-example-live').binding('name')). nameInput.clear();
toBe('user'); nameInput.sendKeys('user');
expect(salutationElem.getText()).toBe('Greetings user!');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
var ngBindTemplateDirective = ['$interpolate', function($interpolate) { var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
...@@ -17195,12 +17334,10 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) { ...@@ -17195,12 +17334,10 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
}]); }]);
</file> </file>
<file name="scenario.js"> <file name="protractorTest.js">
it('should check ng-bind-html', function() { it('should check ng-bind-html', function() {
expect(using('.doc-example-live').binding('myHTML')). expect(element(by.binding('myHTML')).getText()).toBe(
toBe( 'I am an HTMLstring with links! and other stuff');
'I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>'
);
}); });
</file> </file>
</example> </example>
...@@ -17332,31 +17469,34 @@ function classDirective(name, selector) { ...@@ -17332,31 +17469,34 @@ function classDirective(name, selector) {
color: red; color: red;
} }
</file> </file>
<file name="scenario.js"> <file name="protractorTest.js">
var ps = element.all(by.css('.doc-example-live p'));
it('should let you toggle the class', function() { it('should let you toggle the class', function() {
expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/bold/); expect(ps.first().getAttribute('class')).not.toMatch(/bold/);
expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/red/); expect(ps.first().getAttribute('class')).not.toMatch(/red/);
input('important').check(); element(by.model('important')).click();
expect(element('.doc-example-live p:first').prop('className')).toMatch(/bold/); expect(ps.first().getAttribute('class')).toMatch(/bold/);
input('error').check(); element(by.model('error')).click();
expect(element('.doc-example-live p:first').prop('className')).toMatch(/red/); expect(ps.first().getAttribute('class')).toMatch(/red/);
}); });
it('should let you toggle string example', function() { it('should let you toggle string example', function() {
expect(element('.doc-example-live p:nth-of-type(2)').prop('className')).toBe(''); expect(ps.get(1).getAttribute('class')).toBe('');
input('style').enter('red'); element(by.model('style')).clear();
expect(element('.doc-example-live p:nth-of-type(2)').prop('className')).toBe('red'); element(by.model('style')).sendKeys('red');
expect(ps.get(1).getAttribute('class')).toBe('red');
}); });
it('array example should have 3 classes', function() { it('array example should have 3 classes', function() {
expect(element('.doc-example-live p:last').prop('className')).toBe(''); expect(ps.last().getAttribute('class')).toBe('');
input('style1').enter('bold'); element(by.model('style1')).sendKeys('bold');
input('style2').enter('strike'); element(by.model('style2')).sendKeys('strike');
input('style3').enter('red'); element(by.model('style3')).sendKeys('red');
expect(element('.doc-example-live p:last').prop('className')).toBe('bold strike red'); expect(ps.last().getAttribute('class')).toBe('bold strike red');
}); });
</file> </file>
</example> </example>
...@@ -17367,8 +17507,8 @@ function classDirective(name, selector) { ...@@ -17367,8 +17507,8 @@ function classDirective(name, selector) {
<example animations="true"> <example animations="true">
<file name="index.html"> <file name="index.html">
<input type="button" value="set" ng-click="myVar='my-class'"> <input id="setbtn" type="button" value="set" ng-click="myVar='my-class'">
<input type="button" value="clear" ng-click="myVar=''"> <input id="clearbtn" type="button" value="clear" ng-click="myVar=''">
<br> <br>
<span class="base-class" ng-class="myVar">Sample Text</span> <span class="base-class" ng-class="myVar">Sample Text</span>
</file> </file>
...@@ -17383,19 +17523,19 @@ function classDirective(name, selector) { ...@@ -17383,19 +17523,19 @@ function classDirective(name, selector) {
font-size:3em; font-size:3em;
} }
</file> </file>
<file name="scenario.js"> <file name="protractorTest.js">
it('should check ng-class', function() { it('should check ng-class', function() {
expect(element('.doc-example-live span').prop('className')).not(). expect(element(by.css('.base-class')).getAttribute('class')).not.
toMatch(/my-class/); toMatch(/my-class/);
using('.doc-example-live').element(':button:first').click(); element(by.id('setbtn')).click();
expect(element('.doc-example-live span').prop('className')). expect(element(by.css('.base-class')).getAttribute('class')).
toMatch(/my-class/); toMatch(/my-class/);
using('.doc-example-live').element(':button:last').click(); element(by.id('clearbtn')).click();
expect(element('.doc-example-live span').prop('className')).not(). expect(element(by.css('.base-class')).getAttribute('class')).not.
toMatch(/my-class/); toMatch(/my-class/);
}); });
</file> </file>
...@@ -17447,11 +17587,11 @@ var ngClassDirective = classDirective('', true); ...@@ -17447,11 +17587,11 @@ var ngClassDirective = classDirective('', true);
color: blue; color: blue;
} }
</file> </file>
<file name="scenario.js"> <file name="protractorTest.js">
it('should check ng-class-odd and ng-class-even', function() { it('should check ng-class-odd and ng-class-even', function() {
expect(element('.doc-example-live li:first span').prop('className')). expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
toMatch(/odd/); toMatch(/odd/);
expect(element('.doc-example-live li:last span').prop('className')). expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
toMatch(/even/); toMatch(/even/);
}); });
</file> </file>
...@@ -17495,11 +17635,11 @@ var ngClassOddDirective = classDirective('Odd', 0); ...@@ -17495,11 +17635,11 @@ var ngClassOddDirective = classDirective('Odd', 0);
color: blue; color: blue;
} }
</file> </file>
<file name="scenario.js"> <file name="protractorTest.js">
it('should check ng-class-odd and ng-class-even', function() { it('should check ng-class-odd and ng-class-even', function() {
expect(element('.doc-example-live li:first span').prop('className')). expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
toMatch(/odd/); toMatch(/odd/);
expect(element('.doc-example-live li:last span').prop('className')). expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
toMatch(/even/); toMatch(/even/);
}); });
</file> </file>
...@@ -17552,14 +17692,14 @@ var ngClassEvenDirective = classDirective('Even', 1); ...@@ -17552,14 +17692,14 @@ var ngClassEvenDirective = classDirective('Even', 1);
<div id="template1" ng-cloak>{{ 'hello' }}</div> <div id="template1" ng-cloak>{{ 'hello' }}</div>
<div id="template2" ng-cloak class="ng-cloak">{{ 'hello IE7' }}</div> <div id="template2" ng-cloak class="ng-cloak">{{ 'hello IE7' }}</div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should remove the template directive and css class', function() { it('should remove the template directive and css class', function() {
expect(element('.doc-example-live #template1').attr('ng-cloak')). expect($('.doc-example-live #template1').getAttribute('ng-cloak')).
not().toBeDefined(); toBeNull();
expect(element('.doc-example-live #template2').attr('ng-cloak')). expect($('.doc-example-live #template2').getAttribute('ng-cloak')).
not().toBeDefined(); toBeNull();
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
* *
*/ */
...@@ -17652,22 +17792,36 @@ var ngCloakDirective = ngDirective({ ...@@ -17652,22 +17792,36 @@ var ngCloakDirective = ngDirective({
</ul> </ul>
</div> </div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should check controller as', function() { it('should check controller as', function() {
expect(element('#ctrl-as-exmpl>:input').val()).toBe('John Smith'); var container = element(by.id('ctrl-as-exmpl'));
expect(element('#ctrl-as-exmpl li:nth-child(1) input').val())
.toBe('408 555 1212'); expect(container.findElement(by.model('settings.name'))
expect(element('#ctrl-as-exmpl li:nth-child(2) input').val()) .getAttribute('value')).toBe('John Smith');
.toBe('john.smith@example.org');
var firstRepeat =
element('#ctrl-as-exmpl li:first a:contains("clear")').click(); container.findElement(by.repeater('contact in settings.contacts').row(0));
expect(element('#ctrl-as-exmpl li:first input').val()).toBe(''); var secondRepeat =
container.findElement(by.repeater('contact in settings.contacts').row(1));
element('#ctrl-as-exmpl li:last a:contains("add")').click();
expect(element('#ctrl-as-exmpl li:nth-child(3) input').val()) expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
.toBe('yourname@example.org'); .toBe('408 555 1212');
expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value'))
.toBe('john.smith@example.org');
firstRepeat.findElement(by.linkText('clear')).click()
expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
.toBe('');
container.findElement(by.linkText('add')).click();
expect(container.findElement(by.repeater('contact in settings.contacts').row(2))
.findElement(by.model('contact.value'))
.getAttribute('value'))
.toBe('yourname@example.org');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
<doc:example> <doc:example>
<doc:source> <doc:source>
...@@ -17715,22 +17869,36 @@ var ngCloakDirective = ngDirective({ ...@@ -17715,22 +17869,36 @@ var ngCloakDirective = ngDirective({
</ul> </ul>
</div> </div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should check controller', function() { it('should check controller', function() {
expect(element('#ctrl-exmpl>:input').val()).toBe('John Smith'); var container = element(by.id('ctrl-exmpl'));
expect(element('#ctrl-exmpl li:nth-child(1) input').val())
.toBe('408 555 1212'); expect(container.findElement(by.model('name'))
expect(element('#ctrl-exmpl li:nth-child(2) input').val()) .getAttribute('value')).toBe('John Smith');
.toBe('john.smith@example.org');
var firstRepeat =
element('#ctrl-exmpl li:first a:contains("clear")').click(); container.findElement(by.repeater('contact in contacts').row(0));
expect(element('#ctrl-exmpl li:first input').val()).toBe(''); var secondRepeat =
container.findElement(by.repeater('contact in contacts').row(1));
element('#ctrl-exmpl li:last a:contains("add")').click();
expect(element('#ctrl-exmpl li:nth-child(3) input').val()) expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
.toBe('yourname@example.org'); .toBe('408 555 1212');
expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value'))
.toBe('john.smith@example.org');
firstRepeat.findElement(by.linkText('clear')).click()
expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
.toBe('');
container.findElement(by.linkText('add')).click();
expect(container.findElement(by.repeater('contact in contacts').row(2))
.findElement(by.model('contact.value'))
.getAttribute('value'))
.toBe('yourname@example.org');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
...@@ -18111,20 +18279,20 @@ forEach( ...@@ -18111,20 +18279,20 @@ forEach(
<pre>list={{list}}</pre> <pre>list={{list}}</pre>
</form> </form>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should check ng-submit', function() { it('should check ng-submit', function() {
expect(binding('list')).toBe('[]'); expect(element(by.binding('list')).getText()).toBe('list=[]');
element('.doc-example-live #submit').click(); element(by.css('.doc-example-live #submit')).click();
expect(binding('list')).toBe('["hello"]'); expect(element(by.binding('list')).getText()).toContain('hello');
expect(input('text').val()).toBe(''); expect(element(by.input('text')).getAttribute('value')).toBe('');
}); });
it('should ignore empty strings', function() { it('should ignore empty strings', function() {
expect(binding('list')).toBe('[]'); expect(element(by.binding('list')).getText()).toBe('list=[]');
element('.doc-example-live #submit').click(); element(by.css('.doc-example-live #submit')).click();
element('.doc-example-live #submit').click(); element(by.css('.doc-example-live #submit')).click();
expect(binding('list')).toBe('["hello"]'); expect(element(by.binding('list')).getText()).toContain('hello');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
...@@ -18451,19 +18619,33 @@ var ngIfDirective = ['$animate', function($animate) { ...@@ -18451,19 +18619,33 @@ var ngIfDirective = ['$animate', function($animate) {
top:50px; top:50px;
} }
</file> </file>
<file name="scenario.js"> <file name="protractorTest.js">
var templateSelect = element(by.model('template'));
var includeElem = element(by.css('.doc-example-live [ng-include]'));
it('should load template1.html', function() { it('should load template1.html', function() {
expect(element('.doc-example-live [ng-include]').text()). expect(includeElem.getText()).toMatch(/Content of template1.html/);
toMatch(/Content of template1.html/);
}); });
it('should load template2.html', function() { it('should load template2.html', function() {
select('template').option('1'); if (browser.params.browser == 'firefox') {
expect(element('.doc-example-live [ng-include]').text()). // Firefox can't handle using selects
toMatch(/Content of template2.html/); // See https://github.com/angular/protractor/issues/480
return;
}
templateSelect.click();
templateSelect.element.all(by.css('option')).get(2).click();
expect(includeElem.getText()).toMatch(/Content of template2.html/);
}); });
it('should change to blank', function() { it('should change to blank', function() {
select('template').option(''); if (browser.params.browser == 'firefox') {
expect(element('.doc-example-live [ng-include]')).toBe(undefined); // Firefox can't handle using selects
return;
}
templateSelect.click();
templateSelect.element.all(by.css('option')).get(0).click();
expect(includeElem.isPresent()).toBe(false);
}); });
</file> </file>
</example> </example>
...@@ -18623,15 +18805,15 @@ var ngIncludeFillContentDirective = ['$compile', ...@@ -18623,15 +18805,15 @@ var ngIncludeFillContentDirective = ['$compile',
</div> </div>
</div> </div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should alias index positions', function() { it('should alias index positions', function() {
expect(element('.example-init').text()) var elements = element.all(by.css('.example-init'));
.toBe('list[ 0 ][ 0 ] = a;' + expect(elements.get(0).getText()).toBe('list[ 0 ][ 0 ] = a;');
'list[ 0 ][ 1 ] = b;' + expect(elements.get(1).getText()).toBe('list[ 0 ][ 1 ] = b;');
'list[ 1 ][ 0 ] = c;' + expect(elements.get(2).getText()).toBe('list[ 1 ][ 0 ] = c;');
'list[ 1 ][ 1 ] = d;'); expect(elements.get(3).getText()).toBe('list[ 1 ][ 1 ] = d;');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
var ngInitDirective = ngDirective({ var ngInitDirective = ngDirective({
...@@ -18669,13 +18851,12 @@ var ngInitDirective = ngDirective({ ...@@ -18669,13 +18851,12 @@ var ngInitDirective = ngDirective({
<div>Normal: {{1 + 2}}</div> <div>Normal: {{1 + 2}}</div>
<div ng-non-bindable>Ignored: {{1 + 2}}</div> <div ng-non-bindable>Ignored: {{1 + 2}}</div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should check ng-non-bindable', function() { it('should check ng-non-bindable', function() {
expect(using('.doc-example-live').binding('1 + 2')).toBe('3'); expect(element(by.binding('1 + 2')).getText()).toContain('3');
expect(using('.doc-example-live').element('div:last').text()). expect(element.all(by.css('.doc-example-live div')).last().getText()).toMatch(/1 \+ 2/);
toMatch(/1 \+ 2/);
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 }); var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
...@@ -18803,49 +18984,53 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 }); ...@@ -18803,49 +18984,53 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
</ng-pluralize> </ng-pluralize>
</div> </div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should show correct pluralized string', function() { it('should show correct pluralized string', function() {
expect(element('.doc-example-live ng-pluralize:first').text()). var withoutOffset = element.all(by.css('ng-pluralize')).get(0);
toBe('1 person is viewing.'); var withOffset = element.all(by.css('ng-pluralize')).get(1);
expect(element('.doc-example-live ng-pluralize:last').text()). var countInput = element(by.model('personCount'));
toBe('Igor is viewing.');
expect(withoutOffset.getText()).toEqual('1 person is viewing.');
using('.doc-example-live').input('personCount').enter('0'); expect(withOffset.getText()).toEqual('Igor is viewing.');
expect(element('.doc-example-live ng-pluralize:first').text()).
toBe('Nobody is viewing.'); countInput.clear();
expect(element('.doc-example-live ng-pluralize:last').text()). countInput.sendKeys('0');
toBe('Nobody is viewing.');
using('.doc-example-live').input('personCount').enter('2');
expect(element('.doc-example-live ng-pluralize:first').text()).
toBe('2 people are viewing.');
expect(element('.doc-example-live ng-pluralize:last').text()).
toBe('Igor and Misko are viewing.');
using('.doc-example-live').input('personCount').enter('3');
expect(element('.doc-example-live ng-pluralize:first').text()).
toBe('3 people are viewing.');
expect(element('.doc-example-live ng-pluralize:last').text()).
toBe('Igor, Misko and one other person are viewing.');
using('.doc-example-live').input('personCount').enter('4');
expect(element('.doc-example-live ng-pluralize:first').text()).
toBe('4 people are viewing.');
expect(element('.doc-example-live ng-pluralize:last').text()).
toBe('Igor, Misko and 2 other people are viewing.');
});
it('should show data-binded names', function() { expect(withoutOffset.getText()).toEqual('Nobody is viewing.');
using('.doc-example-live').input('personCount').enter('4'); expect(withOffset.getText()).toEqual('Nobody is viewing.');
expect(element('.doc-example-live ng-pluralize:last').text()).
toBe('Igor, Misko and 2 other people are viewing.');
using('.doc-example-live').input('person1').enter('Di'); countInput.clear();
using('.doc-example-live').input('person2').enter('Vojta'); countInput.sendKeys('2');
expect(element('.doc-example-live ng-pluralize:last').text()).
toBe('Di, Vojta and 2 other people are viewing.'); expect(withoutOffset.getText()).toEqual('2 people are viewing.');
expect(withOffset.getText()).toEqual('Igor and Misko are viewing.');
countInput.clear();
countInput.sendKeys('3');
expect(withoutOffset.getText()).toEqual('3 people are viewing.');
expect(withOffset.getText()).toEqual('Igor, Misko and one other person are viewing.');
countInput.clear();
countInput.sendKeys('4');
expect(withoutOffset.getText()).toEqual('4 people are viewing.');
expect(withOffset.getText()).toEqual('Igor, Misko and 2 other people are viewing.');
}); });
</doc:scenario> it('should show data-bound names', function() {
var withOffset = element.all(by.css('ng-pluralize')).get(1);
var personCount = element(by.model('personCount'));
var person1 = element(by.model('person1'));
var person2 = element(by.model('person2'));
personCount.clear();
personCount.sendKeys('4');
person1.clear();
person1.sendKeys('Di');
person2.clear();
person2.sendKeys('Vojta');
expect(withOffset.getText()).toEqual('Di, Vojta and 2 other people are viewing.');
});
</doc:protractor>
</doc:example> </doc:example>
*/ */
var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interpolate) { var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interpolate) {
...@@ -19064,25 +19249,27 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp ...@@ -19064,25 +19249,27 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
max-height:40px; max-height:40px;
} }
</file> </file>
<file name="scenario.js"> <file name="protractorTest.js">
it('should render initial data set', function() { var friends = element(by.css('.doc-example-live'))
var r = using('.doc-example-live').repeater('ul li'); .element.all(by.repeater('friend in friends'));
expect(r.count()).toBe(10);
expect(r.row(0)).toEqual(["1","John","25"]); it('should render initial data set', function() {
expect(r.row(1)).toEqual(["2","Jessie","30"]); expect(friends.count()).toBe(10);
expect(r.row(9)).toEqual(["10","Samantha","60"]); expect(friends.get(0).getText()).toEqual('[1] John who is 25 years old.');
expect(binding('friends.length')).toBe("10"); expect(friends.get(1).getText()).toEqual('[2] Jessie who is 30 years old.');
}); expect(friends.last().getText()).toEqual('[10] Samantha who is 60 years old.');
expect(element(by.binding('friends.length')).getText())
.toMatch("I have 10 friends. They are:");
});
it('should update repeater when filter predicate changes', function() { it('should update repeater when filter predicate changes', function() {
var r = using('.doc-example-live').repeater('ul li'); expect(friends.count()).toBe(10);
expect(r.count()).toBe(10);
input('q').enter('ma'); element(by.css('.doc-example-live')).element(by.model('q')).sendKeys('ma');
expect(r.count()).toBe(2); expect(friends.count()).toBe(2);
expect(r.row(0)).toEqual(["1","Mary","28"]); expect(friends.get(0).getText()).toEqual('[1] Mary who is 28 years old.');
expect(r.row(1)).toEqual(["2","Samantha","60"]); expect(friends.last().getText()).toEqual('[2] Samantha who is 60 years old.');
}); });
</file> </file>
</example> </example>
...@@ -19416,16 +19603,19 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) { ...@@ -19416,16 +19603,19 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
background:white; background:white;
} }
</file> </file>
<file name="scenario.js"> <file name="protractorTest.js">
it('should check ng-show / ng-hide', function() { var thumbsUp = element(by.css('.doc-example-live span.icon-thumbs-up'));
expect(element('.doc-example-live span:first:hidden').count()).toEqual(1); var thumbsDown = element(by.css('.doc-example-live span.icon-thumbs-down'));
expect(element('.doc-example-live span:last:visible').count()).toEqual(1);
input('checked').check(); it('should check ng-show / ng-hide', function() {
expect(thumbsUp.isDisplayed()).toBeFalsy();
expect(thumbsDown.isDisplayed()).toBeTruthy();
expect(element('.doc-example-live span:first:visible').count()).toEqual(1); element(by.model('checked')).click();
expect(element('.doc-example-live span:last:hidden').count()).toEqual(1);
}); expect(thumbsUp.isDisplayed()).toBeTruthy();
expect(thumbsDown.isDisplayed()).toBeFalsy();
});
</file> </file>
</example> </example>
*/ */
...@@ -19570,16 +19760,19 @@ var ngShowDirective = ['$animate', function($animate) { ...@@ -19570,16 +19760,19 @@ var ngShowDirective = ['$animate', function($animate) {
background:white; background:white;
} }
</file> </file>
<file name="scenario.js"> <file name="protractorTest.js">
it('should check ng-show / ng-hide', function() { var thumbsUp = element(by.css('.doc-example-live span.icon-thumbs-up'));
expect(element('.doc-example-live .check-element:first:hidden').count()).toEqual(1); var thumbsDown = element(by.css('.doc-example-live span.icon-thumbs-down'));
expect(element('.doc-example-live .check-element:last:visible').count()).toEqual(1);
input('checked').check(); it('should check ng-show / ng-hide', function() {
expect(thumbsUp.isDisplayed()).toBeFalsy();
expect(thumbsDown.isDisplayed()).toBeTruthy();
expect(element('.doc-example-live .check-element:first:visible').count()).toEqual(1); element(by.model('checked')).click();
expect(element('.doc-example-live .check-element:last:hidden').count()).toEqual(1);
}); expect(thumbsUp.isDisplayed()).toBeTruthy();
expect(thumbsDown.isDisplayed()).toBeFalsy();
});
</file> </file>
</example> </example>
*/ */
...@@ -19618,13 +19811,15 @@ var ngHideDirective = ['$animate', function($animate) { ...@@ -19618,13 +19811,15 @@ var ngHideDirective = ['$animate', function($animate) {
color: black; color: black;
} }
</file> </file>
<file name="scenario.js"> <file name="protractorTest.js">
var colorSpan = element(by.css('.doc-example-live span'));
it('should check ng-style', function() { it('should check ng-style', function() {
expect(element('.doc-example-live span').css('color')).toBe('rgb(0, 0, 0)'); expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
element('.doc-example-live :button[value=set]').click(); element(by.css('.doc-example-live input[value=set]')).click();
expect(element('.doc-example-live span').css('color')).toBe('rgb(255, 0, 0)'); expect(colorSpan.getCssValue('color')).toBe('rgba(255, 0, 0, 1)');
element('.doc-example-live :button[value=clear]').click(); element(by.css('.doc-example-live input[value=clear]')).click();
expect(element('.doc-example-live span').css('color')).toBe('rgb(0, 0, 0)'); expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
}); });
</file> </file>
</example> </example>
...@@ -19649,7 +19844,7 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) { ...@@ -19649,7 +19844,7 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
* as specified in the template. * as specified in the template.
* *
* The directive itself works similar to ngInclude, however, instead of downloading template code (or loading it * The directive itself works similar to ngInclude, however, instead of downloading template code (or loading it
* from the template cache), `ngSwitch` simply choses one of the nested elements and makes it visible based on which element * from the template cache), `ngSwitch` simply chooses one of the nested elements and makes it visible based on which element
* matches the value obtained from the evaluated expression. In other words, you define a container element * matches the value obtained from the evaluated expression. In other words, you define a container element
* (where you place the directive), place an expression on the **`on="..."` attribute** * (where you place the directive), place an expression on the **`on="..."` attribute**
* (or the **`ng-switch="..."` attribute**), define any inner elements inside of the directive and place * (or the **`ng-switch="..."` attribute**), define any inner elements inside of the directive and place
...@@ -19745,17 +19940,20 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) { ...@@ -19745,17 +19940,20 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
top:0; top:0;
} }
</file> </file>
<file name="scenario.js"> <file name="protractorTest.js">
var switchElem = element(by.css('.doc-example-live [ng-switch]'));
var select = element(by.model('selection'));
it('should start in settings', function() { it('should start in settings', function() {
expect(element('.doc-example-live [ng-switch]').text()).toMatch(/Settings Div/); expect(switchElem.getText()).toMatch(/Settings Div/);
}); });
it('should change to home', function() { it('should change to home', function() {
select('selection').option('home'); select.element.all(by.css('option')).get(1).click();
expect(element('.doc-example-live [ng-switch]').text()).toMatch(/Home Span/); expect(switchElem.getText()).toMatch(/Home Span/);
}); });
it('should select default', function() { it('should select default', function() {
select('selection').option('other'); select.element.all(by.css('option')).get(2).click();
expect(element('.doc-example-live [ng-switch]').text()).toMatch(/default/); expect(switchElem.getText()).toMatch(/default/);
}); });
</file> </file>
</example> </example>
...@@ -19862,14 +20060,18 @@ var ngSwitchDefaultDirective = ngDirective({ ...@@ -19862,14 +20060,18 @@ var ngSwitchDefaultDirective = ngDirective({
<pane title="{{title}}">{{text}}</pane> <pane title="{{title}}">{{text}}</pane>
</div> </div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should have transcluded', function() { it('should have transcluded', function() {
input('title').enter('TITLE'); var titleElement = element(by.model('title'));
input('text').enter('TEXT'); titleElement.clear();
expect(binding('title')).toEqual('TITLE'); titleElement.sendKeys('TITLE');
expect(binding('text')).toEqual('TEXT'); var textElement = element(by.model('text'));
textElement.clear();
textElement.sendKeys('TEXT');
expect(element(by.binding('title')).getText()).toEqual('TITLE');
expect(element(by.binding('text')).getText()).toEqual('TEXT');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
* *
*/ */
...@@ -19922,12 +20124,12 @@ var ngTranscludeDirective = ngDirective({ ...@@ -19922,12 +20124,12 @@ var ngTranscludeDirective = ngDirective({
<a ng-click="currentTpl='/tpl.html'" id="tpl-link">Load inlined template</a> <a ng-click="currentTpl='/tpl.html'" id="tpl-link">Load inlined template</a>
<div id="tpl-content" ng-include src="currentTpl"></div> <div id="tpl-content" ng-include src="currentTpl"></div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should load template defined inside script tag', function() { it('should load template defined inside script tag', function() {
element('#tpl-link').click(); element(by.css('#tpl-link')).click();
expect(element('#tpl-content').text()).toMatch(/Content of the template/); expect(element(by.css('#tpl-content')).getText()).toMatch(/Content of the template/);
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
var scriptDirective = ['$templateCache', function($templateCache) { var scriptDirective = ['$templateCache', function($templateCache) {
...@@ -19975,7 +20177,7 @@ var ngOptionsMinErr = minErr('ngOptions'); ...@@ -19975,7 +20177,7 @@ var ngOptionsMinErr = minErr('ngOptions');
* option. See example below for demonstration. * option. See example below for demonstration.
* *
* <div class="alert alert-warning"> * <div class="alert alert-warning">
* **Note:** `ngOptions` provides iterator facility for `<option>` element which should be used instead * **Note:** `ngOptions` provides an iterator facility for the `<option>` element which should be used instead
* of {@link ng.directive:ngRepeat ngRepeat} when you want the * of {@link ng.directive:ngRepeat ngRepeat} when you want the
* `select` model to be bound to a non-string value. This is because an option element can only * `select` model to be bound to a non-string value. This is because an option element can only
* be bound to string values at present. * be bound to string values at present.
...@@ -20066,15 +20268,17 @@ var ngOptionsMinErr = minErr('ngOptions'); ...@@ -20066,15 +20268,17 @@ var ngOptionsMinErr = minErr('ngOptions');
</div> </div>
</div> </div>
</doc:source> </doc:source>
<doc:scenario> <doc:protractor>
it('should check ng-options', function() { it('should check ng-options', function() {
expect(binding('{selected_color:color}')).toMatch('red'); expect(element(by.binding('{selected_color:color}')).getText()).toMatch('red');
select('color').option('0'); element.all(by.select('color')).first().click();
expect(binding('{selected_color:color}')).toMatch('black'); element.all(by.css('select[ng-model="color"] option')).first().click();
using('.nullable').select('color').option(''); expect(element(by.binding('{selected_color:color}')).getText()).toMatch('black');
expect(binding('{selected_color:color}')).toMatch('null'); element(by.css('.nullable select[ng-model="color"]')).click();
element.all(by.css('.nullable select[ng-model="color"] option')).first().click();
expect(element(by.binding('{selected_color:color}')).getText()).toMatch('null');
}); });
</doc:scenario> </doc:protractor>
</doc:example> </doc:example>
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment