diff --git a/Gruntfile.js b/Gruntfile.js index 203cc3be030c..1ec4d66a6afa 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -87,9 +87,7 @@ module.exports = function(grunt) { jqlite: 'karma-jqlite.conf.js', jquery: 'karma-jquery.conf.js', docs: 'karma-docs.conf.js', - modules: 'karma-modules.conf.js', - //NOTE run grunt test:e2e instead and it will start a webserver for you - end2end: 'karma-e2e.conf.js' + modules: 'karma-modules.conf.js' }, @@ -288,15 +286,14 @@ module.exports = function(grunt) { //alias tasks - grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['jshint', 'package','test:unit','test:promises-aplus', 'tests:docs', 'test:e2e', 'webdriver', 'runprotractor:normal']); + grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['jshint', 'package','test:unit','test:promises-aplus', 'tests:docs', 'test:protractor']); grunt.registerTask('test:jqlite', 'Run the unit tests with Karma' , ['tests:jqlite']); grunt.registerTask('test:jquery', 'Run the jQuery unit tests with Karma', ['tests:jquery']); grunt.registerTask('test:modules', 'Run the Karma module tests with Karma', ['tests:modules']); grunt.registerTask('test:docs', 'Run the doc-page tests with Karma', ['package', 'tests:docs']); grunt.registerTask('test:unit', 'Run unit, jQuery and Karma module tests with Karma', ['tests:jqlite', 'tests:jquery', 'tests:modules']); - grunt.registerTask('test:e2e', 'Run the end to end tests with Karma and keep a test server running in the background', ['connect:testserver', 'tests:end2end']); - // This should eventually replace test:e2e grunt.registerTask('test:protractor', 'Run the end to end tests with Protractor and keep a test server running in the background', ['webdriver', 'connect:testserver', 'runprotractor:normal']); + grunt.registerTask('test:e2e', 'Alias for test:protractor', ['test:protractor']); grunt.registerTask('test:docgen', ['jasmine_node']); grunt.registerTask('test:promises-aplus',['build:promises-aplus-adapter','shell:promises-aplus-tests']); diff --git a/docs/component-spec/docsSearchSpec.js b/docs/component-spec/docsSearchSpec.js index 38e6937a9ce8..f5f8d36ec999 100644 --- a/docs/component-spec/docsSearchSpec.js +++ b/docs/component-spec/docsSearchSpec.js @@ -13,8 +13,7 @@ describe("docsSearch", function() { results[0] = { section: 'tutorial', shortName: 'item one', keywords: 'item, one, 1' }; results[1] = { section: 'tutorial', shortName: 'item man', keywords: 'item, man' }; results[2] = { section: 'api', shortName: 'item other', keywords: 'item, other' }; - results[3] = { section: 'cookbook', shortName: 'item cookbook', keywords: 'item, other' }; - results[4] = { section: 'api', shortName: 'ngRepeat', keywords: 'item, other' }; + results[3] = { section: 'api', shortName: 'ngRepeat', keywords: 'item, other' }; $provide.value('NG_PAGES', results); $provide.factory('lunrSearch', function() { @@ -41,19 +40,14 @@ describe("docsSearch", function() { expect(items['api'].length).toBe(2); })); - it("should place cookbook items in the tutorial", inject(function(docsSearch) { - var items = docsSearch('item'); - expect(items['tutorial'].length).toBe(3); - })); - it("should return all results without a search", inject(function(docsSearch) { var items = docsSearch(); - expect(items['tutorial'].length).toBe(3); + expect(items['tutorial'].length).toBe(2); expect(items['api'].length).toBe(2); })); it("should store values with and without a ng prefix", inject(function(docsSearch) { - expect(interceptedLunrResults[4].title).toBe('ngRepeat repeat'); + expect(interceptedLunrResults[3].title).toBe('ngRepeat repeat'); })); }); diff --git a/docs/content/cookbook/advancedform.ngdoc b/docs/content/cookbook/advancedform.ngdoc deleted file mode 100644 index bcf8069a1072..000000000000 --- a/docs/content/cookbook/advancedform.ngdoc +++ /dev/null @@ -1,122 +0,0 @@ -@ngdoc overview -@name Cookbook: Advanced Form -@description - -Here we extend the basic form example to include common features such as reverting, dirty state -detection, and preventing invalid form submission. - - - - -
- -
- -
-

- -
-
- , - -

- - - [ add ] -
- - - [ X ] -
- - -
- -
- Debug View: -
form={{form}}
-
-
- - it('should enable save button', function() { - expect(element(':button:contains(Save)').attr('disabled')).toBeTruthy(); - input('form.name').enter(''); - expect(element(':button:contains(Save)').attr('disabled')).toBeTruthy(); - input('form.name').enter('change'); - expect(element(':button:contains(Save)').attr('disabled')).toBeFalsy(); - element(':button:contains(Save)').click(); - expect(element(':button:contains(Save)').attr('disabled')).toBeTruthy(); - }); - it('should enable cancel button', function() { - expect(element(':button:contains(Cancel)').attr('disabled')).toBeTruthy(); - input('form.name').enter('change'); - expect(element(':button:contains(Cancel)').attr('disabled')).toBeFalsy(); - element(':button:contains(Cancel)').click(); - expect(element(':button:contains(Cancel)').attr('disabled')).toBeTruthy(); - expect(element(':input[ng\\:model="form.name"]').val()).toEqual('John Smith'); - }); - -
- - -#Things to notice - -* Cancel & save buttons are only enabled if the form is dirty — there is something to cancel or -save. -* Save button is only enabled if there are no validation errors on the form. -* Cancel reverts the form changes back to original state. -* Save updates the internal model of the form. -* Debug view shows the two models. One presented to the user form and the other being the pristine -copy master. diff --git a/docs/content/cookbook/buzz.ngdoc b/docs/content/cookbook/buzz.ngdoc deleted file mode 100644 index 00db35cf7b16..000000000000 --- a/docs/content/cookbook/buzz.ngdoc +++ /dev/null @@ -1,63 +0,0 @@ -@ngdoc overview -@name Cookbook: Resources - Buzz -@description - -External resources are URLs that provide JSON data, which are then rendered with the help of -templates. Angular has a resource factory that can be used to give names to the URLs and then -attach behavior to them. For example you can use the -{@link http://code.google.com/apis/buzz/v1/getting_started.html#background-operations| Google Buzz -API} -to retrieve Buzz activity and comments. - - - - -
- - -
-
-

- - {{item.actor.name}} - - Expand replies: {{item.links.replies[0].count}} - -

- {{item.object.content | html}} -
- - {{reply.actor.name}}: - {{reply.content | html}} -
-
-
-
- - xit('fetch buzz and expand', function() { - element(':button:contains(fetch)').click(); - expect(repeater('div.buzz').count()).toBeGreaterThan(0); - element('.buzz a:contains(Expand replies):first').click(); - expect(repeater('div.reply').count()).toBeGreaterThan(0); - }); - -
diff --git a/docs/content/cookbook/deeplinking.ngdoc b/docs/content/cookbook/deeplinking.ngdoc deleted file mode 100644 index bdcf0b0978f0..000000000000 --- a/docs/content/cookbook/deeplinking.ngdoc +++ /dev/null @@ -1,151 +0,0 @@ -@ngdoc overview -@name Cookbook: Deep Linking -@description - -Deep linking allows you to encode the state of the application in the URL so that it can be -bookmarked and the application can be restored from the URL to the same state. - -While Angular does not force you to deal with bookmarks in any particular way, it has services -which make the common case described here very easy to implement. - -# Assumptions - -Your application consists of a single HTML page which bootstraps the application. We will refer -to this page as the chrome. -Your application is divided into several screens (or views) which the user can visit. For example, -the home screen, settings screen, details screen, etc. For each of these screens, we would like to -assign a URL so that it can be bookmarked and later restored. Each of these screens will be -associated with a controller which define the screen's behavior. The most common case is that the -screen will be constructed from an HTML snippet, which we will refer to as the partial. Screens can -have multiple partials, but a single partial is the most common construct. This example makes the -partial boundary visible using a blue line. - -You can make a routing table which shows which URL maps to which partial view template and which -controller. - -# Example - -In this example we have a simple app which consist of two screens: - -* Welcome: url `welcome` Show the user contact information. -* Settings: url `settings` Show an edit screen for user contact information. - - - - angular.module('deepLinking', ['ngRoute', 'ngSanitize']) - .config(function($routeProvider) { - $routeProvider. - when("/welcome", {templateUrl:'welcome.html', controller:WelcomeCntl}). - when("/settings", {templateUrl:'settings.html', controller:SettingsCntl}); - }); - - AppCntl.$inject = ['$scope', '$route'] - function AppCntl($scope, $route) { - $scope.$route = $route; - - // initialize the model to something useful - $scope.person = { - name:'anonymous', - contacts:[{type:'email', url:'anonymous@example.com'}] - }; - } - - function WelcomeCntl($scope) { - $scope.greet = function() { - alert("Hello " + $scope.person.name); - }; - } - - function SettingsCntl($scope, $location) { - $scope.cancel = function() { - $scope.form = angular.copy($scope.person); - }; - - $scope.save = function() { - angular.copy($scope.form, $scope.person); - $location.path('/welcome'); - }; - - $scope.cancel(); - } - - - [ng-view] { - border: 1px solid blue; - margin: 0; - padding:1em; - } - - .partial-info { - background-color: blue; - color: white; - padding: 3px; - } - - -
-

Your App Chrome

- [ Welcome | Settings ] -
- - Partial: {{$route.current.template}} - -
- Your app footer -
-
- - - - -
- - - [ X ] -
-
- [ add ] -
- - - -
- - Hello {{person.name}}, -
- Your contact information: -
{{contact.type}}: - -
-
-
- - it('should navigate to URL', function() { - element('a:contains(Welcome)').click(); - expect(element('[ng-view]').text()).toMatch(/Hello anonymous/); - element('a:contains(Settings)').click(); - input('form.name').enter('yourname'); - element(':button:contains(Save)').click(); - element('a:contains(Welcome)').click(); - expect(element('[ng-view]').text()).toMatch(/Hello yourname/); - }); - -
- - - -# Things to notice - -* Routes are defined in the `AppCntl` class. The initialization of the controller causes the - initialization of the {@link api/ngRoute.$route $route} service with the proper URL - routes. -* The {@link api/ngRoute.$route $route} service then watches the URL and instantiates the - appropriate controller when the URL changes. -* The {@link api/ngRoute.directive:ngView ngView} widget loads the - view when the URL changes. It also sets the view scope to the newly instantiated controller. -* Changing the URL is sufficient to change the controller and view. It makes no difference whether - the URL is changed programmatically or by the user. diff --git a/docs/content/cookbook/form.ngdoc b/docs/content/cookbook/form.ngdoc deleted file mode 100644 index aaa49d2f0d06..000000000000 --- a/docs/content/cookbook/form.ngdoc +++ /dev/null @@ -1,114 +0,0 @@ -@ngdoc overview -@name Cookbook: Form -@description - -A web application's main purpose is to present and gather data. For this reason Angular strives -to make both of these operations trivial. This example shows off how you can build a simple form to -allow a user to enter data. - - - - - -
- -
-

- -
-
- , - -

- - - [ add ] -
- - - [ X ] -
-
- Debug View: -
user={{user | json}}
-
- -
- - it('should show debug', function() { - expect(binding('user')).toMatch(/John Smith/); - }); - it('should add contact', function() { - using('.example').element('a:contains(add)').click(); - using('.example div:last').input('contact.value').enter('you@example.org'); - expect(binding('user')).toMatch(/\(234\) 555\-1212/); - expect(binding('user')).toMatch(/you@example.org/); - }); - - it('should remove contact', function() { - using('.example').element('a:contains(X)').click(); - expect(binding('user')).not().toMatch(/\(234\) 555\-1212/); - }); - - it('should validate zip', function() { - expect(using('.example'). - element(':input[ng\\:model="user.address.zip"]'). - prop('className')).not().toMatch(/ng-invalid/); - using('.example').input('user.address.zip').enter('abc'); - expect(using('.example'). - element(':input[ng\\:model="user.address.zip"]'). - prop('className')).toMatch(/ng-invalid/); - }); - - it('should validate state', function() { - expect(using('.example').element(':input[ng\\:model="user.address.state"]').prop('className')) - .not().toMatch(/ng-invalid/); - using('.example').input('user.address.state').enter('XXX'); - expect(using('.example').element(':input[ng\\:model="user.address.state"]').prop('className')) - .toMatch(/ng-invalid/); - }); - -
- - -# Things to notice - -* The user data model is initialized {@link api/ng.directive:ngController controller} and is - available in the {@link api/ng.$rootScope.Scope scope} with the initial data. -* For debugging purposes we have included a debug view of the model to better understand what - is going on. -* The {@link api/ng.directive:input input directives} simply refer - to the model and are data-bound. -* The inputs validate. (Try leaving them blank or entering non digits in the zip field) -* In your application you can simply read from or write to the model and the form will be updated. -* By clicking the 'add' link you are adding new items into the `user.contacts` array which are then - reflected in the view. diff --git a/docs/content/cookbook/helloworld.ngdoc b/docs/content/cookbook/helloworld.ngdoc deleted file mode 100644 index a24f959a7858..000000000000 --- a/docs/content/cookbook/helloworld.ngdoc +++ /dev/null @@ -1,39 +0,0 @@ -@ngdoc overview -@name Cookbook: Hello World -@description - - - - -
- Your name: -
- Hello {{name || "World"}}! -
-
- - it('should change the binding when user enters text', function() { - expect(binding('name')).toEqual('World'); - input('name').enter('angular'); - expect(binding('name')).toEqual('angular'); - }); - -
- -# Things to notice - -Take a look through the source and note: - -* The script tag that {@link guide/bootstrap bootstraps} the Angular environment. -* The text {@link api/ng.directive:input input form control} which is - bound to the greeting name text. -* There is no need for listener registration and event firing on change events. -* The implicit presence of the `name` variable which is in the root {@link api/ng.$rootScope.Scope scope}. -* The double curly brace `{{markup}}`, which binds the name variable to the greeting text. -* The concept of {@link guide/databinding data binding}, which reflects any -changes to the - input field in the greeting text. diff --git a/docs/content/cookbook/index.ngdoc b/docs/content/cookbook/index.ngdoc deleted file mode 100644 index 4fe3eb4dff31..000000000000 --- a/docs/content/cookbook/index.ngdoc +++ /dev/null @@ -1,58 +0,0 @@ -@ngdoc overview -@name Cookbook -@description - -Welcome to the Angular cookbook. Here we will show you typical uses of Angular by example. - - -# Hello World - -{@link helloworld Hello World}: The simplest possible application that demonstrates the -classic Hello World! - - -# Basic Form - -{@link form Basic Form}: Displaying forms to the user for editing is the bread and butter -of web applications. Angular makes forms easy through bidirectional data binding. - - -# Advanced Form - -{@link advancedform Advanced Form}: Taking the form example to the next level and -providing advanced features such as dirty detection, form reverting and submit disabling if -validation errors exist. - - -# Model View Controller - -{@link mvc MVC}: Tic-Tac-Toe: Model View Controller (MVC) is a time-tested design pattern -to separate the behavior (JavaScript controller) from the presentation (HTML view). This -separation aids in maintainability and testability of your project. - - -# Multi-page App and Deep Linking - -{@link deeplinking Deep Linking}: An AJAX application never navigates away from the -first page it loads. Instead, it changes the DOM of its single page. Eliminating full-page reloads -is what makes AJAX apps responsive, but it creates a problem in that apps with a single URL -prevent you from emailing links to a particular screen within your application. - -Deep linking tries to solve this by changing the URL anchor without reloading a page, thus -allowing you to send links to specific screens in your app. - - -# Services - -{@link api/ng Services}: Services are long lived objects in your applications that are -available across controllers. A collection of useful services are pre-bundled with Angular but you -will likely add your own. Services are initialized using dependency injection, which resolves the -order of initialization. This safeguards you from the perils of global state (a common way to -implement long lived objects). - - -# External Resources - -{@link buzz Resources}: Web applications must be able to communicate with the external -services to get and update data. Resources are the abstractions of external URLs which are -specially tailored to Angular data binding. diff --git a/docs/content/cookbook/mvc.ngdoc b/docs/content/cookbook/mvc.ngdoc deleted file mode 100644 index 59f9ef859696..000000000000 --- a/docs/content/cookbook/mvc.ngdoc +++ /dev/null @@ -1,128 +0,0 @@ -@ngdoc overview -@name Cookbook: MVC -@description - -MVC allows for a clean and testable separation between the behavior (controller) and the view -(HTML template). A Controller is just a JavaScript class which is grafted onto the scope of the -view. This makes it very easy for the controller and the view to share the model. - -The model is a set of objects and primitives that are referenced from the Scope ($scope) object. -This makes it very easy to test the controller in isolation since one can simply instantiate the -controller and test without a view, because there is no connection between the controller and the -view. - - - - - - -

Tic-Tac-Toe

-
- Next Player: {{nextMove}} -
Player {{winner}} has won!
- - - - -
{{cell}}
- -
-
- - it('should play a game', function() { - piece(1, 1); - expect(binding('nextMove')).toEqual('O'); - piece(3, 1); - expect(binding('nextMove')).toEqual('X'); - piece(1, 2); - piece(3, 2); - piece(1, 3); - expect(element('.winner').text()).toEqual('Player X has won!'); - }); - - function piece(row, col) { - element('.board tr:nth-child('+row+') td:nth-child('+col+')').click(); - } - -
- - -# Things to notice - -* The controller is defined in JavaScript and has no reference to the rendering logic. -* The controller is instantiated by Angular and injected into the view. -* The controller can be instantiated in isolation (without a view) and the code will still execute. -This makes it very testable. -* The HTML view is a projection of the model. In the above example, the model is stored in the -board variable. -* All of the controller's properties (such as board and nextMove) are available to the view. -* Changing the model changes the view. -* The view can call any controller function. -* In this example, the `setUrl()` and `readUrl()` functions copy the game state to/from the URL's -hash so the browser's back button will undo game steps. See deep-linking. This example calls {@link -api/ng.$rootScope.Scope#methods_$watch $watch()} to set up a listener that invokes `readUrl()` when needed. diff --git a/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc b/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc index 64fa0aafe351..3dce76721ad7 100644 --- a/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc +++ b/docs/content/guide/dev_guide.services.injecting_controllers.ngdoc @@ -53,18 +53,19 @@ function myController(scope, notifyService) { myController.$inject = ['$scope','notify']; -
+

Let's try this simple notify service, injected into the controller...

(you have to click 3 times to see an alert)

- + it('should test service', function() { - expect(element(':input[ng\\:model="message"]').val()).toEqual('test'); + expect(element(by.id('simple')).element(by.model('message')).getAttribute('value')) + .toEqual('test'); }); - + ## Implicit Dependency Injection @@ -95,7 +96,7 @@ function myController($scope, notify) { }; } -
+

Let's try the notify service, that is implicitly injected into the controller...

diff --git a/docs/content/guide/directive.ngdoc b/docs/content/guide/directive.ngdoc index 040d9e76bd8c..704dd48357c5 100644 --- a/docs/content/guide/directive.ngdoc +++ b/docs/content/guide/directive.ngdoc @@ -84,10 +84,10 @@ Here are some equivalent examples of elements that match `ngBind`:
- + it('should show off bindings', function() { - expect(element('div[ng-controller="Ctrl1"] span[ng-bind]').text()) - .toBe('Max Karl Ernst Ludwig Planck (April 23, 1858 – October 4, 1947)'); + expect(element(by.css('div[ng-controller="Ctrl1"] span[ng-bind]')).getText()) + .toBe('Max Karl Ernst Ludwig Planck (April 23, 1858 – October 4, 1947)'); }); diff --git a/docs/content/guide/expression.ngdoc b/docs/content/guide/expression.ngdoc index b884dd452bac..f1e2735b703e 100644 --- a/docs/content/guide/expression.ngdoc +++ b/docs/content/guide/expression.ngdoc @@ -37,11 +37,11 @@ JavaScript, use the {@link api/ng.$rootScope.Scope#methods_$eval `$eval()`} meth 1+2={{1+2}} - + it('should calculate expression in binding', function() { - expect(binding('1+2')).toEqual('3'); + expect(element(by.binding('1+2')).getText()).toEqual('1+2=3'); }); - + You can try evaluating different expressions here: @@ -73,14 +73,14 @@ You can try evaluating different expressions here:
- + it('should allow user expression testing', function() { - element('.expressions :button').click(); - var li = using('.expressions ul').repeater('li'); - expect(li.count()).toBe(1); - expect(li.row(0)).toEqual(["3*10|currency", "$30.00"]); + element(by.css('.expressions button')).click(); + var lis = element(by.css('.expressions ul')).element.all(by.repeater('expr in exprs')); + expect(lis.count()).toBe(1); + expect(lis.get(0).getText()).toEqual('[ X ] 3*10|currency => $30.00'); }); - + @@ -99,7 +99,7 @@ prevent accidental access to the global state (a common source of subtle bugs). $scope.name = 'World'; $scope.greet = function() { - ($window.mockWindow || $window).alert('Hello ' + $scope.name); + $window.alert('Hello ' + $scope.name); } } @@ -108,21 +108,17 @@ prevent accidental access to the global state (a common source of subtle bugs).
- - it('should calculate expression in binding', function() { - var alertText; - this.addFutureAction('set mock', function($window, $document, done) { - $window.mockWindow = { - alert: function(text){ alertText = text; } - }; - done(); - }); - element(':button:contains(Greet)').click(); - expect(this.addFuture('alert text', function(done) { - done(null, alertText); - })).toBe('Hello World'); - }); - + + it('should calculate expression in binding', function() { + element(by.css('[ng-click="greet()"]')).click(); + + var alertDialog = browser.switchTo().alert(); + + expect(alertDialog.getText()).toEqual('Hello World'); + + alertDialog.accept(); + }); + ## Forgiving diff --git a/docs/content/tutorial/the_end.ngdoc b/docs/content/tutorial/the_end.ngdoc index a4fd72a3d598..3a5fb9f8d05c 100644 --- a/docs/content/tutorial/the_end.ngdoc +++ b/docs/content/tutorial/the_end.ngdoc @@ -8,8 +8,6 @@ previous steps using the `git checkout` command. For more details and examples of the Angular concepts we touched on in this tutorial, see the {@link guide/ Developer Guide}. -For several more examples of code, see the {@link cookbook/ Cookbook}. - When you are ready to start developing a project using Angular, we recommend that you bootstrap your development with the {@link https://github.com/angular/angular-seed angular-seed} project. diff --git a/docs/src/templates/.htaccess b/docs/src/templates/.htaccess index e5a74cc4a4d4..aa3ae5435b97 100644 --- a/docs/src/templates/.htaccess +++ b/docs/src/templates/.htaccess @@ -16,4 +16,4 @@ RewriteCond %{HTTP_HOST} ^docs-next\.angularjs\.org$ RewriteRule appcache.manifest http://code.angularjs.org/next/docs/appcache.manifest [R=301] ## HTML5 URL Support ## -RewriteRule ^(guide|api|cookbook|misc|tutorial)(/.*)?$ index.html +RewriteRule ^(guide|api|misc|tutorial)(/.*)?$ index.html diff --git a/docs/src/templates/index.html b/docs/src/templates/index.html index 848490117faf..bc695119653e 100644 --- a/docs/src/templates/index.html +++ b/docs/src/templates/index.html @@ -26,7 +26,7 @@ } var indexFile = (location.pathname.match(/\/(index[^\.]*\.html)/) || ['', ''])[1], - rUrl = /(#!\/|api|guide|misc|tutorial|cookbook|error|index[^\.]*\.html).*$/, + rUrl = /(#!\/|api|guide|misc|tutorial|error|index[^\.]*\.html).*$/, baseUrl = location.href.replace(rUrl, indexFile), jQuery = /index-jq[^\.]*\.html$/.test(baseUrl), debug = /index[^\.]*-debug\.html$/.test(baseUrl), diff --git a/docs/src/templates/js/docs.js b/docs/src/templates/js/docs.js index 587e15659139..dad57aa55e80 100644 --- a/docs/src/templates/js/docs.js +++ b/docs/src/templates/js/docs.js @@ -111,9 +111,6 @@ docsApp.serviceFactory.docsSearch = ['$rootScope','lunrSearch', 'NG_PAGES', angular.forEach(index.search(q), function(result) { var item = NG_PAGES[result.ref]; var section = item.section; - if(section == 'cookbook') { - section = 'tutorial'; - } results[section] = results[section] || []; if(results[section].length < 15) { results[section].push(item); @@ -630,7 +627,6 @@ docsApp.serviceFactory.sections = ['NG_PAGES', function sections(NG_PAGES) { api: [], tutorial: [], misc: [], - cookbook: [], error: [], getPage: function(sectionId, partialId) { var pages = sections[sectionId]; @@ -675,7 +671,7 @@ docsApp.controller.DocsController = function($scope, $rootScope, $location, $win } }; var OFFLINE_COOKIE_NAME = 'ng-offline', - DOCS_PATH = /^\/(api)|(guide)|(cookbook)|(misc)|(tutorial)|(error)/, + DOCS_PATH = /^\/(api)|(guide)|(misc)|(tutorial)|(error)/, INDEX_PATH = /^(\/|\/index[^\.]*.html)$/, GLOBALS = /^angular\.([^\.]+)$/, ERROR = /^([a-zA-Z0-9_$]+:)?([a-zA-Z0-9_$]+)$/, @@ -737,7 +733,6 @@ docsApp.controller.DocsController = function($scope, $rootScope, $location, $win guide: 'Developer Guide', misc: 'Miscellaneous', tutorial: 'Tutorial', - cookbook: 'Examples', error: 'Error Reference' }; diff --git a/karma-e2e.conf.js b/karma-e2e.conf.js deleted file mode 100644 index c1e066a8e9df..000000000000 --- a/karma-e2e.conf.js +++ /dev/null @@ -1,27 +0,0 @@ -var sharedConfig = require('./karma-shared.conf'); - -module.exports = function(config) { - sharedConfig(config, {testName: 'AngularJS: e2e', logFile: 'karma-e2e.log'}); - - config.set({ - frameworks: [], - files: [ - 'build/angular-scenario.js', - 'node_modules/karma-ng-scenario/lib/adapter.js', - 'build/docs/docs-scenario.js' - ], - - proxies: { - // angular.js, angular-resource.js, etc - '/angular': 'http://localhost:8000/build/angular', - '/': 'http://localhost:8000/build/docs/' - }, - - junitReporter: { - outputFile: 'test_out/e2e.xml', - suite: 'E2E' - }, - - browserNoActivityTimeout: 90000 - }); -}; diff --git a/package.json b/package.json index 32e3025a13d6..eeec930e7f03 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "karma-sauce-launcher": "0.2.0", "karma-script-launcher": "0.1.0", "karma-browserstack-launcher": "0.0.7", - "protractor": "~0.16.1", + "protractor": "~0.17.0", "yaml-js": "~0.0.8", "marked": "0.2.9", "rewire": "1.1.3", diff --git a/scripts/travis/build.sh b/scripts/travis/build.sh index 094859e63dca..32cd8af8e391 100755 --- a/scripts/travis/build.sh +++ b/scripts/travis/build.sh @@ -10,7 +10,6 @@ if [ $JOB = "unit" ]; then grunt test:promises-aplus grunt test:unit --browsers SL_Chrome,SL_Safari,SL_Firefox,SL_IE_8,SL_IE_9,SL_IE_10,SL_IE_11 --reporters dots elif [ $JOB = "e2e" ]; then - grunt test:e2e --browsers SL_Chrome --reporters dots grunt test:protractor --sauceUser $SAUCE_USERNAME \ --sauceKey $SAUCE_ACCESS_KEY \ --capabilities.tunnel-identifier=$TRAVIS_JOB_NUMBER \ diff --git a/src/ng/compile.js b/src/ng/compile.js index dd47ca3bc080..193dff7ad19d 100644 --- a/src/ng/compile.js +++ b/src/ng/compile.js @@ -424,13 +424,17 @@
- + it('should auto compile', function() { - expect(element('div[compile]').text()).toBe('Hello Angular'); - input('html').enter('{{name}}!'); - expect(element('div[compile]').text()).toBe('Angular!'); + var textarea = $('textarea'); + var output = $('div[compile]'); + // The initial state reads 'Hello Angular'. + expect(output.getText()).toBe('Hello Angular'); + textarea.clear(); + textarea.sendKeys('{{name}}!'); + expect(output.getText()).toBe('Angular!'); }); - + * diff --git a/src/ng/directive/booleanAttrs.js b/src/ng/directive/booleanAttrs.js index 30e57bdfd5d9..79199925a15e 100644 --- a/src/ng/directive/booleanAttrs.js +++ b/src/ng/directive/booleanAttrs.js @@ -41,46 +41,48 @@ anchor (no link)
link (link, change location) - + it('should execute ng-click but not reload when href without value', function() { - element('#link-1').click(); - expect(input('value').val()).toEqual('1'); - expect(element('#link-1').attr('href')).toBe(""); + element(by.id('link-1')).click(); + expect(element(by.model('value')).getAttribute('value')).toEqual('1'); + expect(element(by.id('link-1')).getAttribute('href')).toBe(''); }); it('should execute ng-click but not reload when href empty string', function() { - element('#link-2').click(); - expect(input('value').val()).toEqual('2'); - expect(element('#link-2').attr('href')).toBe(""); + element(by.id('link-2')).click(); + expect(element(by.model('value')).getAttribute('value')).toEqual('2'); + expect(element(by.id('link-2')).getAttribute('href')).toBe(''); }); it('should execute ng-click and change url when ng-href specified', function() { - expect(element('#link-3').attr('href')).toBe("/123"); + expect(element(by.id('link-3')).getAttribute('href')).toMatch(/\/123$/); - element('#link-3').click(); - expect(browser().window().path()).toEqual('/123'); + element(by.id('link-3')).click(); + + expect(browser.driver.getCurrentUrl()).toMatch(/\/123$/); }); it('should execute ng-click but not reload when href empty string and name specified', function() { - element('#link-4').click(); - expect(input('value').val()).toEqual('4'); - expect(element('#link-4').attr('href')).toBe(''); + element(by.id('link-4')).click(); + expect(element(by.model('value')).getAttribute('value')).toEqual('4'); + expect(element(by.id('link-4')).getAttribute('href')).toBe(''); }); it('should execute ng-click but not reload when no href but name specified', function() { - element('#link-5').click(); - expect(input('value').val()).toEqual('5'); - expect(element('#link-5').attr('href')).toBe(undefined); + element(by.id('link-5')).click(); + expect(element(by.model('value')).getAttribute('value')).toEqual('5'); + expect(element(by.id('link-5')).getAttribute('href')).toBe(null); }); it('should only change url when only ng-href', function() { - input('value').enter('6'); - expect(element('#link-6').attr('href')).toBe('6'); + element(by.model('value')).clear(); + element(by.model('value')).sendKeys('6'); + expect(element(by.id('link-6')).getAttribute('href')).toMatch(/\/6$/); - element('#link-6').click(); - expect(browser().location().url()).toEqual('/6'); + element(by.id('link-6')).click(); + expect(browser.getCurrentUrl()).toMatch(/\/6$/); }); - + */ @@ -165,13 +167,13 @@ Click me to toggle:
- + it('should toggle button', function() { - expect(element('.doc-example-live :button').prop('disabled')).toBeFalsy(); - input('checked').check(); - expect(element('.doc-example-live :button').prop('disabled')).toBeTruthy(); + expect(element(by.css('.doc-example-live button')).getAttribute('disabled')).toBeFalsy(); + element(by.model('checked')).click(); + expect(element(by.css('.doc-example-live button')).getAttribute('disabled')).toBeTruthy(); }); - + * * @element INPUT @@ -200,13 +202,13 @@ Check me to check both:
- + it('should check both checkBoxes', function() { - expect(element('.doc-example-live #checkSlave').prop('checked')).toBeFalsy(); - input('master').check(); - expect(element('.doc-example-live #checkSlave').prop('checked')).toBeTruthy(); + expect(element(by.id('checkSlave')).getAttribute('checked')).toBeFalsy(); + element(by.model('master')).click(); + expect(element(by.id('checkSlave')).getAttribute('checked')).toBeTruthy(); }); - + * * @element INPUT @@ -235,13 +237,13 @@ Check me to make text readonly:
- + it('should toggle readonly attr', function() { - expect(element('.doc-example-live :text').prop('readonly')).toBeFalsy(); - input('checked').check(); - expect(element('.doc-example-live :text').prop('readonly')).toBeTruthy(); + expect(element(by.css('.doc-example-live [type="text"]')).getAttribute('readonly')).toBeFalsy(); + element(by.model('checked')).click(); + expect(element(by.css('.doc-example-live [type="text"]')).getAttribute('readonly')).toBeTruthy(); }); - + * * @element INPUT @@ -274,13 +276,13 @@ - + it('should select Greetings!', function() { - expect(element('.doc-example-live #greet').prop('selected')).toBeFalsy(); - input('selected').check(); - expect(element('.doc-example-live #greet').prop('selected')).toBeTruthy(); + expect(element(by.id('greet')).getAttribute('selected')).toBeFalsy(); + element(by.model('selected')).click(); + expect(element(by.id('greet')).getAttribute('selected')).toBeTruthy(); }); - + * * @element OPTION @@ -310,13 +312,13 @@ Show/Hide me - + it('should toggle open', function() { - expect(element('#details').prop('open')).toBeFalsy(); - input('open').check(); - expect(element('#details').prop('open')).toBeTruthy(); + expect(element(by.id('details')).getAttribute('open')).toBeFalsy(); + element(by.model('open')).click(); + expect(element(by.id('details')).getAttribute('open')).toBeTruthy(); }); - + * * @element DETAILS diff --git a/src/ng/directive/form.js b/src/ng/directive/form.js index 06ffad868d0c..86776ae7589f 100644 --- a/src/ng/directive/form.js +++ b/src/ng/directive/form.js @@ -305,18 +305,27 @@ function FormController(element, attrs) { myForm.$error.required = {{!!myForm.$error.required}}
- + it('should initialize to model', function() { - expect(binding('userType')).toEqual('guest'); - expect(binding('myForm.input.$valid')).toEqual('true'); + var userType = element(by.binding('userType')); + var valid = element(by.binding('myForm.input.$valid')); + + expect(userType.getText()).toContain('guest'); + expect(valid.getText()).toContain('true'); }); it('should be invalid if empty', function() { - input('userType').enter(''); - expect(binding('userType')).toEqual(''); - expect(binding('myForm.input.$valid')).toEqual('false'); + var userType = element(by.binding('userType')); + var valid = element(by.binding('myForm.input.$valid')); + var userInput = element(by.model('userType')); + + userInput.clear(); + userInput.sendKeys(''); + + expect(userType.getText()).toEqual('userType ='); + expect(valid.getText()).toContain('false'); }); - + */ var formDirectiveFactory = function(isNgForm) { diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 53a8ddd4d70a..85d0f22ddc85 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -62,29 +62,31 @@ var inputType = { myForm.$error.required = {{!!myForm.$error.required}}
- + + var text = element(by.binding('text')); + var valid = element(by.binding('myForm.input.$valid')); + var input = element(by.model('text')); + it('should initialize to model', function() { - expect(binding('text')).toEqual('guest'); - expect(binding('myForm.input.$valid')).toEqual('true'); + expect(text.getText()).toContain('guest'); + expect(valid.getText()).toContain('true'); }); it('should be invalid if empty', function() { - input('text').enter(''); - expect(binding('text')).toEqual(''); - expect(binding('myForm.input.$valid')).toEqual('false'); + input.clear(); + input.sendKeys(''); + + expect(text.getText()).toEqual('text ='); + expect(valid.getText()).toContain('false'); }); it('should be invalid if multi word', function() { - input('text').enter('hello world'); - expect(binding('myForm.input.$valid')).toEqual('false'); - }); + input.clear(); + input.sendKeys('hello world'); - it('should not be trimmed', function() { - input('text').enter('untrimmed '); - expect(binding('text')).toEqual('untrimmed '); - expect(binding('myForm.input.$valid')).toEqual('true'); + expect(valid.getText()).toContain('false'); }); - + */ 'text': textInputType, @@ -138,24 +140,30 @@ var inputType = { myForm.$error.required = {{!!myForm.$error.required}}
- + + var value = element(by.binding('value')); + var valid = element(by.binding('myForm.input.$valid')); + var input = element(by.model('value')); + it('should initialize to model', function() { - expect(binding('value')).toEqual('12'); - expect(binding('myForm.input.$valid')).toEqual('true'); + expect(value.getText()).toContain('12'); + expect(valid.getText()).toContain('true'); }); it('should be invalid if empty', function() { - input('value').enter(''); - expect(binding('value')).toEqual(''); - expect(binding('myForm.input.$valid')).toEqual('false'); + input.clear(); + input.sendKeys(''); + expect(value.getText()).toEqual('value ='); + expect(valid.getText()).toContain('false'); }); it('should be invalid if over max', function() { - input('value').enter('123'); - expect(binding('value')).toEqual(''); - expect(binding('myForm.input.$valid')).toEqual('false'); + input.clear(); + input.sendKeys('123'); + expect(value.getText()).toEqual('value ='); + expect(valid.getText()).toContain('false'); }); - + */ 'number': numberInputType, @@ -207,23 +215,31 @@ var inputType = { myForm.$error.url = {{!!myForm.$error.url}}
- + + var text = element(by.binding('text')); + var valid = element(by.binding('myForm.input.$valid')); + var input = element(by.model('text')); + it('should initialize to model', function() { - expect(binding('text')).toEqual('http://google.com'); - expect(binding('myForm.input.$valid')).toEqual('true'); + expect(text.getText()).toContain('http://google.com'); + expect(valid.getText()).toContain('true'); }); it('should be invalid if empty', function() { - input('text').enter(''); - expect(binding('text')).toEqual(''); - expect(binding('myForm.input.$valid')).toEqual('false'); + input.clear(); + input.sendKeys(''); + + expect(text.getText()).toEqual('text ='); + expect(valid.getText()).toContain('false'); }); it('should be invalid if not url', function() { - input('text').enter('xxx'); - expect(binding('myForm.input.$valid')).toEqual('false'); + input.clear(); + input.sendKeys('box'); + + expect(valid.getText()).toContain('false'); }); - + */ 'url': urlInputType, @@ -275,23 +291,30 @@ var inputType = { myForm.$error.email = {{!!myForm.$error.email}}
- + + var text = element(by.binding('text')); + var valid = element(by.binding('myForm.input.$valid')); + var input = element(by.model('text')); + it('should initialize to model', function() { - expect(binding('text')).toEqual('me@example.com'); - expect(binding('myForm.input.$valid')).toEqual('true'); + expect(text.getText()).toContain('me@example.com'); + expect(valid.getText()).toContain('true'); }); it('should be invalid if empty', function() { - input('text').enter(''); - expect(binding('text')).toEqual(''); - expect(binding('myForm.input.$valid')).toEqual('false'); + input.clear(); + input.sendKeys(''); + expect(text.getText()).toEqual('text ='); + expect(valid.getText()).toContain('false'); }); it('should be invalid if not email', function() { - input('text').enter('xxx'); - expect(binding('myForm.input.$valid')).toEqual('false'); + input.clear(); + input.sendKeys('xxx'); + + expect(valid.getText()).toContain('false'); }); - + */ 'email': emailInputType, @@ -332,14 +355,17 @@ var inputType = { Note that `ng-value="specialValue"` sets radio item's value to be the value of `$scope.specialValue`. - + it('should change state', function() { - expect(binding('color')).toEqual('"blue"'); + var color = element(by.binding('color')); + + expect(color.getText()).toContain('blue'); + + element.all(by.model('color')).get(0).click(); - input('color').select('red'); - expect(binding('color')).toEqual('"red"'); + expect(color.getText()).toContain('red'); }); - + */ 'radio': radioInputType, @@ -376,17 +402,21 @@ var inputType = { value2 = {{value2}}
- + it('should change state', function() { - expect(binding('value1')).toEqual('true'); - expect(binding('value2')).toEqual('YES'); + var value1 = element(by.binding('value1')); + var value2 = element(by.binding('value2')); - input('value1').check(); - input('value2').check(); - expect(binding('value1')).toEqual('false'); - expect(binding('value2')).toEqual('NO'); + expect(value1.getText()).toContain('true'); + expect(value2.getText()).toContain('YES'); + + element(by.model('value1')).click(); + element(by.model('value2')).click(); + + expect(value1.getText()).toContain('false'); + expect(value2.getText()).toContain('NO'); }); - + */ 'checkbox': checkboxInputType, @@ -739,44 +769,59 @@ function checkboxInputType(scope, element, attr, ctrl) { myForm.$error.maxlength = {{!!myForm.$error.maxlength}}
- + + var user = element(by.binding('{{user}}')); + var userNameValid = element(by.binding('myForm.userName.$valid')); + var lastNameValid = element(by.binding('myForm.lastName.$valid')); + var lastNameError = element(by.binding('myForm.lastName.$error')); + var formValid = element(by.binding('myForm.$valid')); + var userNameInput = element(by.model('user.name')); + var userLastInput = element(by.model('user.last')); + it('should initialize to model', function() { - expect(binding('user')).toEqual('{"name":"guest","last":"visitor"}'); - expect(binding('myForm.userName.$valid')).toEqual('true'); - expect(binding('myForm.$valid')).toEqual('true'); + expect(user.getText()).toContain('{"name":"guest","last":"visitor"}'); + expect(userNameValid.getText()).toContain('true'); + expect(formValid.getText()).toContain('true'); }); it('should be invalid if empty when required', function() { - input('user.name').enter(''); - expect(binding('user')).toEqual('{"last":"visitor"}'); - expect(binding('myForm.userName.$valid')).toEqual('false'); - expect(binding('myForm.$valid')).toEqual('false'); + userNameInput.clear(); + userNameInput.sendKeys(''); + + expect(user.getText()).toContain('{"last":"visitor"}'); + expect(userNameValid.getText()).toContain('false'); + expect(formValid.getText()).toContain('false'); }); it('should be valid if empty when min length is set', function() { - input('user.last').enter(''); - expect(binding('user')).toEqual('{"name":"guest","last":""}'); - expect(binding('myForm.lastName.$valid')).toEqual('true'); - expect(binding('myForm.$valid')).toEqual('true'); + userLastInput.clear(); + userLastInput.sendKeys(''); + + expect(user.getText()).toContain('{"name":"guest","last":""}'); + expect(lastNameValid.getText()).toContain('true'); + expect(formValid.getText()).toContain('true'); }); it('should be invalid if less than required min length', function() { - input('user.last').enter('xx'); - expect(binding('user')).toEqual('{"name":"guest"}'); - expect(binding('myForm.lastName.$valid')).toEqual('false'); - expect(binding('myForm.lastName.$error')).toMatch(/minlength/); - expect(binding('myForm.$valid')).toEqual('false'); + userLastInput.clear(); + userLastInput.sendKeys('xx'); + + expect(user.getText()).toContain('{"name":"guest"}'); + expect(lastNameValid.getText()).toContain('false'); + expect(lastNameError.getText()).toContain('minlength'); + expect(formValid.getText()).toContain('false'); }); it('should be invalid if longer than max length', function() { - input('user.last').enter('some ridiculously long name'); - expect(binding('user')) - .toEqual('{"name":"guest"}'); - expect(binding('myForm.lastName.$valid')).toEqual('false'); - expect(binding('myForm.lastName.$error')).toMatch(/maxlength/); - expect(binding('myForm.$valid')).toEqual('false'); + userLastInput.clear(); + userLastInput.sendKeys('some ridiculously long name'); + + expect(user.getText()).toContain('{"name":"guest"}'); + expect(lastNameValid.getText()).toContain('false'); + expect(lastNameError.getText()).toContain('maxlength'); + expect(formValid.getText()).toContain('false'); }); - + */ var inputDirective = ['$browser', '$sniffer', function($browser, $sniffer) { @@ -908,14 +953,17 @@ var VALID_CLASS = 'ng-valid', - + it('should data-bind and become invalid', function() { - var contentEditable = element('[contenteditable]'); + var contentEditable = element(by.css('.doc-example-live [contenteditable]')); + + expect(contentEditable.getText()).toEqual('Change me!'); - expect(contentEditable.text()).toEqual('Change me!'); - input('userContent').enter(''); - expect(contentEditable.text()).toEqual(''); - expect(contentEditable.prop('className')).toMatch(/ng-invalid-required/); + contentEditable.clear(); + contentEditable.sendKeys(protractor.Key.BACK_SPACE); + + expect(contentEditable.getText()).toEqual(''); + expect(contentEditable.getAttribute('class')).toMatch(/ng-invalid-required/); }); * @@ -1222,24 +1270,30 @@ var ngModelDirective = function() { * * *
- * debug = {{confirmed}}
- * counter = {{counter}} + * debug = {{confirmed}}
+ * counter = {{counter}}
* * - * + * + * var counter = element(by.binding('counter')); + * var debug = element(by.binding('confirmed')); + * * it('should evaluate the expression if changing from view', function() { - * expect(binding('counter')).toEqual('0'); - * element('#ng-change-example1').click(); - * expect(binding('counter')).toEqual('1'); - * expect(binding('confirmed')).toEqual('true'); + * expect(counter.getText()).toContain('0'); + * + * element(by.id('ng-change-example1')).click(); + * + * expect(counter.getText()).toContain('1'); + * expect(debug.getText()).toContain('true'); * }); * * it('should not evaluate the expression if changing from model', function() { - * element('#ng-change-example2').click(); - * expect(binding('counter')).toEqual('0'); - * expect(binding('confirmed')).toEqual('true'); + * element(by.id('ng-change-example2')).click(); + + * expect(counter.getText()).toContain('0'); + * expect(debug.getText()).toContain('true'); * }); - * + * * */ var ngChangeDirective = valueFn({ @@ -1312,20 +1366,26 @@ var requiredDirective = function() { myForm.$error.required = {{!!myForm.$error.required}}
- + + var listInput = element(by.model('names')); + var names = element(by.binding('{{names}}')); + var valid = element(by.binding('myForm.namesInput.$valid')); + var error = element(by.css('span.error')); + it('should initialize to model', function() { - expect(binding('names')).toEqual('["igor","misko","vojta"]'); - expect(binding('myForm.namesInput.$valid')).toEqual('true'); - expect(element('span.error').css('display')).toBe('none'); + expect(names.getText()).toContain('["igor","misko","vojta"]'); + expect(valid.getText()).toContain('true'); + expect(error.getCssValue('display')).toBe('none'); }); it('should be invalid if empty', function() { - input('names').enter(''); - expect(binding('names')).toEqual(''); - expect(binding('myForm.namesInput.$valid')).toEqual('false'); - expect(element('span.error').css('display')).not().toBe('none'); - }); - + listInput.clear(); + listInput.sendKeys(''); + + expect(names.getText()).toContain(''); + expect(valid.getText()).toContain('false'); + expect(error.getCssValue('display')).not.toBe('none'); }); + */ var ngListDirective = function() { @@ -1407,15 +1467,17 @@ var CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/;
You chose {{my.favorite}}
- + + var favorite = element(by.binding('my.favorite')); + it('should initialize to model', function() { - expect(binding('my.favorite')).toEqual('unicorns'); + expect(favorite.getText()).toContain('unicorns'); }); it('should bind the values to the inputs', function() { - input('my.favorite').select('pizza'); - expect(binding('my.favorite')).toEqual('pizza'); + element.all(by.model('my.favorite')).get(0).click(); + expect(favorite.getText()).toContain('pizza'); }); - + */ var ngValueDirective = function() { diff --git a/src/ng/directive/ngBind.js b/src/ng/directive/ngBind.js index ecfc8ab63097..5d0e300926f4 100644 --- a/src/ng/directive/ngBind.js +++ b/src/ng/directive/ngBind.js @@ -38,13 +38,17 @@ Hello ! - + it('should check ng-bind', function() { - expect(using('.doc-example-live').binding('name')).toBe('Whirled'); - using('.doc-example-live').input('name').enter('world'); - expect(using('.doc-example-live').binding('name')).toBe('world'); + var exampleContainer = $('.doc-example-live'); + var nameInput = element(by.model('name')); + + expect(exampleContainer.findElement(by.binding('name')).getText()).toBe('Whirled'); + nameInput.clear(); + nameInput.sendKeys('world'); + expect(exampleContainer.findElement(by.binding('name')).getText()).toBe('world'); }); - + */ var ngBindDirective = ngDirective(function(scope, element, attr) { @@ -90,20 +94,22 @@ var ngBindDirective = ngDirective(function(scope, element, attr) {

        
      
-     
+     
        it('should check ng-bind', function() {
-         expect(using('.doc-example-live').binding('salutation')).
-           toBe('Hello');
-         expect(using('.doc-example-live').binding('name')).
-           toBe('World');
-         using('.doc-example-live').input('salutation').enter('Greetings');
-         using('.doc-example-live').input('name').enter('user');
-         expect(using('.doc-example-live').binding('salutation')).
-           toBe('Greetings');
-         expect(using('.doc-example-live').binding('name')).
-           toBe('user');
+         var salutationElem = element(by.binding('salutation'));
+         var salutationInput = element(by.model('salutation'));
+         var nameInput = element(by.model('name'));
+
+         expect(salutationElem.getText()).toBe('Hello World!');
+
+         salutationInput.clear();
+         salutationInput.sendKeys('Greetings');
+         nameInput.clear();
+         nameInput.sendKeys('user');
+
+         expect(salutationElem.getText()).toBe('Greetings user!');
        });
-     
+     
    
  */
 var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
@@ -156,12 +162,10 @@ var ngBindTemplateDirective = ['$interpolate', function($interpolate) {
        }]);
      
- + it('should check ng-bind-html', function() { - expect(using('.doc-example-live').binding('myHTML')). - toBe( - 'I am an HTMLstring with links! and other stuff' - ); + expect(element(by.binding('myHTML')).getText()).toBe( + 'I am an HTMLstring with links! and other stuff'); }); diff --git a/src/ng/directive/ngClass.js b/src/ng/directive/ngClass.js index 21316c5745d6..c9384b087e99 100644 --- a/src/ng/directive/ngClass.js +++ b/src/ng/directive/ngClass.js @@ -114,31 +114,35 @@ function classDirective(name, selector) { color: red; } - + + var ps = element.all(by.css('.doc-example-live p')); + it('should let you toggle the class', function() { - expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/bold/); - expect(element('.doc-example-live p:first').prop('className')).not().toMatch(/red/); + expect(ps.first().getAttribute('class')).not.toMatch(/bold/); + expect(ps.first().getAttribute('class')).not.toMatch(/red/); - input('important').check(); - expect(element('.doc-example-live p:first').prop('className')).toMatch(/bold/); + element(by.model('important')).click(); + expect(ps.first().getAttribute('class')).toMatch(/bold/); - input('error').check(); - expect(element('.doc-example-live p:first').prop('className')).toMatch(/red/); + element(by.model('error')).click(); + expect(ps.first().getAttribute('class')).toMatch(/red/); }); it('should let you toggle string example', function() { - expect(element('.doc-example-live p:nth-of-type(2)').prop('className')).toBe(''); - input('style').enter('red'); - expect(element('.doc-example-live p:nth-of-type(2)').prop('className')).toBe('red'); + expect(ps.get(1).getAttribute('class')).toBe(''); + element(by.model('style')).clear(); + element(by.model('style')).sendKeys('red'); + browser.debugger(); + expect(ps.get(1).getAttribute('class')).toBe('red'); }); it('array example should have 3 classes', function() { - expect(element('.doc-example-live p:last').prop('className')).toBe(''); - input('style1').enter('bold'); - input('style2').enter('strike'); - input('style3').enter('red'); - expect(element('.doc-example-live p:last').prop('className')).toBe('bold strike red'); + expect(ps.last().getAttribute('class')).toBe(''); + element(by.model('style1')).sendKeys('bold'); + element(by.model('style2')).sendKeys('strike'); + element(by.model('style3')).sendKeys('red'); + expect(ps.last().getAttribute('class')).toBe('bold strike red'); }); @@ -149,8 +153,8 @@ function classDirective(name, selector) { - - + +
Sample Text
@@ -165,19 +169,19 @@ function classDirective(name, selector) { font-size:3em; }
- + it('should check ng-class', function() { - expect(element('.doc-example-live span').prop('className')).not(). + expect(element(by.css('.base-class')).getAttribute('class')).not. toMatch(/my-class/); - using('.doc-example-live').element(':button:first').click(); + element(by.id('setbtn')).click(); - expect(element('.doc-example-live span').prop('className')). + expect(element(by.css('.base-class')).getAttribute('class')). toMatch(/my-class/); - using('.doc-example-live').element(':button:last').click(); + element(by.id('clearbtn')).click(); - expect(element('.doc-example-live span').prop('className')).not(). + expect(element(by.css('.base-class')).getAttribute('class')).not. toMatch(/my-class/); }); @@ -229,11 +233,11 @@ var ngClassDirective = classDirective('', true); color: blue; } - + it('should check ng-class-odd and ng-class-even', function() { - expect(element('.doc-example-live li:first span').prop('className')). + expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')). toMatch(/odd/); - expect(element('.doc-example-live li:last span').prop('className')). + expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')). toMatch(/even/); }); @@ -277,11 +281,11 @@ var ngClassOddDirective = classDirective('Odd', 0); color: blue; } - + it('should check ng-class-odd and ng-class-even', function() { - expect(element('.doc-example-live li:first span').prop('className')). + expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')). toMatch(/odd/); - expect(element('.doc-example-live li:last span').prop('className')). + expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')). toMatch(/even/); }); diff --git a/src/ng/directive/ngCloak.js b/src/ng/directive/ngCloak.js index 5072c8c2ee43..220c964dce0e 100644 --- a/src/ng/directive/ngCloak.js +++ b/src/ng/directive/ngCloak.js @@ -45,14 +45,14 @@
{{ 'hello' }}
{{ 'hello IE7' }}
- + it('should remove the template directive and css class', function() { - expect(element('.doc-example-live #template1').attr('ng-cloak')). - not().toBeDefined(); - expect(element('.doc-example-live #template2').attr('ng-cloak')). - not().toBeDefined(); + expect($('.doc-example-live #template1').getAttribute('ng-cloak')). + toBeNull(); + expect($('.doc-example-live #template2').getAttribute('ng-cloak')). + toBeNull(); }); - + * */ diff --git a/src/ng/directive/ngController.js b/src/ng/directive/ngController.js index 5550b77fd852..7149d090d5b9 100644 --- a/src/ng/directive/ngController.js +++ b/src/ng/directive/ngController.js @@ -82,22 +82,36 @@ - + it('should check controller as', function() { - expect(element('#ctrl-as-exmpl>:input').val()).toBe('John Smith'); - expect(element('#ctrl-as-exmpl li:nth-child(1) input').val()) - .toBe('408 555 1212'); - expect(element('#ctrl-as-exmpl li:nth-child(2) input').val()) - .toBe('john.smith@example.org'); - - element('#ctrl-as-exmpl li:first a:contains("clear")').click(); - expect(element('#ctrl-as-exmpl li:first input').val()).toBe(''); - - element('#ctrl-as-exmpl li:last a:contains("add")').click(); - expect(element('#ctrl-as-exmpl li:nth-child(3) input').val()) - .toBe('yourname@example.org'); + var container = element(by.id('ctrl-as-exmpl')); + + expect(container.findElement(by.model('settings.name')) + .getAttribute('value')).toBe('John Smith'); + + var firstRepeat = + container.findElement(by.repeater('contact in settings.contacts').row(0)); + var secondRepeat = + container.findElement(by.repeater('contact in settings.contacts').row(1)); + + expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value')) + .toBe('408 555 1212'); + expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value')) + .toBe('john.smith@example.org'); + + firstRepeat.findElement(by.linkText('clear')).click() + + expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value')) + .toBe(''); + + container.findElement(by.linkText('add')).click(); + + expect(container.findElement(by.repeater('contact in settings.contacts').row(2)) + .findElement(by.model('contact.value')) + .getAttribute('value')) + .toBe('yourname@example.org'); }); - + @@ -145,22 +159,36 @@ - + it('should check controller', function() { - expect(element('#ctrl-exmpl>:input').val()).toBe('John Smith'); - expect(element('#ctrl-exmpl li:nth-child(1) input').val()) - .toBe('408 555 1212'); - expect(element('#ctrl-exmpl li:nth-child(2) input').val()) - .toBe('john.smith@example.org'); - - element('#ctrl-exmpl li:first a:contains("clear")').click(); - expect(element('#ctrl-exmpl li:first input').val()).toBe(''); - - element('#ctrl-exmpl li:last a:contains("add")').click(); - expect(element('#ctrl-exmpl li:nth-child(3) input').val()) - .toBe('yourname@example.org'); + var container = element(by.id('ctrl-exmpl')); + + expect(container.findElement(by.model('name')) + .getAttribute('value')).toBe('John Smith'); + + var firstRepeat = + container.findElement(by.repeater('contact in contacts').row(0)); + var secondRepeat = + container.findElement(by.repeater('contact in contacts').row(1)); + + expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value')) + .toBe('408 555 1212'); + expect(secondRepeat.findElement(by.model('contact.value')).getAttribute('value')) + .toBe('john.smith@example.org'); + + firstRepeat.findElement(by.linkText('clear')).click() + + expect(firstRepeat.findElement(by.model('contact.value')).getAttribute('value')) + .toBe(''); + + container.findElement(by.linkText('add')).click(); + + expect(container.findElement(by.repeater('contact in contacts').row(2)) + .findElement(by.model('contact.value')) + .getAttribute('value')) + .toBe('yourname@example.org'); }); - + */ diff --git a/src/ng/directive/ngEventDirs.js b/src/ng/directive/ngEventDirs.js index 7dba5749b059..f63d3ca1e7bf 100644 --- a/src/ng/directive/ngEventDirs.js +++ b/src/ng/directive/ngEventDirs.js @@ -327,20 +327,20 @@ forEach(
list={{list}}
- + it('should check ng-submit', function() { - expect(binding('list')).toBe('[]'); - element('.doc-example-live #submit').click(); - expect(binding('list')).toBe('["hello"]'); - expect(input('text').val()).toBe(''); + expect(element(by.binding('list')).getText()).toBe('list=[]'); + element(by.css('.doc-example-live #submit')).click(); + expect(element(by.binding('list')).getText()).toContain('hello'); + expect(element(by.input('text')).getAttribute('value')).toBe(''); }); it('should ignore empty strings', function() { - expect(binding('list')).toBe('[]'); - element('.doc-example-live #submit').click(); - element('.doc-example-live #submit').click(); - expect(binding('list')).toBe('["hello"]'); - }); - + expect(element(by.binding('list')).getText()).toBe('list=[]'); + element(by.css('.doc-example-live #submit')).click(); + element(by.css('.doc-example-live #submit')).click(); + expect(element(by.binding('list')).getText()).toContain('hello'); + }); + */ diff --git a/src/ng/directive/ngInclude.js b/src/ng/directive/ngInclude.js index d6b386632641..4935edd42646 100644 --- a/src/ng/directive/ngInclude.js +++ b/src/ng/directive/ngInclude.js @@ -110,19 +110,24 @@ top:50px; }
- + + var templateSelect = element(by.model('template')); + var includeElem = element(by.css('.doc-example-live [ng-include]')); + it('should load template1.html', function() { - expect(element('.doc-example-live [ng-include]').text()). - toMatch(/Content of template1.html/); + expect(includeElem.getText()).toMatch(/Content of template1.html/); }); + it('should load template2.html', function() { - select('template').option('1'); - expect(element('.doc-example-live [ng-include]').text()). - toMatch(/Content of template2.html/); + templateSelect.click(); + templateSelect.element.all(by.css('option')).get(2).click(); + expect(includeElem.getText()).toMatch(/Content of template2.html/); }); + it('should change to blank', function() { - select('template').option(''); - expect(element('.doc-example-live [ng-include]')).toBe(undefined); + templateSelect.click(); + templateSelect.element.all(by.css('option')).get(0).click(); + expect(includeElem.isPresent()).toBe(false); }); diff --git a/src/ng/directive/ngInit.js b/src/ng/directive/ngInit.js index 6270a6d8f8b2..d5a1e24521d4 100644 --- a/src/ng/directive/ngInit.js +++ b/src/ng/directive/ngInit.js @@ -44,15 +44,15 @@ - + it('should alias index positions', function() { - expect(element('.example-init').text()) - .toBe('list[ 0 ][ 0 ] = a;' + - 'list[ 0 ][ 1 ] = b;' + - 'list[ 1 ][ 0 ] = c;' + - 'list[ 1 ][ 1 ] = d;'); + var elements = element.all(by.css('.example-init')); + expect(elements.get(0).getText()).toBe('list[ 0 ][ 0 ] = a;'); + expect(elements.get(1).getText()).toBe('list[ 0 ][ 1 ] = b;'); + expect(elements.get(2).getText()).toBe('list[ 1 ][ 0 ] = c;'); + expect(elements.get(3).getText()).toBe('list[ 1 ][ 1 ] = d;'); }); - + */ var ngInitDirective = ngDirective({ diff --git a/src/ng/directive/ngNonBindable.js b/src/ng/directive/ngNonBindable.js index 473b416b8cde..160733762b09 100644 --- a/src/ng/directive/ngNonBindable.js +++ b/src/ng/directive/ngNonBindable.js @@ -24,13 +24,12 @@
Normal: {{1 + 2}}
Ignored: {{1 + 2}}
- + it('should check ng-non-bindable', function() { - expect(using('.doc-example-live').binding('1 + 2')).toBe('3'); - expect(using('.doc-example-live').element('div:last').text()). - toMatch(/1 \+ 2/); + expect(element(by.binding('1 + 2')).getText()).toContain('3'); + expect(element.all(by.css('.doc-example-live div')).last().getText()).toMatch(/1 \+ 2/); }); - + */ var ngNonBindableDirective = ngDirective({ terminal: true, priority: 1000 }); diff --git a/src/ng/directive/ngPluralize.js b/src/ng/directive/ngPluralize.js index 7004bf4f1baf..58af4515ce28 100644 --- a/src/ng/directive/ngPluralize.js +++ b/src/ng/directive/ngPluralize.js @@ -123,49 +123,53 @@ - + it('should show correct pluralized string', function() { - expect(element('.doc-example-live ng-pluralize:first').text()). - toBe('1 person is viewing.'); - expect(element('.doc-example-live ng-pluralize:last').text()). - toBe('Igor is viewing.'); + var withoutOffset = element.all(by.css('ng-pluralize')).get(0); + var withOffset = element.all(by.css('ng-pluralize')).get(1); + var countInput = element(by.model('personCount')); - using('.doc-example-live').input('personCount').enter('0'); - expect(element('.doc-example-live ng-pluralize:first').text()). - toBe('Nobody is viewing.'); - expect(element('.doc-example-live ng-pluralize:last').text()). - toBe('Nobody is viewing.'); + expect(withoutOffset.getText()).toEqual('1 person is viewing.'); + expect(withOffset.getText()).toEqual('Igor is viewing.'); - using('.doc-example-live').input('personCount').enter('2'); - expect(element('.doc-example-live ng-pluralize:first').text()). - toBe('2 people are viewing.'); - expect(element('.doc-example-live ng-pluralize:last').text()). - toBe('Igor and Misko are viewing.'); + countInput.clear(); + countInput.sendKeys('0'); - using('.doc-example-live').input('personCount').enter('3'); - expect(element('.doc-example-live ng-pluralize:first').text()). - toBe('3 people are viewing.'); - expect(element('.doc-example-live ng-pluralize:last').text()). - toBe('Igor, Misko and one other person are viewing.'); + expect(withoutOffset.getText()).toEqual('Nobody is viewing.'); + expect(withOffset.getText()).toEqual('Nobody is viewing.'); - using('.doc-example-live').input('personCount').enter('4'); - expect(element('.doc-example-live ng-pluralize:first').text()). - toBe('4 people are viewing.'); - expect(element('.doc-example-live ng-pluralize:last').text()). - toBe('Igor, Misko and 2 other people are viewing.'); - }); + countInput.clear(); + countInput.sendKeys('2'); + + expect(withoutOffset.getText()).toEqual('2 people are viewing.'); + expect(withOffset.getText()).toEqual('Igor and Misko are viewing.'); + + countInput.clear(); + countInput.sendKeys('3'); - it('should show data-binded names', function() { - using('.doc-example-live').input('personCount').enter('4'); - expect(element('.doc-example-live ng-pluralize:last').text()). - toBe('Igor, Misko and 2 other people are viewing.'); + expect(withoutOffset.getText()).toEqual('3 people are viewing.'); + expect(withOffset.getText()).toEqual('Igor, Misko and one other person are viewing.'); - using('.doc-example-live').input('person1').enter('Di'); - using('.doc-example-live').input('person2').enter('Vojta'); - expect(element('.doc-example-live ng-pluralize:last').text()). - toBe('Di, Vojta and 2 other people are viewing.'); + countInput.clear(); + countInput.sendKeys('4'); + + expect(withoutOffset.getText()).toEqual('4 people are viewing.'); + expect(withOffset.getText()).toEqual('Igor, Misko and 2 other people are viewing.'); + }); + it('should show data-bound names', function() { + var withOffset = element.all(by.css('ng-pluralize')).get(1); + var personCount = element(by.model('personCount')); + var person1 = element(by.model('person1')); + var person2 = element(by.model('person2')); + personCount.clear(); + personCount.sendKeys('4'); + person1.clear(); + person1.sendKeys('Di'); + person2.clear(); + person2.sendKeys('Vojta'); + expect(withOffset.getText()).toEqual('Di, Vojta and 2 other people are viewing.'); }); - + */ var ngPluralizeDirective = ['$locale', '$interpolate', function($locale, $interpolate) { diff --git a/src/ng/directive/ngRepeat.js b/src/ng/directive/ngRepeat.js index 43db58ba5ab5..e819877c26c0 100644 --- a/src/ng/directive/ngRepeat.js +++ b/src/ng/directive/ngRepeat.js @@ -172,25 +172,27 @@ max-height:40px; }
- - it('should render initial data set', function() { - var r = using('.doc-example-live').repeater('ul li'); - expect(r.count()).toBe(10); - expect(r.row(0)).toEqual(["1","John","25"]); - expect(r.row(1)).toEqual(["2","Jessie","30"]); - expect(r.row(9)).toEqual(["10","Samantha","60"]); - expect(binding('friends.length')).toBe("10"); - }); + + var friends = element(by.css('.doc-example-live')) + .element.all(by.repeater('friend in friends')); + + it('should render initial data set', function() { + expect(friends.count()).toBe(10); + expect(friends.get(0).getText()).toEqual('[1] John who is 25 years old.'); + expect(friends.get(1).getText()).toEqual('[2] Jessie who is 30 years old.'); + expect(friends.last().getText()).toEqual('[10] Samantha who is 60 years old.'); + expect(element(by.binding('friends.length')).getText()) + .toMatch("I have 10 friends. They are:"); + }); it('should update repeater when filter predicate changes', function() { - var r = using('.doc-example-live').repeater('ul li'); - expect(r.count()).toBe(10); + expect(friends.count()).toBe(10); - input('q').enter('ma'); + element(by.css('.doc-example-live')).element(by.model('q')).sendKeys('ma'); - expect(r.count()).toBe(2); - expect(r.row(0)).toEqual(["1","Mary","28"]); - expect(r.row(1)).toEqual(["2","Samantha","60"]); + expect(friends.count()).toBe(2); + expect(friends.get(0).getText()).toEqual('[1] Mary who is 28 years old.'); + expect(friends.last().getText()).toEqual('[2] Samantha who is 60 years old.'); }); diff --git a/src/ng/directive/ngShowHide.js b/src/ng/directive/ngShowHide.js index a3a9348d08d4..ba33bb1a69de 100644 --- a/src/ng/directive/ngShowHide.js +++ b/src/ng/directive/ngShowHide.js @@ -132,16 +132,19 @@ background:white; } - - it('should check ng-show / ng-hide', function() { - expect(element('.doc-example-live span:first:hidden').count()).toEqual(1); - expect(element('.doc-example-live span:last:visible').count()).toEqual(1); + + var thumbsUp = element(by.css('.doc-example-live span.icon-thumbs-up')); + var thumbsDown = element(by.css('.doc-example-live span.icon-thumbs-down')); - input('checked').check(); + it('should check ng-show / ng-hide', function() { + expect(thumbsUp.isDisplayed()).toBeFalsy(); + expect(thumbsDown.isDisplayed()).toBeTruthy(); - expect(element('.doc-example-live span:first:visible').count()).toEqual(1); - expect(element('.doc-example-live span:last:hidden').count()).toEqual(1); - }); + element(by.model('checked')).click(); + + expect(thumbsUp.isDisplayed()).toBeTruthy(); + expect(thumbsDown.isDisplayed()).toBeFalsy(); + }); */ @@ -286,16 +289,19 @@ var ngShowDirective = ['$animate', function($animate) { background:white; } - - it('should check ng-show / ng-hide', function() { - expect(element('.doc-example-live .check-element:first:hidden').count()).toEqual(1); - expect(element('.doc-example-live .check-element:last:visible').count()).toEqual(1); + + var thumbsUp = element(by.css('.doc-example-live span.icon-thumbs-up')); + var thumbsDown = element(by.css('.doc-example-live span.icon-thumbs-down')); + + it('should check ng-show / ng-hide', function() { + expect(thumbsUp.isDisplayed()).toBeFalsy(); + expect(thumbsDown.isDisplayed()).toBeTruthy(); - input('checked').check(); + element(by.model('checked')).click(); - expect(element('.doc-example-live .check-element:first:visible').count()).toEqual(1); - expect(element('.doc-example-live .check-element:last:hidden').count()).toEqual(1); - }); + expect(thumbsUp.isDisplayed()).toBeTruthy(); + expect(thumbsDown.isDisplayed()).toBeFalsy(); + }); */ diff --git a/src/ng/directive/ngStyle.js b/src/ng/directive/ngStyle.js index b9fbe216565b..05dcfab1394d 100644 --- a/src/ng/directive/ngStyle.js +++ b/src/ng/directive/ngStyle.js @@ -27,13 +27,15 @@ color: black; } - + + var colorSpan = element(by.css('.doc-example-live span')); + it('should check ng-style', function() { - expect(element('.doc-example-live span').css('color')).toBe('rgb(0, 0, 0)'); - element('.doc-example-live :button[value=set]').click(); - expect(element('.doc-example-live span').css('color')).toBe('rgb(255, 0, 0)'); - element('.doc-example-live :button[value=clear]').click(); - expect(element('.doc-example-live span').css('color')).toBe('rgb(0, 0, 0)'); + expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)'); + element(by.css('.doc-example-live input[value=set]')).click(); + expect(colorSpan.getCssValue('color')).toBe('rgba(255, 0, 0, 1)'); + element(by.css('.doc-example-live input[value=clear]')).click(); + expect(colorSpan.getCssValue('color')).toBe('rgba(0, 0, 0, 1)'); }); diff --git a/src/ng/directive/ngSwitch.js b/src/ng/directive/ngSwitch.js index a9845a06dafa..97029d412356 100644 --- a/src/ng/directive/ngSwitch.js +++ b/src/ng/directive/ngSwitch.js @@ -107,17 +107,20 @@ top:0; } - + + var switchElem = element(by.css('.doc-example-live [ng-switch]')); + var select = element(by.model('selection')); + it('should start in settings', function() { - expect(element('.doc-example-live [ng-switch]').text()).toMatch(/Settings Div/); + expect(switchElem.getText()).toMatch(/Settings Div/); }); it('should change to home', function() { - select('selection').option('home'); - expect(element('.doc-example-live [ng-switch]').text()).toMatch(/Home Span/); + select.element.all(by.css('option')).get(1).click(); + expect(switchElem.getText()).toMatch(/Home Span/); }); it('should select default', function() { - select('selection').option('other'); - expect(element('.doc-example-live [ng-switch]').text()).toMatch(/default/); + select.element.all(by.css('option')).get(2).click(); + expect(switchElem.getText()).toMatch(/default/); }); diff --git a/src/ng/directive/ngTransclude.js b/src/ng/directive/ngTransclude.js index 8eefb6fff528..295e47a9922c 100644 --- a/src/ng/directive/ngTransclude.js +++ b/src/ng/directive/ngTransclude.js @@ -40,14 +40,18 @@ {{text}} - + it('should have transcluded', function() { - input('title').enter('TITLE'); - input('text').enter('TEXT'); - expect(binding('title')).toEqual('TITLE'); - expect(binding('text')).toEqual('TEXT'); + var titleElement = element(by.model('title')); + titleElement.clear(); + titleElement.sendKeys('TITLE'); + var textElement = element(by.model('text')); + textElement.clear(); + textElement.sendKeys('TEXT'); + expect(element(by.binding('title')).getText()).toEqual('TITLE'); + expect(element(by.binding('text')).getText()).toEqual('TEXT'); }); - + * */ diff --git a/src/ng/directive/script.js b/src/ng/directive/script.js index 86233ff80df3..e86285ae5743 100644 --- a/src/ng/directive/script.js +++ b/src/ng/directive/script.js @@ -25,12 +25,12 @@ Load inlined template
- + it('should load template defined inside script tag', function() { - element('#tpl-link').click(); - expect(element('#tpl-content').text()).toMatch(/Content of the template/); + element(by.css('#tpl-link')).click(); + expect(element(by.css('#tpl-content')).getText()).toMatch(/Content of the template/); }); - + */ var scriptDirective = ['$templateCache', function($templateCache) { diff --git a/src/ng/directive/select.js b/src/ng/directive/select.js index 0e64cc436547..c4498f81e2d6 100644 --- a/src/ng/directive/select.js +++ b/src/ng/directive/select.js @@ -120,15 +120,17 @@ var ngOptionsMinErr = minErr('ngOptions'); - + it('should check ng-options', function() { - expect(binding('{selected_color:color}')).toMatch('red'); - select('color').option('0'); - expect(binding('{selected_color:color}')).toMatch('black'); - using('.nullable').select('color').option(''); - expect(binding('{selected_color:color}')).toMatch('null'); + expect(element(by.binding('{selected_color:color}')).getText()).toMatch('red'); + element.all(by.select('color')).first().click(); + element.all(by.css('select[ng-model="color"] option')).first().click(); + expect(element(by.binding('{selected_color:color}')).getText()).toMatch('black'); + element(by.css('.nullable select[ng-model="color"]')).click(); + element.all(by.css('.nullable select[ng-model="color"] option')).first().click(); + expect(element(by.binding('{selected_color:color}')).getText()).toMatch('null'); }); - + */ diff --git a/src/ng/filter/filter.js b/src/ng/filter/filter.js index e328d61abe7d..7720bb13b011 100644 --- a/src/ng/filter/filter.js +++ b/src/ng/filter/filter.js @@ -70,35 +70,47 @@ Equality
- - - + + +
NamePhone
{{friend.name}}{{friend.phone}}
{{friendObj.name}}{{friendObj.phone}}
- + + var expectFriendNames = function(expectedNames, key) { + element.all(by.repeater(key + ' in friends').column(key + '.name')).then(function(arr) { + arr.forEach(function(wd, i) { + expect(wd.getText()).toMatch(expectedNames[i]); + }); + }); + }; + it('should search across all fields when filtering with a string', function() { - input('searchText').enter('m'); - expect(repeater('#searchTextResults tr', 'friend in friends').column('friend.name')). - toEqual(['Mary', 'Mike', 'Adam']); + var searchText = element(by.model('searchText')); + searchText.clear(); + searchText.sendKeys('m'); + expectFriendNames(['Mary', 'Mike', 'Adam'], 'friend'); - input('searchText').enter('76'); - expect(repeater('#searchTextResults tr', 'friend in friends').column('friend.name')). - toEqual(['John', 'Julie']); + searchText.clear(); + searchText.sendKeys('76'); + expectFriendNames(['John', 'Julie'], 'friend'); }); it('should search in specific fields when filtering with a predicate object', function() { - input('search.$').enter('i'); - expect(repeater('#searchObjResults tr', 'friend in friends').column('friend.name')). - toEqual(['Mary', 'Mike', 'Julie', 'Juliette']); + var searchAny = element(by.model('search.$')); + searchAny.clear(); + searchAny.sendKeys('i'); + expectFriendNames(['Mary', 'Mike', 'Julie', 'Juliette'], 'friendObj'); }); it('should use a equal comparison when comparator is true', function() { - input('search.name').enter('Julie'); - input('strict').check(); - expect(repeater('#searchObjResults tr', 'friend in friends').column('friend.name')). - toEqual(['Julie']); + var searchName = element(by.model('search.name')); + var strict = element(by.model('strict')); + searchName.clear(); + searchName.sendKeys('Julie'); + strict.click(); + expectFriendNames(['Julie'], 'friendObj'); }); - + */ function filterFilter() { diff --git a/src/ng/filter/filters.js b/src/ng/filter/filters.js index c92ed384792e..63ea270c8ba1 100644 --- a/src/ng/filter/filters.js +++ b/src/ng/filter/filters.js @@ -24,21 +24,22 @@

- default currency symbol ($): {{amount | currency}}
- custom currency identifier (USD$): {{amount | currency:"USD$"}} + default currency symbol ($): {{amount | currency}}
+ custom currency identifier (USD$): {{amount | currency:"USD$"}}
- + it('should init with 1234.56', function() { - expect(binding('amount | currency')).toBe('$1,234.56'); - expect(binding('amount | currency:"USD$"')).toBe('USD$1,234.56'); + expect(element(by.id('currency-default')).getText()).toBe('$1,234.56'); + expect(element(by.binding('amount | currency:"USD$"')).getText()).toBe('USD$1,234.56'); }); it('should update', function() { - input('amount').enter('-1234'); - expect(binding('amount | currency')).toBe('($1,234.00)'); - expect(binding('amount | currency:"USD$"')).toBe('(USD$1,234.00)'); + element(by.model('amount')).clear(); + element(by.model('amount')).sendKeys('-1234'); + expect(element(by.id('currency-default')).getText()).toBe('($1,234.00)'); + expect(element(by.binding('amount | currency:"USD$"')).getText()).toBe('(USD$1,234.00)'); }); - + */ currencyFilter.$inject = ['$locale']; @@ -77,25 +78,26 @@ function currencyFilter($locale) {
Enter number:
- Default formatting: {{val | number}}
- No fractions: {{val | number:0}}
- Negative number: {{-val | number:4}} + Default formatting: {{val | number}}
+ No fractions: {{val | number:0}}
+ Negative number: {{-val | number:4}}
- + it('should format numbers', function() { - expect(binding('val | number')).toBe('1,234.568'); - expect(binding('val | number:0')).toBe('1,235'); - expect(binding('-val | number:4')).toBe('-1,234.5679'); + expect(element(by.id('number-default')).getText()).toBe('1,234.568'); + expect(element(by.binding('val | number:0')).getText()).toBe('1,235'); + expect(element(by.binding('-val | number:4')).getText()).toBe('-1,234.5679'); }); it('should update', function() { - input('val').enter('3374.333'); - expect(binding('val | number')).toBe('3,374.333'); - expect(binding('val | number:0')).toBe('3,374'); - expect(binding('-val | number:4')).toBe('-3,374.3330'); - }); - + element(by.model('val')).clear(); + element(by.model('val')).sendKeys('3374.333'); + expect(element(by.id('number-default')).getText()).toBe('3,374.333'); + expect(element(by.binding('val | number:0')).getText()).toBe('3,374'); + expect(element(by.binding('-val | number:4')).getText()).toBe('-3,374.3330'); + }); + */ @@ -325,22 +327,22 @@ var DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZE']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+ {{1288323623006 | date:'medium'}}: - {{1288323623006 | date:'medium'}}
+ {{1288323623006 | date:'medium'}}
{{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}: - {{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}
+ {{1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'}}
{{1288323623006 | date:'MM/dd/yyyy @ h:mma'}}: - {{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}
+ {{'1288323623006' | date:'MM/dd/yyyy @ h:mma'}}
- + it('should format date', function() { - expect(binding("1288323623006 | date:'medium'")). + expect(element(by.binding("1288323623006 | date:'medium'")).getText()). toMatch(/Oct 2\d, 2010 \d{1,2}:\d{2}:\d{2} (AM|PM)/); - expect(binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")). + expect(element(by.binding("1288323623006 | date:'yyyy-MM-dd HH:mm:ss Z'")).getText()). toMatch(/2010\-10\-2\d \d{2}:\d{2}:\d{2} (\-|\+)?\d{4}/); - expect(binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")). + expect(element(by.binding("'1288323623006' | date:'MM/dd/yyyy @ h:mma'")).getText()). toMatch(/10\/2\d\/2010 @ \d{1,2}:\d{2}(AM|PM)/); }); - +
*/ dateFilter.$inject = ['$locale']; @@ -439,11 +441,11 @@ function dateFilter($locale) {
{{ {'name':'value'} | json }}
- + it('should jsonify filtered objects', function() { - expect(binding("{'name':'value'}")).toMatch(/\{\n "name": ?"value"\n}/); + expect(element(by.binding("{'name':'value'}")).getText()).toMatch(/\{\n "name": ?"value"\n}/); }); - + * */ diff --git a/src/ng/filter/limitTo.js b/src/ng/filter/limitTo.js index 07ce675d559d..bb1756f2c86b 100644 --- a/src/ng/filter/limitTo.js +++ b/src/ng/filter/limitTo.js @@ -36,28 +36,37 @@

Output letters: {{ letters | limitTo:letterLimit }}

- + + var numLimitInput = element(by.model('numLimit')); + var letterLimitInput = element(by.model('letterLimit')); + var limitedNumbers = element(by.binding('numbers | limitTo:numLimit')); + var limitedLetters = element(by.binding('letters | limitTo:letterLimit')); + it('should limit the number array to first three items', function() { - expect(element('.doc-example-live input[ng-model=numLimit]').val()).toBe('3'); - expect(element('.doc-example-live input[ng-model=letterLimit]').val()).toBe('3'); - expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3]'); - expect(binding('letters | limitTo:letterLimit')).toEqual('abc'); + expect(numLimitInput.getAttribute('value')).toBe('3'); + expect(letterLimitInput.getAttribute('value')).toBe('3'); + expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3]'); + expect(limitedLetters.getText()).toEqual('Output letters: abc'); }); it('should update the output when -3 is entered', function() { - input('numLimit').enter(-3); - input('letterLimit').enter(-3); - expect(binding('numbers | limitTo:numLimit')).toEqual('[7,8,9]'); - expect(binding('letters | limitTo:letterLimit')).toEqual('ghi'); + numLimitInput.clear(); + numLimitInput.sendKeys('-3'); + letterLimitInput.clear(); + letterLimitInput.sendKeys('-3'); + expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]'); + expect(limitedLetters.getText()).toEqual('Output letters: ghi'); }); it('should not exceed the maximum size of input array', function() { - input('numLimit').enter(100); - input('letterLimit').enter(100); - expect(binding('numbers | limitTo:numLimit')).toEqual('[1,2,3,4,5,6,7,8,9]'); - expect(binding('letters | limitTo:letterLimit')).toEqual('abcdefghi'); + numLimitInput.clear(); + numLimitInput.sendKeys('100'); + letterLimitInput.clear(); + letterLimitInput.sendKeys('100'); + expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3,4,5,6,7,8,9]'); + expect(limitedLetters.getText()).toEqual('Output letters: abcdefghi'); }); - + */ function limitToFilter(){ diff --git a/src/ng/filter/orderBy.js b/src/ng/filter/orderBy.js index 961faa368642..4127f9020b3e 100644 --- a/src/ng/filter/orderBy.js +++ b/src/ng/filter/orderBy.js @@ -58,29 +58,6 @@ - - it('should be reverse ordered by aged', function() { - expect(binding('predicate')).toBe('-age'); - expect(repeater('table.friend', 'friend in friends').column('friend.age')). - toEqual(['35', '29', '21', '19', '10']); - expect(repeater('table.friend', 'friend in friends').column('friend.name')). - toEqual(['Adam', 'Julie', 'Mike', 'Mary', 'John']); - }); - - it('should reorder the table when user selects different predicate', function() { - element('.doc-example-live a:contains("Name")').click(); - expect(repeater('table.friend', 'friend in friends').column('friend.name')). - toEqual(['Adam', 'John', 'Julie', 'Mary', 'Mike']); - expect(repeater('table.friend', 'friend in friends').column('friend.age')). - toEqual(['35', '10', '29', '19', '21']); - - element('.doc-example-live a:contains("Phone")').click(); - expect(repeater('table.friend', 'friend in friends').column('friend.phone')). - toEqual(['555-9876', '555-8765', '555-5678', '555-4321', '555-1212']); - expect(repeater('table.friend', 'friend in friends').column('friend.name')). - toEqual(['Mary', 'Julie', 'Adam', 'Mike', 'John']); - }); - */ orderByFilter.$inject = ['$parse']; diff --git a/src/ng/http.js b/src/ng/http.js index f20d54fd60db..57dc71721d10 100644 --- a/src/ng/http.js +++ b/src/ng/http.js @@ -587,14 +587,14 @@ function $HttpProvider() { -
- -
+ + - @@ -631,27 +631,34 @@ function $HttpProvider() { Hello, $http! - + + var status = element(by.binding('status')); + var data = element(by.binding('data')); + var fetchBtn = element(by.id('fetchbtn')); + var sampleGetBtn = element(by.id('samplegetbtn')); + var sampleJsonpBtn = element(by.id('samplejsonpbtn')); + var invalidJsonpBtn = element(by.id('invalidjsonpbtn')); + it('should make an xhr GET request', function() { - element(':button:contains("Sample GET")').click(); - element(':button:contains("fetch")').click(); - expect(binding('status')).toBe('200'); - expect(binding('data')).toMatch(/Hello, \$http!/); + sampleGetBtn.click(); + fetchBtn.click(); + expect(status.getText()).toMatch('200'); + expect(data.getText()).toMatch(/Hello, \$http!/) }); it('should make a JSONP request to angularjs.org', function() { - element(':button:contains("Sample JSONP")').click(); - element(':button:contains("fetch")').click(); - expect(binding('status')).toBe('200'); - expect(binding('data')).toMatch(/Super Hero!/); + sampleJsonpBtn.click(); + fetchBtn.click(); + expect(status.getText()).toMatch('200'); + expect(data.getText()).toMatch(/Super Hero!/); }); it('should make JSONP request to invalid URL and invoke the error handler', function() { - element(':button:contains("Invalid JSONP")').click(); - element(':button:contains("fetch")').click(); - expect(binding('status')).toBe('0'); - expect(binding('data')).toBe('Request failed'); + invalidJsonpBtn.click(); + fetchBtn.click(); + expect(status.getText()).toMatch('0'); + expect(data.getText()).toMatch('Request failed'); }); diff --git a/src/ng/interpolate.js b/src/ng/interpolate.js index b78f44a4c9c5..1a7e50ad4f6d 100644 --- a/src/ng/interpolate.js +++ b/src/ng/interpolate.js @@ -31,11 +31,11 @@ var $interpolateMinErr = minErr('$interpolate'); //demo.label// - - it('should interpolate binding with custom symbols', function() { - expect(binding('demo.label')).toBe('This binding is brought you by // interpolation symbols.'); - }); - + + it('should interpolate binding with custom symbols', function() { + expect(element(by.binding('demo.label')).getText()).toBe('This binding is brought you by // interpolation symbols.'); + }); + */ function $InterpolateProvider() { diff --git a/src/ng/sce.js b/src/ng/sce.js index 321921f5d4bd..a7d616a5a41b 100644 --- a/src/ng/sce.js +++ b/src/ng/sce.js @@ -624,13 +624,15 @@ function $SceDelegateProvider() { ] - + describe('SCE doc demo', function() { it('should sanitize untrusted values', function() { - expect(element('.htmlComment').html()).toBe('Is anyone reading this?'); + expect(element(by.css('.htmlComment')).getInnerHtml()) + .toBe('Is anyone reading this?'); }); + it('should NOT sanitize explicitly trusted values', function() { - expect(element('#explicitlyTrustedHtml').html()).toBe( + expect(element(by.id('explicitlyTrustedHtml')).getInnerHtml()).toBe( 'Hover over this text.'); }); diff --git a/src/ng/window.js b/src/ng/window.js index 7702f29f8e73..4f0717afa489 100644 --- a/src/ng/window.js +++ b/src/ng/window.js @@ -31,13 +31,13 @@ - + it('should display the greeting in the input box', function() { - input('greeting').enter('Hello, E2E Tests'); + element(by.model('greeting')).sendKeys('Hello, E2E Tests'); // If we click the button it will block the test runner // element(':button').click(); }); - + */ function $WindowProvider(){ diff --git a/src/ngRoute/directive/ngView.js b/src/ngRoute/directive/ngView.js index 41ed9f312391..a88d205d2ce1 100644 --- a/src/ngRoute/directive/ngView.js +++ b/src/ngRoute/directive/ngView.js @@ -151,16 +151,17 @@ ngRouteModule.directive('ngView', ngViewFillContentFactory); } - + it('should load and compile correct template', function() { - element('a:contains("Moby: Ch1")').click(); - var content = element('.doc-example-live [ng-view]').text(); + element(by.linkText('Moby: Ch1')).click(); + var content = element(by.css('.doc-example-live [ng-view]')).getText(); expect(content).toMatch(/controller\: ChapterCntl/); expect(content).toMatch(/Book Id\: Moby/); expect(content).toMatch(/Chapter Id\: 1/); - element('a:contains("Scarlet")').click(); - content = element('.doc-example-live [ng-view]').text(); + element(by.partialLinkText('Scarlet')).click(); + + content = element(by.css('.doc-example-live [ng-view]')).getText(); expect(content).toMatch(/controller\: BookCntl/); expect(content).toMatch(/Book Id\: Scarlet/); }); diff --git a/src/ngRoute/route.js b/src/ngRoute/route.js index 278182da8c33..51404fbc509b 100644 --- a/src/ngRoute/route.js +++ b/src/ngRoute/route.js @@ -345,17 +345,17 @@ function $RouteProvider(){ } - + it('should load and compile correct template', function() { - element('a:contains("Moby: Ch1")').click(); - var content = element('.doc-example-live [ng-view]').text(); + element(by.linkText('Moby: Ch1')).click(); + var content = element(by.css('.doc-example-live [ng-view]')).getText(); expect(content).toMatch(/controller\: ChapterCntl/); expect(content).toMatch(/Book Id\: Moby/); expect(content).toMatch(/Chapter Id\: 1/); - element('a:contains("Scarlet")').click(); - sleep(2); // promises are not part of scenario waiting - content = element('.doc-example-live [ng-view]').text(); + element(by.partialLinkText('Scarlet')).click(); + + content = element(by.css('.doc-example-live [ng-view]')).getText(); expect(content).toMatch(/controller\: BookCntl/); expect(content).toMatch(/Book Id\: Scarlet/); }); diff --git a/src/ngSanitize/filter/linky.js b/src/ngSanitize/filter/linky.js index 2c05d84e5c1f..da96ad2fa542 100644 --- a/src/ngSanitize/filter/linky.js +++ b/src/ngSanitize/filter/linky.js @@ -67,37 +67,38 @@ - + it('should linkify the snippet with urls', function() { - expect(using('#linky-filter').binding('snippet | linky')). - toBe('Pretty text with some links: ' + - 'http://angularjs.org/, ' + - 'us@somewhere.org, ' + - 'another@somewhere.org, ' + - 'and one more: ftp://127.0.0.1/.'); + expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()). + toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' + + 'another@somewhere.org, and one more: ftp://127.0.0.1/.'); + expect(element.all(by.css('#linky-filter a')).count()).toEqual(4); }); - it ('should not linkify snippet without the linky filter', function() { - expect(using('#escaped-html').binding('snippet')). - toBe("Pretty text with some links:\n" + - "http://angularjs.org/,\n" + - "mailto:us@somewhere.org,\n" + - "another@somewhere.org,\n" + - "and one more: ftp://127.0.0.1/."); + it('should not linkify snippet without the linky filter', function() { + expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()). + toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' + + 'another@somewhere.org, and one more: ftp://127.0.0.1/.'); + expect(element.all(by.css('#escaped-html a')).count()).toEqual(0); }); it('should update', function() { - input('snippet').enter('new http://link.'); - expect(using('#linky-filter').binding('snippet | linky')). - toBe('new http://link.'); - expect(using('#escaped-html').binding('snippet')).toBe('new http://link.'); + element(by.model('snippet')).clear(); + element(by.model('snippet')).sendKeys('new http://link.'); + expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()). + toBe('new http://link.'); + expect(element.all(by.css('#linky-filter a')).count()).toEqual(1); + expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()) + .toBe('new http://link.'); }); it('should work with the target property', function() { - expect(using('#linky-target').binding("snippetWithTarget | linky:'_blank'")). - toBe('http://angularjs.org/'); + expect(element(by.id('linky-target')). + element(by.binding("snippetWithTarget | linky:'_blank'")).getText()). + toBe('http://angularjs.org/'); + expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank'); }); - + */ angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) { diff --git a/src/ngSanitize/sanitize.js b/src/ngSanitize/sanitize.js index 5e45eb338b47..1b6cb94ef9e5 100644 --- a/src/ngSanitize/sanitize.js +++ b/src/ngSanitize/sanitize.js @@ -99,35 +99,37 @@ var $sanitizeMinErr = angular.$$minErr('$sanitize'); - + it('should sanitize the html snippet by default', function() { - expect(using('#bind-html-with-sanitize').element('div').html()). + expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()). toBe('

an html\nclick here\nsnippet

'); }); it('should inline raw snippet if bound to a trusted value', function() { - expect(using('#bind-html-with-trust').element("div").html()). + expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()). toBe("

an html\n" + "click here\n" + "snippet

"); }); it('should escape snippet without any filter', function() { - expect(using('#bind-default').element('div').html()). + expect(element(by.css('#bind-default div')).getInnerHtml()). toBe("<p style=\"color:blue\">an html\n" + "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" + "snippet</p>"); }); it('should update', function() { - input('snippet').enter('new text'); - expect(using('#bind-html-with-sanitize').element('div').html()).toBe('new text'); - expect(using('#bind-html-with-trust').element('div').html()).toBe( + element(by.model('snippet')).clear(); + element(by.model('snippet')).sendKeys('new text'); + expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()). + toBe('new text'); + expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).toBe( 'new text'); - expect(using('#bind-default').element('div').html()).toBe( + expect(element(by.css('#bind-default div')).getInnerHtml()).toBe( "new <b onclick=\"alert(1)\">text</b>"); }); -
+ */ function $SanitizeProvider() {