angularjs-rails 1.2.10 → 1.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 02ec76c086b9b1ccd0fe7cc4ee6a0b46267256c6
4
- data.tar.gz: 9d5edb4e20c5e9363236977ae3e6aa3f99526693
3
+ metadata.gz: 92587005a7d7c3164f3314a4e29ca15c51b84ebf
4
+ data.tar.gz: 3fdf694bdaffcca1cdd72714e824228014ba8481
5
5
  SHA512:
6
- metadata.gz: 578b9ae46e141493c6780b3d90a8a844007579f60073ecc7ae7d0a1ebb19de0c6ffe8cac2f6ce2288af3056264d577e408e9037bb9968df1040e4b4ce1de4799
7
- data.tar.gz: a1e5057267ad8e00c86af25896e0a5ea4879f5461a040bcec4ac70b92eefedca28fc74da679715dd010fe6364b30548fd4264d051682527e62f5506c252bef77
6
+ metadata.gz: 8338f7f2d5977c6a06e44d43722ada3d49474ff3bb2da6b93d666fac30e6ffe6d2df06f0e01d000c4d7fcc0745180c3e652ae91ab9a06075721d369ac29fc863
7
+ data.tar.gz: ffc9456c71545a2ab6c6091b4167b9fac7fcd0e6996401991a207f17c1985a205ccd08df42ab14a6fdef5e81248f7ec9de0ba8e452f5c45eb80a5a0c2218f35e
@@ -2,7 +2,10 @@ require "angularjs-rails/version"
2
2
 
3
3
  module AngularJS
4
4
  module Rails
5
- class Engine < ::Rails::Engine
5
+ if defined? Rails::Engine
6
+ require "angularjs-rails/engine"
7
+ elsif defined? Sprockets
8
+ require "angularjs-rails/sprockets"
6
9
  end
7
10
  end
8
11
  end
@@ -0,0 +1,6 @@
1
+ module AngularJS
2
+ module Rails
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,3 @@
1
+ require 'sprockets'
2
+
3
+ Sprockets.append_path File.expand_path("../../../vendor/assets/javascript", __FILE__)
@@ -1,6 +1,6 @@
1
1
  module AngularJS
2
2
  module Rails
3
- VERSION = "1.2.10"
3
+ VERSION = "1.2.12"
4
4
  UNSTABLE_VERSION = "1.1.5"
5
5
  end
6
6
  end
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.10
2
+ * @license AngularJS v1.2.12
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.10
2
+ * @license AngularJS v1.2.12
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.10
2
+ * @license AngularJS v1.2.12
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -69,7 +69,7 @@ function minErr(module) {
69
69
  return match;
70
70
  });
71
71
 
72
- message = message + '\nhttp://errors.angularjs.org/1.2.10/' +
72
+ message = message + '\nhttp://errors.angularjs.org/1.2.12/' +
73
73
  (module ? module + '/' : '') + code;
74
74
  for (i = 2; i < arguments.length; i++) {
75
75
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.10
2
+ * @license AngularJS v1.2.12
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -511,6 +511,7 @@ angular.mock.$IntervalProvider = function() {
511
511
  };
512
512
 
513
513
  $interval.cancel = function(promise) {
514
+ if(!promise) return false;
514
515
  var fnIndex;
515
516
 
516
517
  angular.forEach(repeatFns, function(fn, index) {
@@ -763,70 +764,39 @@ angular.mock.TzDate = function (offset, timestamp) {
763
764
  angular.mock.TzDate.prototype = Date.prototype;
764
765
  /* jshint +W101 */
765
766
 
766
- // TODO(matias): remove this IMMEDIATELY once we can properly detect the
767
- // presence of a registered module
768
- var animateLoaded;
769
- try {
770
- angular.module('ngAnimate');
771
- animateLoaded = true;
772
- } catch(e) {}
767
+ angular.mock.animate = angular.module('ngAnimateMock', ['ng'])
773
768
 
774
- if(animateLoaded) {
775
- angular.module('ngAnimate').config(['$provide', function($provide) {
769
+ .config(['$provide', function($provide) {
776
770
  var reflowQueue = [];
771
+
777
772
  $provide.value('$$animateReflow', function(fn) {
778
773
  reflowQueue.push(fn);
779
774
  return angular.noop;
780
775
  });
781
- $provide.decorator('$animate', function($delegate) {
782
- $delegate.triggerReflow = function() {
783
- if(reflowQueue.length === 0) {
784
- throw new Error('No animation reflows present');
785
- }
786
- angular.forEach(reflowQueue, function(fn) {
787
- fn();
788
- });
789
- reflowQueue = [];
790
- };
791
- return $delegate;
792
- });
793
- }]);
794
- }
795
-
796
- angular.mock.animate = angular.module('mock.animate', ['ng'])
797
-
798
- .config(['$provide', function($provide) {
799
776
 
800
777
  $provide.decorator('$animate', function($delegate) {
801
778
  var animate = {
802
779
  queue : [],
803
780
  enabled : $delegate.enabled,
804
- flushNext : function(name) {
805
- var tick = animate.queue.shift();
806
-
807
- if (!tick) throw new Error('No animation to be flushed');
808
- if(tick.method !== name) {
809
- throw new Error('The next animation is not "' + name +
810
- '", but is "' + tick.method + '"');
781
+ triggerReflow : function() {
782
+ if(reflowQueue.length === 0) {
783
+ throw new Error('No animation reflows present');
811
784
  }
812
- tick.fn();
813
- return tick;
785
+ angular.forEach(reflowQueue, function(fn) {
786
+ fn();
787
+ });
788
+ reflowQueue = [];
814
789
  }
815
790
  };
816
791
 
817
792
  angular.forEach(['enter','leave','move','addClass','removeClass'], function(method) {
818
793
  animate[method] = function() {
819
- var params = arguments;
820
794
  animate.queue.push({
821
- method : method,
822
- params : params,
823
- element : angular.isElement(params[0]) && params[0],
824
- parent : angular.isElement(params[1]) && params[1],
825
- after : angular.isElement(params[2]) && params[2],
826
- fn : function() {
827
- $delegate[method].apply($delegate, params);
828
- }
795
+ event : method,
796
+ element : arguments[0],
797
+ args : arguments
829
798
  });
799
+ $delegate[method].apply($delegate, arguments);
830
800
  };
831
801
  });
832
802
 
@@ -996,18 +966,18 @@ angular.mock.dump = function(object) {
996
966
  *
997
967
  * # Flushing HTTP requests
998
968
  *
999
- * The $httpBackend used in production, always responds to requests with responses asynchronously.
1000
- * If we preserved this behavior in unit testing, we'd have to create async unit tests, which are
1001
- * hard to write, follow and maintain. At the same time the testing mock, can't respond
969
+ * The $httpBackend used in production always responds to requests with responses asynchronously.
970
+ * If we preserved this behavior in unit testing we'd have to create async unit tests, which are
971
+ * hard to write, understand, and maintain. However, the testing mock can't respond
1002
972
  * synchronously because that would change the execution of the code under test. For this reason the
1003
973
  * mock $httpBackend has a `flush()` method, which allows the test to explicitly flush pending
1004
- * requests and thus preserving the async api of the backend, while allowing the test to execute
974
+ * requests and thus preserve the async api of the backend while allowing the test to execute
1005
975
  * synchronously.
1006
976
  *
1007
977
  *
1008
978
  * # Unit testing with mock $httpBackend
1009
- * The following code shows how to setup and use the mock backend in unit testing a controller.
1010
- * First we create the controller under test
979
+ * The following code shows how to setup and use the mock backend when unit testing a controller.
980
+ * First we create the controller under test:
1011
981
  *
1012
982
  <pre>
1013
983
  // The controller code
@@ -1032,7 +1002,7 @@ angular.mock.dump = function(object) {
1032
1002
  }
1033
1003
  </pre>
1034
1004
  *
1035
- * Now we setup the mock backend and create the test specs.
1005
+ * Now we setup the mock backend and create the test specs:
1036
1006
  *
1037
1007
  <pre>
1038
1008
  // testing controller
@@ -1954,7 +1924,7 @@ if(window.jasmine || window.mocha) {
1954
1924
 
1955
1925
  var currentSpec = null,
1956
1926
  isSpecRunning = function() {
1957
- return currentSpec && (window.mocha || currentSpec.queue.running);
1927
+ return !!currentSpec;
1958
1928
  };
1959
1929
 
1960
1930
 
@@ -2132,7 +2102,7 @@ if(window.jasmine || window.mocha) {
2132
2102
  window.inject = angular.mock.inject = function() {
2133
2103
  var blockFns = Array.prototype.slice.call(arguments, 0);
2134
2104
  var errorForStack = new Error('Declaration Location');
2135
- return isSpecRunning() ? workFn() : workFn;
2105
+ return isSpecRunning() ? workFn.call(currentSpec) : workFn;
2136
2106
  /////////////////////
2137
2107
  function workFn() {
2138
2108
  var modules = currentSpec.$modules || [];
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.10
2
+ * @license AngularJS v1.2.12
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -40,7 +40,7 @@ function shallowClearAndCopy(src, dst) {
40
40
  });
41
41
 
42
42
  for (var key in src) {
43
- if (src.hasOwnProperty(key) && key.charAt(0) !== '$' && key.charAt(1) !== '$') {
43
+ if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
44
44
  dst[key] = src[key];
45
45
  }
46
46
  }
@@ -392,7 +392,9 @@ angular.module('ngResource', ['ng']).
392
392
  val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam];
393
393
  if (angular.isDefined(val) && val !== null) {
394
394
  encodedVal = encodeUriSegment(val);
395
- url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), encodedVal + "$1");
395
+ url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), function(match, p1) {
396
+ return encodedVal + p1;
397
+ });
396
398
  } else {
397
399
  url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match,
398
400
  leadingSlashes, tail) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.10
2
+ * @license AngularJS v1.2.12
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -350,17 +350,17 @@ function $RouteProvider(){
350
350
  }
351
351
  </file>
352
352
 
353
- <file name="scenario.js">
353
+ <file name="protractorTest.js">
354
354
  it('should load and compile correct template', function() {
355
- element('a:contains("Moby: Ch1")').click();
356
- var content = element('.doc-example-live [ng-view]').text();
355
+ element(by.linkText('Moby: Ch1')).click();
356
+ var content = element(by.css('.doc-example-live [ng-view]')).getText();
357
357
  expect(content).toMatch(/controller\: ChapterCntl/);
358
358
  expect(content).toMatch(/Book Id\: Moby/);
359
359
  expect(content).toMatch(/Chapter Id\: 1/);
360
360
 
361
- element('a:contains("Scarlet")').click();
362
- sleep(2); // promises are not part of scenario waiting
363
- content = element('.doc-example-live [ng-view]').text();
361
+ element(by.partialLinkText('Scarlet')).click();
362
+
363
+ content = element(by.css('.doc-example-live [ng-view]')).getText();
364
364
  expect(content).toMatch(/controller\: BookCntl/);
365
365
  expect(content).toMatch(/Book Id\: Scarlet/);
366
366
  });
@@ -794,16 +794,17 @@ ngRouteModule.directive('ngView', ngViewFillContentFactory);
794
794
  }
795
795
  </file>
796
796
 
797
- <file name="scenario.js">
797
+ <file name="protractorTest.js">
798
798
  it('should load and compile correct template', function() {
799
- element('a:contains("Moby: Ch1")').click();
800
- var content = element('.doc-example-live [ng-view]').text();
799
+ element(by.linkText('Moby: Ch1')).click();
800
+ var content = element(by.css('.doc-example-live [ng-view]')).getText();
801
801
  expect(content).toMatch(/controller\: ChapterCntl/);
802
802
  expect(content).toMatch(/Book Id\: Moby/);
803
803
  expect(content).toMatch(/Chapter Id\: 1/);
804
804
 
805
- element('a:contains("Scarlet")').click();
806
- content = element('.doc-example-live [ng-view]').text();
805
+ element(by.partialLinkText('Scarlet')).click();
806
+
807
+ content = element(by.css('.doc-example-live [ng-view]')).getText();
807
808
  expect(content).toMatch(/controller\: BookCntl/);
808
809
  expect(content).toMatch(/Book Id\: Scarlet/);
809
810
  });
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.2.10
2
+ * @license AngularJS v1.2.12
3
3
  * (c) 2010-2014 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -104,35 +104,37 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize');
104
104
  </table>
105
105
  </div>
106
106
  </doc:source>
107
- <doc:scenario>
107
+ <doc:protractor>
108
108
  it('should sanitize the html snippet by default', function() {
109
- expect(using('#bind-html-with-sanitize').element('div').html()).
109
+ expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
110
110
  toBe('<p>an html\n<em>click here</em>\nsnippet</p>');
111
111
  });
112
112
 
113
113
  it('should inline raw snippet if bound to a trusted value', function() {
114
- expect(using('#bind-html-with-trust').element("div").html()).
114
+ expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).
115
115
  toBe("<p style=\"color:blue\">an html\n" +
116
116
  "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" +
117
117
  "snippet</p>");
118
118
  });
119
119
 
120
120
  it('should escape snippet without any filter', function() {
121
- expect(using('#bind-default').element('div').html()).
121
+ expect(element(by.css('#bind-default div')).getInnerHtml()).
122
122
  toBe("&lt;p style=\"color:blue\"&gt;an html\n" +
123
123
  "&lt;em onmouseover=\"this.textContent='PWN3D!'\"&gt;click here&lt;/em&gt;\n" +
124
124
  "snippet&lt;/p&gt;");
125
125
  });
126
126
 
127
127
  it('should update', function() {
128
- input('snippet').enter('new <b onclick="alert(1)">text</b>');
129
- expect(using('#bind-html-with-sanitize').element('div').html()).toBe('new <b>text</b>');
130
- expect(using('#bind-html-with-trust').element('div').html()).toBe(
128
+ element(by.model('snippet')).clear();
129
+ element(by.model('snippet')).sendKeys('new <b onclick="alert(1)">text</b>');
130
+ expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()).
131
+ toBe('new <b>text</b>');
132
+ expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).toBe(
131
133
  'new <b onclick="alert(1)">text</b>');
132
- expect(using('#bind-default').element('div').html()).toBe(
134
+ expect(element(by.css('#bind-default div')).getInnerHtml()).toBe(
133
135
  "new &lt;b onclick=\"alert(1)\"&gt;text&lt;/b&gt;");
134
136
  });
135
- </doc:scenario>
137
+ </doc:protractor>
136
138
  </doc:example>
137
139
  */
138
140
  function $SanitizeProvider() {
@@ -537,37 +539,38 @@ angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider);
537
539
  </tr>
538
540
  </table>
539
541
  </doc:source>
540
- <doc:scenario>
542
+ <doc:protractor>
541
543
  it('should linkify the snippet with urls', function() {
542
- expect(using('#linky-filter').binding('snippet | linky')).
543
- toBe('Pretty text with some links:&#10;' +
544
- '<a href="http://angularjs.org/">http://angularjs.org/</a>,&#10;' +
545
- '<a href="mailto:us@somewhere.org">us@somewhere.org</a>,&#10;' +
546
- '<a href="mailto:another@somewhere.org">another@somewhere.org</a>,&#10;' +
547
- 'and one more: <a href="ftp://127.0.0.1/">ftp://127.0.0.1/</a>.');
544
+ expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
545
+ toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' +
546
+ 'another@somewhere.org, and one more: ftp://127.0.0.1/.');
547
+ expect(element.all(by.css('#linky-filter a')).count()).toEqual(4);
548
548
  });
549
549
 
550
- it ('should not linkify snippet without the linky filter', function() {
551
- expect(using('#escaped-html').binding('snippet')).
552
- toBe("Pretty text with some links:\n" +
553
- "http://angularjs.org/,\n" +
554
- "mailto:us@somewhere.org,\n" +
555
- "another@somewhere.org,\n" +
556
- "and one more: ftp://127.0.0.1/.");
550
+ it('should not linkify snippet without the linky filter', function() {
551
+ expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()).
552
+ toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' +
553
+ 'another@somewhere.org, and one more: ftp://127.0.0.1/.');
554
+ expect(element.all(by.css('#escaped-html a')).count()).toEqual(0);
557
555
  });
558
556
 
559
557
  it('should update', function() {
560
- input('snippet').enter('new http://link.');
561
- expect(using('#linky-filter').binding('snippet | linky')).
562
- toBe('new <a href="http://link">http://link</a>.');
563
- expect(using('#escaped-html').binding('snippet')).toBe('new http://link.');
558
+ element(by.model('snippet')).clear();
559
+ element(by.model('snippet')).sendKeys('new http://link.');
560
+ expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()).
561
+ toBe('new http://link.');
562
+ expect(element.all(by.css('#linky-filter a')).count()).toEqual(1);
563
+ expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText())
564
+ .toBe('new http://link.');
564
565
  });
565
566
 
566
567
  it('should work with the target property', function() {
567
- expect(using('#linky-target').binding("snippetWithTarget | linky:'_blank'")).
568
- toBe('<a target="_blank" href="http://angularjs.org/">http://angularjs.org/</a>');
568
+ expect(element(by.id('linky-target')).
569
+ element(by.binding("snippetWithTarget | linky:'_blank'")).getText()).
570
+ toBe('http://angularjs.org/');
571
+ expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank');
569
572
  });
570
- </doc:scenario>
573
+ </doc:protractor>
571
574
  </doc:example>
572
575
  */
573
576
  angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) {
@@ -9790,7 +9790,7 @@ if ( typeof module === "object" && module && typeof module.exports === "object"
9790
9790
  })( window );
9791
9791
 
9792
9792
  /**
9793
- * @license AngularJS v1.2.10
9793
+ * @license AngularJS v1.2.12
9794
9794
  * (c) 2010-2014 Google, Inc. http://angularjs.org
9795
9795
  * License: MIT
9796
9796
  */
@@ -9860,7 +9860,7 @@ function minErr(module) {
9860
9860
  return match;
9861
9861
  });
9862
9862
 
9863
- message = message + '\nhttp://errors.angularjs.org/1.2.10/' +
9863
+ message = message + '\nhttp://errors.angularjs.org/1.2.12/' +
9864
9864
  (module ? module + '/' : '') + code;
9865
9865
  for (i = 2; i < arguments.length; i++) {
9866
9866
  message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
@@ -10063,7 +10063,7 @@ function isArrayLike(obj) {
10063
10063
  * is the value of an object property or an array element and `key` is the object property key or
10064
10064
  * array element index. Specifying a `context` for the function is optional.
10065
10065
  *
10066
- * It is worth nothing that `.forEach` does not iterate over inherited properties because it filters
10066
+ * It is worth noting that `.forEach` does not iterate over inherited properties because it filters
10067
10067
  * using the `hasOwnProperty` method.
10068
10068
  *
10069
10069
  <pre>
@@ -10072,7 +10072,7 @@ function isArrayLike(obj) {
10072
10072
  angular.forEach(values, function(value, key){
10073
10073
  this.push(key + ': ' + value);
10074
10074
  }, log);
10075
- expect(log).toEqual(['name: misko', 'gender:male']);
10075
+ expect(log).toEqual(['name: misko', 'gender: male']);
10076
10076
  </pre>
10077
10077
  *
10078
10078
  * @param {Object|Array} obj Object to iterate over.
@@ -10643,7 +10643,7 @@ function shallowCopy(src, dst) {
10643
10643
  for(var key in src) {
10644
10644
  // shallowCopy is only ever called by $compile nodeLinkFn, which has control over src
10645
10645
  // so we don't need to worry about using our custom hasOwnProperty here
10646
- if (src.hasOwnProperty(key) && key.charAt(0) !== '$' && key.charAt(1) !== '$') {
10646
+ if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
10647
10647
  dst[key] = src[key];
10648
10648
  }
10649
10649
  }
@@ -11626,11 +11626,11 @@ function setupModuleLoader(window) {
11626
11626
  * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
11627
11627
  */
11628
11628
  var version = {
11629
- full: '1.2.10', // all of these placeholder strings will be replaced by grunt's
11629
+ full: '1.2.12', // all of these placeholder strings will be replaced by grunt's
11630
11630
  major: 1, // package task
11631
11631
  minor: 2,
11632
- dot: 10,
11633
- codeName: 'augmented-serendipity'
11632
+ dot: 12,
11633
+ codeName: 'cauliflower-eradication'
11634
11634
  };
11635
11635
 
11636
11636
 
@@ -11927,6 +11927,9 @@ function JQLite(element) {
11927
11927
  if (element instanceof JQLite) {
11928
11928
  return element;
11929
11929
  }
11930
+ if (isString(element)) {
11931
+ element = trim(element);
11932
+ }
11930
11933
  if (!(this instanceof JQLite)) {
11931
11934
  if (isString(element) && element.charAt(0) != '<') {
11932
11935
  throw jqLiteMinErr('nosel', 'Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element');
@@ -13200,17 +13203,16 @@ function annotate(fn) {
13200
13203
  * Here is an example of registering a service using
13201
13204
  * {@link AUTO.$provide#methods_service $provide.service(class)}.
13202
13205
  * <pre>
13203
- * $provide.service('ping', ['$http', function($http) {
13204
- * var Ping = function() {
13205
- * this.$http = $http;
13206
- * };
13207
- *
13208
- * Ping.prototype.send = function() {
13209
- * return this.$http.get('/ping');
13210
- * };
13206
+ * var Ping = function($http) {
13207
+ * this.$http = $http;
13208
+ * };
13209
+ *
13210
+ * Ping.$inject = ['$http'];
13211
13211
  *
13212
- * return Ping;
13213
- * }]);
13212
+ * Ping.prototype.send = function() {
13213
+ * return this.$http.get('/ping');
13214
+ * };
13215
+ * $provide.service('ping', Ping);
13214
13216
  * </pre>
13215
13217
  * You would then inject and use this service like this:
13216
13218
  * <pre>
@@ -13308,7 +13310,7 @@ function annotate(fn) {
13308
13310
  * Here we decorate the {@link ng.$log $log} service to convert warnings to errors by intercepting
13309
13311
  * calls to {@link ng.$log#error $log.warn()}.
13310
13312
  * <pre>
13311
- * $provider.decorator('$log', ['$delegate', function($delegate) {
13313
+ * $provide.decorator('$log', ['$delegate', function($delegate) {
13312
13314
  * $delegate.warn = $delegate.error;
13313
13315
  * return $delegate;
13314
13316
  * }]);
@@ -14911,13 +14913,17 @@ function $TemplateCacheProvider() {
14911
14913
  <div compile="html"></div>
14912
14914
  </div>
14913
14915
  </doc:source>
14914
- <doc:scenario>
14916
+ <doc:protractor>
14915
14917
  it('should auto compile', function() {
14916
- expect(element('div[compile]').text()).toBe('Hello Angular');
14917
- input('html').enter('{{name}}!');
14918
- expect(element('div[compile]').text()).toBe('Angular!');
14918
+ var textarea = $('textarea');
14919
+ var output = $('div[compile]');
14920
+ // The initial state reads 'Hello Angular'.
14921
+ expect(output.getText()).toBe('Hello Angular');
14922
+ textarea.clear();
14923
+ textarea.sendKeys('{{name}}!');
14924
+ expect(output.getText()).toBe('Angular!');
14919
14925
  });
14920
- </doc:scenario>
14926
+ </doc:protractor>
14921
14927
  </doc:example>
14922
14928
 
14923
14929
  *
@@ -15679,7 +15685,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
15679
15685
  hasTranscludeDirective = true;
15680
15686
 
15681
15687
  // Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion.
15682
- // This option should only be used by directives that know how to how to safely handle element transclusion,
15688
+ // This option should only be used by directives that know how to safely handle element transclusion,
15683
15689
  // where the transcluded nodes are added or replaced after linking.
15684
15690
  if (!directive.$$tlb) {
15685
15691
  assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode);
@@ -16194,9 +16200,13 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
16194
16200
  linkNode = $compileNode[0];
16195
16201
 
16196
16202
  if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {
16203
+ var oldClasses = beforeTemplateLinkNode.className;
16197
16204
  // it was cloned therefore we have to clone as well.
16198
16205
  linkNode = jqLiteClone(compileNode);
16199
16206
  replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);
16207
+
16208
+ // Copy in CSS classes from original node
16209
+ safeAddClass(jqLite(linkNode), oldClasses);
16200
16210
  }
16201
16211
  if (afterTemplateNodeLinkFn.transclude) {
16202
16212
  childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude);
@@ -17217,14 +17227,14 @@ function $HttpProvider() {
17217
17227
  <option>JSONP</option>
17218
17228
  </select>
17219
17229
  <input type="text" ng-model="url" size="80"/>
17220
- <button ng-click="fetch()">fetch</button><br>
17221
- <button ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button>
17222
- <button
17230
+ <button id="fetchbtn" ng-click="fetch()">fetch</button><br>
17231
+ <button id="samplegetbtn" ng-click="updateModel('GET', 'http-hello.html')">Sample GET</button>
17232
+ <button id="samplejsonpbtn"
17223
17233
  ng-click="updateModel('JSONP',
17224
17234
  'http://angularjs.org/greet.php?callback=JSON_CALLBACK&name=Super%20Hero')">
17225
17235
  Sample JSONP
17226
17236
  </button>
17227
- <button
17237
+ <button id="invalidjsonpbtn"
17228
17238
  ng-click="updateModel('JSONP', 'http://angularjs.org/doesntexist&callback=JSON_CALLBACK')">
17229
17239
  Invalid JSONP
17230
17240
  </button>
@@ -17261,27 +17271,34 @@ function $HttpProvider() {
17261
17271
  <file name="http-hello.html">
17262
17272
  Hello, $http!
17263
17273
  </file>
17264
- <file name="scenario.js">
17274
+ <file name="protractorTest.js">
17275
+ var status = element(by.binding('status'));
17276
+ var data = element(by.binding('data'));
17277
+ var fetchBtn = element(by.id('fetchbtn'));
17278
+ var sampleGetBtn = element(by.id('samplegetbtn'));
17279
+ var sampleJsonpBtn = element(by.id('samplejsonpbtn'));
17280
+ var invalidJsonpBtn = element(by.id('invalidjsonpbtn'));
17281
+
17265
17282
  it('should make an xhr GET request', function() {
17266
- element(':button:contains("Sample GET")').click();
17267
- element(':button:contains("fetch")').click();
17268
- expect(binding('status')).toBe('200');
17269
- expect(binding('data')).toMatch(/Hello, \$http!/);
17283
+ sampleGetBtn.click();
17284
+ fetchBtn.click();
17285
+ expect(status.getText()).toMatch('200');
17286
+ expect(data.getText()).toMatch(/Hello, \$http!/)
17270
17287
  });
17271
17288
 
17272
17289
  it('should make a JSONP request to angularjs.org', function() {
17273
- element(':button:contains("Sample JSONP")').click();
17274
- element(':button:contains("fetch")').click();
17275
- expect(binding('status')).toBe('200');
17276
- expect(binding('data')).toMatch(/Super Hero!/);
17290
+ sampleJsonpBtn.click();
17291
+ fetchBtn.click();
17292
+ expect(status.getText()).toMatch('200');
17293
+ expect(data.getText()).toMatch(/Super Hero!/);
17277
17294
  });
17278
17295
 
17279
17296
  it('should make JSONP request to invalid URL and invoke the error handler',
17280
17297
  function() {
17281
- element(':button:contains("Invalid JSONP")').click();
17282
- element(':button:contains("fetch")').click();
17283
- expect(binding('status')).toBe('0');
17284
- expect(binding('data')).toBe('Request failed');
17298
+ invalidJsonpBtn.click();
17299
+ fetchBtn.click();
17300
+ expect(status.getText()).toMatch('0');
17301
+ expect(data.getText()).toMatch('Request failed');
17285
17302
  });
17286
17303
  </file>
17287
17304
  </example>
@@ -17663,13 +17680,18 @@ function $HttpProvider() {
17663
17680
  }
17664
17681
 
17665
17682
  function createXhr(method) {
17666
- // IE8 doesn't support PATCH method, but the ActiveX object does
17667
- /* global ActiveXObject */
17668
- return (msie <= 8 && lowercase(method) === 'patch')
17669
- ? new ActiveXObject('Microsoft.XMLHTTP')
17670
- : new window.XMLHttpRequest();
17671
- }
17683
+ //if IE and the method is not RFC2616 compliant, or if XMLHttpRequest
17684
+ //is not available, try getting an ActiveXObject. Otherwise, use XMLHttpRequest
17685
+ //if it is available
17686
+ if (msie <= 8 && (!method.match(/^(get|post|head|put|delete|options)$/i) ||
17687
+ !window.XMLHttpRequest)) {
17688
+ return new window.ActiveXObject("Microsoft.XMLHTTP");
17689
+ } else if (window.XMLHttpRequest) {
17690
+ return new window.XMLHttpRequest();
17691
+ }
17672
17692
 
17693
+ throw minErr('$httpBackend')('noxhr', "This browser does not support XMLHttpRequest.");
17694
+ }
17673
17695
 
17674
17696
  /**
17675
17697
  * @ngdoc object
@@ -17764,7 +17786,20 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc
17764
17786
  }
17765
17787
 
17766
17788
  if (responseType) {
17767
- xhr.responseType = responseType;
17789
+ try {
17790
+ xhr.responseType = responseType;
17791
+ } catch (e) {
17792
+ // WebKit added support for the json responseType value on 09/03/2013
17793
+ // https://bugs.webkit.org/show_bug.cgi?id=73648. Versions of Safari prior to 7 are
17794
+ // known to throw when setting the value "json" as the response type. Other older
17795
+ // browsers implementing the responseType
17796
+ //
17797
+ // The json response type can be ignored if not supported, because JSON payloads are
17798
+ // parsed on the client-side regardless.
17799
+ if (responseType !== 'json') {
17800
+ throw e;
17801
+ }
17802
+ }
17768
17803
  }
17769
17804
 
17770
17805
  xhr.send(post || null);
@@ -17863,11 +17898,11 @@ var $interpolateMinErr = minErr('$interpolate');
17863
17898
  //demo.label//
17864
17899
  </div>
17865
17900
  </doc:source>
17866
- <doc:scenario>
17867
- it('should interpolate binding with custom symbols', function() {
17868
- expect(binding('demo.label')).toBe('This binding is brought you by // interpolation symbols.');
17869
- });
17870
- </doc:scenario>
17901
+ <doc:protractor>
17902
+ it('should interpolate binding with custom symbols', function() {
17903
+ expect(element(by.binding('demo.label')).getText()).toBe('This binding is brought you by // interpolation symbols.');
17904
+ });
17905
+ </doc:protractor>
17871
17906
  </doc:example>
17872
17907
  */
17873
17908
  function $InterpolateProvider() {
@@ -19086,7 +19121,7 @@ function $LogProvider(){
19086
19121
  * @name ng.$logProvider#debugEnabled
19087
19122
  * @methodOf ng.$logProvider
19088
19123
  * @description
19089
- * @param {string=} flag enable or disable debug level messages
19124
+ * @param {boolean=} flag enable or disable debug level messages
19090
19125
  * @returns {*} current value if used as getter or itself (chaining) if used as setter
19091
19126
  */
19092
19127
  this.debugEnabled = function(flag) {
@@ -20542,7 +20577,7 @@ function $ParseProvider() {
20542
20577
  * constructed via `$q.reject`, the promise will be rejected instead.
20543
20578
  * - `reject(reason)` – rejects the derived promise with the `reason`. This is equivalent to
20544
20579
  * resolving it with a rejection constructed via `$q.reject`.
20545
- * - `notify(value)` - provides updates on the status of the promises execution. This may be called
20580
+ * - `notify(value)` - provides updates on the status of the promise's execution. This may be called
20546
20581
  * multiple times before the promise is either resolved or rejected.
20547
20582
  *
20548
20583
  * **Properties**
@@ -20692,7 +20727,7 @@ function qFactory(nextTick, exceptionHandler) {
20692
20727
 
20693
20728
 
20694
20729
  reject: function(reason) {
20695
- deferred.resolve(reject(reason));
20730
+ deferred.resolve(createInternalRejectedPromise(reason));
20696
20731
  },
20697
20732
 
20698
20733
 
@@ -20849,6 +20884,12 @@ function qFactory(nextTick, exceptionHandler) {
20849
20884
  * @returns {Promise} Returns a promise that was already resolved as rejected with the `reason`.
20850
20885
  */
20851
20886
  var reject = function(reason) {
20887
+ var result = defer();
20888
+ result.reject(reason);
20889
+ return result.promise;
20890
+ };
20891
+
20892
+ var createInternalRejectedPromise = function(reason) {
20852
20893
  return {
20853
20894
  then: function(callback, errback) {
20854
20895
  var result = defer();
@@ -21909,7 +21950,7 @@ function $RootScopeProvider(){
21909
21950
  * onto the {@link ng.$exceptionHandler $exceptionHandler} service.
21910
21951
  *
21911
21952
  * @param {string} name Event name to emit.
21912
- * @param {...*} args Optional set of arguments which will be passed onto the event listeners.
21953
+ * @param {...*} args Optional one or more arguments which will be passed onto the event listeners.
21913
21954
  * @return {Object} Event object (see {@link ng.$rootScope.Scope#methods_$on}).
21914
21955
  */
21915
21956
  $emit: function(name, args) {
@@ -21977,7 +22018,7 @@ function $RootScopeProvider(){
21977
22018
  * onto the {@link ng.$exceptionHandler $exceptionHandler} service.
21978
22019
  *
21979
22020
  * @param {string} name Event name to broadcast.
21980
- * @param {...*} args Optional set of arguments which will be passed onto the event listeners.
22021
+ * @param {...*} args Optional one or more arguments which will be passed onto the event listeners.
21981
22022
  * @return {Object} Event object, see {@link ng.$rootScope.Scope#methods_$on}
21982
22023
  */
21983
22024
  $broadcast: function(name, args) {
@@ -22769,13 +22810,15 @@ function $SceDelegateProvider() {
22769
22810
  ]
22770
22811
  </file>
22771
22812
 
22772
- <file name="scenario.js">
22813
+ <file name="protractorTest.js">
22773
22814
  describe('SCE doc demo', function() {
22774
22815
  it('should sanitize untrusted values', function() {
22775
- expect(element('.htmlComment').html()).toBe('<span>Is <i>anyone</i> reading this?</span>');
22816
+ expect(element(by.css('.htmlComment')).getInnerHtml())
22817
+ .toBe('<span>Is <i>anyone</i> reading this?</span>');
22776
22818
  });
22819
+
22777
22820
  it('should NOT sanitize explicitly trusted values', function() {
22778
- expect(element('#explicitlyTrustedHtml').html()).toBe(
22821
+ expect(element(by.id('explicitlyTrustedHtml')).getInnerHtml()).toBe(
22779
22822
  '<span onmouseover="this.textContent=&quot;Explicitly trusted HTML bypasses ' +
22780
22823
  'sanitization.&quot;">Hover over this text.</span>');
22781
22824
  });
@@ -23534,13 +23577,13 @@ function urlIsSameOrigin(requestUrl) {
23534
23577
  <button ng-click="doGreeting(greeting)">ALERT</button>
23535
23578
  </div>
23536
23579
  </doc:source>
23537
- <doc:scenario>
23580
+ <doc:protractor>
23538
23581
  it('should display the greeting in the input box', function() {
23539
- input('greeting').enter('Hello, E2E Tests');
23582
+ element(by.model('greeting')).sendKeys('Hello, E2E Tests');
23540
23583
  // If we click the button it will block the test runner
23541
23584
  // element(':button').click();
23542
23585
  });
23543
- </doc:scenario>
23586
+ </doc:protractor>
23544
23587
  </doc:example>
23545
23588
  */
23546
23589
  function $WindowProvider(){
@@ -23749,35 +23792,47 @@ function $FilterProvider($provide) {
23749
23792
  Equality <input type="checkbox" ng-model="strict"><br>
23750
23793
  <table id="searchObjResults">
23751
23794
  <tr><th>Name</th><th>Phone</th></tr>
23752
- <tr ng-repeat="friend in friends | filter:search:strict">
23753
- <td>{{friend.name}}</td>
23754
- <td>{{friend.phone}}</td>
23795
+ <tr ng-repeat="friendObj in friends | filter:search:strict">
23796
+ <td>{{friendObj.name}}</td>
23797
+ <td>{{friendObj.phone}}</td>
23755
23798
  </tr>
23756
23799
  </table>
23757
23800
  </doc:source>
23758
- <doc:scenario>
23759
- it('should search across all fields when filtering with a string', function() {
23760
- input('searchText').enter('m');
23761
- expect(repeater('#searchTextResults tr', 'friend in friends').column('friend.name')).
23762
- toEqual(['Mary', 'Mike', 'Adam']);
23801
+ <doc:protractor>
23802
+ var expectFriendNames = function(expectedNames, key) {
23803
+ element.all(by.repeater(key + ' in friends').column(key + '.name')).then(function(arr) {
23804
+ arr.forEach(function(wd, i) {
23805
+ expect(wd.getText()).toMatch(expectedNames[i]);
23806
+ });
23807
+ });
23808
+ };
23763
23809
 
23764
- input('searchText').enter('76');
23765
- expect(repeater('#searchTextResults tr', 'friend in friends').column('friend.name')).
23766
- toEqual(['John', 'Julie']);
23810
+ it('should search across all fields when filtering with a string', function() {
23811
+ var searchText = element(by.model('searchText'));
23812
+ searchText.clear();
23813
+ searchText.sendKeys('m');
23814
+ expectFriendNames(['Mary', 'Mike', 'Adam'], 'friend');
23815
+
23816
+ searchText.clear();
23817
+ searchText.sendKeys('76');
23818
+ expectFriendNames(['John', 'Julie'], 'friend');
23767
23819
  });
23768
23820
 
23769
23821
  it('should search in specific fields when filtering with a predicate object', function() {
23770
- input('search.$').enter('i');
23771
- expect(repeater('#searchObjResults tr', 'friend in friends').column('friend.name')).
23772
- toEqual(['Mary', 'Mike', 'Julie', 'Juliette']);
23822
+ var searchAny = element(by.model('search.$'));
23823
+ searchAny.clear();
23824
+ searchAny.sendKeys('i');
23825
+ expectFriendNames(['Mary', 'Mike', 'Julie', 'Juliette'], 'friendObj');
23773
23826
  });
23774
23827
  it('should use a equal comparison when comparator is true', function() {
23775
- input('search.name').enter('Julie');
23776
- input('strict').check();
23777
- expect(repeater('#searchObjResults tr', 'friend in friends').column('friend.name')).
23778
- toEqual(['Julie']);
23828
+ var searchName = element(by.model('search.name'));
23829
+ var strict = element(by.model('strict'));
23830
+ searchName.clear();
23831
+ searchName.sendKeys('Julie');
23832
+ strict.click();
23833
+ expectFriendNames(['Julie'], 'friendObj');
23779
23834
  });
23780
- </doc:scenario>
23835
+ </doc:protractor>
23781
23836
  </doc:example>
23782
23837
  */
23783
23838
  function filterFilter() {
@@ -23855,7 +23910,7 @@ function filterFilter() {
23855
23910
  (function(path) {
23856
23911
  if (typeof expression[path] == 'undefined') return;
23857
23912
  predicates.push(function(value) {
23858
- return search(path == '$' ? value : getter(value, path), expression[path]);
23913
+ return search(path == '$' ? value : (value && value[path]), expression[path]);
23859
23914
  });
23860
23915
  })(key);
23861
23916
  }
@@ -23901,21 +23956,26 @@ function filterFilter() {
23901
23956
  </script>
23902
23957
  <div ng-controller="Ctrl">
23903
23958
  <input type="number" ng-model="amount"> <br>
23904
- default currency symbol ($): {{amount | currency}}<br>
23905
- custom currency identifier (USD$): {{amount | currency:"USD$"}}
23959
+ default currency symbol ($): <span id="currency-default">{{amount | currency}}</span><br>
23960
+ custom currency identifier (USD$): <span>{{amount | currency:"USD$"}}</span>
23906
23961
  </div>
23907
23962
  </doc:source>
23908
- <doc:scenario>
23963
+ <doc:protractor>
23909
23964
  it('should init with 1234.56', function() {
23910
- expect(binding('amount | currency')).toBe('$1,234.56');
23911
- expect(binding('amount | currency:"USD$"')).toBe('USD$1,234.56');
23965
+ expect(element(by.id('currency-default')).getText()).toBe('$1,234.56');
23966
+ expect(element(by.binding('amount | currency:"USD$"')).getText()).toBe('USD$1,234.56');
23912
23967
  });
23913
23968
  it('should update', function() {
23914
- input('amount').enter('-1234');
23915
- expect(binding('amount | currency')).toBe('($1,234.00)');
23916
- expect(binding('amount | currency:"USD$"')).toBe('(USD$1,234.00)');
23969
+ if (browser.params.browser == 'safari') {
23970
+ // Safari does not understand the minus key. See
23971
+ // https://github.com/angular/protractor/issues/481
23972
+ return;
23973
+ }
23974
+ element(by.model('amount')).clear();
23975
+ element(by.model('amount')).sendKeys('-1234'); expect(element(by.id('currency-default')).getText()).toBe('($1,234.00)');
23976
+ expect(element(by.binding('amount | currency:"USD$"')).getText()).toBe('(USD$1,234.00)');
23917
23977
  });
23918
- </doc:scenario>
23978
+ </doc:protractor>
23919
23979
  </doc:example>
23920
23980
  */
23921
23981
  currencyFilter.$inject = ['$locale'];
@@ -23954,25 +24014,26 @@ function currencyFilter($locale) {
23954
24014
  </script>
23955
24015
  <div ng-controller="Ctrl">
23956
24016
  Enter number: <input ng-model='val'><br>
23957
- Default formatting: {{val | number}}<br>
23958
- No fractions: {{val | number:0}}<br>
23959
- Negative number: {{-val | number:4}}
24017
+ Default formatting: <span id='number-default'>{{val | number}}</span><br>
24018
+ No fractions: <span>{{val | number:0}}</span><br>
24019
+ Negative number: <span>{{-val | number:4}}</span>
23960
24020
  </div>
23961
24021
  </doc:source>
23962
- <doc:scenario>
24022
+ <doc:protractor>
23963
24023
  it('should format numbers', function() {
23964
- expect(binding('val | number')).toBe('1,234.568');
23965
- expect(binding('val | number:0')).toBe('1,235');
23966
- expect(binding('-val | number:4')).toBe('-1,234.5679');
24024
+ expect(element(by.id('number-default')).getText()).toBe('1,234.568');
24025
+ expect(element(by.binding('val | number:0')).getText()).toBe('1,235');
24026
+ expect(element(by.binding('-val | number:4')).getText()).toBe('-1,234.5679');
23967
24027
  });
23968
24028
 
23969
24029
  it('should update', function() {
23970
- input('val').enter('3374.333');
23971
- expect(binding('val | number')).toBe('3,374.333');
23972
- expect(binding('val | number:0')).toBe('3,374');
23973
- expect(binding('-val | number:4')).toBe('-3,374.3330');
23974
- });
23975
- </doc:scenario>
24030
+ element(by.model('val')).clear();
24031
+ element(by.model('val')).sendKeys('3374.333');
24032
+ expect(element(by.id('number-default')).getText()).toBe('3,374.333');
24033
+ expect(element(by.binding('val | number:0')).getText()).toBe('3,374');
24034
+ expect(element(by.binding('-val | number:4')).getText()).toBe('-3,374.3330');
24035
+ });
24036
+ </doc:protractor>
23976
24037
  </doc:example>
23977
24038
  */
23978
24039
 
@@ -24202,22 +24263,22 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+
24202
24263
  <doc:example>
24203
24264
  <doc:source>
24204
24265
  <span ng-non-bindable>{{1288323623006 | date:'medium'}}</span>:
24205
- {{1288323623006 | date:'medium'}}<br>
24266
+ <span>{{1288323623006 | date:'medium'}}</span><br>
24206
24267
  <span ng-non-bindable>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span>:
24207
- {{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}<br>
24268
+ <span>{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}</span><br>
24208
24269
  <span ng-non-bindable>{{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}</span>:
24209
- {{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}<br>
24270
+ <span>{{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}</span><br>
24210
24271
  </doc:source>
24211
- <doc:scenario>
24272
+ <doc:protractor>
24212
24273
  it('should format date', function() {
24213
- expect(binding("1288323623006 | date:'medium'")).
24274
+ expect(element(by.binding("1288323623006 | date:'medium'")).getText()).
24214
24275
  toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} (AM|PM)/);
24215
- expect(binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).
24276
+ expect(element(by.binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).getText()).
24216
24277
  toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} (\-|\+)?\d{4}/);
24217
- expect(binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).
24278
+ expect(element(by.binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).getText()).
24218
24279
  toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/);
24219
24280
  });
24220
- </doc:scenario>
24281
+ </doc:protractor>
24221
24282
  </doc:example>
24222
24283
  */
24223
24284
  dateFilter.$inject = ['$locale'];
@@ -24316,11 +24377,11 @@ function dateFilter($locale) {
24316
24377
  <doc:source>
24317
24378
  <pre>{{ {'name':'value'} | json }}</pre>
24318
24379
  </doc:source>
24319
- <doc:scenario>
24380
+ <doc:protractor>
24320
24381
  it('should jsonify filtered objects', function() {
24321
- expect(binding("{'name':'value'}")).toMatch(/\{\n "name": ?"value"\n}/);
24382
+ expect(element(by.binding("{'name':'value'}")).getText()).toMatch(/\{\n "name": ?"value"\n}/);
24322
24383
  });
24323
- </doc:scenario>
24384
+ </doc:protractor>
24324
24385
  </doc:example>
24325
24386
  *
24326
24387
  */
@@ -24388,28 +24449,37 @@ var uppercaseFilter = valueFn(uppercase);
24388
24449
  <p>Output letters: {{ letters | limitTo:letterLimit }}</p>
24389
24450
  </div>
24390
24451
  </doc:source>
24391
- <doc:scenario>
24452
+ <doc:protractor>
24453
+ var numLimitInput = element(by.model('numLimit'));
24454
+ var letterLimitInput = element(by.model('letterLimit'));
24455
+ var limitedNumbers = element(by.binding('numbers | limitTo:numLimit'));
24456
+ var limitedLetters = element(by.binding('letters | limitTo:letterLimit'));
24457
+
24392
24458
  it('should limit the number array to first three items', function() {
24393
- expect(element('.doc-example-live input[ng-model=numLimit]').val()).toBe('3');
24394
- expect(element('.doc-example-live input[ng-model=letterLimit]').val()).toBe('3');
24395
- expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3]');
24396
- expect(binding('letters | limitTo:letterLimit')).toEqual('abc');
24459
+ expect(numLimitInput.getAttribute('value')).toBe('3');
24460
+ expect(letterLimitInput.getAttribute('value')).toBe('3');
24461
+ expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3]');
24462
+ expect(limitedLetters.getText()).toEqual('Output letters: abc');
24397
24463
  });
24398
24464
 
24399
24465
  it('should update the output when -3 is entered', function() {
24400
- input('numLimit').enter(-3);
24401
- input('letterLimit').enter(-3);
24402
- expect(binding('numbers | limitTo:numLimit')).toEqual('[7,8,9]');
24403
- expect(binding('letters | limitTo:letterLimit')).toEqual('ghi');
24466
+ numLimitInput.clear();
24467
+ numLimitInput.sendKeys('-3');
24468
+ letterLimitInput.clear();
24469
+ letterLimitInput.sendKeys('-3');
24470
+ expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]');
24471
+ expect(limitedLetters.getText()).toEqual('Output letters: ghi');
24404
24472
  });
24405
24473
 
24406
24474
  it('should not exceed the maximum size of input array', function() {
24407
- input('numLimit').enter(100);
24408
- input('letterLimit').enter(100);
24409
- expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3,4,5,6,7,8,9]');
24410
- expect(binding('letters | limitTo:letterLimit')).toEqual('abcdefghi');
24475
+ numLimitInput.clear();
24476
+ numLimitInput.sendKeys('100');
24477
+ letterLimitInput.clear();
24478
+ letterLimitInput.sendKeys('100');
24479
+ expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3,4,5,6,7,8,9]');
24480
+ expect(limitedLetters.getText()).toEqual('Output letters: abcdefghi');
24411
24481
  });
24412
- </doc:scenario>
24482
+ </doc:protractor>
24413
24483
  </doc:example>
24414
24484
  */
24415
24485
  function limitToFilter(){
@@ -24510,29 +24580,6 @@ function limitToFilter(){
24510
24580
  </table>
24511
24581
  </div>
24512
24582
  </doc:source>
24513
- <doc:scenario>
24514
- it('should be reverse ordered by aged', function() {
24515
- expect(binding('predicate')).toBe('-age');
24516
- expect(repeater('table.friend', 'friend in friends').column('friend.age')).
24517
- toEqual(['35', '29', '21', '19', '10']);
24518
- expect(repeater('table.friend', 'friend in friends').column('friend.name')).
24519
- toEqual(['Adam', 'Julie', 'Mike', 'Mary', 'John']);
24520
- });
24521
-
24522
- it('should reorder the table when user selects different predicate', function() {
24523
- element('.doc-example-live a:contains("Name")').click();
24524
- expect(repeater('table.friend', 'friend in friends').column('friend.name')).
24525
- toEqual(['Adam', 'John', 'Julie', 'Mary', 'Mike']);
24526
- expect(repeater('table.friend', 'friend in friends').column('friend.age')).
24527
- toEqual(['35', '10', '29', '19', '21']);
24528
-
24529
- element('.doc-example-live a:contains("Phone")').click();
24530
- expect(repeater('table.friend', 'friend in friends').column('friend.phone')).
24531
- toEqual(['555-9876', '555-8765', '555-5678', '555-4321', '555-1212']);
24532
- expect(repeater('table.friend', 'friend in friends').column('friend.name')).
24533
- toEqual(['Mary', 'Julie', 'Adam', 'Mike', 'John']);
24534
- });
24535
- </doc:scenario>
24536
24583
  </doc:example>
24537
24584
  */
24538
24585
  orderByFilter.$inject = ['$parse'];
@@ -24686,46 +24733,55 @@ var htmlAnchorDirective = valueFn({
24686
24733
  <a id="link-5" name="xxx" ng-click="value = 5">anchor</a> (no link)<br />
24687
24734
  <a id="link-6" ng-href="{{value}}">link</a> (link, change location)
24688
24735
  </doc:source>
24689
- <doc:scenario>
24736
+ <doc:protractor>
24690
24737
  it('should execute ng-click but not reload when href without value', function() {
24691
- element('#link-1').click();
24692
- expect(input('value').val()).toEqual('1');
24693
- expect(element('#link-1').attr('href')).toBe("");
24738
+ element(by.id('link-1')).click();
24739
+ expect(element(by.model('value')).getAttribute('value')).toEqual('1');
24740
+ expect(element(by.id('link-1')).getAttribute('href')).toBe('');
24694
24741
  });
24695
24742
 
24696
24743
  it('should execute ng-click but not reload when href empty string', function() {
24697
- element('#link-2').click();
24698
- expect(input('value').val()).toEqual('2');
24699
- expect(element('#link-2').attr('href')).toBe("");
24744
+ element(by.id('link-2')).click();
24745
+ expect(element(by.model('value')).getAttribute('value')).toEqual('2');
24746
+ expect(element(by.id('link-2')).getAttribute('href')).toBe('');
24700
24747
  });
24701
24748
 
24702
24749
  it('should execute ng-click and change url when ng-href specified', function() {
24703
- expect(element('#link-3').attr('href')).toBe("/123");
24750
+ expect(element(by.id('link-3')).getAttribute('href')).toMatch(/\/123$/);
24751
+
24752
+ element(by.id('link-3')).click();
24753
+
24754
+ // At this point, we navigate away from an Angular page, so we need
24755
+ // to use browser.driver to get the base webdriver.
24704
24756
 
24705
- element('#link-3').click();
24706
- expect(browser().window().path()).toEqual('/123');
24757
+ browser.wait(function() {
24758
+ return browser.driver.getCurrentUrl().then(function(url) {
24759
+ return url.match(/\/123$/);
24760
+ });
24761
+ }, 1000, 'page should navigate to /123');
24707
24762
  });
24708
24763
 
24709
24764
  it('should execute ng-click but not reload when href empty string and name specified', function() {
24710
- element('#link-4').click();
24711
- expect(input('value').val()).toEqual('4');
24712
- expect(element('#link-4').attr('href')).toBe('');
24765
+ element(by.id('link-4')).click();
24766
+ expect(element(by.model('value')).getAttribute('value')).toEqual('4');
24767
+ expect(element(by.id('link-4')).getAttribute('href')).toBe('');
24713
24768
  });
24714
24769
 
24715
24770
  it('should execute ng-click but not reload when no href but name specified', function() {
24716
- element('#link-5').click();
24717
- expect(input('value').val()).toEqual('5');
24718
- expect(element('#link-5').attr('href')).toBe(undefined);
24771
+ element(by.id('link-5')).click();
24772
+ expect(element(by.model('value')).getAttribute('value')).toEqual('5');
24773
+ expect(element(by.id('link-5')).getAttribute('href')).toBe(null);
24719
24774
  });
24720
24775
 
24721
24776
  it('should only change url when only ng-href', function() {
24722
- input('value').enter('6');
24723
- expect(element('#link-6').attr('href')).toBe('6');
24777
+ element(by.model('value')).clear();
24778
+ element(by.model('value')).sendKeys('6');
24779
+ expect(element(by.id('link-6')).getAttribute('href')).toMatch(/\/6$/);
24724
24780
 
24725
- element('#link-6').click();
24726
- expect(browser().location().url()).toEqual('/6');
24781
+ element(by.id('link-6')).click();
24782
+ expect(browser.getCurrentUrl()).toMatch(/\/6$/);
24727
24783
  });
24728
- </doc:scenario>
24784
+ </doc:protractor>
24729
24785
  </doc:example>
24730
24786
  */
24731
24787
 
@@ -24810,13 +24866,13 @@ var htmlAnchorDirective = valueFn({
24810
24866
  Click me to toggle: <input type="checkbox" ng-model="checked"><br/>
24811
24867
  <button ng-model="button" ng-disabled="checked">Button</button>
24812
24868
  </doc:source>
24813
- <doc:scenario>
24869
+ <doc:protractor>
24814
24870
  it('should toggle button', function() {
24815
- expect(element('.doc-example-live :button').prop('disabled')).toBeFalsy();
24816
- input('checked').check();
24817
- expect(element('.doc-example-live :button').prop('disabled')).toBeTruthy();
24871
+ expect(element(by.css('.doc-example-live button')).getAttribute('disabled')).toBeFalsy();
24872
+ element(by.model('checked')).click();
24873
+ expect(element(by.css('.doc-example-live button')).getAttribute('disabled')).toBeTruthy();
24818
24874
  });
24819
- </doc:scenario>
24875
+ </doc:protractor>
24820
24876
  </doc:example>
24821
24877
  *
24822
24878
  * @element INPUT
@@ -24845,13 +24901,13 @@ var htmlAnchorDirective = valueFn({
24845
24901
  Check me to check both: <input type="checkbox" ng-model="master"><br/>
24846
24902
  <input id="checkSlave" type="checkbox" ng-checked="master">
24847
24903
  </doc:source>
24848
- <doc:scenario>
24904
+ <doc:protractor>
24849
24905
  it('should check both checkBoxes', function() {
24850
- expect(element('.doc-example-live #checkSlave').prop('checked')).toBeFalsy();
24851
- input('master').check();
24852
- expect(element('.doc-example-live #checkSlave').prop('checked')).toBeTruthy();
24906
+ expect(element(by.id('checkSlave')).getAttribute('checked')).toBeFalsy();
24907
+ element(by.model('master')).click();
24908
+ expect(element(by.id('checkSlave')).getAttribute('checked')).toBeTruthy();
24853
24909
  });
24854
- </doc:scenario>
24910
+ </doc:protractor>
24855
24911
  </doc:example>
24856
24912
  *
24857
24913
  * @element INPUT
@@ -24880,13 +24936,13 @@ var htmlAnchorDirective = valueFn({
24880
24936
  Check me to make text readonly: <input type="checkbox" ng-model="checked"><br/>
24881
24937
  <input type="text" ng-readonly="checked" value="I'm Angular"/>
24882
24938
  </doc:source>
24883
- <doc:scenario>
24939
+ <doc:protractor>
24884
24940
  it('should toggle readonly attr', function() {
24885
- expect(element('.doc-example-live :text').prop('readonly')).toBeFalsy();
24886
- input('checked').check();
24887
- expect(element('.doc-example-live :text').prop('readonly')).toBeTruthy();
24941
+ expect(element(by.css('.doc-example-live [type="text"]')).getAttribute('readonly')).toBeFalsy();
24942
+ element(by.model('checked')).click();
24943
+ expect(element(by.css('.doc-example-live [type="text"]')).getAttribute('readonly')).toBeTruthy();
24888
24944
  });
24889
- </doc:scenario>
24945
+ </doc:protractor>
24890
24946
  </doc:example>
24891
24947
  *
24892
24948
  * @element INPUT
@@ -24919,13 +24975,13 @@ var htmlAnchorDirective = valueFn({
24919
24975
  <option id="greet" ng-selected="selected">Greetings!</option>
24920
24976
  </select>
24921
24977
  </doc:source>
24922
- <doc:scenario>
24978
+ <doc:protractor>
24923
24979
  it('should select Greetings!', function() {
24924
- expect(element('.doc-example-live #greet').prop('selected')).toBeFalsy();
24925
- input('selected').check();
24926
- expect(element('.doc-example-live #greet').prop('selected')).toBeTruthy();
24980
+ expect(element(by.id('greet')).getAttribute('selected')).toBeFalsy();
24981
+ element(by.model('selected')).click();
24982
+ expect(element(by.id('greet')).getAttribute('selected')).toBeTruthy();
24927
24983
  });
24928
- </doc:scenario>
24984
+ </doc:protractor>
24929
24985
  </doc:example>
24930
24986
  *
24931
24987
  * @element OPTION
@@ -24955,13 +25011,13 @@ var htmlAnchorDirective = valueFn({
24955
25011
  <summary>Show/Hide me</summary>
24956
25012
  </details>
24957
25013
  </doc:source>
24958
- <doc:scenario>
25014
+ <doc:protractor>
24959
25015
  it('should toggle open', function() {
24960
- expect(element('#details').prop('open')).toBeFalsy();
24961
- input('open').check();
24962
- expect(element('#details').prop('open')).toBeTruthy();
25016
+ expect(element(by.id('details')).getAttribute('open')).toBeFalsy();
25017
+ element(by.model('open')).click();
25018
+ expect(element(by.id('details')).getAttribute('open')).toBeTruthy();
24963
25019
  });
24964
- </doc:scenario>
25020
+ </doc:protractor>
24965
25021
  </doc:example>
24966
25022
  *
24967
25023
  * @element DETAILS
@@ -25320,18 +25376,27 @@ function FormController(element, attrs) {
25320
25376
  <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br>
25321
25377
  </form>
25322
25378
  </doc:source>
25323
- <doc:scenario>
25379
+ <doc:protractor>
25324
25380
  it('should initialize to model', function() {
25325
- expect(binding('userType')).toEqual('guest');
25326
- expect(binding('myForm.input.$valid')).toEqual('true');
25381
+ var userType = element(by.binding('userType'));
25382
+ var valid = element(by.binding('myForm.input.$valid'));
25383
+
25384
+ expect(userType.getText()).toContain('guest');
25385
+ expect(valid.getText()).toContain('true');
25327
25386
  });
25328
25387
 
25329
25388
  it('should be invalid if empty', function() {
25330
- input('userType').enter('');
25331
- expect(binding('userType')).toEqual('');
25332
- expect(binding('myForm.input.$valid')).toEqual('false');
25389
+ var userType = element(by.binding('userType'));
25390
+ var valid = element(by.binding('myForm.input.$valid'));
25391
+ var userInput = element(by.model('userType'));
25392
+
25393
+ userInput.clear();
25394
+ userInput.sendKeys('');
25395
+
25396
+ expect(userType.getText()).toEqual('userType =');
25397
+ expect(valid.getText()).toContain('false');
25333
25398
  });
25334
- </doc:scenario>
25399
+ </doc:protractor>
25335
25400
  </doc:example>
25336
25401
  */
25337
25402
  var formDirectiveFactory = function(isNgForm) {
@@ -25456,29 +25521,31 @@ var inputType = {
25456
25521
  <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
25457
25522
  </form>
25458
25523
  </doc:source>
25459
- <doc:scenario>
25524
+ <doc:protractor>
25525
+ var text = element(by.binding('text'));
25526
+ var valid = element(by.binding('myForm.input.$valid'));
25527
+ var input = element(by.model('text'));
25528
+
25460
25529
  it('should initialize to model', function() {
25461
- expect(binding('text')).toEqual('guest');
25462
- expect(binding('myForm.input.$valid')).toEqual('true');
25530
+ expect(text.getText()).toContain('guest');
25531
+ expect(valid.getText()).toContain('true');
25463
25532
  });
25464
25533
 
25465
25534
  it('should be invalid if empty', function() {
25466
- input('text').enter('');
25467
- expect(binding('text')).toEqual('');
25468
- expect(binding('myForm.input.$valid')).toEqual('false');
25535
+ input.clear();
25536
+ input.sendKeys('');
25537
+
25538
+ expect(text.getText()).toEqual('text =');
25539
+ expect(valid.getText()).toContain('false');
25469
25540
  });
25470
25541
 
25471
25542
  it('should be invalid if multi word', function() {
25472
- input('text').enter('hello world');
25473
- expect(binding('myForm.input.$valid')).toEqual('false');
25474
- });
25543
+ input.clear();
25544
+ input.sendKeys('hello world');
25475
25545
 
25476
- it('should not be trimmed', function() {
25477
- input('text').enter('untrimmed ');
25478
- expect(binding('text')).toEqual('untrimmed ');
25479
- expect(binding('myForm.input.$valid')).toEqual('true');
25546
+ expect(valid.getText()).toContain('false');
25480
25547
  });
25481
- </doc:scenario>
25548
+ </doc:protractor>
25482
25549
  </doc:example>
25483
25550
  */
25484
25551
  'text': textInputType,
@@ -25532,24 +25599,30 @@ var inputType = {
25532
25599
  <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
25533
25600
  </form>
25534
25601
  </doc:source>
25535
- <doc:scenario>
25602
+ <doc:protractor>
25603
+ var value = element(by.binding('value'));
25604
+ var valid = element(by.binding('myForm.input.$valid'));
25605
+ var input = element(by.model('value'));
25606
+
25536
25607
  it('should initialize to model', function() {
25537
- expect(binding('value')).toEqual('12');
25538
- expect(binding('myForm.input.$valid')).toEqual('true');
25608
+ expect(value.getText()).toContain('12');
25609
+ expect(valid.getText()).toContain('true');
25539
25610
  });
25540
25611
 
25541
25612
  it('should be invalid if empty', function() {
25542
- input('value').enter('');
25543
- expect(binding('value')).toEqual('');
25544
- expect(binding('myForm.input.$valid')).toEqual('false');
25613
+ input.clear();
25614
+ input.sendKeys('');
25615
+ expect(value.getText()).toEqual('value =');
25616
+ expect(valid.getText()).toContain('false');
25545
25617
  });
25546
25618
 
25547
25619
  it('should be invalid if over max', function() {
25548
- input('value').enter('123');
25549
- expect(binding('value')).toEqual('');
25550
- expect(binding('myForm.input.$valid')).toEqual('false');
25620
+ input.clear();
25621
+ input.sendKeys('123');
25622
+ expect(value.getText()).toEqual('value =');
25623
+ expect(valid.getText()).toContain('false');
25551
25624
  });
25552
- </doc:scenario>
25625
+ </doc:protractor>
25553
25626
  </doc:example>
25554
25627
  */
25555
25628
  'number': numberInputType,
@@ -25601,23 +25674,31 @@ var inputType = {
25601
25674
  <tt>myForm.$error.url = {{!!myForm.$error.url}}</tt><br/>
25602
25675
  </form>
25603
25676
  </doc:source>
25604
- <doc:scenario>
25677
+ <doc:protractor>
25678
+ var text = element(by.binding('text'));
25679
+ var valid = element(by.binding('myForm.input.$valid'));
25680
+ var input = element(by.model('text'));
25681
+
25605
25682
  it('should initialize to model', function() {
25606
- expect(binding('text')).toEqual('http://google.com');
25607
- expect(binding('myForm.input.$valid')).toEqual('true');
25683
+ expect(text.getText()).toContain('http://google.com');
25684
+ expect(valid.getText()).toContain('true');
25608
25685
  });
25609
25686
 
25610
25687
  it('should be invalid if empty', function() {
25611
- input('text').enter('');
25612
- expect(binding('text')).toEqual('');
25613
- expect(binding('myForm.input.$valid')).toEqual('false');
25688
+ input.clear();
25689
+ input.sendKeys('');
25690
+
25691
+ expect(text.getText()).toEqual('text =');
25692
+ expect(valid.getText()).toContain('false');
25614
25693
  });
25615
25694
 
25616
25695
  it('should be invalid if not url', function() {
25617
- input('text').enter('xxx');
25618
- expect(binding('myForm.input.$valid')).toEqual('false');
25696
+ input.clear();
25697
+ input.sendKeys('box');
25698
+
25699
+ expect(valid.getText()).toContain('false');
25619
25700
  });
25620
- </doc:scenario>
25701
+ </doc:protractor>
25621
25702
  </doc:example>
25622
25703
  */
25623
25704
  'url': urlInputType,
@@ -25669,23 +25750,30 @@ var inputType = {
25669
25750
  <tt>myForm.$error.email = {{!!myForm.$error.email}}</tt><br/>
25670
25751
  </form>
25671
25752
  </doc:source>
25672
- <doc:scenario>
25753
+ <doc:protractor>
25754
+ var text = element(by.binding('text'));
25755
+ var valid = element(by.binding('myForm.input.$valid'));
25756
+ var input = element(by.model('text'));
25757
+
25673
25758
  it('should initialize to model', function() {
25674
- expect(binding('text')).toEqual('me@example.com');
25675
- expect(binding('myForm.input.$valid')).toEqual('true');
25759
+ expect(text.getText()).toContain('me@example.com');
25760
+ expect(valid.getText()).toContain('true');
25676
25761
  });
25677
25762
 
25678
25763
  it('should be invalid if empty', function() {
25679
- input('text').enter('');
25680
- expect(binding('text')).toEqual('');
25681
- expect(binding('myForm.input.$valid')).toEqual('false');
25764
+ input.clear();
25765
+ input.sendKeys('');
25766
+ expect(text.getText()).toEqual('text =');
25767
+ expect(valid.getText()).toContain('false');
25682
25768
  });
25683
25769
 
25684
25770
  it('should be invalid if not email', function() {
25685
- input('text').enter('xxx');
25686
- expect(binding('myForm.input.$valid')).toEqual('false');
25771
+ input.clear();
25772
+ input.sendKeys('xxx');
25773
+
25774
+ expect(valid.getText()).toContain('false');
25687
25775
  });
25688
- </doc:scenario>
25776
+ </doc:protractor>
25689
25777
  </doc:example>
25690
25778
  */
25691
25779
  'email': emailInputType,
@@ -25726,14 +25814,17 @@ var inputType = {
25726
25814
  </form>
25727
25815
  Note that `ng-value="specialValue"` sets radio item's value to be the value of `$scope.specialValue`.
25728
25816
  </doc:source>
25729
- <doc:scenario>
25817
+ <doc:protractor>
25730
25818
  it('should change state', function() {
25731
- expect(binding('color')).toEqual('"blue"');
25819
+ var color = element(by.binding('color'));
25820
+
25821
+ expect(color.getText()).toContain('blue');
25732
25822
 
25733
- input('color').select('red');
25734
- expect(binding('color')).toEqual('"red"');
25823
+ element.all(by.model('color')).get(0).click();
25824
+
25825
+ expect(color.getText()).toContain('red');
25735
25826
  });
25736
- </doc:scenario>
25827
+ </doc:protractor>
25737
25828
  </doc:example>
25738
25829
  */
25739
25830
  'radio': radioInputType,
@@ -25770,17 +25861,21 @@ var inputType = {
25770
25861
  <tt>value2 = {{value2}}</tt><br/>
25771
25862
  </form>
25772
25863
  </doc:source>
25773
- <doc:scenario>
25864
+ <doc:protractor>
25774
25865
  it('should change state', function() {
25775
- expect(binding('value1')).toEqual('true');
25776
- expect(binding('value2')).toEqual('YES');
25866
+ var value1 = element(by.binding('value1'));
25867
+ var value2 = element(by.binding('value2'));
25868
+
25869
+ expect(value1.getText()).toContain('true');
25870
+ expect(value2.getText()).toContain('YES');
25871
+
25872
+ element(by.model('value1')).click();
25873
+ element(by.model('value2')).click();
25777
25874
 
25778
- input('value1').check();
25779
- input('value2').check();
25780
- expect(binding('value1')).toEqual('false');
25781
- expect(binding('value2')).toEqual('NO');
25875
+ expect(value1.getText()).toContain('false');
25876
+ expect(value2.getText()).toContain('NO');
25782
25877
  });
25783
- </doc:scenario>
25878
+ </doc:protractor>
25784
25879
  </doc:example>
25785
25880
  */
25786
25881
  'checkbox': checkboxInputType,
@@ -26133,44 +26228,59 @@ function checkboxInputType(scope, element, attr, ctrl) {
26133
26228
  <tt>myForm.$error.maxlength = {{!!myForm.$error.maxlength}}</tt><br>
26134
26229
  </div>
26135
26230
  </doc:source>
26136
- <doc:scenario>
26231
+ <doc:protractor>
26232
+ var user = element(by.binding('{{user}}'));
26233
+ var userNameValid = element(by.binding('myForm.userName.$valid'));
26234
+ var lastNameValid = element(by.binding('myForm.lastName.$valid'));
26235
+ var lastNameError = element(by.binding('myForm.lastName.$error'));
26236
+ var formValid = element(by.binding('myForm.$valid'));
26237
+ var userNameInput = element(by.model('user.name'));
26238
+ var userLastInput = element(by.model('user.last'));
26239
+
26137
26240
  it('should initialize to model', function() {
26138
- expect(binding('user')).toEqual('{"name":"guest","last":"visitor"}');
26139
- expect(binding('myForm.userName.$valid')).toEqual('true');
26140
- expect(binding('myForm.$valid')).toEqual('true');
26241
+ expect(user.getText()).toContain('{"name":"guest","last":"visitor"}');
26242
+ expect(userNameValid.getText()).toContain('true');
26243
+ expect(formValid.getText()).toContain('true');
26141
26244
  });
26142
26245
 
26143
26246
  it('should be invalid if empty when required', function() {
26144
- input('user.name').enter('');
26145
- expect(binding('user')).toEqual('{"last":"visitor"}');
26146
- expect(binding('myForm.userName.$valid')).toEqual('false');
26147
- expect(binding('myForm.$valid')).toEqual('false');
26247
+ userNameInput.clear();
26248
+ userNameInput.sendKeys('');
26249
+
26250
+ expect(user.getText()).toContain('{"last":"visitor"}');
26251
+ expect(userNameValid.getText()).toContain('false');
26252
+ expect(formValid.getText()).toContain('false');
26148
26253
  });
26149
26254
 
26150
26255
  it('should be valid if empty when min length is set', function() {
26151
- input('user.last').enter('');
26152
- expect(binding('user')).toEqual('{"name":"guest","last":""}');
26153
- expect(binding('myForm.lastName.$valid')).toEqual('true');
26154
- expect(binding('myForm.$valid')).toEqual('true');
26256
+ userLastInput.clear();
26257
+ userLastInput.sendKeys('');
26258
+
26259
+ expect(user.getText()).toContain('{"name":"guest","last":""}');
26260
+ expect(lastNameValid.getText()).toContain('true');
26261
+ expect(formValid.getText()).toContain('true');
26155
26262
  });
26156
26263
 
26157
26264
  it('should be invalid if less than required min length', function() {
26158
- input('user.last').enter('xx');
26159
- expect(binding('user')).toEqual('{"name":"guest"}');
26160
- expect(binding('myForm.lastName.$valid')).toEqual('false');
26161
- expect(binding('myForm.lastName.$error')).toMatch(/minlength/);
26162
- expect(binding('myForm.$valid')).toEqual('false');
26265
+ userLastInput.clear();
26266
+ userLastInput.sendKeys('xx');
26267
+
26268
+ expect(user.getText()).toContain('{"name":"guest"}');
26269
+ expect(lastNameValid.getText()).toContain('false');
26270
+ expect(lastNameError.getText()).toContain('minlength');
26271
+ expect(formValid.getText()).toContain('false');
26163
26272
  });
26164
26273
 
26165
26274
  it('should be invalid if longer than max length', function() {
26166
- input('user.last').enter('some ridiculously long name');
26167
- expect(binding('user'))
26168
- .toEqual('{"name":"guest"}');
26169
- expect(binding('myForm.lastName.$valid')).toEqual('false');
26170
- expect(binding('myForm.lastName.$error')).toMatch(/maxlength/);
26171
- expect(binding('myForm.$valid')).toEqual('false');
26275
+ userLastInput.clear();
26276
+ userLastInput.sendKeys('some ridiculously long name');
26277
+
26278
+ expect(user.getText()).toContain('{"name":"guest"}');
26279
+ expect(lastNameValid.getText()).toContain('false');
26280
+ expect(lastNameError.getText()).toContain('maxlength');
26281
+ expect(formValid.getText()).toContain('false');
26172
26282
  });
26173
- </doc:scenario>
26283
+ </doc:protractor>
26174
26284
  </doc:example>
26175
26285
  */
26176
26286
  var inputDirective = ['$browser', '$sniffer', function($browser, $sniffer) {
@@ -26302,14 +26412,23 @@ var VALID_CLASS = 'ng-valid',
26302
26412
  <textarea ng-model="userContent"></textarea>
26303
26413
  </form>
26304
26414
  </file>
26305
- <file name="scenario.js">
26415
+ <file name="protractorTest.js">
26306
26416
  it('should data-bind and become invalid', function() {
26307
- var contentEditable = element('[contenteditable]');
26417
+ if (browser.params.browser = 'safari') {
26418
+ // SafariDriver can't handle contenteditable.
26419
+ return;
26420
+ };
26421
+ var contentEditable = element(by.css('.doc-example-live [contenteditable]'));
26308
26422
 
26309
- expect(contentEditable.text()).toEqual('Change me!');
26310
- input('userContent').enter('');
26311
- expect(contentEditable.text()).toEqual('');
26312
- expect(contentEditable.prop('className')).toMatch(/ng-invalid-required/);
26423
+ expect(contentEditable.getText()).toEqual('Change me!');
26424
+
26425
+ // Firefox driver doesn't trigger the proper events on 'clear', so do this hack
26426
+ contentEditable.click();
26427
+ contentEditable.sendKeys(protractor.Key.chord(protractor.Key.COMMAND, "a"));
26428
+ contentEditable.sendKeys(protractor.Key.BACK_SPACE);
26429
+
26430
+ expect(contentEditable.getText()).toEqual('');
26431
+ expect(contentEditable.getAttribute('class')).toMatch(/ng-invalid-required/);
26313
26432
  });
26314
26433
  </file>
26315
26434
  * </example>
@@ -26616,24 +26735,30 @@ var ngModelDirective = function() {
26616
26735
  * <input type="checkbox" ng-model="confirmed" ng-change="change()" id="ng-change-example1" />
26617
26736
  * <input type="checkbox" ng-model="confirmed" id="ng-change-example2" />
26618
26737
  * <label for="ng-change-example2">Confirmed</label><br />
26619
- * debug = {{confirmed}}<br />
26620
- * counter = {{counter}}
26738
+ * <tt>debug = {{confirmed}}</tt><br/>
26739
+ * <tt>counter = {{counter}}</tt><br/>
26621
26740
  * </div>
26622
26741
  * </doc:source>
26623
- * <doc:scenario>
26742
+ * <doc:protractor>
26743
+ * var counter = element(by.binding('counter'));
26744
+ * var debug = element(by.binding('confirmed'));
26745
+ *
26624
26746
  * it('should evaluate the expression if changing from view', function() {
26625
- * expect(binding('counter')).toEqual('0');
26626
- * element('#ng-change-example1').click();
26627
- * expect(binding('counter')).toEqual('1');
26628
- * expect(binding('confirmed')).toEqual('true');
26747
+ * expect(counter.getText()).toContain('0');
26748
+ *
26749
+ * element(by.id('ng-change-example1')).click();
26750
+ *
26751
+ * expect(counter.getText()).toContain('1');
26752
+ * expect(debug.getText()).toContain('true');
26629
26753
  * });
26630
26754
  *
26631
26755
  * it('should not evaluate the expression if changing from model', function() {
26632
- * element('#ng-change-example2').click();
26633
- * expect(binding('counter')).toEqual('0');
26634
- * expect(binding('confirmed')).toEqual('true');
26756
+ * element(by.id('ng-change-example2')).click();
26757
+
26758
+ * expect(counter.getText()).toContain('0');
26759
+ * expect(debug.getText()).toContain('true');
26635
26760
  * });
26636
- * </doc:scenario>
26761
+ * </doc:protractor>
26637
26762
  * </doc:example>
26638
26763
  */
26639
26764
  var ngChangeDirective = valueFn({
@@ -26706,20 +26831,26 @@ var requiredDirective = function() {
26706
26831
  <tt>myForm.$error.required = {{!!myForm.$error.required}}</tt><br/>
26707
26832
  </form>
26708
26833
  </doc:source>
26709
- <doc:scenario>
26834
+ <doc:protractor>
26835
+ var listInput = element(by.model('names'));
26836
+ var names = element(by.binding('{{names}}'));
26837
+ var valid = element(by.binding('myForm.namesInput.$valid'));
26838
+ var error = element(by.css('span.error'));
26839
+
26710
26840
  it('should initialize to model', function() {
26711
- expect(binding('names')).toEqual('["igor","misko","vojta"]');
26712
- expect(binding('myForm.namesInput.$valid')).toEqual('true');
26713
- expect(element('span.error').css('display')).toBe('none');
26841
+ expect(names.getText()).toContain('["igor","misko","vojta"]');
26842
+ expect(valid.getText()).toContain('true');
26843
+ expect(error.getCssValue('display')).toBe('none');
26714
26844
  });
26715
26845
 
26716
26846
  it('should be invalid if empty', function() {
26717
- input('names').enter('');
26718
- expect(binding('names')).toEqual('');
26719
- expect(binding('myForm.namesInput.$valid')).toEqual('false');
26720
- expect(element('span.error').css('display')).not().toBe('none');
26721
- });
26722
- </doc:scenario>
26847
+ listInput.clear();
26848
+ listInput.sendKeys('');
26849
+
26850
+ expect(names.getText()).toContain('');
26851
+ expect(valid.getText()).toContain('false');
26852
+ expect(error.getCssValue('display')).not.toBe('none'); });
26853
+ </doc:protractor>
26723
26854
  </doc:example>
26724
26855
  */
26725
26856
  var ngListDirective = function() {
@@ -26801,15 +26932,17 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
26801
26932
  <div>You chose {{my.favorite}}</div>
26802
26933
  </form>
26803
26934
  </doc:source>
26804
- <doc:scenario>
26935
+ <doc:protractor>
26936
+ var favorite = element(by.binding('my.favorite'));
26937
+
26805
26938
  it('should initialize to model', function() {
26806
- expect(binding('my.favorite')).toEqual('unicorns');
26939
+ expect(favorite.getText()).toContain('unicorns');
26807
26940
  });
26808
26941
  it('should bind the values to the inputs', function() {
26809
- input('my.favorite').select('pizza');
26810
- expect(binding('my.favorite')).toEqual('pizza');
26942
+ element.all(by.model('my.favorite')).get(0).click();
26943
+ expect(favorite.getText()).toContain('pizza');
26811
26944
  });
26812
- </doc:scenario>
26945
+ </doc:protractor>
26813
26946
  </doc:example>
26814
26947
  */
26815
26948
  var ngValueDirective = function() {
@@ -26869,13 +27002,17 @@ var ngValueDirective = function() {
26869
27002
  Hello <span ng-bind="name"></span>!
26870
27003
  </div>
26871
27004
  </doc:source>
26872
- <doc:scenario>
27005
+ <doc:protractor>
26873
27006
  it('should check ng-bind', function() {
26874
- expect(using('.doc-example-live').binding('name')).toBe('Whirled');
26875
- using('.doc-example-live').input('name').enter('world');
26876
- expect(using('.doc-example-live').binding('name')).toBe('world');
27007
+ var exampleContainer = $('.doc-example-live');
27008
+ var nameInput = element(by.model('name'));
27009
+
27010
+ expect(exampleContainer.findElement(by.binding('name')).getText()).toBe('Whirled');
27011
+ nameInput.clear();
27012
+ nameInput.sendKeys('world');
27013
+ expect(exampleContainer.findElement(by.binding('name')).getText()).toBe('world');
26877
27014
  });
26878
- </doc:scenario>
27015
+ </doc:protractor>
26879
27016
  </doc:example>
26880
27017
  */
26881
27018
  var ngBindDirective = ngDirective(function(scope, element, attr) {
@@ -26921,20 +27058,22 @@ var ngBindDirective = ngDirective(function(scope, element, attr) {
26921
27058
  <pre ng-bind-template="{{salutation}} {{name}}!"></pre>
26922
27059
  </div>
26923
27060
  </doc:source>
26924
- <doc:scenario>
27061
+ <doc:protractor>
26925
27062
  it('should check ng-bind', function() {
26926
- expect(using('.doc-example-live').binding('salutation')).
26927
- toBe('Hello');
26928
- expect(using('.doc-example-live').binding('name')).
26929
- toBe('World');
26930
- using('.doc-example-live').input('salutation').enter('Greetings');
26931
- using('.doc-example-live').input('name').enter('user');
26932
- expect(using('.doc-example-live').binding('salutation')).
26933
- toBe('Greetings');
26934
- expect(using('.doc-example-live').binding('name')).
26935
- toBe('user');
27063
+ var salutationElem = element(by.binding('salutation'));
27064
+ var salutationInput = element(by.model('salutation'));
27065
+ var nameInput = element(by.model('name'));
27066
+
27067
+ expect(salutationElem.getText()).toBe('Hello World!');
27068
+
27069
+ salutationInput.clear();
27070
+ salutationInput.sendKeys('Greetings');
27071
+ nameInput.clear();
27072
+ nameInput.sendKeys('user');
27073
+
27074
+ expect(salutationElem.getText()).toBe('Greetings user!');
26936
27075
  });
26937
- </doc:scenario>
27076
+ </doc:protractor>
26938
27077
  </doc:example>
26939
27078
  */
26940
27079
  var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
@@ -26987,12 +27126,10 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
26987
27126
  }]);
26988
27127
  </file>
26989
27128
 
26990
- <file name="scenario.js">
27129
+ <file name="protractorTest.js">
26991
27130
  it('should check ng-bind-html', function() {
26992
- expect(using('.doc-example-live').binding('myHTML')).
26993
- toBe(
26994
- 'I am an <code>HTML</code>string with <a href="#">links!</a> and other <em>stuff</em>'
26995
- );
27131
+ expect(element(by.binding('myHTML')).getText()).toBe(
27132
+ 'I am an HTMLstring with links! and other stuff');
26996
27133
  });
26997
27134
  </file>
26998
27135
  </example>
@@ -27124,31 +27261,34 @@ function classDirective(name, selector) {
27124
27261
  color: red;
27125
27262
  }
27126
27263
  </file>
27127
- <file name="scenario.js">
27264
+ <file name="protractorTest.js">
27265
+ var ps = element.all(by.css('.doc-example-live p'));
27266
+
27128
27267
  it('should let you toggle the class', function() {
27129
27268
 
27130
- expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/bold/);
27131
- expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/red/);
27269
+ expect(ps.first().getAttribute('class')).not.toMatch(/bold/);
27270
+ expect(ps.first().getAttribute('class')).not.toMatch(/red/);
27132
27271
 
27133
- input('important').check();
27134
- expect(element('.doc-example-live p:first').prop('className')).toMatch(/bold/);
27272
+ element(by.model('important')).click();
27273
+ expect(ps.first().getAttribute('class')).toMatch(/bold/);
27135
27274
 
27136
- input('error').check();
27137
- expect(element('.doc-example-live p:first').prop('className')).toMatch(/red/);
27275
+ element(by.model('error')).click();
27276
+ expect(ps.first().getAttribute('class')).toMatch(/red/);
27138
27277
  });
27139
27278
 
27140
27279
  it('should let you toggle string example', function() {
27141
- expect(element('.doc-example-live p:nth-of-type(2)').prop('className')).toBe('');
27142
- input('style').enter('red');
27143
- expect(element('.doc-example-live p:nth-of-type(2)').prop('className')).toBe('red');
27280
+ expect(ps.get(1).getAttribute('class')).toBe('');
27281
+ element(by.model('style')).clear();
27282
+ element(by.model('style')).sendKeys('red');
27283
+ expect(ps.get(1).getAttribute('class')).toBe('red');
27144
27284
  });
27145
27285
 
27146
27286
  it('array example should have 3 classes', function() {
27147
- expect(element('.doc-example-live p:last').prop('className')).toBe('');
27148
- input('style1').enter('bold');
27149
- input('style2').enter('strike');
27150
- input('style3').enter('red');
27151
- expect(element('.doc-example-live p:last').prop('className')).toBe('bold strike red');
27287
+ expect(ps.last().getAttribute('class')).toBe('');
27288
+ element(by.model('style1')).sendKeys('bold');
27289
+ element(by.model('style2')).sendKeys('strike');
27290
+ element(by.model('style3')).sendKeys('red');
27291
+ expect(ps.last().getAttribute('class')).toBe('bold strike red');
27152
27292
  });
27153
27293
  </file>
27154
27294
  </example>
@@ -27159,8 +27299,8 @@ function classDirective(name, selector) {
27159
27299
 
27160
27300
  <example animations="true">
27161
27301
  <file name="index.html">
27162
- <input type="button" value="set" ng-click="myVar='my-class'">
27163
- <input type="button" value="clear" ng-click="myVar=''">
27302
+ <input id="setbtn" type="button" value="set" ng-click="myVar='my-class'">
27303
+ <input id="clearbtn" type="button" value="clear" ng-click="myVar=''">
27164
27304
  <br>
27165
27305
  <span class="base-class" ng-class="myVar">Sample Text</span>
27166
27306
  </file>
@@ -27175,19 +27315,19 @@ function classDirective(name, selector) {
27175
27315
  font-size:3em;
27176
27316
  }
27177
27317
  </file>
27178
- <file name="scenario.js">
27318
+ <file name="protractorTest.js">
27179
27319
  it('should check ng-class', function() {
27180
- expect(element('.doc-example-live span').prop('className')).not().
27320
+ expect(element(by.css('.base-class')).getAttribute('class')).not.
27181
27321
  toMatch(/my-class/);
27182
27322
 
27183
- using('.doc-example-live').element(':button:first').click();
27323
+ element(by.id('setbtn')).click();
27184
27324
 
27185
- expect(element('.doc-example-live span').prop('className')).
27325
+ expect(element(by.css('.base-class')).getAttribute('class')).
27186
27326
  toMatch(/my-class/);
27187
27327
 
27188
- using('.doc-example-live').element(':button:last').click();
27328
+ element(by.id('clearbtn')).click();
27189
27329
 
27190
- expect(element('.doc-example-live span').prop('className')).not().
27330
+ expect(element(by.css('.base-class')).getAttribute('class')).not.
27191
27331
  toMatch(/my-class/);
27192
27332
  });
27193
27333
  </file>
@@ -27239,11 +27379,11 @@ var ngClassDirective = classDirective('', true);
27239
27379
  color: blue;
27240
27380
  }
27241
27381
  </file>
27242
- <file name="scenario.js">
27382
+ <file name="protractorTest.js">
27243
27383
  it('should check ng-class-odd and ng-class-even', function() {
27244
- expect(element('.doc-example-live li:first span').prop('className')).
27384
+ expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
27245
27385
  toMatch(/odd/);
27246
- expect(element('.doc-example-live li:last span').prop('className')).
27386
+ expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
27247
27387
  toMatch(/even/);
27248
27388
  });
27249
27389
  </file>
@@ -27287,11 +27427,11 @@ var ngClassOddDirective = classDirective('Odd', 0);
27287
27427
  color: blue;
27288
27428
  }
27289
27429
  </file>
27290
- <file name="scenario.js">
27430
+ <file name="protractorTest.js">
27291
27431
  it('should check ng-class-odd and ng-class-even', function() {
27292
- expect(element('.doc-example-live li:first span').prop('className')).
27432
+ expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
27293
27433
  toMatch(/odd/);
27294
- expect(element('.doc-example-live li:last span').prop('className')).
27434
+ expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
27295
27435
  toMatch(/even/);
27296
27436
  });
27297
27437
  </file>
@@ -27344,14 +27484,14 @@ var ngClassEvenDirective = classDirective('Even', 1);
27344
27484
  <div id="template1" ng-cloak>{{ 'hello' }}</div>
27345
27485
  <div id="template2" ng-cloak class="ng-cloak">{{ 'hello IE7' }}</div>
27346
27486
  </doc:source>
27347
- <doc:scenario>
27487
+ <doc:protractor>
27348
27488
  it('should remove the template directive and css class', function() {
27349
- expect(element('.doc-example-live #template1').attr('ng-cloak')).
27350
- not().toBeDefined();
27351
- expect(element('.doc-example-live #template2').attr('ng-cloak')).
27352
- not().toBeDefined();
27489
+ expect($('.doc-example-live #template1').getAttribute('ng-cloak')).
27490
+ toBeNull();
27491
+ expect($('.doc-example-live #template2').getAttribute('ng-cloak')).
27492
+ toBeNull();
27353
27493
  });
27354
- </doc:scenario>
27494
+ </doc:protractor>
27355
27495
  </doc:example>
27356
27496
  *
27357
27497
  */
@@ -27444,22 +27584,36 @@ var ngCloakDirective = ngDirective({
27444
27584
  </ul>
27445
27585
  </div>
27446
27586
  </doc:source>
27447
- <doc:scenario>
27587
+ <doc:protractor>
27448
27588
  it('should check controller as', function() {
27449
- expect(element('#ctrl-as-exmpl>:input').val()).toBe('John Smith');
27450
- expect(element('#ctrl-as-exmpl li:nth-child(1) input').val())
27451
- .toBe('408 555 1212');
27452
- expect(element('#ctrl-as-exmpl li:nth-child(2) input').val())
27453
- .toBe('john.smith@example.org');
27454
-
27455
- element('#ctrl-as-exmpl li:first a:contains("clear")').click();
27456
- expect(element('#ctrl-as-exmpl li:first input').val()).toBe('');
27457
-
27458
- element('#ctrl-as-exmpl li:last a:contains("add")').click();
27459
- expect(element('#ctrl-as-exmpl li:nth-child(3) input').val())
27460
- .toBe('yourname@example.org');
27589
+ var container = element(by.id('ctrl-as-exmpl'));
27590
+
27591
+ expect(container.findElement(by.model('settings.name'))
27592
+ .getAttribute('value')).toBe('John Smith');
27593
+
27594
+ var firstRepeat =
27595
+ container.findElement(by.repeater('contact in settings.contacts').row(0));
27596
+ var secondRepeat =
27597
+ container.findElement(by.repeater('contact in settings.contacts').row(1));
27598
+
27599
+ expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
27600
+ .toBe('408 555 1212');
27601
+ expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value'))
27602
+ .toBe('john.smith@example.org');
27603
+
27604
+ firstRepeat.findElement(by.linkText('clear')).click()
27605
+
27606
+ expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
27607
+ .toBe('');
27608
+
27609
+ container.findElement(by.linkText('add')).click();
27610
+
27611
+ expect(container.findElement(by.repeater('contact in settings.contacts').row(2))
27612
+ .findElement(by.model('contact.value'))
27613
+ .getAttribute('value'))
27614
+ .toBe('yourname@example.org');
27461
27615
  });
27462
- </doc:scenario>
27616
+ </doc:protractor>
27463
27617
  </doc:example>
27464
27618
  <doc:example>
27465
27619
  <doc:source>
@@ -27507,22 +27661,36 @@ var ngCloakDirective = ngDirective({
27507
27661
  </ul>
27508
27662
  </div>
27509
27663
  </doc:source>
27510
- <doc:scenario>
27664
+ <doc:protractor>
27511
27665
  it('should check controller', function() {
27512
- expect(element('#ctrl-exmpl>:input').val()).toBe('John Smith');
27513
- expect(element('#ctrl-exmpl li:nth-child(1) input').val())
27514
- .toBe('408 555 1212');
27515
- expect(element('#ctrl-exmpl li:nth-child(2) input').val())
27516
- .toBe('john.smith@example.org');
27517
-
27518
- element('#ctrl-exmpl li:first a:contains("clear")').click();
27519
- expect(element('#ctrl-exmpl li:first input').val()).toBe('');
27520
-
27521
- element('#ctrl-exmpl li:last a:contains("add")').click();
27522
- expect(element('#ctrl-exmpl li:nth-child(3) input').val())
27523
- .toBe('yourname@example.org');
27666
+ var container = element(by.id('ctrl-exmpl'));
27667
+
27668
+ expect(container.findElement(by.model('name'))
27669
+ .getAttribute('value')).toBe('John Smith');
27670
+
27671
+ var firstRepeat =
27672
+ container.findElement(by.repeater('contact in contacts').row(0));
27673
+ var secondRepeat =
27674
+ container.findElement(by.repeater('contact in contacts').row(1));
27675
+
27676
+ expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
27677
+ .toBe('408 555 1212');
27678
+ expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value'))
27679
+ .toBe('john.smith@example.org');
27680
+
27681
+ firstRepeat.findElement(by.linkText('clear')).click()
27682
+
27683
+ expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value'))
27684
+ .toBe('');
27685
+
27686
+ container.findElement(by.linkText('add')).click();
27687
+
27688
+ expect(container.findElement(by.repeater('contact in contacts').row(2))
27689
+ .findElement(by.model('contact.value'))
27690
+ .getAttribute('value'))
27691
+ .toBe('yourname@example.org');
27524
27692
  });
27525
- </doc:scenario>
27693
+ </doc:protractor>
27526
27694
  </doc:example>
27527
27695
 
27528
27696
  */
@@ -27903,20 +28071,20 @@ forEach(
27903
28071
  <pre>list={{list}}</pre>
27904
28072
  </form>
27905
28073
  </doc:source>
27906
- <doc:scenario>
28074
+ <doc:protractor>
27907
28075
  it('should check ng-submit', function() {
27908
- expect(binding('list')).toBe('[]');
27909
- element('.doc-example-live #submit').click();
27910
- expect(binding('list')).toBe('["hello"]');
27911
- expect(input('text').val()).toBe('');
28076
+ expect(element(by.binding('list')).getText()).toBe('list=[]');
28077
+ element(by.css('.doc-example-live #submit')).click();
28078
+ expect(element(by.binding('list')).getText()).toContain('hello');
28079
+ expect(element(by.input('text')).getAttribute('value')).toBe('');
27912
28080
  });
27913
28081
  it('should ignore empty strings', function() {
27914
- expect(binding('list')).toBe('[]');
27915
- element('.doc-example-live #submit').click();
27916
- element('.doc-example-live #submit').click();
27917
- expect(binding('list')).toBe('["hello"]');
27918
- });
27919
- </doc:scenario>
28082
+ expect(element(by.binding('list')).getText()).toBe('list=[]');
28083
+ element(by.css('.doc-example-live #submit')).click();
28084
+ element(by.css('.doc-example-live #submit')).click();
28085
+ expect(element(by.binding('list')).getText()).toContain('hello');
28086
+ });
28087
+ </doc:protractor>
27920
28088
  </doc:example>
27921
28089
  */
27922
28090
 
@@ -28243,19 +28411,33 @@ var ngIfDirective = ['$animate', function($animate) {
28243
28411
  top:50px;
28244
28412
  }
28245
28413
  </file>
28246
- <file name="scenario.js">
28414
+ <file name="protractorTest.js">
28415
+ var templateSelect = element(by.model('template'));
28416
+ var includeElem = element(by.css('.doc-example-live [ng-include]'));
28417
+
28247
28418
  it('should load template1.html', function() {
28248
- expect(element('.doc-example-live [ng-include]').text()).
28249
- toMatch(/Content of template1.html/);
28419
+ expect(includeElem.getText()).toMatch(/Content of template1.html/);
28250
28420
  });
28421
+
28251
28422
  it('should load template2.html', function() {
28252
- select('template').option('1');
28253
- expect(element('.doc-example-live [ng-include]').text()).
28254
- toMatch(/Content of template2.html/);
28423
+ if (browser.params.browser == 'firefox') {
28424
+ // Firefox can't handle using selects
28425
+ // See https://github.com/angular/protractor/issues/480
28426
+ return;
28427
+ }
28428
+ templateSelect.click();
28429
+ templateSelect.element.all(by.css('option')).get(2).click();
28430
+ expect(includeElem.getText()).toMatch(/Content of template2.html/);
28255
28431
  });
28432
+
28256
28433
  it('should change to blank', function() {
28257
- select('template').option('');
28258
- expect(element('.doc-example-live [ng-include]')).toBe(undefined);
28434
+ if (browser.params.browser == 'firefox') {
28435
+ // Firefox can't handle using selects
28436
+ return;
28437
+ }
28438
+ templateSelect.click();
28439
+ templateSelect.element.all(by.css('option')).get(0).click();
28440
+ expect(includeElem.isPresent()).toBe(false);
28259
28441
  });
28260
28442
  </file>
28261
28443
  </example>
@@ -28415,15 +28597,15 @@ var ngIncludeFillContentDirective = ['$compile',
28415
28597
  </div>
28416
28598
  </div>
28417
28599
  </doc:source>
28418
- <doc:scenario>
28600
+ <doc:protractor>
28419
28601
  it('should alias index positions', function() {
28420
- expect(element('.example-init').text())
28421
- .toBe('list[ 0 ][ 0 ] = a;' +
28422
- 'list[ 0 ][ 1 ] = b;' +
28423
- 'list[ 1 ][ 0 ] = c;' +
28424
- 'list[ 1 ][ 1 ] = d;');
28602
+ var elements = element.all(by.css('.example-init'));
28603
+ expect(elements.get(0).getText()).toBe('list[ 0 ][ 0 ] = a;');
28604
+ expect(elements.get(1).getText()).toBe('list[ 0 ][ 1 ] = b;');
28605
+ expect(elements.get(2).getText()).toBe('list[ 1 ][ 0 ] = c;');
28606
+ expect(elements.get(3).getText()).toBe('list[ 1 ][ 1 ] = d;');
28425
28607
  });
28426
- </doc:scenario>
28608
+ </doc:protractor>
28427
28609
  </doc:example>
28428
28610
  */
28429
28611
  var ngInitDirective = ngDirective({
@@ -28461,13 +28643,12 @@ var ngInitDirective = ngDirective({
28461
28643
  <div>Normal: {{1 + 2}}</div>
28462
28644
  <div ng-non-bindable>Ignored: {{1 + 2}}</div>
28463
28645
  </doc:source>
28464
- <doc:scenario>
28646
+ <doc:protractor>
28465
28647
  it('should check ng-non-bindable', function() {
28466
- expect(using('.doc-example-live').binding('1 + 2')).toBe('3');
28467
- expect(using('.doc-example-live').element('div:last').text()).
28468
- toMatch(/1 \+ 2/);
28648
+ expect(element(by.binding('1 + 2')).getText()).toContain('3');
28649
+ expect(element.all(by.css('.doc-example-live div')).last().getText()).toMatch(/1 \+ 2/);
28469
28650
  });
28470
- </doc:scenario>
28651
+ </doc:protractor>
28471
28652
  </doc:example>
28472
28653
  */
28473
28654
  var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
@@ -28595,49 +28776,53 @@ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 });
28595
28776
  </ng-pluralize>
28596
28777
  </div>
28597
28778
  </doc:source>
28598
- <doc:scenario>
28779
+ <doc:protractor>
28599
28780
  it('should show correct pluralized string', function() {
28600
- expect(element('.doc-example-live ng-pluralize:first').text()).
28601
- toBe('1 person is viewing.');
28602
- expect(element('.doc-example-live ng-pluralize:last').text()).
28603
- toBe('Igor is viewing.');
28604
-
28605
- using('.doc-example-live').input('personCount').enter('0');
28606
- expect(element('.doc-example-live ng-pluralize:first').text()).
28607
- toBe('Nobody is viewing.');
28608
- expect(element('.doc-example-live ng-pluralize:last').text()).
28609
- toBe('Nobody is viewing.');
28610
-
28611
- using('.doc-example-live').input('personCount').enter('2');
28612
- expect(element('.doc-example-live ng-pluralize:first').text()).
28613
- toBe('2 people are viewing.');
28614
- expect(element('.doc-example-live ng-pluralize:last').text()).
28615
- toBe('Igor and Misko are viewing.');
28616
-
28617
- using('.doc-example-live').input('personCount').enter('3');
28618
- expect(element('.doc-example-live ng-pluralize:first').text()).
28619
- toBe('3 people are viewing.');
28620
- expect(element('.doc-example-live ng-pluralize:last').text()).
28621
- toBe('Igor, Misko and one other person are viewing.');
28622
-
28623
- using('.doc-example-live').input('personCount').enter('4');
28624
- expect(element('.doc-example-live ng-pluralize:first').text()).
28625
- toBe('4 people are viewing.');
28626
- expect(element('.doc-example-live ng-pluralize:last').text()).
28627
- toBe('Igor, Misko and 2 other people are viewing.');
28628
- });
28781
+ var withoutOffset = element.all(by.css('ng-pluralize')).get(0);
28782
+ var withOffset = element.all(by.css('ng-pluralize')).get(1);
28783
+ var countInput = element(by.model('personCount'));
28784
+
28785
+ expect(withoutOffset.getText()).toEqual('1 person is viewing.');
28786
+ expect(withOffset.getText()).toEqual('Igor is viewing.');
28787
+
28788
+ countInput.clear();
28789
+ countInput.sendKeys('0');
28629
28790
 
28630
- it('should show data-binded names', function() {
28631
- using('.doc-example-live').input('personCount').enter('4');
28632
- expect(element('.doc-example-live ng-pluralize:last').text()).
28633
- toBe('Igor, Misko and 2 other people are viewing.');
28791
+ expect(withoutOffset.getText()).toEqual('Nobody is viewing.');
28792
+ expect(withOffset.getText()).toEqual('Nobody is viewing.');
28634
28793
 
28635
- using('.doc-example-live').input('person1').enter('Di');
28636
- using('.doc-example-live').input('person2').enter('Vojta');
28637
- expect(element('.doc-example-live ng-pluralize:last').text()).
28638
- toBe('Di, Vojta and 2 other people are viewing.');
28794
+ countInput.clear();
28795
+ countInput.sendKeys('2');
28796
+
28797
+ expect(withoutOffset.getText()).toEqual('2 people are viewing.');
28798
+ expect(withOffset.getText()).toEqual('Igor and Misko are viewing.');
28799
+
28800
+ countInput.clear();
28801
+ countInput.sendKeys('3');
28802
+
28803
+ expect(withoutOffset.getText()).toEqual('3 people are viewing.');
28804
+ expect(withOffset.getText()).toEqual('Igor, Misko and one other person are viewing.');
28805
+
28806
+ countInput.clear();
28807
+ countInput.sendKeys('4');
28808
+
28809
+ expect(withoutOffset.getText()).toEqual('4 people are viewing.');
28810
+ expect(withOffset.getText()).toEqual('Igor, Misko and 2 other people are viewing.');
28639
28811
  });
28640
- </doc:scenario>
28812
+ it('should show data-bound names', function() {
28813
+ var withOffset = element.all(by.css('ng-pluralize')).get(1);
28814
+ var personCount = element(by.model('personCount'));
28815
+ var person1 = element(by.model('person1'));
28816
+ var person2 = element(by.model('person2'));
28817
+ personCount.clear();
28818
+ personCount.sendKeys('4');
28819
+ person1.clear();
28820
+ person1.sendKeys('Di');
28821
+ person2.clear();
28822
+ person2.sendKeys('Vojta');
28823
+ expect(withOffset.getText()).toEqual('Di, Vojta and 2 other people are viewing.');
28824
+ });
28825
+ </doc:protractor>
28641
28826
  </doc:example>
28642
28827
  */
28643
28828
  var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interpolate) {
@@ -28856,25 +29041,27 @@ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interp
28856
29041
  max-height:40px;
28857
29042
  }
28858
29043
  </file>
28859
- <file name="scenario.js">
28860
- it('should render initial data set', function() {
28861
- var r = using('.doc-example-live').repeater('ul li');
28862
- expect(r.count()).toBe(10);
28863
- expect(r.row(0)).toEqual(["1","John","25"]);
28864
- expect(r.row(1)).toEqual(["2","Jessie","30"]);
28865
- expect(r.row(9)).toEqual(["10","Samantha","60"]);
28866
- expect(binding('friends.length')).toBe("10");
28867
- });
29044
+ <file name="protractorTest.js">
29045
+ var friends = element(by.css('.doc-example-live'))
29046
+ .element.all(by.repeater('friend in friends'));
29047
+
29048
+ it('should render initial data set', function() {
29049
+ expect(friends.count()).toBe(10);
29050
+ expect(friends.get(0).getText()).toEqual('[1] John who is 25 years old.');
29051
+ expect(friends.get(1).getText()).toEqual('[2] Jessie who is 30 years old.');
29052
+ expect(friends.last().getText()).toEqual('[10] Samantha who is 60 years old.');
29053
+ expect(element(by.binding('friends.length')).getText())
29054
+ .toMatch("I have 10 friends. They are:");
29055
+ });
28868
29056
 
28869
29057
  it('should update repeater when filter predicate changes', function() {
28870
- var r = using('.doc-example-live').repeater('ul li');
28871
- expect(r.count()).toBe(10);
29058
+ expect(friends.count()).toBe(10);
28872
29059
 
28873
- input('q').enter('ma');
29060
+ element(by.css('.doc-example-live')).element(by.model('q')).sendKeys('ma');
28874
29061
 
28875
- expect(r.count()).toBe(2);
28876
- expect(r.row(0)).toEqual(["1","Mary","28"]);
28877
- expect(r.row(1)).toEqual(["2","Samantha","60"]);
29062
+ expect(friends.count()).toBe(2);
29063
+ expect(friends.get(0).getText()).toEqual('[1] Mary who is 28 years old.');
29064
+ expect(friends.last().getText()).toEqual('[2] Samantha who is 60 years old.');
28878
29065
  });
28879
29066
  </file>
28880
29067
  </example>
@@ -29208,16 +29395,19 @@ var ngRepeatDirective = ['$parse', '$animate', function($parse, $animate) {
29208
29395
  background:white;
29209
29396
  }
29210
29397
  </file>
29211
- <file name="scenario.js">
29212
- it('should check ng-show / ng-hide', function() {
29213
- expect(element('.doc-example-live span:first:hidden').count()).toEqual(1);
29214
- expect(element('.doc-example-live span:last:visible').count()).toEqual(1);
29398
+ <file name="protractorTest.js">
29399
+ var thumbsUp = element(by.css('.doc-example-live span.icon-thumbs-up'));
29400
+ var thumbsDown = element(by.css('.doc-example-live span.icon-thumbs-down'));
29215
29401
 
29216
- input('checked').check();
29402
+ it('should check ng-show / ng-hide', function() {
29403
+ expect(thumbsUp.isDisplayed()).toBeFalsy();
29404
+ expect(thumbsDown.isDisplayed()).toBeTruthy();
29217
29405
 
29218
- expect(element('.doc-example-live span:first:visible').count()).toEqual(1);
29219
- expect(element('.doc-example-live span:last:hidden').count()).toEqual(1);
29220
- });
29406
+ element(by.model('checked')).click();
29407
+
29408
+ expect(thumbsUp.isDisplayed()).toBeTruthy();
29409
+ expect(thumbsDown.isDisplayed()).toBeFalsy();
29410
+ });
29221
29411
  </file>
29222
29412
  </example>
29223
29413
  */
@@ -29362,16 +29552,19 @@ var ngShowDirective = ['$animate', function($animate) {
29362
29552
  background:white;
29363
29553
  }
29364
29554
  </file>
29365
- <file name="scenario.js">
29366
- it('should check ng-show / ng-hide', function() {
29367
- expect(element('.doc-example-live .check-element:first:hidden').count()).toEqual(1);
29368
- expect(element('.doc-example-live .check-element:last:visible').count()).toEqual(1);
29555
+ <file name="protractorTest.js">
29556
+ var thumbsUp = element(by.css('.doc-example-live span.icon-thumbs-up'));
29557
+ var thumbsDown = element(by.css('.doc-example-live span.icon-thumbs-down'));
29369
29558
 
29370
- input('checked').check();
29559
+ it('should check ng-show / ng-hide', function() {
29560
+ expect(thumbsUp.isDisplayed()).toBeFalsy();
29561
+ expect(thumbsDown.isDisplayed()).toBeTruthy();
29371
29562
 
29372
- expect(element('.doc-example-live .check-element:first:visible').count()).toEqual(1);
29373
- expect(element('.doc-example-live .check-element:last:hidden').count()).toEqual(1);
29374
- });
29563
+ element(by.model('checked')).click();
29564
+
29565
+ expect(thumbsUp.isDisplayed()).toBeTruthy();
29566
+ expect(thumbsDown.isDisplayed()).toBeFalsy();
29567
+ });
29375
29568
  </file>
29376
29569
  </example>
29377
29570
  */
@@ -29410,13 +29603,15 @@ var ngHideDirective = ['$animate', function($animate) {
29410
29603
  color: black;
29411
29604
  }
29412
29605
  </file>
29413
- <file name="scenario.js">
29606
+ <file name="protractorTest.js">
29607
+ var colorSpan = element(by.css('.doc-example-live span'));
29608
+
29414
29609
  it('should check ng-style', function() {
29415
- expect(element('.doc-example-live span').css('color')).toBe('rgb(0, 0, 0)');
29416
- element('.doc-example-live :button[value=set]').click();
29417
- expect(element('.doc-example-live span').css('color')).toBe('rgb(255, 0, 0)');
29418
- element('.doc-example-live :button[value=clear]').click();
29419
- expect(element('.doc-example-live span').css('color')).toBe('rgb(0, 0, 0)');
29610
+ expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
29611
+ element(by.css('.doc-example-live input[value=set]')).click();
29612
+ expect(colorSpan.getCssValue('color')).toBe('rgba(255, 0, 0, 1)');
29613
+ element(by.css('.doc-example-live input[value=clear]')).click();
29614
+ expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)');
29420
29615
  });
29421
29616
  </file>
29422
29617
  </example>
@@ -29441,7 +29636,7 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
29441
29636
  * as specified in the template.
29442
29637
  *
29443
29638
  * The directive itself works similar to ngInclude, however, instead of downloading template code (or loading it
29444
- * from the template cache), `ngSwitch` simply choses one of the nested elements and makes it visible based on which element
29639
+ * from the template cache), `ngSwitch` simply chooses one of the nested elements and makes it visible based on which element
29445
29640
  * matches the value obtained from the evaluated expression. In other words, you define a container element
29446
29641
  * (where you place the directive), place an expression on the **`on="..."` attribute**
29447
29642
  * (or the **`ng-switch="..."` attribute**), define any inner elements inside of the directive and place
@@ -29537,17 +29732,20 @@ var ngStyleDirective = ngDirective(function(scope, element, attr) {
29537
29732
  top:0;
29538
29733
  }
29539
29734
  </file>
29540
- <file name="scenario.js">
29735
+ <file name="protractorTest.js">
29736
+ var switchElem = element(by.css('.doc-example-live [ng-switch]'));
29737
+ var select = element(by.model('selection'));
29738
+
29541
29739
  it('should start in settings', function() {
29542
- expect(element('.doc-example-live [ng-switch]').text()).toMatch(/Settings Div/);
29740
+ expect(switchElem.getText()).toMatch(/Settings Div/);
29543
29741
  });
29544
29742
  it('should change to home', function() {
29545
- select('selection').option('home');
29546
- expect(element('.doc-example-live [ng-switch]').text()).toMatch(/Home Span/);
29743
+ select.element.all(by.css('option')).get(1).click();
29744
+ expect(switchElem.getText()).toMatch(/Home Span/);
29547
29745
  });
29548
29746
  it('should select default', function() {
29549
- select('selection').option('other');
29550
- expect(element('.doc-example-live [ng-switch]').text()).toMatch(/default/);
29747
+ select.element.all(by.css('option')).get(2).click();
29748
+ expect(switchElem.getText()).toMatch(/default/);
29551
29749
  });
29552
29750
  </file>
29553
29751
  </example>
@@ -29654,14 +29852,18 @@ var ngSwitchDefaultDirective = ngDirective({
29654
29852
  <pane title="{{title}}">{{text}}</pane>
29655
29853
  </div>
29656
29854
  </doc:source>
29657
- <doc:scenario>
29855
+ <doc:protractor>
29658
29856
  it('should have transcluded', function() {
29659
- input('title').enter('TITLE');
29660
- input('text').enter('TEXT');
29661
- expect(binding('title')).toEqual('TITLE');
29662
- expect(binding('text')).toEqual('TEXT');
29857
+ var titleElement = element(by.model('title'));
29858
+ titleElement.clear();
29859
+ titleElement.sendKeys('TITLE');
29860
+ var textElement = element(by.model('text'));
29861
+ textElement.clear();
29862
+ textElement.sendKeys('TEXT');
29863
+ expect(element(by.binding('title')).getText()).toEqual('TITLE');
29864
+ expect(element(by.binding('text')).getText()).toEqual('TEXT');
29663
29865
  });
29664
- </doc:scenario>
29866
+ </doc:protractor>
29665
29867
  </doc:example>
29666
29868
  *
29667
29869
  */
@@ -29714,12 +29916,12 @@ var ngTranscludeDirective = ngDirective({
29714
29916
  <a ng-click="currentTpl='/tpl.html'" id="tpl-link">Load inlined template</a>
29715
29917
  <div id="tpl-content" ng-include src="currentTpl"></div>
29716
29918
  </doc:source>
29717
- <doc:scenario>
29919
+ <doc:protractor>
29718
29920
  it('should load template defined inside script tag', function() {
29719
- element('#tpl-link').click();
29720
- expect(element('#tpl-content').text()).toMatch(/Content of the template/);
29921
+ element(by.css('#tpl-link')).click();
29922
+ expect(element(by.css('#tpl-content')).getText()).toMatch(/Content of the template/);
29721
29923
  });
29722
- </doc:scenario>
29924
+ </doc:protractor>
29723
29925
  </doc:example>
29724
29926
  */
29725
29927
  var scriptDirective = ['$templateCache', function($templateCache) {
@@ -29767,7 +29969,7 @@ var ngOptionsMinErr = minErr('ngOptions');
29767
29969
  * option. See example below for demonstration.
29768
29970
  *
29769
29971
  * <div class="alert alert-warning">
29770
- * **Note:** `ngOptions` provides iterator facility for `<option>` element which should be used instead
29972
+ * **Note:** `ngOptions` provides an iterator facility for the `<option>` element which should be used instead
29771
29973
  * of {@link ng.directive:ngRepeat ngRepeat} when you want the
29772
29974
  * `select` model to be bound to a non-string value. This is because an option element can only
29773
29975
  * be bound to string values at present.
@@ -29858,15 +30060,17 @@ var ngOptionsMinErr = minErr('ngOptions');
29858
30060
  </div>
29859
30061
  </div>
29860
30062
  </doc:source>
29861
- <doc:scenario>
30063
+ <doc:protractor>
29862
30064
  it('should check ng-options', function() {
29863
- expect(binding('{selected_color:color}')).toMatch('red');
29864
- select('color').option('0');
29865
- expect(binding('{selected_color:color}')).toMatch('black');
29866
- using('.nullable').select('color').option('');
29867
- expect(binding('{selected_color:color}')).toMatch('null');
30065
+ expect(element(by.binding('{selected_color:color}')).getText()).toMatch('red');
30066
+ element.all(by.select('color')).first().click();
30067
+ element.all(by.css('select[ng-model="color"] option')).first().click();
30068
+ expect(element(by.binding('{selected_color:color}')).getText()).toMatch('black');
30069
+ element(by.css('.nullable select[ng-model="color"]')).click();
30070
+ element.all(by.css('.nullable select[ng-model="color"] option')).first().click();
30071
+ expect(element(by.binding('{selected_color:color}')).getText()).toMatch('null');
29868
30072
  });
29869
- </doc:scenario>
30073
+ </doc:protractor>
29870
30074
  </doc:example>
29871
30075
  */
29872
30076