angularjs-rails 1.2.10 → 1.2.12

Sign up to get free protection for your applications and to get access to all the features.
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