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.
-
-
-
-
-
-
-
-
-
- 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.
-
-
-
-
-
-
-
- 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;
- }
-
-
-
-
-
- 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.
-
-
-
-
-
-
-
-
-
- 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...
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+)$/;
-
+
+ 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("