├── .bowerrc ├── .gitignore ├── .jshintrc ├── .travis.yml ├── LICENSE ├── README.md ├── app ├── app.css ├── app.js ├── components │ ├── service-worker │ │ ├── service-worker.js │ │ └── serviceWorkerService.js │ └── version │ │ ├── interpolate-filter.js │ │ ├── interpolate-filter_test.js │ │ ├── version-directive.js │ │ ├── version-directive_test.js │ │ ├── version.js │ │ └── version_test.js ├── index-async.html ├── index.html ├── view1 │ ├── view1.html │ ├── view1.js │ └── view1_test.js └── view2 │ ├── view2.html │ ├── view2.js │ └── view2_test.js ├── bower.json ├── e2e-tests ├── protractor.conf.js └── scenarios.js ├── karma.conf.js └── package.json /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "app/bower_components" 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | logs/* 2 | !.gitkeep 3 | node_modules/ 4 | bower_components/ 5 | tmp 6 | .DS_Store 7 | .idea -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "globalstrict": true, 3 | "globals": { 4 | "angular": false, 5 | "describe": false, 6 | "it": false, 7 | "expect": false, 8 | "beforeEach": false, 9 | "afterEach": false, 10 | "module": false, 11 | "inject": false 12 | } 13 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | 5 | before_script: 6 | - export DISPLAY=:99.0 7 | - sh -e /etc/init.d/xvfb start 8 | - npm start > /dev/null & 9 | - npm run update-webdriver 10 | - sleep 1 # give server time to start 11 | 12 | script: 13 | - node_modules/.bin/karma start karma.conf.js --no-auto-watch --single-run --reporters=dots --browsers=Firefox 14 | - node_modules/.bin/protractor e2e-tests/protractor.conf.js --browser=firefox 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2010-2014 Google, Inc. http://angularjs.org 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # angular-seed — the seed for AngularJS apps 2 | 3 | This project is an application skeleton for a typical [AngularJS](http://angularjs.org/) web app. 4 | You can use it to quickly bootstrap your angular webapp projects and dev environment for these 5 | projects. 6 | 7 | The seed contains a sample AngularJS application and is preconfigured to install the Angular 8 | framework and a bunch of development and testing tools for instant web development gratification. 9 | 10 | The seed app doesn't do much, just shows how to wire two controllers and views together. 11 | 12 | 13 | ## Getting Started 14 | 15 | To get you started you can simply clone the angular-seed repository and install the dependencies: 16 | 17 | ### Prerequisites 18 | 19 | You need git to clone the angular-seed repository. You can get git from 20 | [http://git-scm.com/](http://git-scm.com/). 21 | 22 | We also use a number of node.js tools to initialize and test angular-seed. You must have node.js and 23 | its package manager (npm) installed. You can get them from [http://nodejs.org/](http://nodejs.org/). 24 | 25 | ### Clone angular-seed 26 | 27 | Clone the angular-seed repository using [git][git]: 28 | 29 | ``` 30 | git clone https://github.com/angular/angular-seed.git 31 | cd angular-seed 32 | ``` 33 | 34 | ### Install Dependencies 35 | 36 | We have two kinds of dependencies in this project: tools and angular framework code. The tools help 37 | us manage and test the application. 38 | 39 | * We get the tools we depend upon via `npm`, the [node package manager][npm]. 40 | * We get the angular code via `bower`, a [client-side code package manager][bower]. 41 | 42 | We have preconfigured `npm` to automatically run `bower` so we can simply do: 43 | 44 | ``` 45 | npm install 46 | ``` 47 | 48 | Behind the scenes this will also call `bower install`. You should find that you have two new 49 | folders in your project. 50 | 51 | * `node_modules` - contains the npm packages for the tools we need 52 | * `app/bower_components` - contains the angular framework files 53 | 54 | *Note that the `bower_components` folder would normally be installed in the root folder but 55 | angular-seed changes this location through the `.bowerrc` file. Putting it in the app folder makes 56 | it easier to serve the files by a webserver.* 57 | 58 | ### Run the Application 59 | 60 | We have preconfigured the project with a simple development web server. The simplest way to start 61 | this server is: 62 | 63 | ``` 64 | npm start 65 | ``` 66 | 67 | Now browse to the app at `http://localhost:8000/app/index.html`. 68 | 69 | 70 | 71 | ## Directory Layout 72 | 73 | ``` 74 | app/ --> all of the source files for the application 75 | app.css --> default stylesheet 76 | components/ --> all app specific modules 77 | version/ --> version related components 78 | version.js --> version module declaration and basic "version" value service 79 | version_test.js --> "version" value service tests 80 | version-directive.js --> custom directive that returns the current app version 81 | version-directive_test.js --> version directive tests 82 | interpolate-filter.js --> custom interpolation filter 83 | interpolate-filter_test.js --> interpolate filter tests 84 | view1/ --> the view1 view template and logic 85 | view1.html --> the partial template 86 | view1.js --> the controller logic 87 | view1_test.js --> tests of the controller 88 | view2/ --> the view2 view template and logic 89 | view2.html --> the partial template 90 | view2.js --> the controller logic 91 | view2_test.js --> tests of the controller 92 | app.js --> main application module 93 | index.html --> app layout file (the main html template file of the app) 94 | index-async.html --> just like index.html, but loads js files asynchronously 95 | karma.conf.js --> config file for running unit tests with Karma 96 | e2e-tests/ --> end-to-end tests 97 | protractor-conf.js --> Protractor config file 98 | scenarios.js --> end-to-end scenarios to be run by Protractor 99 | ``` 100 | 101 | ## Testing 102 | 103 | There are two kinds of tests in the angular-seed application: Unit tests and End to End tests. 104 | 105 | ### Running Unit Tests 106 | 107 | The angular-seed app comes preconfigured with unit tests. These are written in 108 | [Jasmine][jasmine], which we run with the [Karma Test Runner][karma]. We provide a Karma 109 | configuration file to run them. 110 | 111 | * the configuration is found at `karma.conf.js` 112 | * the unit tests are found next to the code they are testing and are named as `..._test.js`. 113 | 114 | The easiest way to run the unit tests is to use the supplied npm script: 115 | 116 | ``` 117 | npm test 118 | ``` 119 | 120 | This script will start the Karma test runner to execute the unit tests. Moreover, Karma will sit and 121 | watch the source and test files for changes and then re-run the tests whenever any of them change. 122 | This is the recommended strategy; if your unit tests are being run every time you save a file then 123 | you receive instant feedback on any changes that break the expected code functionality. 124 | 125 | You can also ask Karma to do a single run of the tests and then exit. This is useful if you want to 126 | check that a particular version of the code is operating as expected. The project contains a 127 | predefined script to do this: 128 | 129 | ``` 130 | npm run test-single-run 131 | ``` 132 | 133 | 134 | ### End to end testing 135 | 136 | The angular-seed app comes with end-to-end tests, again written in [Jasmine][jasmine]. These tests 137 | are run with the [Protractor][protractor] End-to-End test runner. It uses native events and has 138 | special features for Angular applications. 139 | 140 | * the configuration is found at `e2e-tests/protractor-conf.js` 141 | * the end-to-end tests are found in `e2e-tests/scenarios.js` 142 | 143 | Protractor simulates interaction with our web app and verifies that the application responds 144 | correctly. Therefore, our web server needs to be serving up the application, so that Protractor 145 | can interact with it. 146 | 147 | ``` 148 | npm start 149 | ``` 150 | 151 | In addition, since Protractor is built upon WebDriver we need to install this. The angular-seed 152 | project comes with a predefined script to do this: 153 | 154 | ``` 155 | npm run update-webdriver 156 | ``` 157 | 158 | This will download and install the latest version of the stand-alone WebDriver tool. 159 | 160 | Once you have ensured that the development web server hosting our application is up and running 161 | and WebDriver is updated, you can run the end-to-end tests using the supplied npm script: 162 | 163 | ``` 164 | npm run protractor 165 | ``` 166 | 167 | This script will execute the end-to-end tests against the application being hosted on the 168 | development server. 169 | 170 | 171 | ## Updating Angular 172 | 173 | Previously we recommended that you merge in changes to angular-seed into your own fork of the project. 174 | Now that the angular framework library code and tools are acquired through package managers (npm and 175 | bower) you can use these tools instead to update the dependencies. 176 | 177 | You can update the tool dependencies by running: 178 | 179 | ``` 180 | npm update 181 | ``` 182 | 183 | This will find the latest versions that match the version ranges specified in the `package.json` file. 184 | 185 | You can update the Angular dependencies by running: 186 | 187 | ``` 188 | bower update 189 | ``` 190 | 191 | This will find the latest versions that match the version ranges specified in the `bower.json` file. 192 | 193 | 194 | ## Loading Angular Asynchronously 195 | 196 | The angular-seed project supports loading the framework and application scripts asynchronously. The 197 | special `index-async.html` is designed to support this style of loading. For it to work you must 198 | inject a piece of Angular JavaScript into the HTML page. The project has a predefined script to help 199 | do this. 200 | 201 | ``` 202 | npm run update-index-async 203 | ``` 204 | 205 | This will copy the contents of the `angular-loader.js` library file into the `index-async.html` page. 206 | You can run this every time you update the version of Angular that you are using. 207 | 208 | 209 | ## Serving the Application Files 210 | 211 | While angular is client-side-only technology and it's possible to create angular webapps that 212 | don't require a backend server at all, we recommend serving the project files using a local 213 | webserver during development to avoid issues with security restrictions (sandbox) in browsers. The 214 | sandbox implementation varies between browsers, but quite often prevents things like cookies, xhr, 215 | etc to function properly when an html page is opened via `file://` scheme instead of `http://`. 216 | 217 | 218 | ### Running the App during Development 219 | 220 | The angular-seed project comes preconfigured with a local development webserver. It is a node.js 221 | tool called [http-server][http-server]. You can start this webserver with `npm start` but you may choose to 222 | install the tool globally: 223 | 224 | ``` 225 | sudo npm install -g http-server 226 | ``` 227 | 228 | Then you can start your own development web server to serve static files from a folder by 229 | running: 230 | 231 | ``` 232 | http-server -a localhost -p 8000 233 | ``` 234 | 235 | Alternatively, you can choose to configure your own webserver, such as apache or nginx. Just 236 | configure your server to serve the files under the `app/` directory. 237 | 238 | 239 | ### Running the App in Production 240 | 241 | This really depends on how complex your app is and the overall infrastructure of your system, but 242 | the general rule is that all you need in production are all the files under the `app/` directory. 243 | Everything else should be omitted. 244 | 245 | Angular apps are really just a bunch of static html, css and js files that just need to be hosted 246 | somewhere they can be accessed by browsers. 247 | 248 | If your Angular app is talking to the backend server via xhr or other means, you need to figure 249 | out what is the best way to host the static files to comply with the same origin policy if 250 | applicable. Usually this is done by hosting the files by the backend server or through 251 | reverse-proxying the backend server(s) and webserver(s). 252 | 253 | 254 | ## Continuous Integration 255 | 256 | ### Travis CI 257 | 258 | [Travis CI][travis] is a continuous integration service, which can monitor GitHub for new commits 259 | to your repository and execute scripts such as building the app or running tests. The angular-seed 260 | project contains a Travis configuration file, `.travis.yml`, which will cause Travis to run your 261 | tests when you push to GitHub. 262 | 263 | You will need to enable the integration between Travis and GitHub. See the Travis website for more 264 | instruction on how to do this. 265 | 266 | ### CloudBees 267 | 268 | CloudBees have provided a CI/deployment setup: 269 | 270 | 271 | 272 | 273 | If you run this, you will get a cloned version of this repo to start working on in a private git repo, 274 | along with a CI service (in Jenkins) hosted that will run unit and end to end tests in both Firefox and Chrome. 275 | 276 | 277 | ## Contact 278 | 279 | For more information on AngularJS please check out http://angularjs.org/ 280 | 281 | [git]: http://git-scm.com/ 282 | [bower]: http://bower.io 283 | [npm]: https://www.npmjs.org/ 284 | [node]: http://nodejs.org 285 | [protractor]: https://github.com/angular/protractor 286 | [jasmine]: http://jasmine.github.io 287 | [karma]: http://karma-runner.github.io 288 | [travis]: https://travis-ci.org/ 289 | [http-server]: https://github.com/nodeapps/http-server 290 | -------------------------------------------------------------------------------- /app/app.css: -------------------------------------------------------------------------------- 1 | /* app css stylesheet */ 2 | 3 | .menu { 4 | list-style: none; 5 | border-bottom: 0.1em solid black; 6 | margin-bottom: 2em; 7 | padding: 0 0 0.5em; 8 | } 9 | 10 | .menu:before { 11 | content: "["; 12 | } 13 | 14 | .menu:after { 15 | content: "]"; 16 | } 17 | 18 | .menu > li { 19 | display: inline; 20 | } 21 | 22 | .menu > li:before { 23 | content: "|"; 24 | padding-right: 0.3em; 25 | } 26 | 27 | .menu > li:nth-child(1):before { 28 | content: ""; 29 | padding: 0; 30 | } 31 | -------------------------------------------------------------------------------- /app/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Declare app level module which depends on views, and components 4 | angular.module('myApp', [ 5 | 'ngRoute', 6 | 'myApp.view1', 7 | 'myApp.view2', 8 | 'myApp.version', 9 | 'myApp.serviceWorker' 10 | ]). 11 | config(['$routeProvider', function($routeProvider) { 12 | $routeProvider.otherwise({redirectTo: '/view1'}); 13 | }]); 14 | -------------------------------------------------------------------------------- /app/components/service-worker/service-worker.js: -------------------------------------------------------------------------------- 1 | importScripts('./templates.js'); 2 | importScripts('./caches-polyfill.js'); 3 | 4 | var api = 'https://offline-news-api.herokuapp.com/stories'; 5 | var db; 6 | var templates = this.templates; 7 | 8 | this.oninstall = function(e) { 9 | e.waitUntil(Promise.all([ 10 | updateContent(), updateApplication() 11 | ])); 12 | }; 13 | 14 | this.onactivate = function() { 15 | setInterval(updateContent, 3*60*1000); 16 | }; 17 | 18 | this.onfetch = function(e) { 19 | var url = e.request.url; 20 | var path = url.replace(location.origin, ''); 21 | var guidMatches = path.match(/^\/article\/([0-9]+)\/?$/); 22 | var promise; 23 | 24 | if (path === '/') { 25 | promise = polyfillCaches.match(new Request(api)) 26 | .then(function(response) { 27 | return response.json(); 28 | }).then(function(stories) { 29 | return new Response(templates.list(stories), { headers: { "Content-Type": "text/html" } }); 30 | }); 31 | } else if (guidMatches) { 32 | promise = polyfillCaches.match(new Request(api)) 33 | .then(function(response) { 34 | return response.json(); 35 | }).then(function(stories) { 36 | var story = stories.filter(function(story) { 37 | return guidMatches[1] === story.guid; 38 | }); 39 | var body = templates.article(story[0]); 40 | return new Response(body, { headers: { "Content-Type": "text/html" } }); 41 | }); 42 | } else { 43 | promise = polyfillCaches.match(e.request); 44 | } 45 | e.respondWith(promise); 46 | }; 47 | 48 | function updateContent() { 49 | return polyfillCaches.open('news-content-cache').then(function(cache) { 50 | return cache.addAll([api]); 51 | }); 52 | } 53 | 54 | function updateApplication() { 55 | return polyfillCaches.open('news-static-cache').then(function(cache) { 56 | return cache.addAll([ 57 | '/styles.css', 58 | '/templates.js', 59 | '/application.js' 60 | ]); 61 | }); 62 | } 63 | -------------------------------------------------------------------------------- /app/components/service-worker/serviceWorkerService.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('myApp.serviceWorker', []) 4 | .service('serviceWorkerService', ['$http', 5 | function($http) { 6 | this.checkServiceWorker = function () { 7 | if ('serviceWorker' in navigator) { 8 | //navigator.serviceWorker.register('/service-worker.js'); 9 | return true; 10 | } 11 | return false; 12 | }; 13 | 14 | this.registerWorker = function (worker) { 15 | console.log(worker); 16 | if(this.checkServiceWorker()){ 17 | navigator.serviceWorker.register(worker); 18 | } 19 | } 20 | } 21 | ]); -------------------------------------------------------------------------------- /app/components/version/interpolate-filter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('myApp.version.interpolate-filter', []) 4 | 5 | .filter('interpolate', ['version', function(version) { 6 | return function(text) { 7 | return String(text).replace(/\%VERSION\%/mg, version); 8 | }; 9 | }]); 10 | -------------------------------------------------------------------------------- /app/components/version/interpolate-filter_test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('myApp.version module', function() { 4 | beforeEach(module('myApp.version')); 5 | 6 | describe('interpolate filter', function() { 7 | beforeEach(module(function($provide) { 8 | $provide.value('version', 'TEST_VER'); 9 | })); 10 | 11 | it('should replace VERSION', inject(function(interpolateFilter) { 12 | expect(interpolateFilter('before %VERSION% after')).toEqual('before TEST_VER after'); 13 | })); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /app/components/version/version-directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('myApp.version.version-directive', []) 4 | 5 | .directive('appVersion', ['version', function(version) { 6 | return function(scope, elm, attrs) { 7 | elm.text(version); 8 | }; 9 | }]); 10 | -------------------------------------------------------------------------------- /app/components/version/version-directive_test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('myApp.version module', function() { 4 | beforeEach(module('myApp.version')); 5 | 6 | describe('app-version directive', function() { 7 | it('should print current version', function() { 8 | module(function($provide) { 9 | $provide.value('version', 'TEST_VER'); 10 | }); 11 | inject(function($compile, $rootScope) { 12 | var element = $compile('')($rootScope); 13 | expect(element.text()).toEqual('TEST_VER'); 14 | }); 15 | }); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /app/components/version/version.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('myApp.version', [ 4 | 'myApp.version.interpolate-filter', 5 | 'myApp.version.version-directive' 6 | ]) 7 | 8 | .value('version', '0.1'); 9 | -------------------------------------------------------------------------------- /app/components/version/version_test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('myApp.version module', function() { 4 | beforeEach(module('myApp.version')); 5 | 6 | describe('version service', function() { 7 | it('should return current version', inject(function(version) { 8 | expect(version).toEqual('0.1'); 9 | })); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /app/index-async.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | 44 | My AngularJS App 45 | 46 | 47 | 48 | 52 | 53 |
54 | 55 |
Angular seed app: v
56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | My AngularJS App 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 22 | 23 | 26 | 27 |
28 | 29 |
Angular seed app: v
30 | 31 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /app/view1/view1.html: -------------------------------------------------------------------------------- 1 |

2 | Status do Service Worker: {{ serviceWorkerStatus }} 3 |

-------------------------------------------------------------------------------- /app/view1/view1.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('myApp.view1', ['ngRoute']) 4 | 5 | .config(['$routeProvider', function($routeProvider) { 6 | $routeProvider.when('/view1', { 7 | templateUrl: 'view1/view1.html', 8 | controller: 'View1Ctrl' 9 | }); 10 | }]) 11 | 12 | .controller('View1Ctrl', ['$scope', 'serviceWorkerService', function($scope, serviceWorkerService) { 13 | var status = serviceWorkerService.checkServiceWorker(); 14 | $scope.serviceWorkerStatus = status; 15 | console.log('status', status); 16 | 17 | var worker = 'components/service-worker/service-worker.js'; 18 | serviceWorkerService.registerWorker(worker); 19 | }]); -------------------------------------------------------------------------------- /app/view1/view1_test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('myApp.view1 module', function() { 4 | 5 | beforeEach(module('myApp.view1')); 6 | 7 | describe('view1 controller', function(){ 8 | 9 | it('should ....', inject(function($controller) { 10 | //spec body 11 | var view1Ctrl = $controller('View1Ctrl'); 12 | expect(view1Ctrl).toBeDefined(); 13 | })); 14 | 15 | }); 16 | }); -------------------------------------------------------------------------------- /app/view2/view2.html: -------------------------------------------------------------------------------- 1 |

This is the partial for view 2.

2 |

3 | Showing of 'interpolate' filter: 4 | {{ 'Current version is v%VERSION%.' | interpolate }} 5 |

6 | -------------------------------------------------------------------------------- /app/view2/view2.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('myApp.view2', ['ngRoute']) 4 | 5 | .config(['$routeProvider', function($routeProvider) { 6 | $routeProvider.when('/view2', { 7 | templateUrl: 'view2/view2.html', 8 | controller: 'View2Ctrl' 9 | }); 10 | }]) 11 | 12 | .controller('View2Ctrl', [function() { 13 | 14 | }]); -------------------------------------------------------------------------------- /app/view2/view2_test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('myApp.view2 module', function() { 4 | 5 | beforeEach(module('myApp.view2')); 6 | 7 | describe('view2 controller', function(){ 8 | 9 | it('should ....', inject(function($controller) { 10 | //spec body 11 | var view2Ctrl = $controller('View2Ctrl'); 12 | expect(view2Ctrl).toBeDefined(); 13 | })); 14 | 15 | }); 16 | }); -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-seed", 3 | "description": "A starter project for AngularJS", 4 | "version": "0.0.0", 5 | "homepage": "https://github.com/angular/angular-seed", 6 | "license": "MIT", 7 | "private": true, 8 | "dependencies": { 9 | "angular": "1.2.x", 10 | "angular-route": "1.2.x", 11 | "angular-loader": "1.2.x", 12 | "angular-mocks": "~1.2.x", 13 | "html5-boilerplate": "~4.3.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /e2e-tests/protractor.conf.js: -------------------------------------------------------------------------------- 1 | exports.config = { 2 | allScriptsTimeout: 11000, 3 | 4 | specs: [ 5 | '*.js' 6 | ], 7 | 8 | capabilities: { 9 | 'browserName': 'chrome' 10 | }, 11 | 12 | baseUrl: 'http://localhost:8000/app/', 13 | 14 | framework: 'jasmine', 15 | 16 | jasmineNodeOpts: { 17 | defaultTimeoutInterval: 30000 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /e2e-tests/scenarios.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* https://github.com/angular/protractor/blob/master/docs/toc.md */ 4 | 5 | describe('my app', function() { 6 | 7 | browser.get('index.html'); 8 | 9 | it('should automatically redirect to /view1 when location hash/fragment is empty', function() { 10 | expect(browser.getLocationAbsUrl()).toMatch("/view1"); 11 | }); 12 | 13 | 14 | describe('view1', function() { 15 | 16 | beforeEach(function() { 17 | browser.get('index.html#/view1'); 18 | }); 19 | 20 | 21 | it('should render view1 when user navigates to /view1', function() { 22 | expect(element.all(by.css('[ng-view] p')).first().getText()). 23 | toMatch(/partial for view 1/); 24 | }); 25 | 26 | }); 27 | 28 | 29 | describe('view2', function() { 30 | 31 | beforeEach(function() { 32 | browser.get('index.html#/view2'); 33 | }); 34 | 35 | 36 | it('should render view2 when user navigates to /view2', function() { 37 | expect(element.all(by.css('[ng-view] p')).first().getText()). 38 | toMatch(/partial for view 2/); 39 | }); 40 | 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function(config){ 2 | config.set({ 3 | 4 | basePath : './', 5 | 6 | files : [ 7 | 'app/bower_components/angular/angular.js', 8 | 'app/bower_components/angular-route/angular-route.js', 9 | 'app/bower_components/angular-mocks/angular-mocks.js', 10 | 'app/components/**/*.js', 11 | 'app/view*/**/*.js' 12 | ], 13 | 14 | autoWatch : true, 15 | 16 | frameworks: ['jasmine'], 17 | 18 | browsers : ['Chrome'], 19 | 20 | plugins : [ 21 | 'karma-chrome-launcher', 22 | 'karma-firefox-launcher', 23 | 'karma-jasmine', 24 | 'karma-junit-reporter' 25 | ], 26 | 27 | junitReporter : { 28 | outputFile: 'test_out/unit.xml', 29 | suite: 'unit' 30 | } 31 | 32 | }); 33 | }; 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-seed", 3 | "private": true, 4 | "version": "0.0.0", 5 | "description": "A starter project for AngularJS", 6 | "repository": "https://github.com/angular/angular-seed", 7 | "license": "MIT", 8 | "devDependencies": { 9 | "karma": "~0.10", 10 | "protractor": "^1.1.1", 11 | "http-server": "^0.6.1", 12 | "bower": "^1.3.1", 13 | "shelljs": "^0.2.6", 14 | "karma-junit-reporter": "^0.2.2" 15 | }, 16 | "scripts": { 17 | "postinstall": "bower install", 18 | 19 | "prestart": "npm install", 20 | "start": "http-server -a localhost -p 8000 -c-1", 21 | 22 | "pretest": "npm install", 23 | "test": "karma start karma.conf.js", 24 | "test-single-run": "karma start karma.conf.js --single-run", 25 | 26 | "preupdate-webdriver": "npm install", 27 | "update-webdriver": "webdriver-manager update", 28 | 29 | "preprotractor": "npm run update-webdriver", 30 | "protractor": "protractor e2e-tests/protractor.conf.js", 31 | 32 | "update-index-async": "node -e \"require('shelljs/global'); sed('-i', /\\/\\/@@NG_LOADER_START@@[\\s\\S]*\\/\\/@@NG_LOADER_END@@/, '//@@NG_LOADER_START@@\\n' + sed(/sourceMappingURL=angular-loader.min.js.map/,'sourceMappingURL=bower_components/angular-loader/angular-loader.min.js.map','app/bower_components/angular-loader/angular-loader.min.js') + '\\n//@@NG_LOADER_END@@', 'app/index-async.html');\"" 33 | } 34 | } 35 | --------------------------------------------------------------------------------