SlideShare a Scribd company logo
AngularJS application
architecture
Gabriele Falace
workshop 11.03.2015
Separation of Concerns
Rule of 1
ā— each component has 1 role
ā— 1 component per file
ā— each component has a single purpose
Separation of Concerns - example
Classifying concerns:
ā— Cross-Cutting and generic
ā—‹ logging
ā—‹ exception handling
ā— Cross-Cutting and feature-specific
ā—‹ a service fetching Customer data
ā— Features
ā—‹ Customer Controller
ā—‹ Customer Address widget
Consistent syntax
Many things can be done with different styles.
It is strongly recommended to stick with one,
especially when working in team!
Consistent syntax - example
It is often needed to create an alias for the this
reference.
WHY: in JavaScript a scope is created by a
function definition (and not by {} blocks) →
while nesting function definitions, the reference
to the ā€œoriginalā€ this is lost.
Consistent syntax - example
function foo(){
this.x = 5;
// other code
function bar(){
// can’t access x through ā€œthisā€
// this ā€œthisā€ belongs to bar
this.x = 6;
}
}
Consistent syntax - example
function foo(){
var self = this;
self.x = 5;
// other code
function bar(){
// can access ā€œexternalā€ x through ā€œselfā€
this.x = 6;
console.log(self.x);
}
}
Consistent syntax - example
widely used aliases
ā— in controllers: var vm = this; // view model
ā— in general js: var self = this;
Consistent syntax - services
angular.module('globalServices')
.service('paymentService', PaymentService); // a service is a SINGLETON
/* @ngInject */
function PaymentService($http, tokenService){
var service = {
validateCardNumber: validateCardNumber,
properCardNumberLength: properCardNumberLength
};
return service;
// implementation
}
Organizing the App
can be by type of by feature
by type can be ok for small-medium
sized apps.
When the size grows this gets confusing.
larger app → by feature, then by type
naming conventions
Controllers: avoid the suffix ā€œControllerā€ use
uppercase for the function name (it’s a
constructor)
Factories/Services: same as file name
Directives: same as file name + short and
consistent prefix (e.g. ā€œebā€)
Modules
Modules
use angular.module() for both declaring and
fetching modules.
angular.module(ā€˜app’, []); // CREATES
angular.module(ā€˜app’); // FETCHES
var app = angular.module(ā€˜app’, []); //not recommended
Modules
Aggregate dependencies, in order to avoid an
overly long list of dependencies in our
modules.
Use a root ā€œapp.coreā€ module to aggregate 3rd
party and other generic modules.
Controllers
Controllers
ā— only presentation logic in here
ā— don’t use anonymous functions
ā— use the ā€œController Asā€ syntax with ā€œthisā€
instead of scope
ā— separate registration, injection, declaration
angular.module(ā€˜app’).controller(ā€˜foo’, Foo);
Foo.$inject = [ā€˜$http’, ā€˜$scope’];
function Foo($http, $scope){ … }
Controllers
Declare the ā€œController Asā€ in ngRoutes,
whenever possible, also using resolve for
bootstrapping logic
controller: ā€˜Controller’
controllerAs: ā€˜ctrl’
resolve: {
message: [ā€˜customerService’, function(customerService) {
return customerService.getGreetingMessage();
}]
}
Controllers
The controller can be injected with ā€œmessageā€
before the controller is instantiated → good
mechanism for bootstrapping logic, better than
ā€œapp.runā€ when logic should be specific to the
controller
Controller.$inject = [ā€˜message’];
function Controller(message){ … }
AJAX - sequential requests
$http.get(PRICELIST_URL)
.then(function (data) {
pricelist = data['data'];
console.log('AFTER CALL 1 __ ' + pricelist + '(pricelist)');
return $http.get(CURRENCY_URL);
})
.then(function (data) {
currency = data['data'];
var actualUrl = TARIFFS_URL.replace('{priceListId}', pricelist);
return $http.get(actualUrl);
})
.then(function (data){
console.log('AFTER CALL 3 __ (tariffs) n' + JSON.stringify(data['data']));
});
AJAX - parallel requests
$q.all([fn1(), fn2(),]);
array of functions each returning a Promise
function fn1(){
return $http.get(SERVICE_URL);
}
Tips
using value/constant to keep everything in the
scope of the application. constants and values
can be injected.
angular.module('application').constant('origin', 'Sydney');
service('simpleService', ['origin', function (origin) {
// implementation ...
}
Tips
It’s usually nice to consider …
ā— using ngAnnotate (e.g. /* @ngInject */)
ā— using jshint (to impose some coding style)
ā— using JavaScript
ā—‹ especially iterators over arrays:
ā–  someArray.forEach(fn)
ā–  someArray.filter(fn)
ā–  someArray.some(fn)
ā–  someArray.every(fn)
ā–  someArray.map(fn)
Unit Testing - installation
ā— choose a framework (e.g. Jasmine)
ā— choose a test runner (e.g. Karma)
ā— setup:
npm install -g karma
npm install -g karma-cli
in the project folder run the following
karma init
Unit Testing - configuring
ā— in the project root a karma.conf.js file
specifies settings for the tests
ā—‹ make sure that the file property in the file references an array of file
path where the JS app file and the test are located!
ā— Typically, most important things to test are
Services, as they’re the components which
hold business logic
Unit Testing - example
describe('testPaymentService', function () {
var paymentService, $httpBackend;
beforeEach(module('globalServices'));
beforeEach(function () {
inject(function($injector){
$httpBackend = $injector.get('$httpBackend');
paymentService = $injector.get('paymentService');
});
});
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
});
it('should check mastercard', function () {
$httpBackend
.when('GET', REST_API_URL + '/services/payment/validateCreditCard/5105105105105100')
.respond('MASTERCARD');
var res = paymentService.validateCardNumber('5105105105105100');
$httpBackend.flush();
expect(res.$$state.value.data).toEqual('MASTERCARD');
});
});
E2E Testing - installation
ā— choose a framework (e.g. Jasmine)
ā— choose a test runner (e.g. Protractor)
ā— setup:
npm install -g protractor
in the project folder run the following, to start the
Selenium WebDriver
webdriver-manager start
Configuring
create the configuration file. Copy the following into conf.js:
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['todo-spec.js']
};
This configuration tells Protractor where your test files (specs) are, and where to talk to your Selenium
Server (seleniumAddress).
Write a test
A protractor test, manipulates the actual elements in the app launching the browser and picking up
stuff in the page through matchers. Run it with protractor conf.js
describe('Ebuero CSW number fields validation', function () {
beforeEach(function () {
browser.sleep(2000);
browser.get(URL);
...
});
it('should format, validate and copy the phone, mobile and fax number', function () {
companyName.sendKeys('000TEST000 ebuero AG');
...
expect(faxNumber.getAttribute('value')).toBe(FORMATTED_PHONE_NUMBER);
element(by.cssContainingText('option', 'AG')).click();
nextButton1.click();
expect(createErrorBox.isDisplayed()).toBeFalsy();
});
});
References
ā— John Papa’s course on PluralSight
ā— Style guide: https://github.com/johnpapa/angular-styleguide
ā— More on Services, Providers: http://slides.wesalvaro.com/20121113/#/2/5
ā— Possible JSON security threat: http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-
json-vulnerability.aspx/

More Related Content

PDF
AngularJS - What is it & Why is it awesome ? (with demos)
Gary Arora
Ā 
PDF
Advanced Tips & Tricks for using Angular JS
Simon Guest
Ā 
PDF
AngularJS introduction
Tania Gonzales
Ā 
PDF
Introduction to AngularJS
Jussi Pohjolainen
Ā 
PPTX
Why angular js Framework
Sakthi Bro
Ā 
PPTX
Introduction to Angularjs
Manish Shekhawat
Ā 
PDF
Angularjs architecture
Michael He
Ā 
PDF
AngularJS best-practices
Henry Tao
Ā 
AngularJS - What is it & Why is it awesome ? (with demos)
Gary Arora
Ā 
Advanced Tips & Tricks for using Angular JS
Simon Guest
Ā 
AngularJS introduction
Tania Gonzales
Ā 
Introduction to AngularJS
Jussi Pohjolainen
Ā 
Why angular js Framework
Sakthi Bro
Ā 
Introduction to Angularjs
Manish Shekhawat
Ā 
Angularjs architecture
Michael He
Ā 
AngularJS best-practices
Henry Tao
Ā 

What's hot (20)

PDF
AngularJS Basics and Best Practices - CC FE &UX
JWORKS powered by Ordina
Ā 
ODP
AngularJs Crash Course
Keith Bloomfield
Ā 
PPTX
Angular js
Manav Prasad
Ā 
PDF
AngularJS Best Practices
Betclic Everest Group Tech Team
Ā 
PPTX
The AngularJS way
Boyan Mihaylov
Ā 
PPTX
AngularJS Best Practices
Narek Mamikonyan
Ā 
PPTX
Angular JS - Introduction
Sagar Acharya
Ā 
PPTX
AngularJs presentation
Phan Tuan
Ā 
PPTX
AngularJS - The Next Big Thing?
Tom Hombergs
Ā 
PPTX
Introduction to Angular js 2.0
Nagaraju Sangam
Ā 
PDF
AngularJS 101 - Everything you need to know to get started
StƩphane BƩgaudeau
Ā 
PDF
AngularJS Project Setup step-by- step guide - RapidValue Solutions
RapidValue
Ā 
PPTX
Angular js architecture (v1.4.8)
Gabi Costel Lapusneanu
Ā 
PPTX
AngularJS - Architecture decisions in a large projectĀ 
Elad Hirsch
Ā 
PPTX
Angular js tutorial slides
samhelman
Ā 
PPTX
Angular js
Dinusha Nandika
Ā 
PPTX
Front end development with Angular JS
Bipin
Ā 
PDF
Angularjs - lazy loading techniques
Nir Kaufman
Ā 
ODP
Angularjs
Vincenzo Ferrari
Ā 
PPTX
Angular js
Behind D Walls
Ā 
AngularJS Basics and Best Practices - CC FE &UX
JWORKS powered by Ordina
Ā 
AngularJs Crash Course
Keith Bloomfield
Ā 
Angular js
Manav Prasad
Ā 
AngularJS Best Practices
Betclic Everest Group Tech Team
Ā 
The AngularJS way
Boyan Mihaylov
Ā 
AngularJS Best Practices
Narek Mamikonyan
Ā 
Angular JS - Introduction
Sagar Acharya
Ā 
AngularJs presentation
Phan Tuan
Ā 
AngularJS - The Next Big Thing?
Tom Hombergs
Ā 
Introduction to Angular js 2.0
Nagaraju Sangam
Ā 
AngularJS 101 - Everything you need to know to get started
StƩphane BƩgaudeau
Ā 
AngularJS Project Setup step-by- step guide - RapidValue Solutions
RapidValue
Ā 
Angular js architecture (v1.4.8)
Gabi Costel Lapusneanu
Ā 
AngularJS - Architecture decisions in a large projectĀ 
Elad Hirsch
Ā 
Angular js tutorial slides
samhelman
Ā 
Angular js
Dinusha Nandika
Ā 
Front end development with Angular JS
Bipin
Ā 
Angularjs - lazy loading techniques
Nir Kaufman
Ā 
Angularjs
Vincenzo Ferrari
Ā 
Angular js
Behind D Walls
Ā 
Ad

Similar to AngularJS application architecture (20)

ODP
Unit Testing and Coverage for AngularJS
Knoldus Inc.
Ā 
PPTX
Protractor framework architecture with example
shadabgilani
Ā 
PDF
Field injection, type safe configuration, and more new goodies in Declarative...
bjhargrave
Ā 
PDF
Voorhoede - Front-end architecture
Jasper Moelker
Ā 
PDF
How to write maintainable code without tests
Juti Noppornpitak
Ā 
PDF
Angular Intermediate
LinkMe Srl
Ā 
PDF
Build Web Apps using Node.js
davidchubbs
Ā 
PDF
Javascript ui for rest services
Ioan Eugen Stan
Ā 
ODP
Declarative Services - Dependency Injection OSGi Style
Felix Meschberger
Ā 
ODP
Declarative Services - Dependency Injection OSGi Style
Felix Meschberger
Ā 
PPTX
Angular training - Day 3 - custom directives, $http, $resource, setup with ye...
murtazahaveliwala
Ā 
PDF
Angular.js Primer in Aalto University
SC5.io
Ā 
PDF
Language enhancements in cold fusion 11
ColdFusionConference
Ā 
PDF
TypeScript for Java Developers
Yakov Fain
Ā 
PDF
Workshop 23: ReactJS, React & Redux testing
Visual Engineering
Ā 
PDF
dokumen.tips_rediscovering-spring-with-spring-boot1 (1).pdf
Appster1
Ā 
PDF
dokumen.tips_rediscovering-spring-with-spring-boot1.pdf
Appster1
Ā 
KEY
How and why i roll my own node.js framework
Ben Lin
Ā 
PDF
SCR Annotations for Fun and Profit
Mike Pfaff
Ā 
PPTX
Osgi
Heena Madan
Ā 
Unit Testing and Coverage for AngularJS
Knoldus Inc.
Ā 
Protractor framework architecture with example
shadabgilani
Ā 
Field injection, type safe configuration, and more new goodies in Declarative...
bjhargrave
Ā 
Voorhoede - Front-end architecture
Jasper Moelker
Ā 
How to write maintainable code without tests
Juti Noppornpitak
Ā 
Angular Intermediate
LinkMe Srl
Ā 
Build Web Apps using Node.js
davidchubbs
Ā 
Javascript ui for rest services
Ioan Eugen Stan
Ā 
Declarative Services - Dependency Injection OSGi Style
Felix Meschberger
Ā 
Declarative Services - Dependency Injection OSGi Style
Felix Meschberger
Ā 
Angular training - Day 3 - custom directives, $http, $resource, setup with ye...
murtazahaveliwala
Ā 
Angular.js Primer in Aalto University
SC5.io
Ā 
Language enhancements in cold fusion 11
ColdFusionConference
Ā 
TypeScript for Java Developers
Yakov Fain
Ā 
Workshop 23: ReactJS, React & Redux testing
Visual Engineering
Ā 
dokumen.tips_rediscovering-spring-with-spring-boot1 (1).pdf
Appster1
Ā 
dokumen.tips_rediscovering-spring-with-spring-boot1.pdf
Appster1
Ā 
How and why i roll my own node.js framework
Ben Lin
Ā 
SCR Annotations for Fun and Profit
Mike Pfaff
Ā 
Osgi
Heena Madan
Ā 
Ad

Recently uploaded (20)

PPT
Coupa-Kickoff-Meeting-Template presentai
annapureddyn
Ā 
PDF
How Open Source Changed My Career by abdelrahman ismail
a0m0rajab1
Ā 
PDF
Beyond Automation: The Role of IoT Sensor Integration in Next-Gen Industries
Rejig Digital
Ā 
PDF
A Day in the Life of Location Data - Turning Where into How.pdf
Precisely
Ā 
PPTX
Coupa-Overview _Assumptions presentation
annapureddyn
Ā 
PDF
AI Unleashed - Shaping the Future -Starting Today - AIOUG Yatra 2025 - For Co...
Sandesh Rao
Ā 
PDF
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
Ā 
PPTX
cloud computing vai.pptx for the project
vaibhavdobariyal79
Ā 
PDF
Google I/O Extended 2025 Baku - all ppts
HusseinMalikMammadli
Ā 
PDF
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
Ā 
PPTX
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
Ā 
PDF
Tea4chat - another LLM Project by Kerem Atam
a0m0rajab1
Ā 
PPTX
Dev Dives: Automate, test, and deploy in one place—with Unified Developer Exp...
AndreeaTom
Ā 
PDF
Oracle AI Vector Search- Getting Started and what's new in 2025- AIOUG Yatra ...
Sandesh Rao
Ā 
PDF
Event Presentation Google Cloud Next Extended 2025
minhtrietgect
Ā 
PDF
A Strategic Analysis of the MVNO Wave in Emerging Markets.pdf
IPLOOK Networks
Ā 
PDF
SparkLabs Primer on Artificial Intelligence 2025
SparkLabs Group
Ā 
PDF
Cloud-Migration-Best-Practices-A-Practical-Guide-to-AWS-Azure-and-Google-Clou...
Artjoker Software Development Company
Ā 
PDF
Software Development Methodologies in 2025
KodekX
Ā 
PDF
Orbitly Pitch Deck|A Mission-Driven Platform for Side Project Collaboration (...
zz41354899
Ā 
Coupa-Kickoff-Meeting-Template presentai
annapureddyn
Ā 
How Open Source Changed My Career by abdelrahman ismail
a0m0rajab1
Ā 
Beyond Automation: The Role of IoT Sensor Integration in Next-Gen Industries
Rejig Digital
Ā 
A Day in the Life of Location Data - Turning Where into How.pdf
Precisely
Ā 
Coupa-Overview _Assumptions presentation
annapureddyn
Ā 
AI Unleashed - Shaping the Future -Starting Today - AIOUG Yatra 2025 - For Co...
Sandesh Rao
Ā 
Automating ArcGIS Content Discovery with FME: A Real World Use Case
Safe Software
Ā 
cloud computing vai.pptx for the project
vaibhavdobariyal79
Ā 
Google I/O Extended 2025 Baku - all ppts
HusseinMalikMammadli
Ā 
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
Ā 
New ThousandEyes Product Innovations: Cisco Live June 2025
ThousandEyes
Ā 
Tea4chat - another LLM Project by Kerem Atam
a0m0rajab1
Ā 
Dev Dives: Automate, test, and deploy in one place—with Unified Developer Exp...
AndreeaTom
Ā 
Oracle AI Vector Search- Getting Started and what's new in 2025- AIOUG Yatra ...
Sandesh Rao
Ā 
Event Presentation Google Cloud Next Extended 2025
minhtrietgect
Ā 
A Strategic Analysis of the MVNO Wave in Emerging Markets.pdf
IPLOOK Networks
Ā 
SparkLabs Primer on Artificial Intelligence 2025
SparkLabs Group
Ā 
Cloud-Migration-Best-Practices-A-Practical-Guide-to-AWS-Azure-and-Google-Clou...
Artjoker Software Development Company
Ā 
Software Development Methodologies in 2025
KodekX
Ā 
Orbitly Pitch Deck|A Mission-Driven Platform for Side Project Collaboration (...
zz41354899
Ā 

AngularJS application architecture

  • 2. Separation of Concerns Rule of 1 ā— each component has 1 role ā— 1 component per file ā— each component has a single purpose
  • 3. Separation of Concerns - example Classifying concerns: ā— Cross-Cutting and generic ā—‹ logging ā—‹ exception handling ā— Cross-Cutting and feature-specific ā—‹ a service fetching Customer data ā— Features ā—‹ Customer Controller ā—‹ Customer Address widget
  • 4. Consistent syntax Many things can be done with different styles. It is strongly recommended to stick with one, especially when working in team!
  • 5. Consistent syntax - example It is often needed to create an alias for the this reference. WHY: in JavaScript a scope is created by a function definition (and not by {} blocks) → while nesting function definitions, the reference to the ā€œoriginalā€ this is lost.
  • 6. Consistent syntax - example function foo(){ this.x = 5; // other code function bar(){ // can’t access x through ā€œthisā€ // this ā€œthisā€ belongs to bar this.x = 6; } }
  • 7. Consistent syntax - example function foo(){ var self = this; self.x = 5; // other code function bar(){ // can access ā€œexternalā€ x through ā€œselfā€ this.x = 6; console.log(self.x); } }
  • 8. Consistent syntax - example widely used aliases ā— in controllers: var vm = this; // view model ā— in general js: var self = this;
  • 9. Consistent syntax - services angular.module('globalServices') .service('paymentService', PaymentService); // a service is a SINGLETON /* @ngInject */ function PaymentService($http, tokenService){ var service = { validateCardNumber: validateCardNumber, properCardNumberLength: properCardNumberLength }; return service; // implementation }
  • 10. Organizing the App can be by type of by feature by type can be ok for small-medium sized apps. When the size grows this gets confusing. larger app → by feature, then by type
  • 11. naming conventions Controllers: avoid the suffix ā€œControllerā€ use uppercase for the function name (it’s a constructor) Factories/Services: same as file name Directives: same as file name + short and consistent prefix (e.g. ā€œebā€)
  • 13. Modules use angular.module() for both declaring and fetching modules. angular.module(ā€˜app’, []); // CREATES angular.module(ā€˜app’); // FETCHES var app = angular.module(ā€˜app’, []); //not recommended
  • 14. Modules Aggregate dependencies, in order to avoid an overly long list of dependencies in our modules. Use a root ā€œapp.coreā€ module to aggregate 3rd party and other generic modules.
  • 16. Controllers ā— only presentation logic in here ā— don’t use anonymous functions ā— use the ā€œController Asā€ syntax with ā€œthisā€ instead of scope ā— separate registration, injection, declaration angular.module(ā€˜app’).controller(ā€˜foo’, Foo); Foo.$inject = [ā€˜$http’, ā€˜$scope’]; function Foo($http, $scope){ … }
  • 17. Controllers Declare the ā€œController Asā€ in ngRoutes, whenever possible, also using resolve for bootstrapping logic controller: ā€˜Controller’ controllerAs: ā€˜ctrl’ resolve: { message: [ā€˜customerService’, function(customerService) { return customerService.getGreetingMessage(); }] }
  • 18. Controllers The controller can be injected with ā€œmessageā€ before the controller is instantiated → good mechanism for bootstrapping logic, better than ā€œapp.runā€ when logic should be specific to the controller Controller.$inject = [ā€˜message’]; function Controller(message){ … }
  • 19. AJAX - sequential requests $http.get(PRICELIST_URL) .then(function (data) { pricelist = data['data']; console.log('AFTER CALL 1 __ ' + pricelist + '(pricelist)'); return $http.get(CURRENCY_URL); }) .then(function (data) { currency = data['data']; var actualUrl = TARIFFS_URL.replace('{priceListId}', pricelist); return $http.get(actualUrl); }) .then(function (data){ console.log('AFTER CALL 3 __ (tariffs) n' + JSON.stringify(data['data'])); });
  • 20. AJAX - parallel requests $q.all([fn1(), fn2(),]); array of functions each returning a Promise function fn1(){ return $http.get(SERVICE_URL); }
  • 21. Tips using value/constant to keep everything in the scope of the application. constants and values can be injected. angular.module('application').constant('origin', 'Sydney'); service('simpleService', ['origin', function (origin) { // implementation ... }
  • 22. Tips It’s usually nice to consider … ā— using ngAnnotate (e.g. /* @ngInject */) ā— using jshint (to impose some coding style) ā— using JavaScript ā—‹ especially iterators over arrays: ā–  someArray.forEach(fn) ā–  someArray.filter(fn) ā–  someArray.some(fn) ā–  someArray.every(fn) ā–  someArray.map(fn)
  • 23. Unit Testing - installation ā— choose a framework (e.g. Jasmine) ā— choose a test runner (e.g. Karma) ā— setup: npm install -g karma npm install -g karma-cli in the project folder run the following karma init
  • 24. Unit Testing - configuring ā— in the project root a karma.conf.js file specifies settings for the tests ā—‹ make sure that the file property in the file references an array of file path where the JS app file and the test are located! ā— Typically, most important things to test are Services, as they’re the components which hold business logic
  • 25. Unit Testing - example describe('testPaymentService', function () { var paymentService, $httpBackend; beforeEach(module('globalServices')); beforeEach(function () { inject(function($injector){ $httpBackend = $injector.get('$httpBackend'); paymentService = $injector.get('paymentService'); }); }); afterEach(function() { $httpBackend.verifyNoOutstandingExpectation(); $httpBackend.verifyNoOutstandingRequest(); }); it('should check mastercard', function () { $httpBackend .when('GET', REST_API_URL + '/services/payment/validateCreditCard/5105105105105100') .respond('MASTERCARD'); var res = paymentService.validateCardNumber('5105105105105100'); $httpBackend.flush(); expect(res.$$state.value.data).toEqual('MASTERCARD'); }); });
  • 26. E2E Testing - installation ā— choose a framework (e.g. Jasmine) ā— choose a test runner (e.g. Protractor) ā— setup: npm install -g protractor in the project folder run the following, to start the Selenium WebDriver webdriver-manager start
  • 27. Configuring create the configuration file. Copy the following into conf.js: exports.config = { seleniumAddress: 'http://localhost:4444/wd/hub', specs: ['todo-spec.js'] }; This configuration tells Protractor where your test files (specs) are, and where to talk to your Selenium Server (seleniumAddress).
  • 28. Write a test A protractor test, manipulates the actual elements in the app launching the browser and picking up stuff in the page through matchers. Run it with protractor conf.js describe('Ebuero CSW number fields validation', function () { beforeEach(function () { browser.sleep(2000); browser.get(URL); ... }); it('should format, validate and copy the phone, mobile and fax number', function () { companyName.sendKeys('000TEST000 ebuero AG'); ... expect(faxNumber.getAttribute('value')).toBe(FORMATTED_PHONE_NUMBER); element(by.cssContainingText('option', 'AG')).click(); nextButton1.click(); expect(createErrorBox.isDisplayed()).toBeFalsy(); }); });
  • 29. References ā— John Papa’s course on PluralSight ā— Style guide: https://github.com/johnpapa/angular-styleguide ā— More on Services, Providers: http://slides.wesalvaro.com/20121113/#/2/5 ā— Possible JSON security threat: http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle- json-vulnerability.aspx/