Merge remote-tracking branch 'remotes/angular.io/master'

# Conflicts:
#	README.md
#	public/contribute.jade
#	public/docs/_examples/cb-component-communication/e2e-spec.ts
#	public/docs/ts/latest/glossary.jade
#	public/docs/ts/latest/guide/architecture.jade
#	public/docs/ts/latest/guide/forms.jade
#	public/docs/ts/latest/guide/npm-packages.jade
#	public/docs/ts/latest/guide/template-syntax.jade
#	public/docs/ts/latest/guide/webpack.jade
#	public/docs/ts/latest/quickstart.jade
#	public/docs/ts/latest/tutorial/toh-pt5.jade
This commit is contained in:
Zhimin YE (Rex) 2016-06-01 09:51:27 +01:00
commit 72efc8f055
83 changed files with 1254 additions and 937 deletions

View File

@ -18,7 +18,8 @@ before_script:
install:
- npm install --no-optional
- npm install --prefix public/docs/_examples
- npm run webdriver:update --prefix public/docs/_examples
- npm install --prefix public/docs/_examples/_protractor
- npm run webdriver:update --prefix public/docs/_examples/_protractor
- gulp add-example-boilerplate
script:
- gulp $SCRIPT

View File

@ -22,6 +22,10 @@
"source": "/docs/ts/latest/guide/setup.html",
"destination": "/docs/ts/latest/index.html"
},
{
"source": "/docs/ts/latest/testing",
"destination": "/docs/ts/latest/guide/testing.html"
},
{
"source": "/cheatsheet",
"destination": "/docs/ts/latest/guide/cheatsheet.html"

View File

@ -38,6 +38,7 @@ var TEMP_PATH = './_temp';
var DOCS_PATH = path.join(PUBLIC_PATH, 'docs');
var EXAMPLES_PATH = path.join(DOCS_PATH, '_examples');
var EXAMPLES_PROTRACTOR_PATH = path.join(EXAMPLES_PATH, '_protractor');
var NOT_API_DOCS_GLOB = path.join(PUBLIC_PATH, './{docs/*/latest/!(api),!(docs)}/**/*');
var RESOURCES_PATH = path.join(PUBLIC_PATH, 'resources');
var LIVE_EXAMPLES_PATH = path.join(RESOURCES_PATH, 'live-examples');
@ -86,107 +87,134 @@ var _exampleBoilerplateFiles = [
var _exampleDartWebBoilerPlateFiles = ['styles.css'];
var _exampleProtractorBoilerplateFiles = [
'tsconfig.json'
];
/**
* Run Protractor End-to-End Specs for Doc Samples
* Alias for 'run-e2e-tests'
*/
gulp.task('e2e', runE2e);
gulp.task('run-e2e-tests', runE2e);
/**
* Run Protractor End-to-End Tests for Doc Samples
*
* Flags
* --filter to filter/select _example app subdir names
* e.g. gulp run-e2e-tests --filter=foo // all example apps with 'foo' in their folder names.
* e.g. gulp e2e --filter=foo // all example apps with 'foo' in their folder names.
*
* --fast by-passes the npm install and webdriver update
* Use it for repeated test runs (but not the FIRST run)
* e.g. gulp run-e2e-tests --fast
* e.g. gulp e2e --fast
*
* --lang to filter by code language
* e.g. gulp run-e2e-tests --lang=ts // only TypeScript apps
* e.g. gulp e2e --lang=ts // only TypeScript apps
* default is (ts|js)
* all means (ts|js|dart)
*/
gulp.task('run-e2e-tests', function() {
function runE2e() {
var promise;
if (argv.fast) {
// fast; skip all setup
promise = Promise.resolve(true);
} else {
// Not 'fast'; do full setup
/*
// Not 'fast'; do full setup
var spawnInfo = spawnExt('npm', ['install'], { cwd: EXAMPLES_PATH});
promise = spawnInfo.promise.then(function() {
copyExampleBoilerplate();
spawnInfo = spawnExt('npm', ['run', 'webdriver:update'], {cwd: EXAMPLES_PATH});
return spawnInfo.promise;
});
}
*/
// Not 'fast'; do full setup
gutil.log('runE2e: install _protractor stuff');
var spawnInfo = spawnExt('npm', ['install'], { cwd: EXAMPLES_PROTRACTOR_PATH});
promise = spawnInfo.promise
.then(function() {
gutil.log('runE2e: install _examples stuff');
spawnInfo = spawnExt('npm', ['install'], { cwd: EXAMPLES_PATH})
return spawnInfo.promise;
})
.then(function() {
copyExampleBoilerplate();
gutil.log('runE2e: update webdriver');
spawnInfo = spawnExt('npm', ['run', 'webdriver:update'], {cwd: EXAMPLES_PROTRACTOR_PATH});
return spawnInfo.promise;
});
};
var outputFile = path.join(process.cwd(), 'protractor-results.txt');
promise.then(function() {
return findAndRunE2eTests(argv.filter);
return findAndRunE2eTests(argv.filter, outputFile);
}).then(function(status) {
reportStatus(status);
reportStatus(status, outputFile);
if (status.failed.length > 0){
return Promise.reject('Some test suites failed');
}
}).catch(function(e) {
gutil.log(e);
process.exit(1);
process.exitCode = 1;
});
});
return promise;
}
// finds all of the *e2e-spec.tests under the _examples folder along
// with the corresponding apps that they should run under. Then run
// each app/spec collection sequentially.
function findAndRunE2eTests(filter) {
function findAndRunE2eTests(filter, outputFile) {
// create an output file with header.
var lang = (argv.lang || '(ts|js)').toLowerCase();
if (lang === 'all') { lang = '(ts|js|dart)'; }
var startTime = new Date().getTime();
// create an output file with header.
var outputFile = path.join(process.cwd(), 'protractor-results.txt');
var header = `Doc Sample Protractor Results for ${lang} on ${new Date().toLocaleString()}\n`;
header += argv.fast ?
' Fast Mode (--fast): no npm install, webdriver update, or boilerplate copy\n' :
' Slow Mode: npm install, webdriver update, and boilerplate copy\n';
header += ` Filter: ${filter ? filter : 'All tests'}\n\n`;
fs.writeFileSync(outputFile, header);
// create an array of combos where each
// combo consists of { examplePath: ... , protractorConfigFilename: ... }
var exeConfigs = [];
var examplePaths = [];
var e2eSpecPaths = getE2eSpecPaths(EXAMPLES_PATH);
var srcConfig = path.join(EXAMPLES_PATH, 'protractor.config.js');
e2eSpecPaths.forEach(function(specPath) {
e2eSpecPaths.forEach(function(specPath) {
var destConfig = path.join(specPath, 'protractor.config.js');
fsExtra.copySync(srcConfig, destConfig);
// get all of the examples under each dir where a pcFilename is found
examplePaths = getExamplePaths(specPath, true);
localExamplePaths = getExamplePaths(specPath, true);
// Filter by language
examplePaths = examplePaths.filter(function (fn) {
localExamplePaths = localExamplePaths.filter(function (fn) {
return fn.match('/'+lang+'$') != null;
});
if (filter) {
examplePaths = examplePaths.filter(function (fn) {
localExamplePaths = localExamplePaths.filter(function (fn) {
return fn.match(filter) != null;
})
}
examplePaths.forEach(function(exPath) {
exeConfigs.push( { examplePath: exPath, protractorConfigFilename: destConfig });
localExamplePaths.forEach(function(examplePath) {
examplePaths.push(examplePath);
})
});
// run the tests sequentially
var status = { passed: [], failed: [] };
return exeConfigs.reduce(function (promise, combo) {
return examplePaths.reduce(function (promise, examplePath) {
return promise.then(function () {
var isDart = combo.examplePath.indexOf('/dart') > -1;
var isDart = examplePath.indexOf('/dart') > -1;
var runTests = isDart ? runE2eDartTests : runE2eTsTests;
return runTests(combo.examplePath, combo.protractorConfigFilename, outputFile).then(function(ok) {
return runTests(examplePath, outputFile).then(function(ok) {
var arr = ok ? status.passed : status.failed;
arr.push(combo.examplePath);
arr.push(examplePath);
})
});
}, Q.resolve()).then(function() {
var stopTime = new Date().getTime();
status.elapsedTime = (stopTime - startTime)/1000;
fs.appendFileSync(outputFile, '\nElaped Time: ' + status.elapsedTime + ' seconds');
return status;
});
}
@ -194,15 +222,15 @@ function findAndRunE2eTests(filter) {
// start the example in appDir; then run protractor with the specified
// fileName; then shut down the example. All protractor output is appended
// to the outputFile.
function runE2eTsTests(appDir, protractorConfigFilename, outputFile) {
function runE2eTsTests(appDir, outputFile) {
// start the app
var appRunSpawnInfo = spawnExt('npm',['run','http-server:e2e', '--', '-s' ], { cwd: appDir });
var tscRunSpawnInfo = spawnExt('npm',['run','tsc'], { cwd: appDir });
return runProtractor(tscRunSpawnInfo.promise, appDir, appRunSpawnInfo, protractorConfigFilename, outputFile);
return runProtractor(tscRunSpawnInfo.promise, appDir, appRunSpawnInfo, outputFile);
}
function runProtractor(prepPromise, appDir, appRunSpawnInfo, protractorConfigFilename, outputFile) {
function runProtractor(prepPromise, appDir, appRunSpawnInfo, outputFile) {
return prepPromise
.catch(function(){
var emsg = `AppDir failed during compile: ${appDir}\n\n`;
@ -212,10 +240,10 @@ function runProtractor(prepPromise, appDir, appRunSpawnInfo, protractorConfigFil
})
.then(function (data) {
// start protractor
var pcFilename = path.resolve(protractorConfigFilename); // need to resolve because we are going to be running from a different dir
var spawnInfo = spawnExt('npm', [ 'run', 'protractor', '--', pcFilename,
'--params.appDir=' + appDir, '--params.outputFile=' + outputFile], { cwd: EXAMPLES_PATH });
return spawnInfo.promise
var specFilename = path.resolve(`${appDir}/../e2e-spec.ts`);
var spawnInfo = spawnExt('npm', [ 'run', 'protractor', '--', 'protractor.config.js',
`--specs=${specFilename}`, '--params.appDir=' + appDir, '--params.outputFile=' + outputFile], { cwd: EXAMPLES_PROTRACTOR_PATH });
return spawnInfo.promise;
})
.then(
function() { return finish(true);},
@ -233,7 +261,7 @@ function runProtractor(prepPromise, appDir, appRunSpawnInfo, protractorConfigFil
// start the server in appDir/build/web; then run protractor with the specified
// fileName; then shut down the example. All protractor output is appended
// to the outputFile.
function runE2eDartTests(appDir, protractorConfigFilename, outputFile) {
function runE2eDartTests(appDir, outputFile) {
var deployDir = path.resolve(path.join(appDir, 'build/web'));
gutil.log('AppDir for Dart e2e: ' + appDir);
gutil.log('Deploying from: ' + deployDir);
@ -247,24 +275,28 @@ function runE2eDartTests(appDir, protractorConfigFilename, outputFile) {
var prepPromise = pubUpgradeSpawnInfo.promise.then(function (data) {
return spawnExt('pub', ['build'], { cwd: appDir }).promise;
});
return runProtractor(prepPromise, appDir, appRunSpawnInfo, protractorConfigFilename, outputFile);
return runProtractor(prepPromise, appDir, appRunSpawnInfo, outputFile);
}
function reportStatus(status) {
gutil.log('Suites passed:');
function reportStatus(status, outputFile) {
var log = [''];
log.push('Suites passed:');
status.passed.forEach(function(val) {
gutil.log(' ' + val);
log.push(' ' + val);
});
if (status.failed.length == 0) {
gutil.log('All tests passed');
log.push('All tests passed');
} else {
gutil.log('Suites failed:');
log.push('Suites failed:');
status.failed.forEach(function (val) {
gutil.log(' ' + val);
log.push(' ' + val);
});
}
gutil.log('Elapsed time: ' + status.elapsedTime + ' seconds');
log.push('\nElapsed time: ' + status.elapsedTime + ' seconds');
var log = log.join('\n');
gutil.log(log);
fs.appendFileSync(outputFile, log);
}
// returns both a promise and the spawned process so that it can be killed if needed.
@ -312,7 +344,7 @@ gulp.task('help', taskListing.withFilters(function(taskName) {
return shouldRemove;
}));
// requires admin access
// requires admin access because it adds symlinks
gulp.task('add-example-boilerplate', function() {
var realPath = path.join(EXAMPLES_PATH, '/node_modules');
var nodeModulesPaths = getNodeModulesPaths(EXAMPLES_PATH);
@ -332,11 +364,18 @@ gulp.task('add-example-boilerplate', function() {
return copyExampleBoilerplate();
});
// copies boilerplate files to locations
// where an example app is found
gulp.task('_copy-example-boilerplate', copyExampleBoilerplate);
// copies boilerplate files to locations
// where an example app is found
// also copies certain web files (e.g., styles.css) to ~/_examples/**/dart/**/web
// also copies protractor.config.js file
function copyExampleBoilerplate() {
gutil.log('Copying example boilerplate files');
var sourceFiles = _exampleBoilerplateFiles.map(function(fn) {
return path.join(EXAMPLES_PATH, fn);
});
@ -351,12 +390,14 @@ function copyExampleBoilerplate() {
.then(function() {
return copyFiles(dartWebSourceFiles, dartExampleWebPaths);
})
// copy protractor.config.js from _examples dir to each subdir that
// copy files from _examples/_protractor dir to each subdir that
// contains a e2e-spec file.
.then(function() {
var sourceFiles = [ path.join(EXAMPLES_PATH, 'protractor.config.js') ];
var protractorSourceFiles =
_exampleProtractorBoilerplateFiles
.map(function(name) {return path.join(EXAMPLES_PROTRACTOR_PATH, name);});;
var e2eSpecPaths = getE2eSpecPaths(EXAMPLES_PATH);
return copyFiles(sourceFiles, e2eSpecPaths);
return copyFiles(protractorSourceFiles, e2eSpecPaths);
});
}
@ -371,6 +412,15 @@ gulp.task('remove-example-boilerplate', function() {
fsUtils.removeSymlink(linkPath);
});
deleteExampleBoilerPlate();
});
// deletes boilerplate files that were added by copyExampleBoilerplate
// from locations where an example app is found
gulp.task('_delete-example-boilerplate', deleteExampleBoilerPlate);
function deleteExampleBoilerPlate() {
gutil.log('Deleting example boilerplate files');
var examplePaths = getExamplePaths(EXAMPLES_PATH);
var dartExampleWebPaths = getDartExampleWebPaths(EXAMPLES_PATH);
@ -379,10 +429,11 @@ gulp.task('remove-example-boilerplate', function() {
return deleteFiles(_exampleDartWebBoilerPlateFiles, dartExampleWebPaths);
})
.then(function() {
var protractorFiles = _exampleProtractorBoilerplateFiles;
var e2eSpecPaths = getE2eSpecPaths(EXAMPLES_PATH);
return deleteFiles(['protractor.config.js'], e2eSpecPaths);
})
});
return deleteFiles(protractorFiles, e2eSpecPaths);
});
}
gulp.task('serve-and-sync', ['build-docs'], function (cb) {
// watchAndSync({devGuide: true, apiDocs: true, apiExamples: true, localFiles: true}, cb);
@ -640,7 +691,7 @@ function linkChecker(options) {
var handlers = {
robots: function(robots, customData){},
html: function(tree, robots, response, pageUrl, customData){
//gutil.log('Scanning ' + pageUrl);docs/ts/latest/api/core/
// gutil.log('Scanning ' + pageUrl);
},
junk: function(result, customData){},
@ -657,8 +708,8 @@ function linkChecker(options) {
}
var msg = '\n [' + result.html.location.line + ', ' + result.brokenReason + '] ' + result.url.resolved;
fs.appendFileSync(outputFile, msg);
//gutil.log(msg);
//gutil.log(result);
// gutil.log(msg);
// gutil.log(result);
},
page: function(error, pageUrl, customData){},
@ -686,8 +737,11 @@ function linkChecker(options) {
var startTime = new Date().getTime();
try {
gutil.log('link checker started');
siteChecker.enqueue(siteUrl, customData);
} catch (err) {
gutil.log('link checker died');
console.error('link checker died', err);
deferred.reject(err);
}
return deferred.promise;
@ -744,7 +798,7 @@ function deleteFiles(baseFileNames, destPaths) {
// TODO: filter out all paths that are subdirs of another
// path in the result.
function getE2eSpecPaths(basePath) {
var paths = getPaths(basePath, '*e2e-spec.js', true);
var paths = getPaths(basePath, '*e2e-spec.+(js|ts)', true);
return _.uniq(paths);
}

View File

@ -322,7 +322,7 @@
"name": "Elad Bezalel",
"picture": "/resources/images/bios/eladbezalel.jpg",
"website": "https://github.com/EladBezalel",
"bio": "Elad is a fullstack developer with a very storng love for design. Since 8 years old, he's been designing in Photoshop and later on fell in love with programing. This strong bond between design and computer programming gave birth to a new kind of love. And he is currently doing the combination of both, as a core member of the ngMaterial project.",
"bio": "Elad is a fullstack developer with a very strong love for design. Since 8 years old, he's been designing in Photoshop and later on fell in love with programing. This strong bond between design and computer programming gave birth to a new kind of love. And he is currently doing the combination of both, as a core member of the ngMaterial project.",
"type": "Community"
},

View File

@ -27,7 +27,7 @@
"devDependencies": {
"archiver": "^0.16.0",
"assert-plus": "^0.1.5",
"broken-link-checker": "0.7.0",
"broken-link-checker": "0.7.1",
"browser-sync": "^2.9.3",
"canonical-path": "0.0.2",
"cross-spawn": "^2.1.0",

View File

@ -24,13 +24,18 @@
//- TS arrays vs. Dart lists
- var _Array = 'Array';
- var _array = 'array';
//- Deprecate now that we have the articles _a and _an
- var _an_array = 'an array';
//- Promise vs. Future, etc
- var _Promise = 'Promise';
- var _PromiseUrl = 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise';
- var _PromiseLinked = '<a href="' + _PromiseUrl + '">' + _Promise + '</a>';
- var _Observable = 'Observable';
//- Directories & folders
- var _appDir = 'app';
- var _indexHtmlDir = 'project root';
- var _mainDir = _appDir;
//- Location of sample code
- var _liveLink = 'live link';

View File

@ -34,9 +34,9 @@
p Our goal is to deliver a lean, lightweight set of Angular-based UI elements that implement the material design specification for use in Angular single-page applications (SPAs).
p 我们的目标是精益、轻量级、基于Angular的一组UI组件它们实现了material设计规范可以用在Angular单页面应用中。
a(href="https://github.com/angular/material/blob/master/CONTRIBUTING.md" class="button" md-button) Contribute to Angular Material
a(href="https://github.com/angular/material/blob/master/CONTRIBUTING.md" class="button" md-button).
帮助Angular Material
a(href="https://github.com/angular/material/blob/master/.github/CONTRIBUTING.md" class="button" md-button) Contribute to Angular Material
a(href="https://github.com/angular/material/blob/master/.github/CONTRIBUTING.md" class="button" md-button) 帮助Angular Material
.l-sub-section
h3 AngularFire

View File

@ -0,0 +1,14 @@
/// <reference path="typings/index.d.ts" />
// Defined in protractor.config.js
declare function setProtractorToNg1Mode(): void;
declare function sendKeys(element: protractor.ElementFinder, str: string): webdriver.promise.Promise<void>;
declare function describeIf(cond: boolean, name: string, func: Function): void;
declare function itIf(cond: boolean, name: string, func: Function): void;
declare namespace protractor {
interface IBrowser {
appIsTs: boolean;
appIsJs: boolean;
}
}

View File

@ -0,0 +1,19 @@
{
"name": "angular2-examples-protractor",
"version": "1.0.0",
"description": "Manage _protractor folder installations",
"scripts": {
"postinstall": "typings install",
"typings": "typings",
"protractor": "protractor",
"webdriver:update": "webdriver-manager update"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"protractor": "^3.3.0",
"typings": "^1.0.4"
},
"repository": {}
}

View File

@ -26,10 +26,6 @@ exports.config = {
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// Spec patterns are relative to this config file
specs: ['**/*e2e-spec.js' ],
// For angular2 tests
useAllAngular2AppRoots: true,
@ -86,6 +82,11 @@ exports.config = {
defaultTimeoutInterval: 10000,
showTiming: true,
print: function() {}
},
beforeLaunch: function() {
// add TS support for specs
require('ts-node').register();
}
};
@ -117,7 +118,7 @@ function sendKeys(element, str) {
}
function Reporter(options) {
var _defaultOutputFile = path.resolve(process.cwd(), "../../", 'protractor-results.txt');
var _defaultOutputFile = path.resolve(process.cwd(), "../../../../", 'protractor-results.txt');
options.outputFile = options.outputFile || _defaultOutputFile;
var _root = { appDir: options.appDir, suites: [] };

View File

@ -0,0 +1,16 @@
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true
},
"files": [
"e2e-spec.ts"
]
}

View File

@ -0,0 +1,9 @@
{
"globalDependencies": {
"angular-protractor": "registry:dt/angular-protractor#1.5.0+20160425143459",
"core-js": "registry:dt/core-js#0.0.0+20160317120654",
"jasmine": "registry:dt/jasmine#2.2.0+20160505161446",
"node": "registry:dt/node#4.0.0+20160509154515",
"selenium-webdriver": "registry:dt/selenium-webdriver#2.44.0+20160317120654"
}
}

View File

@ -1,48 +1,49 @@
/// <reference path='../_protractor/e2e.d.ts' />
describe('Architecture', function () {
var _title = "Hero List";
let title = 'Hero List';
beforeAll(function () {
browser.get('');
});
function itReset(name, func) {
function itReset(name: string, func: (v: void) => any) {
it(name, function() {
browser.get('').then(func);
});
}
it('should display correct title: ' + _title, function () {
expect(element(by.css('h2')).getText()).toEqual(_title);
it('should display correct title: ' + title, function () {
expect(element(by.css('h2')).getText()).toEqual(title);
});
it('should display correct detail after selection', function() {
var detailView = element(by.css('hero-detail'));
let detailView = element(by.css('hero-detail'));
expect(detailView.isPresent()).toBe(false);
// select the 2nd element
var selectEle = element.all(by.css('hero-list > div')).get(1);
let selectEle = element.all(by.css('hero-list > div')).get(1);
selectEle.click().then(function() {
return selectEle.getText();
}).then(function(selectedHeroName) {
// works but too specific if we change the app
// expect(selectedHeroName).toEqual('Mr. Nice');
expect(detailView.isDisplayed()).toBe(true);
var detailTitleEle = element(by.css('hero-detail > h4'));
let detailTitleEle = element(by.css('hero-detail > h4'));
expect(detailTitleEle.getText()).toContain(selectedHeroName);
});
})
});
itReset('should display correct detail after modification', function() {
var detailView = element(by.css('hero-detail'));
let detailView = element(by.css('hero-detail'));
expect(detailView.isPresent()).toBe(false);
// select the 2nd element
var selectEle = element.all(by.css('hero-list > div')).get(1);
let selectEle = element.all(by.css('hero-list > div')).get(1);
selectEle.click().then(function () {
return selectEle.getText();
}).then(function (selectedHeroName) {
var detailTitleEle = element(by.css('hero-detail > h4'));
let detailTitleEle = element(by.css('hero-detail > h4'));
expect(detailTitleEle.getText()).toContain(selectedHeroName);
var heroNameEle = element.all(by.css('hero-detail input')).get(0);
let heroNameEle = element.all(by.css('hero-detail input')).get(0);
// check that both the initial selected item and the detail title reflect changes
// made to the input box.
@ -56,6 +57,6 @@ describe('Architecture', function () {
// expect(heroNameEle.getText()).toEqual(selectedHeroName);
expect(heroNameEle.getAttribute('value')).toEqual(selectedHeroName + 'foo');
});
})
});
});

View File

@ -1,6 +1,7 @@
/// <reference path='../_protractor/e2e.d.ts' />
describe('Attribute directives', function () {
var _title = "My First Attribute Directive";
let _title = 'My First Attribute Directive';
beforeAll(function () {
browser.get('');
@ -11,14 +12,15 @@ describe('Attribute directives', function () {
});
it('should be able to select green highlight', function () {
var highlightedEle = element(by.cssContainingText('p', 'Highlight me'));
var lightGreen = "rgba(144, 238, 144, 1)";
let highlightedEle = element(by.cssContainingText('p', 'Highlight me'));
let lightGreen = 'rgba(144, 238, 144, 1)';
expect(highlightedEle.getCssValue('background-color')).not.toEqual(lightGreen);
// var greenRb = element(by.cssContainingText('input', 'Green'));
var greenRb = element.all(by.css('input')).get(0);
// let greenRb = element(by.cssContainingText('input', 'Green'));
let greenRb = element.all(by.css('input')).get(0);
greenRb.click().then(function() {
browser.actions().mouseMove(highlightedEle).perform();
// TypeScript Todo: find the right type for highlightedEle
browser.actions().mouseMove(highlightedEle as any).perform();
expect(highlightedEle.getCssValue('background-color')).toEqual(lightGreen);
});

View File

@ -1,3 +1,4 @@
/// <reference path='../_protractor/e2e.d.ts' />
describe('Angular 1 to 2 Quick Reference Tests', function () {
beforeAll(function () {
@ -10,7 +11,7 @@ describe('Angular 1 to 2 Quick Reference Tests', function () {
it('should display proper movie data', function () {
// We check only a few samples
var expectedSamples = [
let expectedSamples: any[] = [
{row: 0, column: 0, element: 'img', attr: 'src', value: 'images/hero.png', contains: true},
{row: 0, column: 2, value: 'Celeritas'},
{row: 1, column: 3, matches: /Dec 1[678], 2015/}, // absorb timezone dif; we care about date format
@ -21,18 +22,18 @@ describe('Angular 1 to 2 Quick Reference Tests', function () {
];
// Go through the samples
var movieRows = getMovieRows();
for (var i = 0; i < expectedSamples.length; i++) {
var sample = expectedSamples[i];
var tableCell = movieRows.get(sample.row)
let movieRows = getMovieRows();
for (let i = 0; i < expectedSamples.length; i++) {
let sample = expectedSamples[i];
let tableCell = movieRows.get(sample.row)
.all(by.tagName('td')).get(sample.column);
// Check the cell or its nested element
var elementToCheck = sample.element
let elementToCheck = sample.element
? tableCell.element(by.tagName(sample.element))
: tableCell;
// Check element attribute or text
var valueToCheck = sample.attr
let valueToCheck = sample.attr
? elementToCheck.getAttribute(sample.attr)
: elementToCheck.getText();
@ -48,38 +49,38 @@ describe('Angular 1 to 2 Quick Reference Tests', function () {
});
it('should display images after Show Poster', function () {
testPosterButtonClick("Show Poster", true);
testPosterButtonClick('Show Poster', true);
});
it('should hide images after Hide Poster', function () {
testPosterButtonClick("Hide Poster", false);
testPosterButtonClick('Hide Poster', false);
});
it('should display no movie when no favorite hero is specified', function () {
testFavoriteHero(null, "Please enter your favorite hero.");
testFavoriteHero(null, 'Please enter your favorite hero.');
});
it('should display no movie for Magneta', function () {
testFavoriteHero("Magneta", "No movie, sorry!");
testFavoriteHero('Magneta', 'No movie, sorry!');
});
it('should display a movie for Mr. Nice', function () {
testFavoriteHero("Mr. Nice", "Excellent choice!");
testFavoriteHero('Mr. Nice', 'Excellent choice!');
});
function testImagesAreDisplayed(isDisplayed) {
var expectedMovieCount = 3;
function testImagesAreDisplayed(isDisplayed: boolean) {
let expectedMovieCount = 3;
var movieRows = getMovieRows();
let movieRows = getMovieRows();
expect(movieRows.count()).toBe(expectedMovieCount);
for (var i = 0; i < expectedMovieCount; i++) {
var movieImage = movieRows.get(i).element(by.css('td > img'));
for (let i = 0; i < expectedMovieCount; i++) {
let movieImage = movieRows.get(i).element(by.css('td > img'));
expect(movieImage.isDisplayed()).toBe(isDisplayed);
}
}
function testPosterButtonClick(expectedButtonText, isDisplayed) {
var posterButton = element(by.css('movie-list tr > th > button'));
function testPosterButtonClick(expectedButtonText: string, isDisplayed: boolean) {
let posterButton = element(by.css('movie-list tr > th > button'));
expect(posterButton.getText()).toBe(expectedButtonText);
posterButton.click().then(function () {
@ -91,11 +92,11 @@ describe('Angular 1 to 2 Quick Reference Tests', function () {
return element.all(by.css('movie-list tbody > tr'));
}
function testFavoriteHero(heroName, expectedLabel) {
var movieListComp = element(by.tagName('movie-list'));
var heroInput = movieListComp.element(by.tagName('input'));
var favoriteHeroLabel = movieListComp.element(by.tagName('h3'));
var resultLabel = movieListComp.element(by.css('span > p'));
function testFavoriteHero(heroName: string, expectedLabel: string) {
let movieListComp = element(by.tagName('movie-list'));
let heroInput = movieListComp.element(by.tagName('input'));
let favoriteHeroLabel = movieListComp.element(by.tagName('h3'));
let resultLabel = movieListComp.element(by.css('span > p'));
heroInput.clear().then(function () {
sendKeys(heroInput, heroName || '').then(function () {

View File

@ -1,3 +1,4 @@
/// <reference path='../_protractor/e2e.d.ts' />
describe('Component Communication Cookbook Tests', function () {
@ -8,16 +9,16 @@ describe('Component Communication Cookbook Tests', function () {
describe('Parent-to-child communication', function() {
// #docregion parent-to-child
// ...
var _heroNames = ['Mr. IQ', 'Magneta', 'Bombasto'];
var _masterName = 'Master';
let _heroNames = ['Mr. IQ', 'Magneta', 'Bombasto'];
let _masterName = 'Master';
it('should pass properties to children properly', function () {
var parent = element.all(by.tagName('hero-parent')).get(0);
var heroes = parent.all(by.tagName('hero-child'));
let parent = element.all(by.tagName('hero-parent')).get(0);
let heroes = parent.all(by.tagName('hero-child'));
for (var i = 0; i < _heroNames.length; i++) {
var childTitle = heroes.get(i).element(by.tagName('h3')).getText();
var childDetail = heroes.get(i).element(by.tagName('p')).getText();
for (let i = 0; i < _heroNames.length; i++) {
let childTitle = heroes.get(i).element(by.tagName('h3')).getText();
let childDetail = heroes.get(i).element(by.tagName('p')).getText();
expect(childTitle).toEqual(_heroNames[i] + ' says:')
expect(childDetail).toContain(_masterName)
}
@ -30,22 +31,22 @@ describe('Component Communication Cookbook Tests', function () {
// #docregion parent-to-child-setter
// ...
it('should display trimmed, non-empty names', function () {
var _nonEmptyNameIndex = 0;
var _nonEmptyName = '"Mr. IQ"';
var parent = element.all(by.tagName('name-parent')).get(0);
var hero = parent.all(by.tagName('name-child')).get(_nonEmptyNameIndex);
let _nonEmptyNameIndex = 0;
let _nonEmptyName = '"Mr. IQ"';
let parent = element.all(by.tagName('name-parent')).get(0);
let hero = parent.all(by.tagName('name-child')).get(_nonEmptyNameIndex);
var displayName = hero.element(by.tagName('h3')).getText();
let displayName = hero.element(by.tagName('h3')).getText();
expect(displayName).toEqual(_nonEmptyName)
});
it('should replace empty name with default name', function () {
var _emptyNameIndex = 1;
var _defaultName = '"<no name set>"';
var parent = element.all(by.tagName('name-parent')).get(0);
var hero = parent.all(by.tagName('name-child')).get(_emptyNameIndex);
let _emptyNameIndex = 1;
let _defaultName = '"<no name set>"';
let parent = element.all(by.tagName('name-parent')).get(0);
let hero = parent.all(by.tagName('name-child')).get(_emptyNameIndex);
var displayName = hero.element(by.tagName('h3')).getText();
let displayName = hero.element(by.tagName('h3')).getText();
expect(displayName).toEqual(_defaultName)
});
// ...
@ -57,26 +58,26 @@ describe('Component Communication Cookbook Tests', function () {
// ...
// Test must all execute in this exact order
it('should set expected initial values', function () {
var actual = getActual();
let actual = getActual();
var initialLabel = "Version 1.23";
var initialLog = 'major changed from {} to 1, minor changed from {} to 23';
let initialLabel = 'Version 1.23';
let initialLog = 'major changed from {} to 1, minor changed from {} to 23';
expect(actual.label).toBe(initialLabel);
expect(actual.count).toBe(1);
expect(actual.logs.get(0).getText()).toBe(initialLog);
});
it('should set expected values after clicking "Minor" twice', function () {
var repoTag = element(by.tagName('version-parent'));
var newMinorButton = repoTag.all(by.tagName('button')).get(0);
it('should set expected values after clicking \'Minor\' twice', function () {
let repoTag = element(by.tagName('version-parent'));
let newMinorButton = repoTag.all(by.tagName('button')).get(0);
newMinorButton.click().then(function() {
newMinorButton.click().then(function() {
var actual = getActual();
let actual = getActual();
var labelAfter2Minor = "Version 1.25";
var logAfter2Minor = 'minor changed from 24 to 25';
let labelAfter2Minor = 'Version 1.25';
let logAfter2Minor = 'minor changed from 24 to 25';
expect(actual.label).toBe(labelAfter2Minor);
expect(actual.count).toBe(3);
@ -85,15 +86,15 @@ describe('Component Communication Cookbook Tests', function () {
});
});
it('should set expected values after clicking "Major" once', function () {
var repoTag = element(by.tagName('version-parent'));
var newMajorButton = repoTag.all(by.tagName('button')).get(1);
it('should set expected values after clicking \'Major\' once', function () {
let repoTag = element(by.tagName('version-parent'));
let newMajorButton = repoTag.all(by.tagName('button')).get(1);
newMajorButton.click().then(function() {
var actual = getActual();
let actual = getActual();
var labelAfterMajor = "Version 2.0";
var logAfterMajor = 'major changed from 1 to 2, minor changed from 25 to 0';
let labelAfterMajor = 'Version 2.0';
let logAfterMajor = 'major changed from 1 to 2, minor changed from 25 to 0';
expect(actual.label).toBe(labelAfterMajor);
expect(actual.count).toBe(4);
@ -102,10 +103,10 @@ describe('Component Communication Cookbook Tests', function () {
});
function getActual() {
var versionTag = element(by.tagName('version-child'));
var label = versionTag.element(by.tagName('h3')).getText();
var ul = versionTag.element((by.tagName('ul')));
var logs = ul.all(by.tagName('li'));
let versionTag = element(by.tagName('version-child'));
let label = versionTag.element(by.tagName('h3')).getText();
let ul = versionTag.element((by.tagName('ul')));
let logs = ul.all(by.tagName('li'));
return {
label: label,
@ -122,28 +123,28 @@ describe('Component Communication Cookbook Tests', function () {
// #docregion child-to-parent
// ...
it('should not emit the event initially', function () {
var voteLabel = element(by.tagName('vote-taker'))
let voteLabel = element(by.tagName('vote-taker'))
.element(by.tagName('h3')).getText();
expect(voteLabel).toBe("Agree: 0, Disagree: 0");
expect(voteLabel).toBe('Agree: 0, Disagree: 0');
});
it('should process Agree vote', function () {
var agreeButton1 = element.all(by.tagName('my-voter')).get(0)
let agreeButton1 = element.all(by.tagName('my-voter')).get(0)
.all(by.tagName('button')).get(0);
agreeButton1.click().then(function() {
var voteLabel = element(by.tagName('vote-taker'))
let voteLabel = element(by.tagName('vote-taker'))
.element(by.tagName('h3')).getText();
expect(voteLabel).toBe("Agree: 1, Disagree: 0");
expect(voteLabel).toBe('Agree: 1, Disagree: 0');
});
});
it('should process Disagree vote', function () {
var agreeButton1 = element.all(by.tagName('my-voter')).get(1)
let agreeButton1 = element.all(by.tagName('my-voter')).get(1)
.all(by.tagName('button')).get(1);
agreeButton1.click().then(function() {
var voteLabel = element(by.tagName('vote-taker'))
let voteLabel = element(by.tagName('vote-taker'))
.element(by.tagName('h3')).getText();
expect(voteLabel).toBe("Agree: 1, Disagree: 1");
expect(voteLabel).toBe('Agree: 1, Disagree: 1');
});
});
// ...
@ -158,23 +159,23 @@ describe('Component Communication Cookbook Tests', function () {
countDownTimerTests('countdown-parent-vc')
});
function countDownTimerTests(parentTag) {
function countDownTimerTests(parentTag: string) {
// #docregion countdown-timer-tests
// ...
it('timer and parent seconds should match', function () {
var parent = element(by.tagName(parentTag));
var message = parent.element(by.tagName('countdown-timer')).getText();
let parent = element(by.tagName(parentTag));
let message = parent.element(by.tagName('countdown-timer')).getText();
browser.sleep(10); // give `seconds` a chance to catchup with `message`
var seconds = parent.element(by.className('seconds')).getText();
let seconds = parent.element(by.className('seconds')).getText();
expect(message).toContain(seconds);
});
it('should stop the countdown', function () {
var parent = element(by.tagName(parentTag));
var stopButton = parent.all(by.tagName('button')).get(1);
let parent = element(by.tagName(parentTag));
let stopButton = parent.all(by.tagName('button')).get(1);
stopButton.click().then(function() {
var message = parent.element(by.tagName('countdown-timer')).getText();
let message = parent.element(by.tagName('countdown-timer')).getText();
expect(message).toContain('Holding');
});
});
@ -187,10 +188,10 @@ describe('Component Communication Cookbook Tests', function () {
// #docregion bidirectional-service
// ...
it('should announce a mission', function () {
var missionControl = element(by.tagName('mission-control'));
var announceButton = missionControl.all(by.tagName('button')).get(0);
let missionControl = element(by.tagName('mission-control'));
let announceButton = missionControl.all(by.tagName('button')).get(0);
announceButton.click().then(function () {
var history = missionControl.all(by.tagName('li'));
let history = missionControl.all(by.tagName('li'));
expect(history.count()).toBe(1);
expect(history.get(0).getText()).toMatch(/Mission.* announced/);
});
@ -208,14 +209,14 @@ describe('Component Communication Cookbook Tests', function () {
testConfirmMission(2, 4, 'Swigert');
});
function testConfirmMission(buttonIndex, expectedLogCount, astronaut) {
var _confirmedLog = ' confirmed the mission';
var missionControl = element(by.tagName('mission-control'));
var confirmButton = missionControl.all(by.tagName('button')).get(buttonIndex);
function testConfirmMission(buttonIndex: number, expectedLogCount: number, astronaut: string) {
let _confirmedLog = ' confirmed the mission';
let missionControl = element(by.tagName('mission-control'));
let confirmButton = missionControl.all(by.tagName('button')).get(buttonIndex);
confirmButton.click().then(function () {
var history = missionControl.all(by.tagName('li'));
let history = missionControl.all(by.tagName('li'));
expect(history.count()).toBe(expectedLogCount);
expect(history.get(expectedLogCount-1).getText()).toBe(astronaut + _confirmedLog);
expect(history.get(expectedLogCount - 1).getText()).toBe(astronaut + _confirmedLog);
});
}
// ...

View File

@ -1,5 +1,12 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Cookbook: component-relative paths', function () {
interface Page {
title: protractor.ElementFinder;
absComp: protractor.ElementFinder;
relComp: protractor.ElementFinder;
}
function getPageStruct() {
return {
title: element( by.tagName( 'h1' )),
@ -8,7 +15,7 @@ describe('Cookbook: component-relative paths', function () {
}
}
var page;
let page: Page;
beforeAll(function () {
browser.get('');
page = getPageStruct();

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Dependency Injection Cookbook', function () {
beforeAll(function () {
@ -5,89 +6,89 @@ describe('Dependency Injection Cookbook', function () {
});
it('should render Logged in User example', function () {
var loggedInUser = element.all(by.xpath('//h3[text()="Logged in user"]')).get(0);
let loggedInUser = element.all(by.xpath('//h3[text()="Logged in user"]')).get(0);
expect(loggedInUser).toBeDefined();
});
it('"Bombasto" should be the logged in user', function () {
loggedInUser = element.all(by.xpath('//div[text()="Name: Bombasto"]')).get(0);
let loggedInUser = element.all(by.xpath('//div[text()="Name: Bombasto"]')).get(0);
expect(loggedInUser).toBeDefined();
});
it('should render sorted heroes', function () {
var sortedHeroes = element.all(by.xpath('//h3[text()="Sorted Heroes" and position()=1]')).get(0);
let sortedHeroes = element.all(by.xpath('//h3[text()="Sorted Heroes" and position()=1]')).get(0);
expect(sortedHeroes).toBeDefined();
});
it('Mr. Nice should be in sorted heroes', function () {
var sortedHero = element.all(by.xpath('//sorted-heroes/[text()="Mr. Nice" and position()=2]')).get(0);
let sortedHero = element.all(by.xpath('//sorted-heroes/[text()="Mr. Nice" and position()=2]')).get(0);
expect(sortedHero).toBeDefined();
});
it('RubberMan should be in sorted heroes', function () {
sortedHero = element.all(by.xpath('//sorted-heroes/[text()="RubberMan" and position()=3]')).get(0);
let sortedHero = element.all(by.xpath('//sorted-heroes/[text()="RubberMan" and position()=3]')).get(0);
expect(sortedHero).toBeDefined();
});
it('Magma should be in sorted heroes', function () {
sortedHero = element.all(by.xpath('//sorted-heroes/[text()="Magma"]')).get(0);
let sortedHero = element.all(by.xpath('//sorted-heroes/[text()="Magma"]')).get(0);
expect(sortedHero).toBeDefined();
});
it('should render Hero of the Month when DI deps are defined using provide()', function () {
var heroOfTheMonth = element.all(by.xpath('//h3[text()="Hero of the month"]')).get(0);
let heroOfTheMonth = element.all(by.xpath('//h3[text()="Hero of the month"]')).get(0);
expect(heroOfTheMonth).toBeDefined();
});
it('should render Hero of the Month when DI deps are defined using provide object literal', function () {
var heroOfTheMonth = element.all(by.xpath('//h3[text()="Hero of the month 2"]')).get(0);
let heroOfTheMonth = element.all(by.xpath('//h3[text()="Hero of the month 2"]')).get(0);
expect(heroOfTheMonth).toBeDefined();
});
it('should render Hero Bios', function () {
var heroBios = element.all(by.xpath('//h3[text()="Hero Bios"]')).get(0);
let heroBios = element.all(by.xpath('//h3[text()="Hero Bios"]')).get(0);
expect(heroBios).toBeDefined();
});
it('should render Magma\'s description in Hero Bios', function () {
var magmaText = element.all(by.xpath('//textarea[text()="Hero of all trades"]')).get(0);
let magmaText = element.all(by.xpath('//textarea[text()="Hero of all trades"]')).get(0);
expect(magmaText).toBeDefined();
});
it('should render Magma\'s phone in Hero Bios and Contacts', function () {
var magmaPhone = element.all(by.xpath('//div[text()="Phone #: 555-555-5555"]')).get(0);
let magmaPhone = element.all(by.xpath('//div[text()="Phone #: 555-555-5555"]')).get(0);
expect(magmaPhone).toBeDefined();
});
it('should render Hero-of-the-Month runner-ups when DI deps are defined using provide()', function () {
var runnersUp = element(by.id('rups1')).getText();
let runnersUp = element(by.id('rups1')).getText();
expect(runnersUp).toContain('RubberMan, Mr. Nice');
});
it('should render Hero-of-the-Month runner-ups when DI deps are defined using provide object literal', function () {
var runnersUp = element(by.id('rups2')).getText();
let runnersUp = element(by.id('rups2')).getText();
expect(runnersUp).toContain('RubberMan, Mr. Nice');
});
it('should render DateLogger log entry in Hero-of-the-Month', function () {
var logs = element.all(by.id('logs')).get(0).getText();
let logs = element.all(by.id('logs')).get(0).getText();
expect(logs).toContain('INFO: starting up at');
});
it('should highlight Hero Bios and Contacts container when mouseover', function () {
var target = element(by.css('div[myHighlight="yellow"]'))
var yellow = "rgba(255, 255, 0, 1)";
let target = element(by.css('div[myHighlight="yellow"]'))
let yellow = 'rgba(255, 255, 0, 1)';
expect(target.getCssValue('background-color')).not.toEqual(yellow);
browser.actions().mouseMove(target).perform();
browser.actions().mouseMove(target as any as webdriver.WebElement).perform();
expect(target.getCssValue('background-color')).toEqual(yellow);
});
describe('in Parent Finder', function () {
var cathy1 = element(by.css('alex cathy'));
var craig1 = element(by.css('alex craig'));
var carol1 = element(by.css('alex carol p'));
var carol2 = element(by.css('barry carol p'));
let cathy1 = element(by.css('alex cathy'));
let craig1 = element(by.css('alex craig'));
let carol1 = element(by.css('alex carol p'));
let carol2 = element(by.css('barry carol p'));
it('"Cathy" should find "Alex" via the component class', function () {
expect(cathy1.getText()).toContain('Found Alex via the component');
@ -104,5 +105,5 @@ describe('Dependency Injection Cookbook', function () {
it('"Carol" within "Barry" should have "Barry" parent', function () {
expect(carol2.getText()).toContain('Barry');
});
})
});
});

View File

@ -1,3 +1,5 @@
/// <reference path="../_protractor/e2e.d.ts" />
/* tslint:disable:quotemark */
describe('Dynamic Form', function () {
beforeAll(function () {
@ -5,17 +7,17 @@ describe('Dynamic Form', function () {
});
it('should submit form', function () {
var firstNameElement = element.all(by.css('input[id=firstName]')).get(0);
let firstNameElement = element.all(by.css('input[id=firstName]')).get(0);
expect(firstNameElement.getAttribute('value')).toEqual('Bombasto');
var emailElement = element.all(by.css('input[id=emailAddress]')).get(0);
var email = 'test@test.com';
let emailElement = element.all(by.css('input[id=emailAddress]')).get(0);
let email = 'test@test.com';
emailElement.sendKeys(email);
expect(emailElement.getAttribute('value')).toEqual(email);
element(by.css('select option[value="solid"]')).click()
var saveButton = element.all(by.css('button')).get(0);
let saveButton = element.all(by.css('button')).get(0);
saveButton.click().then(function(){
expect(element(by.xpath("//strong[contains(text(),'Saved the following values')]")).isPresent()).toBe(true);
});

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
// gulp run-e2e-tests --filter=cb-set-document-title
describe('Set Document Title', function () {
@ -7,7 +8,7 @@ describe('Set Document Title', function () {
it('should set the document title', function () {
var titles = [
let titles = [
'Good morning!',
'Good afternoon!',
'Good evening!'

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('TypeScript to Javascript tests', function () {
beforeAll(function () {
@ -21,9 +22,9 @@ describe('TypeScript to Javascript tests', function () {
});
it('should support optional, attribute, and query injections', function () {
var app = element(by.css('hero-di-inject-additional'));
var h1 = app.element(by.css('h1'));
var okMsg = app.element(by.css('.ok-msg'));
let app = element(by.css('hero-di-inject-additional'));
let h1 = app.element(by.css('h1'));
let okMsg = app.element(by.css('.ok-msg'));
expect(h1.getText()).toBe('Tour of Heroes');
app.element(by.buttonText('OK')).click();
@ -31,8 +32,8 @@ describe('TypeScript to Javascript tests', function () {
});
it('should support component with inputs and outputs', function () {
var app = element(by.css('hero-io'));
var confirmComponent = app.element(by.css('my-confirm'));
let app = element(by.css('hero-io'));
let confirmComponent = app.element(by.css('my-confirm'));
confirmComponent.element(by.buttonText('OK')).click();
expect(app.element(by.cssContainingText('span', 'OK clicked')).isPresent()).toBe(true);
@ -42,8 +43,8 @@ describe('TypeScript to Javascript tests', function () {
});
it('should support host bindings and host listeners', function() {
var app = element(by.css('heroes-bindings'));
var h1 = app.element(by.css('h1'));
let app = element(by.css('heroes-bindings'));
let h1 = app.element(by.css('h1'));
expect(app.getAttribute('class')).toBe('heading');
expect(app.getAttribute('title')).toBe('Tooltip content');
@ -52,21 +53,21 @@ describe('TypeScript to Javascript tests', function () {
expect(h1.getAttribute('class')).toBe('active');
h1.click();
browser.actions().doubleClick(h1).perform();
browser.actions().doubleClick(h1 as any as webdriver.WebElement).perform();
expect(h1.getAttribute('class')).toBe('active');
});
it('should support content and view queries', function() {
var app = element(by.css('heroes-queries'));
var windstorm = app.element(by.css('hero:first-child'));
let app = element(by.css('heroes-queries'));
let windstorm = app.element(by.css('hero:first-child'));
app.element(by.buttonText('Activate')).click();
expect(windstorm.element(by.css('h2')).getAttribute('class')).toBe('active');
expect(windstorm.element(by.css('active-label')).getText()).toBe('Active');
});
function testTag(selector, expectedText) {
var component = element(by.css(selector));
function testTag(selector: string, expectedText: string) {
let component = element(by.css(selector));
expect(component.getText()).toBe(expectedText);
}

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Component Style Tests', function () {
beforeAll(function () {
@ -5,8 +6,8 @@ describe('Component Style Tests', function () {
});
it('scopes component styles to component view', function() {
var componentH1 = element(by.css('hero-app > h1'));
var externalH1 = element(by.css('body > h1'));
let componentH1 = element(by.css('hero-app > h1'));
let externalH1 = element(by.css('body > h1'));
expect(componentH1.getCssValue('fontWeight')).toEqual('normal');
expect(externalH1.getCssValue('fontWeight')).not.toEqual('normal');
@ -14,55 +15,55 @@ describe('Component Style Tests', function () {
it('allows styling :host element', function() {
var host = element(by.css('hero-details'));
let host = element(by.css('hero-details'));
expect(host.getCssValue('borderWidth')).toEqual('1px');
});
it('supports :host() in function form', function() {
var host = element(by.css('hero-details'));
let host = element(by.css('hero-details'));
host.element(by.buttonText('Activate')).click();
expect(host.getCssValue('borderWidth')).toEqual('3px');
});
it('allows conditional :host-context() styling', function() {
var h2 = element(by.css('hero-details h2'));
let h2 = element(by.css('hero-details h2'));
expect(h2.getCssValue('backgroundColor')).toEqual('rgba(238, 238, 255, 1)'); // #eeeeff
});
it('styles both view and content children with /deep/', function() {
var viewH3 = element(by.css('hero-team h3'));
var contentH3 = element(by.css('hero-controls h3'));
let viewH3 = element(by.css('hero-team h3'));
let contentH3 = element(by.css('hero-controls h3'));
expect(viewH3.getCssValue('fontStyle')).toEqual('italic');
expect(contentH3.getCssValue('fontStyle')).toEqual('italic');
});
it('includes styles loaded with CSS @import', function() {
var host = element(by.css('hero-details'));
let host = element(by.css('hero-details'));
expect(host.getCssValue('padding')).toEqual('10px');
});
it('processes template inline styles', function() {
var button = element(by.css('hero-controls button'));
var externalButton = element(by.css('body > button'));
let button = element(by.css('hero-controls button'));
let externalButton = element(by.css('body > button'));
expect(button.getCssValue('backgroundColor')).toEqual('rgba(255, 255, 255, 1)'); // #ffffff
expect(externalButton.getCssValue('backgroundColor')).not.toEqual('rgba(255, 255, 255, 1)');
});
it('processes template <link>s', function() {
var li = element(by.css('hero-team li:first-child'));
var externalLi = element(by.css('body > ul li'));
let li = element(by.css('hero-team li:first-child'));
let externalLi = element(by.css('body > ul li'));
expect(li.getCssValue('listStyleType')).toEqual('square');
expect(externalLi.getCssValue('listStyleType')).not.toEqual('square');
});
it('supports relative loading with moduleId', function() {
var host = element(by.css('quest-summary'));
let host = element(by.css('quest-summary'));
expect(host.getCssValue('color')).toEqual('rgba(255, 255, 255, 1)'); // #ffffff
});

View File

@ -1,8 +1,9 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Dependency Injection Tests', function () {
var expectedMsg;
let expectedMsg: string;
let expectedMsgRx: RegExp;
beforeAll(function () {
browser.get('');
@ -66,8 +67,8 @@ describe('Dependency Injection Tests', function () {
describe('Tests:', function() {
it('Tests display as expected', function () {
expectedMsg = /Tests passed/;
expect(element(by.css('#tests')).getText()).toMatch(expectedMsg);
expectedMsgRx = /Tests passed/;
expect(element(by.css('#tests')).getText()).toMatch(expectedMsgRx);
});
});
@ -147,22 +148,22 @@ describe('Dependency Injection Tests', function () {
describe('User/Heroes:', function() {
it('User is Bob - unauthorized', function () {
expectedMsg = /Bob, is not authorized/;
expect(element(by.css('#user')).getText()).toMatch(expectedMsg);
expectedMsgRx = /Bob, is not authorized/;
expect(element(by.css('#user')).getText()).toMatch(expectedMsgRx);
});
it('should have button', function () {
expect(element.all(by.cssContainingText('button','Next User'))
.get(0).isDisplayed()).toBe(true, "'Next User' button should be displayed");
expect(element.all(by.cssContainingText('button', 'Next User'))
.get(0).isDisplayed()).toBe(true, '\'Next User\' button should be displayed');
});
it('unauthorized user should have multiple unauthorized heroes', function () {
var heroes = element.all(by.css('#unauthorized hero-list div'));
let heroes = element.all(by.css('#unauthorized hero-list div'));
expect(heroes.count()).toBeGreaterThan(0);
});
it('unauthorized user should have no secret heroes', function () {
var heroes = element.all(by.css('#unauthorized hero-list div'));
let heroes = element.all(by.css('#unauthorized hero-list div'));
expect(heroes.count()).toBeGreaterThan(0);
heroes.filter(function(elem, index){
@ -170,7 +171,7 @@ describe('Dependency Injection Tests', function () {
return /secret/.test(text);
});
}).then(function(filteredElements) {
//console.log("******Secret heroes count: "+filteredElements.length);
// console.log("******Secret heroes count: "+filteredElements.length);
expect(filteredElements.length).toEqual(0);
});
});
@ -182,22 +183,22 @@ describe('Dependency Injection Tests', function () {
describe('after button click', function() {
beforeAll(function (done) {
var buttonEle = element.all(by.cssContainingText('button','Next User')).get(0);
let buttonEle = element.all(by.cssContainingText('button','Next User')).get(0);
buttonEle.click().then(done,done);
});
it('User is Alice - authorized', function () {
expectedMsg = /Alice, is authorized/;
expect(element(by.css('#user')).getText()).toMatch(expectedMsg);
expectedMsgRx = /Alice, is authorized/;
expect(element(by.css('#user')).getText()).toMatch(expectedMsgRx);
});
it('authorized user should have multiple authorized heroes ', function () {
var heroes = element.all(by.css('#authorized hero-list div'));
let heroes = element.all(by.css('#authorized hero-list div'));
expect(heroes.count()).toBeGreaterThan(0);
});
it('authorized user should have secret heroes', function () {
var heroes = element.all(by.css('#authorized hero-list div'));
let heroes = element.all(by.css('#authorized hero-list div'));
expect(heroes.count()).toBeGreaterThan(0);
heroes.filter(function(elem, index){
@ -205,7 +206,7 @@ describe('Dependency Injection Tests', function () {
return /secret/.test(text);
});
}).then(function(filteredElements) {
//console.log("******Secret heroes count: "+filteredElements.length);
// console.log("******Secret heroes count: "+filteredElements.length);
expect(filteredElements.length).toBeGreaterThan(0);
});
});

View File

@ -1,6 +1,7 @@
/// <reference path='../_protractor/e2e.d.ts' />
describe('Displaying Data Tests', function () {
var _title = "Tour of Heroes";
var _defaultHero = 'Windstorm'
let _title = 'Tour of Heroes';
let _defaultHero = 'Windstorm';
beforeAll(function () {
browser.get('');
@ -15,7 +16,7 @@ describe('Displaying Data Tests', function () {
});
it('should have heroes', function () {
var heroEls = element.all(by.css('li'));
let heroEls = element.all(by.css('li'));
expect(heroEls.count()).not.toBe(0, 'should have heroes');
});

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
describeIf(browser.appIsTs || browser.appIsJs, 'Forms Tests', function () {
beforeEach(function () {
@ -10,51 +11,51 @@ describeIf(browser.appIsTs || browser.appIsJs, 'Forms Tests', function () {
it('should not display message before submit', function () {
var ele = element(by.css('h2'));
let ele = element(by.css('h2'));
expect(ele.isDisplayed()).toBe(false);
});
it('should hide form after submit', function () {
var ele = element.all(by.css('h1')).get(0);
let ele = element.all(by.css('h1')).get(0);
expect(ele.isDisplayed()).toBe(true);
var b = element.all(by.css('button[type=submit]')).get(0);
let b = element.all(by.css('button[type=submit]')).get(0);
b.click().then(function() {
expect(ele.isDisplayed()).toBe(false);
});
});
it('should display message after submit', function () {
var b = element.all(by.css('button[type=submit]')).get(0);
let b = element.all(by.css('button[type=submit]')).get(0);
b.click().then(function() {
expect(element(by.css('h2')).getText()).toContain('You submitted the following');
});
});
it('should hide form after submit', function () {
var alterEgoEle = element.all(by.css('input[ngcontrol=alterEgo]')).get(0);
let alterEgoEle = element.all(by.css('input[ngcontrol=alterEgo]')).get(0);
expect(alterEgoEle.isDisplayed()).toBe(true);
var submitButtonEle = element.all(by.css('button[type=submit]')).get(0);
let submitButtonEle = element.all(by.css('button[type=submit]')).get(0);
submitButtonEle.click().then(function() {
expect(alterEgoEle.isDisplayed()).toBe(false);
})
});
});
it('should reflect submitted data after submit', function () {
var test = 'testing 1 2 3';
var newValue;
var alterEgoEle = element.all(by.css('input[ngcontrol=alterEgo]')).get(0);
let test = 'testing 1 2 3';
let newValue: string;
let alterEgoEle = element.all(by.css('input[ngcontrol=alterEgo]')).get(0);
alterEgoEle.getAttribute('value').then(function(value) {
// alterEgoEle.sendKeys(test);
sendKeys(alterEgoEle, test);
newValue = value + test;
expect(alterEgoEle.getAttribute('value')).toEqual(newValue);
}).then(function() {
var b = element.all(by.css('button[type=submit]')).get(0);
let b = element.all(by.css('button[type=submit]')).get(0);
return b.click();
}).then(function() {
var alterEgoTextEle = element(by.cssContainingText('div', 'Alter Ego'));
let alterEgoTextEle = element(by.cssContainingText('div', 'Alter Ego'));
expect(alterEgoTextEle.isPresent()).toBe(true, 'cannot locate "Alter Ego" label');
var divEle = element(by.cssContainingText('div', newValue));
let divEle = element(by.cssContainingText('div', newValue));
expect(divEle.isPresent()).toBe(true, 'cannot locate div with this text: ' + newValue);
});
});

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Hierarchical dependency injection', function () {
beforeEach(function () {
@ -14,7 +15,7 @@ describe('Hierarchical dependency injection', function () {
});
it('should change to editor view after selection', function () {
var editButtonEle = element.all(by.cssContainingText('button','edit')).get(0);
let editButtonEle = element.all(by.cssContainingText('button','edit')).get(0);
editButtonEle.click().then(function() {
expect(editButtonEle.isDisplayed()).toBe(false, "edit button should be hidden after selection");
})
@ -29,19 +30,19 @@ describe('Hierarchical dependency injection', function () {
});
function testEdit(shouldSave) {
var inputEle;
let inputEle;
// select 2nd ele
var heroEle = element.all(by.css('heroes-list li')).get(1);
let heroEle = element.all(by.css('heroes-list li')).get(1);
// get the 2nd span which is the name of the hero
var heroNameEle = heroEle.all(by.css('hero-card span')).get(1);
var editButtonEle = heroEle.element(by.cssContainingText('button','edit'));
let heroNameEle = heroEle.all(by.css('hero-card span')).get(1);
let editButtonEle = heroEle.element(by.cssContainingText('button','edit'));
editButtonEle.click().then(function() {
inputEle = heroEle.element(by.css('hero-editor input'));
// return inputEle.sendKeys("foo");
return sendKeys(inputEle, "foo");
}).then(function() {
buttonName = shouldSave ? 'save' : 'cancel';
var buttonEle = heroEle.element(by.cssContainingText('button', buttonName));
let buttonEle = heroEle.element(by.cssContainingText('button', buttonName));
return buttonEle.click();
}).then(function() {
if (shouldSave) {

View File

@ -1,4 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Homepage Hello World', function () {
beforeAll(function () {
@ -6,15 +6,15 @@ describe('Homepage Hello World', function () {
});
// Does it even launch?
var expectedLabel = 'Name:';
let expectedLabel = 'Name:';
it('should display the label: ' + expectedLabel, function () {
expect(element(by.css('label')).getText()).toEqual(expectedLabel);
});
it('should display entered name', function () {
var testName = 'Bobby Joe';
var newValue;
var nameEle = element.all(by.css('input')).get(0);
let testName = 'Bobby Joe';
let newValue;
let nameEle = element.all(by.css('input')).get(0);
nameEle.getAttribute('value').then(function(value) {
// nameEle.sendKeys(testName); // should work but doesn't
sendKeys(nameEle, testName); // utility that does work
@ -22,7 +22,7 @@ describe('Homepage Hello World', function () {
expect(nameEle.getAttribute('value')).toEqual(newValue);
}).then(function() {
// Check the interpolated message built from name
var helloEle = element.all(by.css('h1')).get(0);
let helloEle = element.all(by.css('h1')).get(0);
expect(helloEle.getText()).toEqual('Hello ' + testName + '!');
});
});

View File

@ -1,4 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Homepage Tabs', function () {
beforeAll(function () {
@ -6,7 +6,7 @@ describe('Homepage Tabs', function () {
});
// Does it even launch?
var expectedAppTitle = 'Tabs Demo';
let expectedAppTitle = 'Tabs Demo';
it('should display app title: ' + expectedAppTitle, function () {
expect(element(by.css('h4')).getText()).toEqual(expectedAppTitle);
});

View File

@ -1,4 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Homepage Todo', function () {
beforeAll(function () {
@ -6,7 +6,7 @@ describe('Homepage Todo', function () {
});
// Does it even launch?
var expectedAppTitle = 'Todo';
let expectedAppTitle = 'Todo';
it('should display app title: ' + expectedAppTitle, function () {
expect(element(by.css('h2')).getText()).toEqual(expectedAppTitle);
});

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Lifecycle hooks', function () {
beforeAll(function () {
@ -9,10 +10,10 @@ describe('Lifecycle hooks', function () {
});
it('should support peek-a-boo', function () {
var pabComp = element(by.css('peek-a-boo-parent peek-a-boo'));
let pabComp = element(by.css('peek-a-boo-parent peek-a-boo'));
expect(pabComp.isPresent()).toBe(false, "should not be able to find the 'peek-a-boo' component");
var pabButton = element.all(by.css('peek-a-boo-parent button')).get(0);
var updateHeroButton = element.all(by.css('peek-a-boo-parent button')).get(1);
let pabButton = element.all(by.css('peek-a-boo-parent button')).get(0);
let updateHeroButton = element.all(by.css('peek-a-boo-parent button')).get(1);
expect(pabButton.getText()).toContain('Create Peek');
pabButton.click().then(function () {
expect(pabButton.getText()).toContain('Destroy Peek');
@ -30,12 +31,12 @@ describe('Lifecycle hooks', function () {
});
it('should support OnChanges hook', function () {
var onChangesViewEle = element.all(by.css('on-changes div')).get(0);
var inputEles = element.all(by.css('on-changes-parent input'));
var heroNameInputEle = inputEles.get(1);
var powerInputEle = inputEles.get(0);
var titleEle = onChangesViewEle.element(by.css('p'));
var changeLogEles = onChangesViewEle.all(by.css('div'));
let onChangesViewEle = element.all(by.css('on-changes div')).get(0);
let inputEles = element.all(by.css('on-changes-parent input'));
let heroNameInputEle = inputEles.get(1);
let powerInputEle = inputEles.get(0);
let titleEle = onChangesViewEle.element(by.css('p'));
let changeLogEles = onChangesViewEle.all(by.css('div'));
expect(titleEle.getText()).toContain('Windstorm can sing');
expect(changeLogEles.count()).toEqual(2, "should start with 2 messages");
@ -54,13 +55,13 @@ describe('Lifecycle hooks', function () {
});
it('should support DoCheck hook', function () {
var doCheckViewEle = element.all(by.css('do-check div')).get(0);
var inputEles = element.all(by.css('do-check-parent input'));
var heroNameInputEle = inputEles.get(1);
var powerInputEle = inputEles.get(0);
var titleEle = doCheckViewEle.element(by.css('p'));
var changeLogEles = doCheckViewEle.all(by.css('div'));
var logCount;
let doCheckViewEle = element.all(by.css('do-check div')).get(0);
let inputEles = element.all(by.css('do-check-parent input'));
let heroNameInputEle = inputEles.get(1);
let powerInputEle = inputEles.get(0);
let titleEle = doCheckViewEle.element(by.css('p'));
let changeLogEles = doCheckViewEle.all(by.css('div'));
let logCount;
expect(titleEle.getText()).toContain('Windstorm can sing');
changeLogEles.count().then(function(count) {
@ -86,12 +87,12 @@ describe('Lifecycle hooks', function () {
});
it('should support AfterView hooks', function () {
var parentEle = element(by.tagName('after-view-parent'));
var buttonEle = parentEle.element(by.tagName('button')); // Reset
var commentEle = parentEle.element(by.className('comment'));
var logEles = parentEle.all(by.css('h4 ~ div'));
var childViewInputEle = parentEle.element(by.css('my-child input'));
var logCount;
let parentEle = element(by.tagName('after-view-parent'));
let buttonEle = parentEle.element(by.tagName('button')); // Reset
let commentEle = parentEle.element(by.className('comment'));
let logEles = parentEle.all(by.css('h4 ~ div'));
let childViewInputEle = parentEle.element(by.css('my-child input'));
let logCount;
expect(childViewInputEle.getAttribute('value')).toContain('Magneta');
expect(commentEle.isPresent()).toBe(false, 'comment should not be in DOM');
@ -115,12 +116,12 @@ describe('Lifecycle hooks', function () {
it('should support AfterContent hooks', function () {
var parentEle = element(by.tagName('after-content-parent'));
var buttonEle = parentEle.element(by.tagName('button')); // Reset
var commentEle = parentEle.element(by.className('comment'));
var logEles = parentEle.all(by.css('h4 ~ div'));
var childViewInputEle = parentEle.element(by.css('my-child input'));
var logCount;
let parentEle = element(by.tagName('after-content-parent'));
let buttonEle = parentEle.element(by.tagName('button')); // Reset
let commentEle = parentEle.element(by.className('comment'));
let logEles = parentEle.all(by.css('h4 ~ div'));
let childViewInputEle = parentEle.element(by.css('my-child input'));
let logCount;
expect(childViewInputEle.getAttribute('value')).toContain('Magneta');
expect(commentEle.isPresent()).toBe(false, 'comment should not be in DOM');
@ -143,11 +144,11 @@ describe('Lifecycle hooks', function () {
});
it('should support spy\'s OnInit & OnDestroy hooks', function () {
var inputEle = element(by.css('spy-parent input'));
var addHeroButtonEle = element(by.cssContainingText('spy-parent button','Add Hero'));
var resetHeroesButtonEle = element(by.cssContainingText('spy-parent button','Reset Heroes'));
var heroEles = element.all(by.css('spy-parent div[mySpy'));
var logEles = element.all(by.css('spy-parent h4 ~ div'));
let inputEle = element(by.css('spy-parent input'));
let addHeroButtonEle = element(by.cssContainingText('spy-parent button','Add Hero'));
let resetHeroesButtonEle = element(by.cssContainingText('spy-parent button','Reset Heroes'));
let heroEles = element.all(by.css('spy-parent div[mySpy'));
let logEles = element.all(by.css('spy-parent h4 ~ div'));
expect(heroEles.count()).toBe(2, 'should have two heroes displayed');
expect(logEles.count()).toBe(2, 'should have two log entries');
sendKeys(inputEle, "-test-").then(function() {
@ -164,10 +165,10 @@ describe('Lifecycle hooks', function () {
});
it('should support "spy counter"', function () {
var updateCounterButtonEle = element(by.cssContainingText('counter-parent button','Update'));
var resetCounterButtonEle = element(by.cssContainingText('counter-parent button','Reset'));
var textEle = element(by.css('counter-parent my-counter > div'));
var logEles = element.all(by.css('counter-parent h4 ~ div'));
let updateCounterButtonEle = element(by.cssContainingText('counter-parent button','Update'));
let resetCounterButtonEle = element(by.cssContainingText('counter-parent button','Reset'));
let textEle = element(by.css('counter-parent my-counter > div'));
let logEles = element.all(by.css('counter-parent h4 ~ div'));
expect(textEle.getText()).toContain('Counter = 0');
expect(logEles.count()).toBe(2, 'should start with two log entries');
updateCounterButtonEle.click().then(function() {

View File

@ -69,6 +69,7 @@
"rimraf": "^2.5.2",
"style-loader": "^0.13.1",
"ts-loader": "^0.8.2",
"ts-node": "^0.7.3",
"typescript": "^1.8.10",
"typings": "^1.0.4",
"webpack": "^1.13.0",

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Pipes', function () {
beforeAll(function () {
@ -23,9 +24,9 @@ describe('Pipes', function () {
});
it('should be able to toggle birthday formats', function () {
var birthDayEle = element(by.css('hero-birthday2 > p'));
let birthDayEle = element(by.css('hero-birthday2 > p'));
expect(birthDayEle.getText()).toEqual("The hero's birthday is 4/15/1988");
var buttonEle = element(by.cssContainingText('hero-birthday2 > button', "Toggle Format"));
let buttonEle = element(by.cssContainingText('hero-birthday2 > button', "Toggle Format"));
expect(buttonEle.isDisplayed()).toBe(true);
buttonEle.click().then(function() {
expect(birthDayEle.getText()).toEqual("The hero's birthday is Friday, April 15, 1988");
@ -33,7 +34,7 @@ describe('Pipes', function () {
});
it('should be able to chain and compose pipes', function () {
var chainedPipeEles = element.all(by.cssContainingText('my-app p', "The chained hero's"));
let chainedPipeEles = element.all(by.cssContainingText('my-app p', "The chained hero's"));
expect(chainedPipeEles.count()).toBe(3, "should have 3 chained pipe examples");
expect(chainedPipeEles.get(0).getText()).toContain('APR 15, 1988');
expect(chainedPipeEles.get(1).getText()).toContain('FRIDAY, APRIL 15, 1988');
@ -41,15 +42,15 @@ describe('Pipes', function () {
});
it('should be able to use ExponentialStrengthPipe pipe', function () {
var ele = element(by.css('power-booster p'));
let ele = element(by.css('power-booster p'));
expect(ele.getText()).toContain('Super power boost: 1024');
});
it('should be able to use the exponential calculator', function () {
var eles = element.all(by.css('power-boost-calculator input'));
var baseInputEle = eles.get(0);
var factorInputEle = eles.get(1);
var outputEle = element(by.css('power-boost-calculator p'));
let eles = element.all(by.css('power-boost-calculator input'));
let baseInputEle = eles.get(0);
let factorInputEle = eles.get(1);
let outputEle = element(by.css('power-boost-calculator p'));
baseInputEle.clear().then(function() {
return sendKeys(baseInputEle, "7");
}).then(function() {
@ -63,11 +64,11 @@ describe('Pipes', function () {
it('should support flying heroes (pure) ', function () {
var nameEle = element(by.css('flying-heroes input[type="text"]'));
var canFlyCheckEle = element(by.css('flying-heroes #can-fly'));
var mutateCheckEle = element(by.css('flying-heroes #mutate'));
var resetEle = element(by.css('flying-heroes button'));
var flyingHeroesEle = element.all(by.css('flying-heroes #flyers div'));
let nameEle = element(by.css('flying-heroes input[type="text"]'));
let canFlyCheckEle = element(by.css('flying-heroes #can-fly'));
let mutateCheckEle = element(by.css('flying-heroes #mutate'));
let resetEle = element(by.css('flying-heroes button'));
let flyingHeroesEle = element.all(by.css('flying-heroes #flyers div'));
expect(canFlyCheckEle.getAttribute('checked')).toEqual('true', 'should default to "can fly"');
expect(mutateCheckEle.getAttribute('checked')).toEqual('true', 'should default to mutating array');
@ -94,11 +95,11 @@ describe('Pipes', function () {
it('should support flying heroes (impure) ', function () {
var nameEle = element(by.css('flying-heroes-impure input[type="text"]'));
var canFlyCheckEle = element(by.css('flying-heroes-impure #can-fly'));
var mutateCheckEle = element(by.css('flying-heroes-impure #mutate'));
var resetEle = element(by.css('flying-heroes-impure button'));
var flyingHeroesEle = element.all(by.css('flying-heroes-impure #flyers div'));
let nameEle = element(by.css('flying-heroes-impure input[type="text"]'));
let canFlyCheckEle = element(by.css('flying-heroes-impure #can-fly'));
let mutateCheckEle = element(by.css('flying-heroes-impure #mutate'));
let resetEle = element(by.css('flying-heroes-impure button'));
let flyingHeroesEle = element.all(by.css('flying-heroes-impure #flyers div'));
expect(canFlyCheckEle.getAttribute('checked')).toEqual('true', 'should default to "can fly"');
expect(mutateCheckEle.getAttribute('checked')).toEqual('true', 'should default to mutating array');

View File

@ -1,7 +1,7 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('QuickStart E2E Tests', function () {
var expectedMsg = 'My First Angular 2 App';
let expectedMsg = 'My First Angular 2 App';
beforeEach(function () {

View File

@ -1,123 +1,111 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Router', function () {
beforeAll(function () {
browser.get('');
});
function getPageStruct() {
hrefEles = element.all(by.css('my-app a'));
return {
hrefs: hrefEles,
routerParent: element(by.css('my-app > undefined')),
routerTitle: element(by.css('my-app > undefined > h2')),
crisisHref: hrefEles.get(0),
crisisList: element.all(by.css('my-app > undefined > undefined li')),
crisisDetail: element(by.css('my-app > undefined > undefined > div')),
crisisDetailTitle: element(by.css('my-app > undefined > undefined > div > h3')),
heroesHref: hrefEles.get(1),
heroesList: element.all(by.css('my-app > undefined li')),
heroDetail: element(by.css('my-app > undefined > div')),
heroDetailTitle: element(by.css('my-app > undefined > div > h3')),
beforeAll(function () {
browser.get('');
});
function getPageStruct() {
hrefEles = element.all(by.css('my-app a'));
return {
hrefs: hrefEles,
routerParent: element(by.css('my-app > undefined')),
routerTitle: element(by.css('my-app > undefined > h2')),
crisisHref: hrefEles.get(0),
crisisList: element.all(by.css('my-app > undefined > undefined li')),
crisisDetail: element(by.css('my-app > undefined > undefined > div')),
crisisDetailTitle: element(by.css('my-app > undefined > undefined > div > h3')),
heroesHref: hrefEles.get(1),
heroesList: element.all(by.css('my-app > undefined li')),
heroDetail: element(by.css('my-app > undefined > div')),
heroDetailTitle: element(by.css('my-app > undefined > div > h3')),
};
}
}
it('should be able to see the start screen', function () {
var page = getPageStruct();
expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices');
expect(page.crisisHref.getText()).toEqual("Crisis Center");
expect(page.heroesHref.getText()).toEqual("Heroes");
});
it('should be able to see crises center items', function () {
var page = getPageStruct();
expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries at start");
});
it('should be able to see hero items', function () {
var page = getPageStruct();
page.heroesHref.click().then(function() {
expect(page.routerTitle.getText()).toContain('HEROES');
expect(page.heroesList.count()).toBe(6, "should be 6 heroes");
it('should be able to see the start screen', function () {
var page = getPageStruct();
expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices');
expect(page.crisisHref.getText()).toEqual("Crisis Center");
expect(page.heroesHref.getText()).toEqual("Heroes");
});
});
it('should be able to toggle the views', function () {
var page = getPageStruct();
page.crisisHref.click().then(function() {
expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries");
return page.heroesHref.click();
}).then(function() {
expect(page.heroesList.count()).toBe(6, "should be 6 heroes");
it('should be able to see crises center items', function () {
var page = getPageStruct();
expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries at start");
});
});
it('should be able to edit and save details from the crisis center view', function () {
crisisCenterEdit(2, true);
});
it('should be able to edit and cancel details from the crisis center view', function () {
crisisCenterEdit(3, false);
});
it('should be able to edit and save details from the heroes view', function () {
var page = getPageStruct();
var heroEle, heroText;
page.heroesHref.click().then(function() {
heroEle = page.heroesList.get(4);
return heroEle.getText();
}).then(function(text) {
expect(text.length).toBeGreaterThan(0, 'should have some text');
// remove leading id from text
heroText = text.substr(text.indexOf(' ')).trim();
return heroEle.click();
}).then(function() {
expect(page.heroesList.count()).toBe(0, "should no longer see crisis center entries");
expect(page.heroDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
expect(page.heroDetailTitle.getText()).toContain(heroText);
var inputEle = page.heroDetail.element(by.css('input'));
return sendKeys(inputEle, '-foo');
}).then(function() {
expect(page.heroDetailTitle.getText()).toContain(heroText + '-foo');
var buttonEle = page.heroDetail.element(by.css('button'));
return buttonEle.click();
}).then(function() {
expect(heroEle.getText()).toContain(heroText + '-foo');
})
});
function crisisCenterEdit(index, shouldSave) {
var page = getPageStruct();
var crisisEle, crisisText;
page.crisisHref.click()
.then(function () {
crisisEle = page.crisisList.get(index);
return crisisEle.getText();
}).then(function (text) {
expect(text.length).toBeGreaterThan(0, 'should have some text');
// remove leading id from text
crisisText = text.substr(text.indexOf(' ')).trim();
return crisisEle.click();
}).then(function () {
expect(page.crisisList.count()).toBe(0, "should no longer see crisis center entries");
expect(page.crisisDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
expect(page.crisisDetailTitle.getText()).toContain(crisisText);
var inputEle = page.crisisDetail.element(by.css('input'));
return sendKeys(inputEle, '-foo');
}).then(function () {
expect(page.crisisDetailTitle.getText()).toContain(crisisText + '-foo');
var buttonEle = page.crisisDetail.element(by.cssContainingText('button', shouldSave ? 'Save' : 'Cancel'));
return buttonEle.click();
}).then(function () {
if (shouldSave) {
expect(crisisEle.getText()).toContain(crisisText + '-foo');
} else {
expect(crisisEle.getText()).not.toContain(crisisText + '-foo');
}
it('should be able to see hero items', function () {
var page = getPageStruct();
page.heroesHref.click().then(function () {
expect(page.routerTitle.getText()).toContain('HEROES');
expect(page.heroesList.count()).toBe(6, "should be 6 heroes");
});
});
}
it('should be able to toggle the views', function () {
var page = getPageStruct();
page.crisisHref.click().then(function () {
expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries");
return page.heroesHref.click();
}).then(function () {
expect(page.heroesList.count()).toBe(6, "should be 6 heroes");
});
});
it('should be able to edit and save details from the crisis center view', function () {
crisisCenterEdit(2, true);
});
it('should be able to edit and cancel details from the crisis center view', function () {
crisisCenterEdit(3, false);
});
it('should be able to edit and save details from the heroes view', function () {
var page = getPageStruct();
var heroEle, heroText;
page.heroesHref.click().then(function () {
heroEle = page.heroesList.get(4);
return heroEle.getText();
}).then(function (text) {
expect(text.length).toBeGreaterThan(0, 'should have some text');
// remove leading id from text
heroText = text.substr(text.indexOf(' ')).trim();
return heroEle.click();
}).then(function () {
expect(page.heroesList.count()).toBe(0, "should no longer see crisis center entries");
expect(page.heroDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
expect(page.heroDetailTitle.getText()).toContain(heroText);
var inputEle = page.heroDetail.element(by.css('input'));
return sendKeys(inputEle, '-foo');
}).then(function () {
expect(page.heroDetailTitle.getText()).toContain(heroText + '-foo');
var buttonEle = page.heroDetail.element(by.css('button'));
return buttonEle.click();
}).then(function () {
expect(heroEle.getText()).toContain(heroText + '-foo');
});
});
function crisisCenterEdit(index, shouldSave) {
var page = getPageStruct();
var crisisEle, crisisText;
page.crisisHref.click()
.then(function () {
crisisEle = page.crisisList.get(index);
return crisisEle.getText();
}).then(function (text) {
expect(text.length).toBeGreaterThan(0, 'should have some text');
// remove leading id from text
crisisText = text.substr(text.indexOf(' ')).trim();
return crisisEle.click();
}).then(function () {
expect(page.crisisList.count()).toBe(0, "should no longer see crisis center entries");
expect(page.crisisDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
expect(page.crisisDetailTitle.getText()).toContain(crisisText);
var inputEle = page.crisisDetail.element(by.css('input'));
return sendKeys(inputEle, '-foo');
}).then(function () {
expect(page.crisisDetailTitle.getText()).toContain(crisisText + '-foo');
var buttonEle = page.crisisDetail.element(by.cssContainingText('button', shouldSave ? 'Save' : 'Cancel'));
return buttonEle.click();
}).then(function () {
if (shouldSave) {
expect(crisisEle.getText()).toContain(crisisText + '-foo');
}
else {
expect(crisisEle.getText()).not.toContain(crisisText + '-foo');
}
});
}
});
//# sourceMappingURL=e2e-spec.js.map

View File

@ -0,0 +1,124 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Router', function () {
beforeAll(function () {
browser.get('');
});
function getPageStruct() {
hrefEles = element.all(by.css('my-app a'));
return {
hrefs: hrefEles,
routerParent: element(by.css('my-app > undefined')),
routerTitle: element(by.css('my-app > undefined > h2')),
crisisHref: hrefEles.get(0),
crisisList: element.all(by.css('my-app > undefined > undefined li')),
crisisDetail: element(by.css('my-app > undefined > undefined > div')),
crisisDetailTitle: element(by.css('my-app > undefined > undefined > div > h3')),
heroesHref: hrefEles.get(1),
heroesList: element.all(by.css('my-app > undefined li')),
heroDetail: element(by.css('my-app > undefined > div')),
heroDetailTitle: element(by.css('my-app > undefined > div > h3')),
}
}
it('should be able to see the start screen', function () {
let page = getPageStruct();
expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices');
expect(page.crisisHref.getText()).toEqual("Crisis Center");
expect(page.heroesHref.getText()).toEqual("Heroes");
});
it('should be able to see crises center items', function () {
let page = getPageStruct();
expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries at start");
});
it('should be able to see hero items', function () {
let page = getPageStruct();
page.heroesHref.click().then(function() {
expect(page.routerTitle.getText()).toContain('HEROES');
expect(page.heroesList.count()).toBe(6, "should be 6 heroes");
});
});
it('should be able to toggle the views', function () {
let page = getPageStruct();
page.crisisHref.click().then(function() {
expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries");
return page.heroesHref.click();
}).then(function() {
expect(page.heroesList.count()).toBe(6, "should be 6 heroes");
});
});
it('should be able to edit and save details from the crisis center view', function () {
crisisCenterEdit(2, true);
});
it('should be able to edit and cancel details from the crisis center view', function () {
crisisCenterEdit(3, false);
});
it('should be able to edit and save details from the heroes view', function () {
let page = getPageStruct();
let heroEle, heroText;
page.heroesHref.click().then(function() {
heroEle = page.heroesList.get(4);
return heroEle.getText();
}).then(function(text) {
expect(text.length).toBeGreaterThan(0, 'should have some text');
// remove leading id from text
heroText = text.substr(text.indexOf(' ')).trim();
return heroEle.click();
}).then(function() {
expect(page.heroesList.count()).toBe(0, "should no longer see crisis center entries");
expect(page.heroDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
expect(page.heroDetailTitle.getText()).toContain(heroText);
let inputEle = page.heroDetail.element(by.css('input'));
return sendKeys(inputEle, '-foo');
}).then(function() {
expect(page.heroDetailTitle.getText()).toContain(heroText + '-foo');
let buttonEle = page.heroDetail.element(by.css('button'));
return buttonEle.click();
}).then(function() {
expect(heroEle.getText()).toContain(heroText + '-foo');
})
});
function crisisCenterEdit(index, shouldSave) {
let page = getPageStruct();
let crisisEle, crisisText;
page.crisisHref.click()
.then(function () {
crisisEle = page.crisisList.get(index);
return crisisEle.getText();
}).then(function (text) {
expect(text.length).toBeGreaterThan(0, 'should have some text');
// remove leading id from text
crisisText = text.substr(text.indexOf(' ')).trim();
return crisisEle.click();
}).then(function () {
expect(page.crisisList.count()).toBe(0, "should no longer see crisis center entries");
expect(page.crisisDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
expect(page.crisisDetailTitle.getText()).toContain(crisisText);
let inputEle = page.crisisDetail.element(by.css('input'));
return sendKeys(inputEle, '-foo');
}).then(function () {
expect(page.crisisDetailTitle.getText()).toContain(crisisText + '-foo');
let buttonEle = page.crisisDetail.element(by.cssContainingText('button', shouldSave ? 'Save' : 'Cancel'));
return buttonEle.click();
}).then(function () {
if (shouldSave) {
expect(crisisEle.getText()).toContain(crisisText + '-foo');
} else {
expect(crisisEle.getText()).not.toContain(crisisText + '-foo');
}
});
}
});

View File

@ -3,7 +3,7 @@ import { Injectable } from '@angular/core';
/**
* Async modal dialog service
* DialogService makes this app easier to test by faking this service.
* TODO: better modal implemenation that doesn't use window.confirm
* TODO: better modal implementation that doesn't use window.confirm
*/
@Injectable()
export class DialogService {

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Router', function () {
beforeAll(function () {
@ -26,19 +27,19 @@ describe('Router', function () {
}
it('should be able to see the start screen', function () {
var page = getPageStruct();
let page = getPageStruct();
expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices');
expect(page.crisisHref.getText()).toEqual("Crisis Center");
expect(page.heroesHref.getText()).toEqual("Heroes");
});
it('should be able to see crises center items', function () {
var page = getPageStruct();
let page = getPageStruct();
expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries at start");
});
it('should be able to see hero items', function () {
var page = getPageStruct();
let page = getPageStruct();
page.heroesHref.click().then(function() {
expect(page.routerTitle.getText()).toContain('HEROES');
expect(page.heroesList.count()).toBe(6, "should be 6 heroes");
@ -46,7 +47,7 @@ describe('Router', function () {
});
it('should be able to toggle the views', function () {
var page = getPageStruct();
let page = getPageStruct();
page.crisisHref.click().then(function() {
expect(page.crisisList.count()).toBe(4, "should be 4 crisis center entries");
return page.heroesHref.click();
@ -64,8 +65,8 @@ describe('Router', function () {
});
it('should be able to edit and save details from the heroes view', function () {
var page = getPageStruct();
var heroEle, heroText;
let page = getPageStruct();
let heroEle, heroText;
page.heroesHref.click().then(function() {
heroEle = page.heroesList.get(4);
return heroEle.getText();
@ -78,11 +79,11 @@ describe('Router', function () {
expect(page.heroesList.count()).toBe(0, "should no longer see crisis center entries");
expect(page.heroDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
expect(page.heroDetailTitle.getText()).toContain(heroText);
var inputEle = page.heroDetail.element(by.css('input'));
let inputEle = page.heroDetail.element(by.css('input'));
return sendKeys(inputEle, '-foo');
}).then(function() {
expect(page.heroDetailTitle.getText()).toContain(heroText + '-foo');
var buttonEle = page.heroDetail.element(by.css('button'));
let buttonEle = page.heroDetail.element(by.css('button'));
return buttonEle.click();
}).then(function() {
expect(heroEle.getText()).toContain(heroText + '-foo');
@ -90,8 +91,8 @@ describe('Router', function () {
});
function crisisCenterEdit(index, shouldSave) {
var page = getPageStruct();
var crisisEle, crisisText;
let page = getPageStruct();
let crisisEle, crisisText;
page.crisisHref.click()
.then(function () {
crisisEle = page.crisisList.get(index);
@ -105,11 +106,11 @@ describe('Router', function () {
expect(page.crisisList.count()).toBe(0, "should no longer see crisis center entries");
expect(page.crisisDetail.isPresent()).toBe(true, 'should be able to see crisis detail');
expect(page.crisisDetailTitle.getText()).toContain(crisisText);
var inputEle = page.crisisDetail.element(by.css('input'));
let inputEle = page.crisisDetail.element(by.css('input'));
return sendKeys(inputEle, '-foo');
}).then(function () {
expect(page.crisisDetailTitle.getText()).toContain(crisisText + '-foo');
var buttonEle = page.crisisDetail.element(by.cssContainingText('button', shouldSave ? 'Save' : 'Cancel'));
let buttonEle = page.crisisDetail.element(by.cssContainingText('button', shouldSave ? 'Save' : 'Cancel'));
return buttonEle.click();
}).then(function () {
if (shouldSave) {

View File

@ -3,7 +3,7 @@ import { Injectable } from '@angular/core';
/**
* Async modal dialog service
* DialogService makes this app easier to test by faking this service.
* TODO: better modal implemenation that doesn't use window.confirm
* TODO: better modal implementation that doesn't use window.confirm
*/
@Injectable()
export class DialogService {

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Server Communication', function () {
beforeAll(function () {
@ -6,14 +7,14 @@ describe('Server Communication', function () {
describe('Tour of Heroes (Observable)', function () {
var initialHeroCount = 4;
var newHeroName = 'Mr. IQ';
var heroCountAfterAdd = 5;
let initialHeroCount = 4;
let newHeroName = 'Mr. IQ';
let heroCountAfterAdd = 5;
var heroListComp = element(by.tagName('hero-list'));
var addButton = heroListComp.element(by.tagName('button'));
var heroTags = heroListComp.all(by.tagName('li'));
var heroNameInput = heroListComp.element(by.tagName('input'));
let heroListComp = element(by.tagName('hero-list'));
let addButton = heroListComp.element(by.tagName('button'));
let heroTags = heroListComp.all(by.tagName('li'));
let heroNameInput = heroListComp.element(by.tagName('input'));
it('should exist', function() {
expect(heroListComp).toBeDefined('<hero-list> must exist');
@ -36,7 +37,7 @@ describe('Server Communication', function () {
sendKeys(heroNameInput, newHeroName);
addButton.click().then(function() {
expect(heroTags.count()).toBe(heroCountAfterAdd, 'A new hero should be added');
var newHeroInList = heroTags.get(heroCountAfterAdd - 1).getText();
let newHeroInList = heroTags.get(heroCountAfterAdd - 1).getText();
expect(newHeroInList).toBe(newHeroName, 'The hero should be added to the end of the list');
});
})
@ -45,9 +46,9 @@ describe('Server Communication', function () {
describe('Wikipedia Demo', function () {
it('should initialize the demo with empty result list', function () {
var myWikiComp = element(by.tagName('my-wiki'));
let myWikiComp = element(by.tagName('my-wiki'));
expect(myWikiComp).toBeDefined('<my-wiki> must exist');
var resultList = myWikiComp.all(by.tagName('li'));
let resultList = myWikiComp.all(by.tagName('li'));
expect(resultList.count()).toBe(0, 'result list must be empty');
});
@ -77,9 +78,9 @@ describe('Server Communication', function () {
describe('Smarter Wikipedia Demo', function () {
it('should initialize the demo with empty result list', function () {
var myWikiSmartComp = element(by.tagName('my-wiki-smart'));
let myWikiSmartComp = element(by.tagName('my-wiki-smart'));
expect(myWikiSmartComp).toBeDefined('<my-wiki-smart> must exist');
var resultList = myWikiSmartComp.all(by.tagName('li'));
let resultList = myWikiSmartComp.all(by.tagName('li'));
expect(resultList.count()).toBe(0, 'result list must be empty');
});
@ -111,14 +112,14 @@ describe('Server Communication', function () {
});
function testForResult(componentTagName, keyPressed, hasListBeforeSearch, done) {
var searchWait = 1000; // Wait for wikipedia but not so long that tests timeout
var wikiComponent = element(by.tagName(componentTagName));
let searchWait = 1000; // Wait for wikipedia but not so long that tests timeout
let wikiComponent = element(by.tagName(componentTagName));
expect(wikiComponent).toBeDefined('<' + componentTagName + '> must exist');
var searchBox = wikiComponent.element(by.tagName('input'));
let searchBox = wikiComponent.element(by.tagName('input'));
expect(searchBox).toBeDefined('<input> for search must exist');
searchBox.sendKeys(keyPressed).then(function () {
var resultList = wikiComponent.all(by.tagName('li'));
let resultList = wikiComponent.all(by.tagName('li'));
if (hasListBeforeSearch) {
expect(resultList.count()).toBeGreaterThan(0, 'result list should not be empty before search');

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Structural Directives', function () {
// tests interact - so we need beforeEach instead of beforeAll
@ -6,16 +7,16 @@ describe('Structural Directives', function () {
});
it('should be able to use ngFor, ngIf and ngWhen together', function () {
var allDivEles = element.all(by.css('structural-directives > div'));
let allDivEles = element.all(by.css('structural-directives > div'));
expect(allDivEles.get(0).getText()).toEqual('Mr. Nice');
expect(allDivEles.get(1).getText()).toEqual('Mr. Nice');
expect(allDivEles.get(4).getText()).toEqual('Ready');
});
it('should be able to toggle ngIf with a button', function () {
var setConditionButtonEle = element.all(by.css('button')).get(0);
var conditionTrueEles = element.all(by.cssContainingText('p', 'condition is true'));
var conditionFalseEles = element.all(by.cssContainingText('p', 'condition is false'));
let setConditionButtonEle = element.all(by.css('button')).get(0);
let conditionTrueEles = element.all(by.cssContainingText('p', 'condition is true'));
let conditionFalseEles = element.all(by.cssContainingText('p', 'condition is false'));
expect(conditionTrueEles.count()).toBe(2, 'should be two condition true elements');
expect(conditionFalseEles.count()).toBe(0, 'should be no condition false elements');
setConditionButtonEle.click().then(function() {
@ -25,13 +26,13 @@ describe('Structural Directives', function () {
});
it('should be able to compare use of ngIf with changing css visibility', function () {
var setConditionButtonEle = element.all(by.css('button')).get(0);
var ngIfButtonEle = element(by.cssContainingText('button', 'if | !if'));
var ngIfParentEle = ngIfButtonEle.element(by.xpath('..'));
var ngIfSiblingEle = ngIfParentEle.element(by.css('heavy-loader'));
var cssButtonEle = element(by.cssContainingText('button', 'show | hide'));
var cssSiblingEle = cssButtonEle.element(by.xpath('..')).element(by.css('heavy-loader'));
var setConditionText;
let setConditionButtonEle = element.all(by.css('button')).get(0);
let ngIfButtonEle = element(by.cssContainingText('button', 'if | !if'));
let ngIfParentEle = ngIfButtonEle.element(by.xpath('..'));
let ngIfSiblingEle = ngIfParentEle.element(by.css('heavy-loader'));
let cssButtonEle = element(by.cssContainingText('button', 'show | hide'));
let cssSiblingEle = cssButtonEle.element(by.xpath('..')).element(by.css('heavy-loader'));
let setConditionText;
setConditionButtonEle.getText().then(function(text) {
setConditionText = text;
expect(ngIfButtonEle.isPresent()).toBe(true, 'should be able to find ngIfButton');
@ -54,8 +55,8 @@ describe('Structural Directives', function () {
});
it('should be able to use *ngIf ', function () {
var setConditionButtonEle = element.all(by.css('button')).get(0);
var displayEles = element.all(by.cssContainingText('p', 'Our heroes are true!'));
let setConditionButtonEle = element.all(by.css('button')).get(0);
let displayEles = element.all(by.cssContainingText('p', 'Our heroes are true!'));
expect(displayEles.count()).toBe(2, "should be displaying two ngIf elements");
setConditionButtonEle.click().then(function() {
expect(displayEles.count()).toBe(0, "should nog longer be displaying ngIf elements");

View File

@ -1,8 +1,9 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Style Guide', function () {
it('01-01', function () {
browser.get('#/01-01');
var pre = element(by.tagName('toh-heroes > pre'));
let pre = element(by.tagName('toh-heroes > pre'));
expect(pre.getText()).toContain('Bombasto');
expect(pre.getText()).toContain('Tornado');
expect(pre.getText()).toContain('Magneta');
@ -11,8 +12,8 @@ describe('Style Guide', function () {
it('02-07', function () {
browser.get('#/02-07');
var hero = element(by.tagName('toh-hero > div'));
var users = element(by.tagName('admin-users > div'));
let hero = element(by.tagName('toh-hero > div'));
let users = element(by.tagName('admin-users > div'));
expect(hero.getText()).toBe('hero component');
expect(users.getText()).toBe('users component');
@ -21,21 +22,21 @@ describe('Style Guide', function () {
it('02-08', function () {
browser.get('#/02-08');
var input = element(by.tagName('input[tohvalidate]'));
let input = element(by.tagName('input[tohvalidate]'));
expect(input.isPresent()).toBe(true);
});
it('03-01', function () {
browser.get('#/03-01');
var div = element(by.tagName('sg-app > div'));
let div = element(by.tagName('sg-app > div'));
expect(div.getText()).toBe('The expected error is 42');
});
it('03-02', function () {
browser.get('#/03-02');
var divs = element.all(by.tagName('sg-app > div'));
let divs = element.all(by.tagName('sg-app > div'));
expect(divs.get(0).getText()).toBe('Heroes url: api/heroes');
expect(divs.get(1).getText()).toBe('Villains url: api/villains');
});
@ -43,14 +44,14 @@ describe('Style Guide', function () {
it('03-03', function () {
browser.get('#/03-03');
var div = element(by.tagName('sg-app > div'));
let div = element(by.tagName('sg-app > div'));
expect(div.getText()).toBe('Our hero is RubberMan and He is so elastic');
});
it('03-04', function () {
browser.get('#/03-04');
var buttons = element.all(by.tagName('sg-app > button'));
let buttons = element.all(by.tagName('sg-app > button'));
expect(buttons.get(0).getText()).toBe('Show toast');
expect(buttons.get(1).getText()).toBe('Hide toast');
});
@ -58,10 +59,10 @@ describe('Style Guide', function () {
it('03-05', function () {
browser.get('#/03-05');
var div = element(by.tagName('sg-app > div'));
let div = element(by.tagName('sg-app > div'));
expect(div.getText()).toBe('Actual favorite: Windstorm');
var lis = element.all(by.tagName('sg-app > ul > li'));
let lis = element.all(by.tagName('sg-app > ul > li'));
expect(lis.get(0).getText()).toBe('Windstorm');
expect(lis.get(1).getText()).toBe('Bombasto');
expect(lis.get(2).getText()).toBe('Magneta');
@ -71,10 +72,10 @@ describe('Style Guide', function () {
it('03-06', function () {
browser.get('#/03-06');
var div = element(by.tagName('sg-app > div'));
let div = element(by.tagName('sg-app > div'));
expect(div.getText()).toBe('Actual favorite: Windstorm');
var lis = element.all(by.tagName('sg-app > ul > li'));
let lis = element.all(by.tagName('sg-app > ul > li'));
expect(lis.get(0).getText()).toBe('Windstorm');
expect(lis.get(1).getText()).toBe('Bombasto');
expect(lis.get(2).getText()).toBe('Magneta');
@ -84,77 +85,77 @@ describe('Style Guide', function () {
it('04-10', function () {
browser.get('#/04-10');
var div = element(by.tagName('sg-app > toh-heroes > div'));
let div = element(by.tagName('sg-app > toh-heroes > div'));
expect(div.getText()).toBe('This is heroes component');
});
it('04-14', function () {
browser.get('#/04-14');
var h2 = element(by.tagName('sg-app > toh-heroes > div > h2'));
let h2 = element(by.tagName('sg-app > toh-heroes > div > h2'));
expect(h2.getText()).toBe('My Heroes');
});
it('05-02', function () {
browser.get('#/05-02');
var button = element(by.tagName('sg-app > toh-hero-button > button'));
let button = element(by.tagName('sg-app > toh-hero-button > button'));
expect(button.getText()).toBe('Hero button');
});
it('05-03', function () {
browser.get('#/05-03');
var button = element(by.tagName('sg-app > toh-hero-button > button'));
let button = element(by.tagName('sg-app > toh-hero-button > button'));
expect(button.getText()).toBe('Hero button');
});
it('05-04', function () {
browser.get('#/05-04');
var h2 = element(by.tagName('sg-app > toh-heroes > div > h2'));
let h2 = element(by.tagName('sg-app > toh-heroes > div > h2'));
expect(h2.getText()).toBe('My Heroes');
});
it('05-12', function () {
browser.get('#/05-12');
var button = element(by.tagName('sg-app > toh-hero-button > button'));
let button = element(by.tagName('sg-app > toh-hero-button > button'));
expect(button.getText()).toBe('OK');
});
it('05-13', function () {
browser.get('#/05-13');
var button = element(by.tagName('sg-app > toh-hero-button > button'));
let button = element(by.tagName('sg-app > toh-hero-button > button'));
expect(button.getText()).toBe('OK');
});
it('05-14', function () {
browser.get('#/05-14');
var toast = element(by.tagName('sg-app > toh-toast'));
let toast = element(by.tagName('sg-app > toh-toast'));
expect(toast.getText()).toBe('...');
});
it('05-15', function () {
browser.get('#/05-15');
var heroList = element(by.tagName('sg-app > toh-hero-list'));
let heroList = element(by.tagName('sg-app > toh-hero-list'));
expect(heroList.getText()).toBe('...');
});
it('05-16', function () {
browser.get('#/05-16');
var hero = element(by.tagName('sg-app > toh-hero'));
let hero = element(by.tagName('sg-app > toh-hero'));
expect(hero.getText()).toBe('...');
});
it('05-17', function () {
browser.get('#/05-17');
var section = element(by.tagName('sg-app > toh-hero-list > section'));
let section = element(by.tagName('sg-app > toh-hero-list > section'));
expect(section.getText()).toContain('Our list of heroes');
expect(section.getText()).toContain('Total powers');
expect(section.getText()).toContain('Average power');
@ -163,21 +164,21 @@ describe('Style Guide', function () {
it('06-01', function () {
browser.get('#/06-01');
var div = element(by.tagName('sg-app > div[tohhighlight]'));
let div = element(by.tagName('sg-app > div[tohhighlight]'));
expect(div.getText()).toBe('Bombasta');
});
it('06-03', function () {
browser.get('#/06-03');
var input = element(by.tagName('input[tohvalidator]'));
let input = element(by.tagName('input[tohvalidator]'));
expect(input.isPresent()).toBe(true);
});
it('07-01', function () {
browser.get('#/07-01');
var lis = element.all(by.tagName('sg-app > ul > li'));
let lis = element.all(by.tagName('sg-app > ul > li'));
expect(lis.get(0).getText()).toBe('Windstorm');
expect(lis.get(1).getText()).toBe('Bombasto');
expect(lis.get(2).getText()).toBe('Magneta');
@ -187,21 +188,21 @@ describe('Style Guide', function () {
it('07-03', function () {
browser.get('#/07-03');
var pre = element(by.tagName('toh-heroes > pre'));
let pre = element(by.tagName('toh-heroes > pre'));
expect(pre.getText()).toContain('[]');
});
it('07-04', function () {
browser.get('#/07-04');
var pre = element(by.tagName('toh-app > pre'));
let pre = element(by.tagName('toh-app > pre'));
expect(pre.getText()).toContain('[]');
});
it('09-01', function () {
browser.get('#/09-01');
var button = element(by.tagName('sg-app > toh-hero-button > button'));
let button = element(by.tagName('sg-app > toh-hero-button > button'));
expect(button.getText()).toBe('OK');
});
});

View File

@ -8,7 +8,7 @@ import { Component } from '@angular/core';
template: `<button>OK<button>`
})
export class HeroButtonComponent {
onInit() { // mispelled
onInit() { // misspelled
console.log('The component is initialized');
}
}

View File

@ -1,27 +0,0 @@
/*global browser, element, by */
describe('Getting Started E2E Tests', function() {
// #docregion shared
var expectedMsg = 'My First Angular 2 App';
// tests shared across languages
function sharedTests(basePath) {
beforeEach(function () {
browser.get(basePath + 'index.html');
});
it('should display: '+ expectedMsg, function() {
expect(element(by.id('output')).getText()).toEqual(expectedMsg);
});
}
// #enddocregion
describe('Getting Started in JavaScript', function() {
sharedTests('gettingstarted/js/');
});
describe('Getting Started in TypeScript', function() {
sharedTests('gettingstarted/ts/');
});
});

View File

@ -0,0 +1,28 @@
/// <reference path="../_protractor/e2e.d.ts" />
/*global browser, element, by */
describe('Getting Started E2E Tests', function() {
// #docregion shared
let expectedMsg = 'My First Angular 2 App';
// tests shared across languages
function sharedTests(basePath) {
beforeEach(function () {
browser.get(basePath + 'index.html');
});
it('should display: '+ expectedMsg, function() {
expect(element(by.id('output')).getText()).toEqual(expectedMsg);
});
}
// #enddocregion
describe('Getting Started in JavaScript', function() {
sharedTests('gettingstarted/js/');
});
describe('Getting Started in TypeScript', function() {
sharedTests('gettingstarted/ts/');
});
});

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
// Not yet complete
describe('Template Syntax', function () {
@ -6,24 +7,24 @@ describe('Template Syntax', function () {
});
it('should be able to use interpolation with a hero', function () {
var heroInterEle = element.all(by.css('h2+p')).get(0);
let heroInterEle = element.all(by.css('h2+p')).get(0);
expect(heroInterEle.getText()).toEqual('My current hero is Hercules');
});
it('should be able to use interpolation with a calculation', function () {
var theSumEles = element.all(by.cssContainingText('h3~p','The sum of'));
let theSumEles = element.all(by.cssContainingText('h3~p','The sum of'));
expect(theSumEles.count()).toBe(2);
expect(theSumEles.get(0).getText()).toEqual('The sum of 1 + 1 is 2');
expect(theSumEles.get(1).getText()).toEqual('The sum of 1 + 1 is not 4');
});
it('should be able to use class binding syntax', function () {
var specialEle = element(by.cssContainingText('div','Special'));
let specialEle = element(by.cssContainingText('div','Special'));
expect(specialEle.getAttribute('class')).toMatch('special');
});
it('should be able to use style binding syntax', function () {
var specialButtonEle = element(by.cssContainingText('div.special~button', 'button'));
let specialButtonEle = element(by.cssContainingText('div.special~button', 'button'));
expect(specialButtonEle.getAttribute('style')).toMatch('color: red');
});
});

View File

@ -197,13 +197,18 @@ button</button>
<!-- #enddocregion property-binding-7 -->
<!-- #docregion property-binding-vs-interpolation -->
Interpolated: <img src="{{heroImageUrl}}"><br>
Property bound: <img [src]="heroImageUrl">
<p><img src="{{heroImageUrl}}"> is the <i>interpolated</i> image.</p>
<p><img [src]="heroImageUrl"> is the <i>property bound</i> image.</p>
<div>The interpolated title is {{title}}</div>
<div [innerHTML]="'The [innerHTML] title is '+title"></div>
<p><span>"{{title}}" is the <i>interpolated</i> title.</span></p>
<p>"<span [innerHTML]="title"></span>" is the <i>property bound</i> title.</p>
<!-- #enddocregion property-binding-vs-interpolation -->
<!-- #docregion property-binding-vs-interpolation-sanitization -->
<p><span>"{{evilTitle}}" is the <i>interpolated</i> evil title.</span></p>
<p>"<span [innerHTML]="evilTitle"></span>" is the <i>property bound</i> evil title.</p>
<!-- #enddocregion property-binding-vs-interpolation-sanitization -->
<a class="to-toc" href="#toc">top</a>
<!-- attribute binding -->

View File

@ -1,4 +1,5 @@
//#docplaster
/* tslint:disable:member-ordering forin */
// #docplaster
import { AfterViewInit, Component, ElementRef, OnInit, QueryList, ViewChildren } from '@angular/core';
import { NgForm } from '@angular/common';
@ -8,7 +9,7 @@ import { HeroDetailComponent, BigHeroDetailComponent } from './hero-detail.compo
import { MyClickDirective, MyClickDirective2 } from './my-click.directive';
// Alerter fn: monkey patch during test
export function alerter(msg?:string) {
export function alerter(msg?: string) {
window.alert(msg);
}
@ -27,7 +28,7 @@ export enum Color {Red, Green, Blue};
})
export class AppComponent implements AfterViewInit, OnInit {
ngOnInit(){
ngOnInit() {
this.refreshHeroes();
}
@ -40,43 +41,48 @@ export class AppComponent implements AfterViewInit, OnInit {
badCurly = 'bad curly';
classes = 'special';
callFax(value:string) {this.alert(`Faxing ${value} ...`)}
callPhone(value:string) {this.alert(`Calling ${value} ...`)}
callFax(value: string) {this.alert(`Faxing ${value} ...`); }
callPhone(value: string) {this.alert(`Calling ${value} ...`); }
canSave = true;
Color = Color;
color = Color.Red;
colorToggle() {this.color = (this.color === Color.Red)? Color.Blue : Color.Red}
colorToggle() {this.color = (this.color === Color.Red) ? Color.Blue : Color.Red; }
currentHero = Hero.MockHeroes[0];
deleteHero(hero:Hero){
this.alert('Deleted hero: '+ (hero && hero.firstName))
deleteHero(hero: Hero) {
this.alert('Deleted hero: ' + (hero && hero.firstName));
}
// DevMode memoization fields
private priorClasses:{};
private _priorStyles:{};
private _priorStyles2:{};
// #docregion evil-title
evilTitle = 'Template <script>alert("evil never sleeps")</script>Syntax';
// #enddocregion evil-title
getStyles(el:Element){
title = 'Template Syntax';
// DevMode memoization fields
private priorClasses: {};
private _priorStyles: {};
getStyles(el: Element) {
let styles = window.getComputedStyle(el);
let showStyles = {};
for (var p in this.setStyles()){
for (let p in this.setStyles()) {
showStyles[p] = styles[p];
}
return JSON.stringify(showStyles);
}
getVal() {return this.val};
getVal() { return this.val; }
heroes:Hero[];
heroes: Hero[];
// heroImageUrl = 'http://www.wpclipart.com/cartoon/people/hero/hero_silhoutte_T.png';
// Public Domain terms of use: http://www.wpclipart.com/terms.html
heroImageUrl = 'images/hero.png';
//iconUrl = 'https://angular.io/resources/images/logos/standard/shield-large.png';
// iconUrl = 'https://angular.io/resources/images/logos/standard/shield-large.png';
clicked = '';
clickMessage = '';
clickMessage2 = '';
@ -85,28 +91,28 @@ export class AppComponent implements AfterViewInit, OnInit {
isSpecial = true;
isUnchanged = true;
nullHero:Hero = null; // or undefined
nullHero: Hero = null; // or undefined
onCancel(event:KeyboardEvent){
let evtMsg = event ? ' Event target is '+ (<HTMLElement>event.target).innerHTML : '';
this.alert('Canceled.'+evtMsg)
onCancel(event: KeyboardEvent) {
let evtMsg = event ? ' Event target is ' + (<HTMLElement>event.target).innerHTML : '';
this.alert('Canceled.' + evtMsg);
}
onClickMe(event:KeyboardEvent){
let evtMsg = event ? ' Event target class is '+ (<HTMLElement>event.target).className : '';
this.alert('Click me.'+evtMsg)
onClickMe(event: KeyboardEvent) {
let evtMsg = event ? ' Event target class is ' + (<HTMLElement>event.target).className : '';
this.alert('Click me.' + evtMsg);
}
onSave(event:KeyboardEvent){
let evtMsg = event ? ' Event target is '+ (<HTMLElement>event.target).innerText : '';
this.alert('Saved.'+evtMsg)
onSave(event: KeyboardEvent) {
let evtMsg = event ? ' Event target is ' + (<HTMLElement>event.target).innerText : '';
this.alert('Saved.' + evtMsg);
}
onSubmit(form:NgForm){
onSubmit(form: NgForm) {
let evtMsg = form.valid ?
' Form value is '+ JSON.stringify(form.value) :
' Form value is ' + JSON.stringify(form.value) :
' Form is invalid';
this.alert('Form submitted.'+evtMsg)
this.alert('Form submitted.' + evtMsg);
}
product = {
@ -123,10 +129,10 @@ export class AppComponent implements AfterViewInit, OnInit {
// #docregion same-as-it-ever-was
private samenessCount = 5;
moreOfTheSame() {this.samenessCount++;};
moreOfTheSame() { this.samenessCount++; };
get sameAsItEverWas() {
var result:string[] = Array(this.samenessCount);
for (var i=result.length; i-- > 0;){result[i]='same as it ever was ...'}
let result: string[] = Array(this.samenessCount);
for ( let i = result.length; i-- > 0; ) { result[i] = 'same as it ever was ...'; }
return result;
// return [1,2,3,4,5].map(id => {
// return {id:id, text: 'same as it ever was ...'};
@ -134,8 +140,8 @@ export class AppComponent implements AfterViewInit, OnInit {
}
// #enddocregion same-as-it-ever-was
setUpperCaseFirstName(firstName:string){
//console.log(firstName);
setUpperCaseFirstName(firstName: string) {
// console.log(firstName);
this.currentHero.firstName = firstName.toUpperCase();
}
@ -145,10 +151,10 @@ export class AppComponent implements AfterViewInit, OnInit {
saveable: this.canSave, // true
modified: !this.isUnchanged, // false
special: this.isSpecial, // true
}
};
// #enddocregion setClasses
// compensate for DevMode (sigh)
if (JSON.stringify(classes) === JSON.stringify(this.priorClasses)){
if (JSON.stringify(classes) === JSON.stringify(this.priorClasses)) {
return this.priorClasses;
}
this.priorClasses = classes;
@ -165,10 +171,10 @@ export class AppComponent implements AfterViewInit, OnInit {
'font-style': this.canSave ? 'italic' : 'normal', // italic
'font-weight': !this.isUnchanged ? 'bold' : 'normal', // normal
'font-size': this.isSpecial ? '24px' : '8px', // 24px
}
};
// #enddocregion setStyles
// compensate for DevMode (sigh)
if (JSON.stringify(styles) === JSON.stringify(this._priorStyles)){
if (JSON.stringify(styles) === JSON.stringify(this._priorStyles)) {
return this._priorStyles;
}
this._priorStyles = styles;
@ -178,15 +184,14 @@ export class AppComponent implements AfterViewInit, OnInit {
// #enddocregion setStyles
toeChoice = '';
toeChooser(picker:HTMLFieldSetElement){
toeChooser(picker: HTMLFieldSetElement) {
let choices = picker.children;
for (let i=0; i<choices.length; i++){
var choice = <HTMLInputElement>choices[i];
if (choice.checked) {return this.toeChoice = choice.value}
for (let i = 0; i < choices.length; i++) {
let choice = <HTMLInputElement>choices[i];
if (choice.checked) {return this.toeChoice = choice.value; }
}
}
title = 'Template Syntax';
// #docregion trackByHeroes
trackByHeroes(index: number, hero: Hero) { return hero.id; }
@ -196,18 +201,18 @@ export class AppComponent implements AfterViewInit, OnInit {
trackById(index: number, item: any): string { return item['id']; }
// #enddocregion trackById
val=2;
// villainImageUrl = 'http://www.clker.com/cliparts/u/s/y/L/x/9/villain-man-hi.png'
val = 2;
// villainImageUrl = 'http://www.clker.com/cliparts/u/s/y/L/x/9/villain-man-hi.png'
// Public Domain terms of use http://www.clker.com/disclaimer.html
villainImageUrl = 'images/villain.png'
villainImageUrl = 'images/villain.png';
//////// Detect effects of NgForTrackBy ///////////////
@ViewChildren('noTrackBy') childrenNoTrackBy:QueryList<ElementRef>;
@ViewChildren('withTrackBy') childrenWithTrackBy:QueryList<ElementRef>;
@ViewChildren('noTrackBy') childrenNoTrackBy: QueryList<ElementRef>;
@ViewChildren('withTrackBy') childrenWithTrackBy: QueryList<ElementRef>;
private _oldNoTrackBy:HTMLElement[];
private _oldWithTrackBy:HTMLElement[];
private _oldNoTrackBy: HTMLElement[];
private _oldWithTrackBy: HTMLElement[];
heroesNoTrackByChangeCount = 0;
heroesWithTrackByChangeCount = 0;
@ -216,32 +221,32 @@ export class AppComponent implements AfterViewInit, OnInit {
this._oldNoTrackBy = toArray(this.childrenNoTrackBy);
this._oldWithTrackBy = toArray(this.childrenWithTrackBy);
this.childrenNoTrackBy.changes.subscribe((changes:any) => {
this.childrenNoTrackBy.changes.subscribe((changes: any) => {
let newNoTrackBy = toArray(changes);
let isSame = this._oldNoTrackBy.every((v:any, i:number) => v === newNoTrackBy[i]);
let isSame = this._oldNoTrackBy.every((v: any, i: number) => v === newNoTrackBy[i]);
if (!isSame) {
this._oldNoTrackBy = newNoTrackBy;
this.heroesNoTrackByChangeCount++;
}
})
});
this.childrenWithTrackBy.changes.subscribe((changes:any) => {
this.childrenWithTrackBy.changes.subscribe((changes: any) => {
let newWithTrackBy = toArray(changes);
let isSame = this._oldWithTrackBy.every((v:any, i:number) => v === newWithTrackBy[i]);
let isSame = this._oldWithTrackBy.every((v: any, i: number) => v === newWithTrackBy[i]);
if (!isSame) {
this._oldWithTrackBy = newWithTrackBy;
this.heroesWithTrackByChangeCount++;
}
})
});
}
///////////////////
}
// helper to convert viewChildren to an array of HTMLElements
function toArray(viewChildren:QueryList<ElementRef>) {
function toArray(viewChildren: QueryList<ElementRef>) {
let result: HTMLElement[] = [];
let children = viewChildren.toArray()[0].nativeElement.children;
for (var i = 0; i < children.length; i++) { result.push(children[i]); }
for (let i = 0; i < children.length; i++) { result.push(children[i]); }
return result;
}

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Tutorial', function () {
beforeAll(function () {
@ -23,19 +24,19 @@ describe('Tutorial', function () {
}
it('should be able to see the start screen', function () {
var page = getPageStruct();
let page = getPageStruct();
expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices');
expect(page.myDashboardHref.getText()).toEqual("Dashboard");
expect(page.myHeroesHref.getText()).toEqual("Heroes");
});
it('should be able to see dashboard choices', function () {
var page = getPageStruct();
let page = getPageStruct();
expect(page.topHeroes.count()).toBe(4, "should be 4 dashboard hero choices");
});
it('should be able to toggle the views', function () {
var page = getPageStruct();
let page = getPageStruct();
expect(page.myDashboardParent.element(by.css('h3')).getText()).toEqual('Top Heroes');
page.myHeroesHref.click().then(function() {
@ -49,11 +50,11 @@ describe('Tutorial', function () {
});
it('should be able to edit details from "Dashboard" view', function () {
var page = getPageStruct();
let page = getPageStruct();
expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be available');
var heroEle = page.topHeroes.get(3);
var heroDescrEle = heroEle.element(by.css('h4'));
var heroDescr;
let heroEle = page.topHeroes.get(3);
let heroDescrEle = heroEle.element(by.css('h4'));
let heroDescr;
return heroDescrEle.getText().then(function(text) {
heroDescr = text;
return heroEle.click();
@ -66,10 +67,10 @@ describe('Tutorial', function () {
});
it('should be able to edit details from "Heroes" view', function () {
var page = getPageStruct();
let page = getPageStruct();
expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be present');
var viewDetailsButtonEle = page.myHeroesParent.element(by.cssContainingText('button', 'View Details'));
var heroEle, heroDescr;
let viewDetailsButtonEle = page.myHeroesParent.element(by.cssContainingText('button', 'View Details'));
let heroEle, heroDescr;
page.myHeroesHref.click().then(function() {
expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present');
expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be present');
@ -96,11 +97,11 @@ describe('Tutorial', function () {
expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present');
expect(page.myHeroesParent.isPresent()).toBe(false, 'myHeroes element should NOT be present');
expect(page.heroDetail.isDisplayed()).toBe(true, 'should be able to see hero-details');
var inputEle = page.heroDetail.element(by.css('input'));
let inputEle = page.heroDetail.element(by.css('input'));
expect(inputEle.isDisplayed()).toBe(true, 'should be able to see the input box');
var backButtonEle = page.heroDetail.element(by.css('button'));
let backButtonEle = page.heroDetail.element(by.css('button'));
expect(backButtonEle.isDisplayed()).toBe(true, 'should be able to see the back button');
var detailTextEle = page.heroDetail.element(by.css('div h2'));
let detailTextEle = page.heroDetail.element(by.css('div h2'));
expect(detailTextEle.getText()).toContain(origValue);
return sendKeys(inputEle, textToAdd).then(function () {
expect(detailTextEle.getText()).toContain(origValue + textToAdd);

View File

@ -19,9 +19,8 @@ export class HeroService {
//#docregion get-hero
getHero(id: number) {
return Promise.resolve(HEROES).then(
heroes => heroes.filter(hero => hero.id === id)[0]
);
return this.getHeroes()
.then(heroes => heroes.filter(hero => hero.id === id)[0]);
}
//#enddocregion get-hero
}

View File

@ -1,3 +1,4 @@
/// <reference path='../_protractor/e2e.d.ts' />
describe('TOH Http Chapter', function () {
beforeEach(function () {
@ -5,7 +6,7 @@ describe('TOH Http Chapter', function () {
});
function getPageStruct() {
hrefEles = element.all(by.css('my-app a'));
let hrefEles = element.all(by.css('my-app a'));
return {
hrefs: hrefEles,
@ -22,12 +23,12 @@ describe('TOH Http Chapter', function () {
addButton: element.all(by.buttonText('Add New Hero')).get(0),
heroDetail: element(by.css('my-app my-hero-detail'))
}
};
}
it('should be able to add a hero from the "Heroes" view', function(){
var page = getPageStruct();
var heroCount;
let page = getPageStruct();
let heroCount: webdriver.promise.Promise<number>;
page.myHeroesHref.click().then(function() {
browser.waitForAngular();
@ -43,14 +44,14 @@ describe('TOH Http Chapter', function () {
heroCount = page.allHeroes.count();
expect(heroCount).toBe(11, 'should show 11');
var newHero = element(by.xpath('//span[@class="hero-element" and contains(text(),"The New Hero")]'));
let newHero = element(by.xpath('//span[@class="hero-element" and contains(text(),"The New Hero")]'));
expect(newHero).toBeDefined();
});
});
it('should be able to delete hero from "Heroes" view', function(){
var page = getPageStruct();
var heroCount;
let page = getPageStruct();
let heroCount: webdriver.promise.Promise<number>;
page.myHeroesHref.click().then(function() {
browser.waitForAngular();
@ -66,11 +67,11 @@ describe('TOH Http Chapter', function () {
});
it('should be able to save details from "Dashboard" view', function () {
var page = getPageStruct();
let page = getPageStruct();
expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be available');
var heroEle = page.topHeroes.get(2);
var heroDescrEle = heroEle.element(by.css('h4'));
var heroDescr;
let heroEle = page.topHeroes.get(2);
let heroDescrEle = heroEle.element(by.css('h4'));
let heroDescr: string;
return heroDescrEle.getText().then(function(text) {
heroDescr = text;
@ -88,10 +89,10 @@ describe('TOH Http Chapter', function () {
});
it('should be able to save details from "Heroes" view', function () {
var page = getPageStruct();
let page = getPageStruct();
var viewDetailsButtonEle = page.myHeroesParent.element(by.cssContainingText('button', 'View Details'));
var heroEle, heroDescr;
let viewDetailsButtonEle = page.myHeroesParent.element(by.cssContainingText('button', 'View Details'));
let heroEle: protractor.ElementFinder, heroDescr: string;
page.myHeroesHref.click().then(function() {
expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present');
@ -101,7 +102,7 @@ describe('TOH Http Chapter', function () {
return heroEle.getText();
}).then(function(text) {
// remove leading 'id' from the element
heroDescr = text.substr(text.indexOf(' ')+1);
heroDescr = text.substr(text.indexOf(' ') + 1);
return heroEle.click();
}).then(function() {
expect(viewDetailsButtonEle.isDisplayed()).toBe(true, 'viewDetails button should now be visible');
@ -117,13 +118,13 @@ describe('TOH Http Chapter', function () {
});
});
function save(page, origValue, textToAdd) {
var inputEle = page.heroDetail.element(by.css('input'));
function save(page: any, origValue: string, textToAdd: string) {
let inputEle = page.heroDetail.element(by.css('input'));
expect(inputEle.isDisplayed()).toBe(true, 'should be able to see the input box');
var saveButtonEle = page.heroDetail.element(by.buttonText('Save'));
var backButtonEle = page.heroDetail.element(by.buttonText('Back'));
let saveButtonEle = page.heroDetail.element(by.buttonText('Save'));
let backButtonEle = page.heroDetail.element(by.buttonText('Back'));
expect(backButtonEle.isDisplayed()).toBe(true, 'should be able to see the back button');
var detailTextEle = page.heroDetail.element(by.css('div h2'));
let detailTextEle = page.heroDetail.element(by.css('div h2'));
expect(detailTextEle.getText()).toContain(origValue);
return sendKeys(inputEle, textToAdd).then(function () {
expect(detailTextEle.getText()).toContain(origValue + textToAdd);
@ -132,24 +133,24 @@ describe('TOH Http Chapter', function () {
}
it('should be able to see the start screen', function () {
var page = getPageStruct();
let page = getPageStruct();
expect(page.hrefs.count()).toEqual(2, 'should be two dashboard choices');
expect(page.myDashboardHref.getText()).toEqual("Dashboard");
expect(page.myHeroesHref.getText()).toEqual("Heroes");
expect(page.myDashboardHref.getText()).toEqual('Dashboard');
expect(page.myHeroesHref.getText()).toEqual('Heroes');
});
it('should be able to see dashboard choices', function () {
var page = getPageStruct();
expect(page.topHeroes.count()).toBe(4, "should be 4 dashboard hero choices");
let page = getPageStruct();
expect(page.topHeroes.count()).toBe(4, 'should be 4 dashboard hero choices');
});
it('should be able to toggle the views', function () {
var page = getPageStruct();
let page = getPageStruct();
expect(page.myDashboardParent.element(by.css('h3')).getText()).toEqual('Top Heroes');
page.myHeroesHref.click().then(function() {
expect(page.myDashboardParent.isPresent()).toBe(false, 'should no longer see dashboard element');
expect(page.allHeroes.count()).toBeGreaterThan(4, "should be more than 4 heroes shown");
expect(page.allHeroes.count()).toBeGreaterThan(4, 'should be more than 4 heroes shown');
return page.myDashboardHref.click();
}).then(function() {
expect(page.myDashboardParent.isPresent()).toBe(true, 'should once again see the dashboard element');
@ -158,11 +159,11 @@ describe('TOH Http Chapter', function () {
});
it('should be able to edit details from "Dashboard" view', function () {
var page = getPageStruct();
let page = getPageStruct();
expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be available');
var heroEle = page.topHeroes.get(3);
var heroDescrEle = heroEle.element(by.css('h4'));
var heroDescr;
let heroEle = page.topHeroes.get(3);
let heroDescrEle = heroEle.element(by.css('h4'));
let heroDescr: string;
return heroDescrEle.getText().then(function(text) {
heroDescr = text;
return heroEle.click();
@ -175,10 +176,10 @@ describe('TOH Http Chapter', function () {
});
it('should be able to edit details from "Heroes" view', function () {
var page = getPageStruct();
let page = getPageStruct();
expect(page.myDashboardParent.isPresent()).toBe(true, 'dashboard element should be present');
var viewDetailsButtonEle = page.myHeroesParent.element(by.cssContainingText('button', 'View Details'));
var heroEle, heroDescr;
let viewDetailsButtonEle = page.myHeroesParent.element(by.cssContainingText('button', 'View Details'));
let heroEle: protractor.ElementFinder, heroDescr: string;
page.myHeroesHref.click().then(function() {
expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present');
expect(page.myHeroesParent.isPresent()).toBe(true, 'myHeroes element should be present');
@ -187,7 +188,7 @@ describe('TOH Http Chapter', function () {
return heroEle.getText();
}).then(function(text) {
// remove leading 'id' from the element
heroDescr = text.substr(text.indexOf(' ')+1);
heroDescr = text.substr(text.indexOf(' ') + 1);
return heroEle.click();
}).then(function() {
expect(viewDetailsButtonEle.isDisplayed()).toBe(true, 'viewDetails button should now be visible');
@ -201,18 +202,18 @@ describe('TOH Http Chapter', function () {
});
});
function editDetails(page, origValue, textToAdd) {
function editDetails(page: any, origValue: string, textToAdd: string) {
expect(page.myDashboardParent.isPresent()).toBe(false, 'dashboard element should NOT be present');
expect(page.myHeroesParent.isPresent()).toBe(false, 'myHeroes element should NOT be present');
expect(page.heroDetail.isDisplayed()).toBe(true, 'should be able to see hero-details');
var inputEle = page.heroDetail.element(by.css('input'));
let inputEle = page.heroDetail.element(by.css('input'));
expect(inputEle.isDisplayed()).toBe(true, 'should be able to see the input box');
var buttons = page.heroDetail.all(by.css('button'));
var backButtonEle = buttons.get(0);
var saveButtonEle = buttons.get(1);
let buttons = page.heroDetail.all(by.css('button'));
let backButtonEle = buttons.get(0);
let saveButtonEle = buttons.get(1);
expect(backButtonEle.isDisplayed()).toBe(true, 'should be able to see the back button');
expect(saveButtonEle.isDisplayed()).toBe(true, 'should be able to see the save button');
var detailTextEle = page.heroDetail.element(by.css('div h2'));
let detailTextEle = page.heroDetail.element(by.css('div h2'));
expect(detailTextEle.getText()).toContain(origValue);
return sendKeys(inputEle, textToAdd).then(function () {
expect(detailTextEle.getText()).toContain(origValue + textToAdd);

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('Upgrade Tests', function () {
// Protractor doesn't support the UpgradeAdapter's asynchronous

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
'use strict';
// Angular E2E Testing Guide:
@ -22,8 +23,8 @@ describe('PhoneCat Application', function() {
});
it('should filter the phone list as a user types into the search box', function() {
var phoneList = element.all(by.repeater('phone in $ctrl.phones'));
var query = element(by.model('$ctrl.query'));
let phoneList = element.all(by.repeater('phone in $ctrl.phones'));
let query = element(by.model('$ctrl.query'));
expect(phoneList.count()).toBe(20);
@ -36,10 +37,10 @@ describe('PhoneCat Application', function() {
});
it('should be possible to control phone order via the drop-down menu', function() {
var queryField = element(by.model('$ctrl.query'));
var orderSelect = element(by.model('$ctrl.orderProp'));
var nameOption = orderSelect.element(by.css('option[value="name"]'));
var phoneNameColumn = element.all(by.repeater('phone in $ctrl.phones').column('phone.name'));
let queryField = element(by.model('$ctrl.query'));
let orderSelect = element(by.model('$ctrl.orderProp'));
let nameOption = orderSelect.element(by.css('option[value="name"]'));
let phoneNameColumn = element.all(by.repeater('phone in $ctrl.phones').column('phone.name'));
function getNames() {
return phoneNameColumn.map(function(elem) {
@ -63,7 +64,7 @@ describe('PhoneCat Application', function() {
});
it('should render phone specific links', function() {
var query = element(by.model('$ctrl.query'));
let query = element(by.model('$ctrl.query'));
query.sendKeys('nexus');
element.all(by.css('.phones li a')).first().click();
@ -83,14 +84,14 @@ describe('PhoneCat Application', function() {
});
it('should display the first phone image as the main phone image', function() {
var mainImage = element(by.css('img.phone.selected'));
let mainImage = element(by.css('img.phone.selected'));
expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/);
});
it('should swap the main image when clicking on a thumbnail image', function() {
var mainImage = element(by.css('img.phone.selected'));
var thumbnails = element.all(by.css('.phone-thumbs img'));
let mainImage = element(by.css('img.phone.selected'));
let thumbnails = element.all(by.css('.phone-thumbs img'));
thumbnails.get(2).click();
expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.2.jpg/);

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/typings/index.d.ts" />
'use strict';
// Angular E2E Testing Guide:
@ -21,8 +22,8 @@ describe('PhoneCat Application', function() {
});
it('should filter the phone list as a user types into the search box', function() {
var phoneList = element.all(by.css('.phones li'));
var query = element(by.css('input'));
let phoneList = element.all(by.css('.phones li'));
let query = element(by.css('input'));
expect(phoneList.count()).toBe(20);
@ -35,10 +36,10 @@ describe('PhoneCat Application', function() {
});
it('should be possible to control phone order via the drop-down menu', function() {
var queryField = element(by.css('input'));
var orderSelect = element(by.css('select'));
var nameOption = orderSelect.element(by.css('option[value="name"]'));
var phoneNameColumn = element.all(by.css('.phones .name'));
let queryField = element(by.css('input'));
let orderSelect = element(by.css('select'));
let nameOption = orderSelect.element(by.css('option[value="name"]'));
let phoneNameColumn = element.all(by.css('.phones .name'));
function getNames() {
return phoneNameColumn.map(function(elem) {
@ -62,7 +63,7 @@ describe('PhoneCat Application', function() {
});
it('should render phone specific links', function() {
var query = element(by.css('input'));
let query = element(by.css('input'));
sendKeys(query, 'nexus');
element.all(by.css('.phones li a')).first().click();
@ -83,14 +84,14 @@ describe('PhoneCat Application', function() {
});
it('should display the first phone image as the main phone image', function() {
var mainImage = element(by.css('img.phone.selected'));
let mainImage = element(by.css('img.phone.selected'));
expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/);
});
it('should swap the main image when clicking on a thumbnail image', function() {
var mainImage = element(by.css('img.phone.selected'));
var thumbnails = element.all(by.css('.phone-thumbs img'));
let mainImage = element(by.css('img.phone.selected'));
let thumbnails = element.all(by.css('.phone-thumbs img'));
thumbnails.get(2).click();
expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.2.jpg/);

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
'use strict';
// Angular E2E Testing Guide:
@ -22,8 +23,8 @@ describe('PhoneCat Application', function() {
});
it('should filter the phone list as a user types into the search box', function() {
var phoneList = element.all(by.css('.phones li'));
var query = element(by.css('input'));
let phoneList = element.all(by.css('.phones li'));
let query = element(by.css('input'));
expect(phoneList.count()).toBe(20);
@ -36,10 +37,10 @@ describe('PhoneCat Application', function() {
});
it('should be possible to control phone order via the drop-down menu', function() {
var queryField = element(by.css('input'));
var orderSelect = element(by.css('select'));
var nameOption = orderSelect.element(by.css('option[value="name"]'));
var phoneNameColumn = element.all(by.css('.phones .name'));
let queryField = element(by.css('input'));
let orderSelect = element(by.css('select'));
let nameOption = orderSelect.element(by.css('option[value="name"]'));
let phoneNameColumn = element.all(by.css('.phones .name'));
function getNames() {
return phoneNameColumn.map(function(elem) {
@ -64,10 +65,10 @@ describe('PhoneCat Application', function() {
// #docregion links
it('should render phone specific links', function() {
var query = element(by.css('input'));
let query = element(by.css('input'));
// https://github.com/angular/protractor/issues/2019
var str = 'nexus';
for (var i = 0; i < str.length; i++) {
let str = 'nexus';
for (let i = 0; i < str.length; i++) {
query.sendKeys(str.charAt(i));
}
element.all(by.css('.phones li a')).first().click();
@ -90,14 +91,14 @@ describe('PhoneCat Application', function() {
});
it('should display the first phone image as the main phone image', function() {
var mainImage = element(by.css('img.phone.selected'));
let mainImage = element(by.css('img.phone.selected'));
expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.0.jpg/);
});
it('should swap the main image when clicking on a thumbnail image', function() {
var mainImage = element(by.css('img.phone.selected'));
var thumbnails = element.all(by.css('.phone-thumbs img'));
let mainImage = element(by.css('img.phone.selected'));
let thumbnails = element.all(by.css('.phone-thumbs img'));
thumbnails.get(2).click();
expect(mainImage.getAttribute('src')).toMatch(/img\/phones\/nexus-s.2.jpg/);

View File

@ -1,3 +1,4 @@
/// <reference path="../_protractor/e2e.d.ts" />
describe('User Input Tests', function () {
beforeAll(function () {
@ -5,8 +6,8 @@ describe('User Input Tests', function () {
});
it('should support the click event', function () {
var mainEle = element(by.css('click-me'));
var buttonEle =element(by.css('click-me button'));
let mainEle = element(by.css('click-me'));
let buttonEle =element(by.css('click-me button'));
expect(mainEle.getText()).not.toContain('You are my hero!');
buttonEle.click().then(function() {
expect(mainEle.getText()).toContain('You are my hero!');
@ -14,8 +15,8 @@ describe('User Input Tests', function () {
});
it('should support the click event with an event payload', function () {
var mainEle = element(by.css('click-me2'));
var buttonEle =element(by.css('click-me2 button'));
let mainEle = element(by.css('click-me2'));
let buttonEle =element(by.css('click-me2 button'));
expect(mainEle.getText()).not.toContain('Event target is ');
buttonEle.click().then(function() {
expect(mainEle.getText()).toContain('Event target is BUTTON');
@ -23,19 +24,19 @@ describe('User Input Tests', function () {
});
it('should support the keyup event ', function () {
var mainEle = element(by.css('key-up1'));
var inputEle = mainEle.element(by.css('input'));
var outputTextEle = mainEle.element(by.css('p'));
let mainEle = element(by.css('key-up1'));
let inputEle = mainEle.element(by.css('input'));
let outputTextEle = mainEle.element(by.css('p'));
expect(outputTextEle.getText()).toEqual('');
return sendKeys(inputEle,'abc').then(function() {
expect(outputTextEle.getText()).toEqual('a | ab | abc |');
});
});
it('should support user input from a local template var (loopback)', function () {
var mainEle = element(by.css('loop-back'));
var inputEle = mainEle.element(by.css('input'));
var outputTextEle = mainEle.element(by.css('p'));
it('should support user input from a local template let (loopback)', function () {
let mainEle = element(by.css('loop-back'));
let inputEle = mainEle.element(by.css('input'));
let outputTextEle = mainEle.element(by.css('p'));
expect(outputTextEle.getText()).toEqual('');
return sendKeys(inputEle,'abc').then(function() {
expect(outputTextEle.getText()).toEqual('abc');
@ -43,9 +44,9 @@ describe('User Input Tests', function () {
});
it('should be able to combine click event with a local template var', function () {
var mainEle = element(by.css('key-up2'));
var inputEle = mainEle.element(by.css('input'));
var outputTextEle = mainEle.element(by.css('p'));
let mainEle = element(by.css('key-up2'));
let inputEle = mainEle.element(by.css('input'));
let outputTextEle = mainEle.element(by.css('p'));
expect(outputTextEle.getText()).toEqual('');
return sendKeys(inputEle,'abc').then(function() {
expect(outputTextEle.getText()).toEqual('a | ab | abc |');
@ -53,9 +54,9 @@ describe('User Input Tests', function () {
});
it('should be able to filter key events', function () {
var mainEle = element(by.css('key-up3'));
var inputEle = mainEle.element(by.css('input'));
var outputTextEle = mainEle.element(by.css('p'));
let mainEle = element(by.css('key-up3'));
let inputEle = mainEle.element(by.css('input'));
let outputTextEle = mainEle.element(by.css('p'));
expect(outputTextEle.getText()).toEqual('');
return sendKeys(inputEle,'abc').then(function() {
expect(outputTextEle.getText()).toEqual('', 'should be blank - have not sent enter yet');
@ -66,10 +67,10 @@ describe('User Input Tests', function () {
});
it('should be able to filter blur events', function () {
var prevInputEle = element(by.css('key-up3 input'));
var mainEle = element(by.css('key-up4'));
var inputEle = mainEle.element(by.css('input'));
var outputTextEle = mainEle.element(by.css('p'));
let prevInputEle = element(by.css('key-up3 input'));
let mainEle = element(by.css('key-up4'));
let inputEle = mainEle.element(by.css('input'));
let outputTextEle = mainEle.element(by.css('p'));
expect(outputTextEle.getText()).toEqual('');
return sendKeys(inputEle,'abc').then(function() {
expect(outputTextEle.getText()).toEqual('', 'should be blank - have not sent enter yet');
@ -81,11 +82,11 @@ describe('User Input Tests', function () {
});
it('should be able to compose little tour of heroes', function () {
var mainEle = element(by.css('little-tour'));
var inputEle = mainEle.element(by.css('input'));
var addButtonEle = mainEle.element(by.css('button'));
var heroEles = mainEle.all(by.css('li'));
var numHeroes;
let mainEle = element(by.css('little-tour'));
let inputEle = mainEle.element(by.css('input'));
let addButtonEle = mainEle.element(by.css('button'));
let heroEles = mainEle.all(by.css('li'));
let numHeroes;
expect(heroEles.count()).toBeGreaterThan(0);
heroEles.count().then(function(count) {
numHeroes = count;

View File

@ -11,7 +11,7 @@
h3 Adding an aside
aside.is-right Did you know that hipsum is a replacment for Lorem Ipsum? To find out more visit <a href="http://hipsum.co/">hipsum.co</a>
aside.is-right Did you know that hipsum is a replacement for Lorem Ipsum? To find out more visit <a href="http://hipsum.co/">hipsum.co</a>
p.
Etsy artisan Thundercats, authentic sustainable bitters wolf roof party meditation 90's asymmetrical XOXO hoodie. Twee umami cray iPhone. Chillwave shabby chic tilde occupy sriracha squid Brooklyn street art. Selvage heirloom kogi American Apparel bicycle rights. Carles Etsy Truffaut mlkshk trust fund. Jean shorts fashion axe Williamsburg wolf cardigan beard, twee blog locavore organic. Cred skateboard dreamcatcher, taxidermy Bushwick actually aesthetic normcore fanny pack.
@ -19,7 +19,7 @@
pre.prettyprint.linenums.lang-html
code.
aside.is-right Did you know that hipsum is a replacment for Lorem Ipsum? To find out more visit <a href="http://hipsum.co/">hipsum.co</a>
aside.is-right Did you know that hipsum is a replacement for Lorem Ipsum? To find out more visit <a href="http://hipsum.co/">hipsum.co</a>
p.
Etsy artisan Thundercats, authentic sustainable bitters

View File

@ -12,7 +12,7 @@ include ../../../_includes/_util-fns
:marked
### Including a code example from the `_examples` folder
One of the design goals for this documention was that any code samples that appear within the documentation be 'testable'.
One of the design goals for this documentation was that any code samples that appear within the documentation be 'testable'.
In practice this means that a set of standalone testable examples exist somewhere in the same repository as the rest
of the documentation. These examples will each typically consist of a collection of html, javascript and css files.
@ -130,7 +130,7 @@ include ../../../_includes/_util-fns
Multiple `#docregion` tags may be defined on a single line as shown below. In addition, anytime a file contains multiple
`#docregion` tags with the same name they will automatically be combined. Each of the individually tagged sections of the combined document
will be separated from one another by a comment consisting of '. . .'. This default separator, known
as 'plaster' can be overriden anywhere within the affected file via a `#docplaster` comment as shown below. This example creates
as 'plaster' can be overridden anywhere within the affected file via a `#docplaster` comment as shown below. This example creates
a separator that consists of `/* more code here */` in the output file.
code-example(format="linenums" language="js" escape="html").

View File

@ -2,7 +2,7 @@
header.showcase-header
h2 Basic Layouts
p.
You will use the following layouts throughout your documenation
You will use the following layouts throughout your documentation
to specify sections and sub-sections of content.
.showcase-content

View File

@ -2,7 +2,7 @@
header.showcase-header
h2 Tables
p.
Tables can be used to present tablular data as it relates
Tables can be used to present tabular data as it relates
to each other.
.showcase-content

View File

@ -5,16 +5,20 @@ include ../../../_includes/_util-fns
- var _decorator = 'annotation';
- var _Array = 'List';
- var _array = 'list';
- var _an_array = 'a list'; //- Deprecate now that we have the articles
- var _a = 'an';
- var _an = 'a';
- var _priv = '_';
- var _Lang = 'Dart';
- var _Promise = 'Future';
- var _FutureUrl = 'https://api.dartlang.org/dart_async/Future.html';
- var _PromiseLinked = '<a href="' + _FutureUrl + '">' + _Promise + '</a>';
- var _Observable = 'Stream';
- var _liveLink = 'sample repo';
- var _truthy = 'true';
- var _falsey = 'false';
- var _appDir = 'lib';
- var _indexHtmlDir = 'web';
- var _mainDir = 'web';
mixin liveExampleLink(linkText, exampleUrlPartName)
- var text = linkText || '在线例子';
@ -36,7 +40,7 @@ mixin liveExampleLink2(linkText, exampleUrlPartName)
- // if(extn == 'dart') return path;
- var baseName = getBaseFileName(path) || path; // TODO: have getBaseFileName() return path
- var baseNameNoExt = baseName.substr(0,baseName.length - (extn.length + 1));
- var inWebFolder = baseNameNoExt.match(/^(main|index(\.\d)?)$/);
- var inWebFolder = baseNameNoExt.match(/^(main|index)(\.\d)?$/);
- // Adjust the folder path, e.g., ts -> dart
- folder = folder.replace(/(^|\/)ts($|\/)/, '$1dart$2').replace(/(^|\/)app($|\/)/, inWebFolder ? '$1web$2' : '$1lib$2');
- // Special case not handled above: e.g., index.html -> web/index.html

View File

@ -6,8 +6,6 @@ block includes
- var _prereq = 'the Dart SDK'
- var _angular_browser_uri = 'package:angular2/platform/browser.dart'
- var _angular_core_uri = 'package:angular2/core.dart'
- var _appDir = 'lib'
- var _indexHtmlDir = 'web'
block setup-tooling
:marked

View File

@ -29,5 +29,10 @@
"title": "Routing",
"intro": "We add the Angular Component Router and learn to navigate among the views",
"nextable": true
},
"toh-pt6": {
"title": "Http",
"intro": "We convert our service and components to use Http",
"nextable": true
}
}

View File

@ -131,7 +131,7 @@ code-example(format=".").
.l-sub-section
:marked
We explain input properties in more detail [here](../guide/attribute-directives.html#why-input)
where we also explain why *target* properties require this special treament and
where we also explain why *target* properties require this special treatment and
*source* properties do not.
:marked
There are a couple of ways we can declare that `hero` is an *input*.

View File

@ -0,0 +1 @@
!= partial("../../../_includes/_ts-temp")

View File

@ -489,7 +489,7 @@ figure.image-display
We just set a template local variable with the value of an `NgForm` directive.
Why did that work? We didn't add the **[`NgForm`](../api/common/NgForm-directive.html) directive** explicitly.
Angular added it surreptiously, wrapping it around the `<form>` element
Angular added it surreptitiously, wrapping it around the `<form>` element
The `NgForm` directive supplements the `form` element with additional features.
It collects `Controls` (elements identified by an `ngControl` directive)
@ -531,7 +531,7 @@ figure.image-display
Re-run the application. The form opens in a valid state and the button is enabled.
Now delete the *Name*. We violate the "name required" rule which
is duely noted in our error message as before. And now the Submit button is also disabled.
is duly noted in our error message as before. And now the Submit button is also disabled.
Not impressed? Think about it for a moment. What would we have to do to
wire the button's enable/disabled state to the form's validity without Angular's help?

View File

@ -448,7 +448,7 @@ code-example(format="").
True, most Angular applications run only in a browser and we'll call the bootstrap function from
this library most of the time. It's pretty "core" if we're always writing for a browser.
But it is possible to load a component in a different enviroment.
But it is possible to load a component in a different environment.
We might load it on a mobile device with [Apache Cordova](https://cordova.apache.org/) or [NativeScript](https://www.nativescript.org/).
We might wish to render the first page of our application on the server
to improve launch performance or facilitate

View File

@ -29,5 +29,10 @@
"title": "Routing",
"intro": "We add the Angular Component Router and learn to navigate among the views",
"nextable": true
},
"toh-pt6": {
"title": "Http",
"intro": "We convert our service and components to use Http",
"nextable": true
}
}

View File

@ -0,0 +1 @@
!= partial("../../../_includes/_ts-temp")

View File

@ -129,7 +129,7 @@ figure.image-display
我们通常会推荐在应用程序的根组件`AppComponent`中提供应用程序级的服务。
Here we recommend registering the title service during bootstrapping,
a location we reserve for configuring the runtime Angular enviroment.
a location we reserve for configuring the runtime Angular environment.
但这里我们推荐在引导过程中注册这个Title服务这个位置是我们为设置Angular运行环境而保留的。

View File

@ -253,23 +253,23 @@ include _util-fns
The many forms of binding include:
绑定形式包括:
* [Interpolation](guide/template-syntax.html#interpolation)
* [插值表达式Interpolation](guide/template-syntax.html#interpolation)
* [Property Binding](guide/template-syntax.html#property-binding)
* [属性绑定Property Binding](guide/template-syntax.html#property-binding)
* [Event Binding](guide/template-syntax.html#event-binding)
* [事件绑定Event Binding](guide/template-syntax.html#event-binding)
* [Attribute Binding](guide/template-syntax.html#attribute-binding)
* [Attribute绑定Attribute Binding](guide/template-syntax.html#attribute-binding)
* [Class Binding](guide/template-syntax.html#class-binding)
* [类绑定Class Binding](guide/template-syntax.html#class-binding)
* [Style Binding](guide/template-syntax.html#style-binding)
* [样式绑定Style Binding](guide/template-syntax.html#style-binding)
* [Two-way data binding with ngModel](guide/template-syntax.html#ng-model)
* [基于ngModel的双向数据绑定Two-way data binding with ngModel](guide/template-syntax.html#ng-model)
* [Interpolation](/docs/ts/latest/guide/template-syntax.html#interpolation)
* [插值表达式Interpolation](/docs/ts/latest/guide/template-syntax.html#interpolation)
* [Property Binding](/docs/ts/latest/guide/template-syntax.html#property-binding)
* [属性绑定Property Binding](/docs/ts/latest/guide/template-syntax.html#property-binding)
* [Event Binding](/docs/ts/latest/guide/template-syntax.html#event-binding)
* [事件绑定Event Binding](/docs/ts/latest/guide/template-syntax.html#event-binding)
* [Attribute Binding](/docs/ts/latest/guide/template-syntax.html#attribute-binding)
* [Attribute绑定Attribute Binding](/docs/ts/latest/guide/template-syntax.html#attribute-binding)
* [Class Binding](/docs/ts/latest/guide/template-syntax.html#class-binding)
* [类绑定Class Binding](/docs/ts/latest/guide/template-syntax.html#class-binding)
* [Style Binding](/docs/ts/latest/guide/template-syntax.html#style-binding)
* [样式绑定Style Binding](/docs/ts/latest/guide/template-syntax.html#style-binding)
* [Two-way data binding with ngModel](/docs/ts/latest/guide/template-syntax.html#ng-model)
* [基于ngModel的双向数据绑定Two-way data binding with ngModel](/docs/ts/latest/guide/template-syntax.html#ng-model)
Learn more about data binding in the
[Template Syntax](guide/template-syntax.html#data-binding) chapter.
[Template Syntax](/docs/ts/latest/guide/template-syntax.html#data-binding) chapter.
要了解关于数据绑定的更多知识,请参见[模板语法](guide/template-syntax.html#data-binding)一章。
@ -407,7 +407,7 @@ include _util-fns
Angular会为每个注册器注册很多自己的内建Provider。我们也可以注册自己的Provider。通常注册Provider的最佳时间是在应用程序开始[引导](#bootstrap)的时候。
当然我们也有其它很多机会注册Provider。
Learn more in the [Dependency Injection](guide/dependency-injection.html) chapter.
Learn more in the [Dependency Injection](/docs/ts/latest/guide/dependency-injection.html) chapter.
要了解关于依赖注入的更多知识,请参见[依赖注入](guide/dependency-injection.html)一章。
@ -494,7 +494,7 @@ include _util-fns
## ECMAScript 2015
.l-sub-section
:marked
The lastest released version of JavaScript,
The latest released version of JavaScript,
[ECMAScript 2015](http://www.ecma-international.org/ecma-262/6.0/)
(AKA "ES2015" or "ES6")
@ -545,15 +545,15 @@ include _util-fns
.l-sub-section
:marked
A directive property that can be the ***target*** of a
[Property Binding](guide/template-syntax.html#property-binding).
[Property Binding](/docs/ts/latest/guide/template-syntax.html#property-binding).
Data values flow *into* this property from the data source identified
in the template expression to the right of the equal sign.
指令属性可以作为[属性绑定](guide/template-syntax.html#property-binding)的目标。数据值会从模板表达式等号右侧的数据源中,流入这个属性。
指令属性可以作为[属性绑定](/docs/ts/latest/guide/template-syntax.html#property-binding)的目标。数据值会从模板表达式等号右侧的数据源中,流入这个属性。
See the [Template Syntax](guide/template-syntax.html#inputs-outputs) chapter.
See the [Template Syntax](/docs/ts/latest/guide/template-syntax.html#inputs-outputs) chapter.
参见[模板语法Template Syntax](guide/template-syntax.html#inputs-outputs)一章。
参见[模板语法Template Syntax](/docs/ts/latest/guide/template-syntax.html#inputs-outputs)一章。
:marked
## Interpolation
@ -573,9 +573,9 @@ include _util-fns
:marked
Learn more about interpolation in the
[Template Syntax](guide/template-syntax.html#interpolation) chapter.
[Template Syntax](/docs/ts/latest/guide/template-syntax.html#interpolation) chapter.
要学习关于插值表达式的更多知识,参见[模板语法](guide/template-syntax.html#interpolation)一章。
要学习关于插值表达式的更多知识,参见[模板语法](/docs/ts/latest/guide/template-syntax.html#interpolation)一章。
<a id="J"></a>
@ -641,9 +641,9 @@ include _util-fns
* `ngOnDestroy` - just before the directive is destroyed.
* `ngOnDestroy` - 在指令销毁前调用。
Learn more in the [Lifecycle Hooks](guide/lifecycle-hooks.html) chapter.
Learn more in the [Lifecycle Hooks](/docs/ts/latest/guide/lifecycle-hooks.html) chapter.
要了解更多,参见[生命周期钩子Lifecycle Hooks](guide/lifecycle-hooks.html)一章。
要了解更多,参见[生命周期钩子Lifecycle Hooks](/docs/ts/latest/guide/lifecycle-hooks.html)一章。
// #enddocregion f-l
// #docregion m1
@ -691,7 +691,7 @@ include _util-fns
应用程序开发者可以自己选择任何与这个标准兼容的模块化库。
Modules are typically named after the file in which the exported thing is defined.
The Angular [DatePipe](https://github.com/angular/angular/blob/master/modules/angular2/src/common/pipes/date_pipe.ts)
The Angular [DatePipe](https://github.com/angular/angular/blob/master/modules/@angular/common/src/pipes/date_pipe.ts)
class belongs to a feature module named `date_pipe` in the file `date_pipe.ts`.
模块一般与它用于导出东西的文件同名。比如, Angular的[日期管道DatePipe](https://github.com/angular/angular/blob/master/modules/angular2/src/common/pipes/date_pipe.ts)类属于名叫`date_pipe`的特性模块,位于文件`date_pipe.ts`中。
@ -718,16 +718,16 @@ include _util-fns
.l-sub-section
:marked
A directive property that can be the ***target*** of an
[Event Binding](guide/template-syntax.html#property-binding).
[Event Binding](/docs/ts/latest/guide/template-syntax.html#property-binding).
Events stream *out* of this property to the receiver identified
in the template expression to the right of the equal sign.
输出Output是指令的一个属性它可作为[事件绑定Event Binding](guide/template-syntax.html#property-binding)的 **目标** 。
输出Output是指令的一个属性它可作为[事件绑定Event Binding](/docs/ts/latest/guide/template-syntax.html#property-binding)的 **目标** 。
事件流可以通过这个属性,流出到接收者(模板表达式等号的右边就是接收者)。
See the [Template Syntax](guide/template-syntax.html#inputs-outputs) chapter.
See the [Template Syntax](/docs/ts/latest/guide/template-syntax.html#inputs-outputs) chapter.
参见[模板语法Template Syntax](guide/template-syntax.html#inputs-outputs)一章。
参见[模板语法Template Syntax](/docs/ts/latest/guide/template-syntax.html#inputs-outputs)一章。
.l-main-section
<a id="P"></a>
@ -768,9 +768,9 @@ include _util-fns
code-example(language="html" escape="html").
<label>Price: </label>{{product.price | currency}}
:marked
Learn more in the chapter on [pipes](guide/pipes.html) .
Learn more in the chapter on [pipes](/docs/ts/latest/guide/pipes.html) .
要了解更多,参见[管道pipes](guide/pipes.html)一章。
要了解更多,参见[管道pipes](/docs/ts/latest/guide/pipes.html)一章。
:marked
## Provider
@ -807,7 +807,7 @@ include _util-fns
大部分应用程序包含多个屏或视图[views](#view)。用户通过点击链接、按钮和其它类似动作,在它们之间穿梭,这样应用程序从一个视图变换到另一个视图。
The Angular [Component Router](guide/router.html) is a richly featured mechanism for configuring
The Angular [Component Router](/docs/ts/latest/guide/router.html) is a richly featured mechanism for configuring
and managing the entire view navigation process including the creation and destruction
of views.
@ -885,9 +885,9 @@ include _util-fns
模板是一块HTML。在Angular指令最典型的 指令[组件Component](#component)的支持和范围下Angular用它来渲染试图。
We write templates in a special [Template Syntax](guide/template-syntax.html).
We write templates in a special [Template Syntax](/docs/ts/latest/guide/template-syntax.html).
我们使用特殊的[模板语法Template Syntax](guide/template-syntax.html)来编写模板。
我们使用特殊的[模板语法Template Syntax](/docs/ts/latest/guide/template-syntax.html)来编写模板。
:marked
## Template Expression
@ -896,7 +896,7 @@ include _util-fns
:marked
An expression in a JavaScript-like syntax that Angular evaluates within
a [data binding](#data-binding). Learn how to write template expressions
in the [Template Syntax](guide/template-syntax.html#template-expressions) chapter.
in the [Template Syntax](/docs/ts/latest/guide/template-syntax.html#template-expressions) chapter.
Angular在[数据绑定data binding](#data-binding)内求值的类似JavaScript语法的表达式。在[模板语法Template Syntax](guide/template-syntax.html#template-expressions)章节了解更多模板表达式的知识。
// #enddocregion t1
@ -987,8 +987,7 @@ include _util-fns
The browser DOM and JavaScript have a limited number
of asynchronous activities, activities such as DOM events (e.g., clicks),
[promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/
Promise), and
[promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise), and
[XHR](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest)
calls to remote servers.

View File

@ -519,20 +519,20 @@ figure
在[范例](#template)模板中,我们看到了数据绑定的三种形式:
+makeExample('architecture/ts/app/hero-list.component.1.html', 'binding', 'app/hero-list.component.html (节选)')(format=".")
:marked
* The `{{hero.name}}` "[interpolation](displaying-data.html#interpolation)"
* The `{{hero.name}}` [*interpolation*](displaying-data.html#interpolation)
displays the component's `hero.name` property value within the `<div>` tags.
* `{{hero.name}}`[插值表达式](displaying-data.html#interpolation):在`<div>`标签中显示了组件的`hero.name`属性的值。
* `{{hero.name}}`[*插值表达式*](displaying-data.html#interpolation):在`<div>`标签中显示了组件的`hero.name`属性的值。
* The `[hero]` [property binding](template-syntax.html#property-binding) passes the `selectedHero` from
* The `[hero]` [*property binding*](template-syntax.html#property-binding) passes the `selectedHero` from
the parent `HeroListComponent` to the `hero` property of the child `HeroDetailComponent`.
* `[hero]`[属性绑定](template-syntax.html#property-binding):把父组件`HeroListComponent`的`selectedHero`传到子组件`HeroDetailComponent`的`hero`属性中。
* `[hero]`[*属性绑定*](template-syntax.html#property-binding):把父组件`HeroListComponent`的`selectedHero`传到子组件`HeroDetailComponent`的`hero`属性中。
* The `(click)` [event binding](user-input.html#click) calls the Component's `selectHero` method when the user clicks
* The `(click)` [*event binding*](user-input.html#click) calls the Component's `selectHero` method when the user clicks
on a hero's name
* `(click)`[事件绑定](user-input.html#click):当用户点击英雄的名字时,调用组件的`selectHero`方法。
* `(click)`[*事件绑定*](user-input.html#click):当用户点击英雄的名字时,调用组件的`selectHero`方法。
* **Two-way data binding** is an important fourth form
that combines property and event binding in a single notation using the `ngModel` directive.
@ -996,7 +996,7 @@ code-example(language="javascript" linenumbers=".").
>把"42.33"显示为`$42.33`。
>**[Testing](../testing/index.html)** - Angular provides a testing library for "unit testing" our application parts as they
>**[Testing](testing.html)** - Angular provides a testing library for "unit testing" our application parts as they
interact with the Angular framework.
>**[Testing](../testing/index.html)** - Angular提供了一个测试库在程序各个部分与Angular框架交互同时用来“单元测试”它们。
>**[Testing](testing.html)** - Angular提供了一个测试库在程序各个部分与Angular框架交互同时用来“单元测试”它们。

View File

@ -49,7 +49,7 @@ p 运行本章这些代码的#[+liveExampleLink2()]
只要需要,我们就可以指定任何选择器、规则和媒体查询。
One way to do this is to set the `styles` property in the component metadata.
The `styles` property takes #{_an_array} of strings that contain CSS code.
The `styles` property takes #{_an} #{_array} of strings that contain CSS code.
Usually we give it one string as in this example:
它的实现方式之一,是在组件的元数据中设置`styles`属性。

View File

@ -60,7 +60,7 @@ include ../_util-fns
We didn't care about `Engine` constructor parameters when we first wrote `Car`.
We don't really care about them now.
But we'll *have* to start caring because
when the definion of `Engine` changes, our `Car` class must change.
when the definition of `Engine` changes, our `Car` class must change.
That makes `Car` brittle.
如果`Engine`类升级了,并且它的构造函数要求传入一个参数了,该怎么办?

View File

@ -1066,10 +1066,11 @@ figure.image-display
重新运行应用。表单打开时,状态是有效的,按钮是可用的。
Now delete the *Name*. We violate the "name required" rule which
is duely noted in our error message as before. And now the Submit button is also disabled.
is duly noted in our error message as before. And now the Submit button is also disabled.
现在,删除*姓名*。我们违反了“必填姓名”规则,它还是像以前那样显示了错误信息来提醒我们。同时,“提交”按钮也被禁用了。
Not impressed? Think about it for a moment. What would we have to do to
wire the button's enable/disabled state to the form's validity without Angular's help?

View File

@ -93,7 +93,7 @@ a(id="dependencies")
应用程序的`package.json`文件中,`dependencies`区下有三类包:
* ***Features*** - Feature packages provide our application with framework and utility capabilites.
* ***Features*** - Feature packages provide our application with framework and utility capabilities.
* ***特性*** - 特性包为我们的应用程序提供了框架和工具方面的能力。
* ***Polyfills*** - Polyfills plug gaps in the browser's JavaScript implementation.
@ -290,8 +290,7 @@ a(id="why-peer-dependencies")
We don't have a *peerDependencies* section in the QuickStart `package.json`.
But Angular itself has a *peerDependencies* section in
[*its* package.json](https://github.com/angular/angular/blob/master/modules/angular2/package.json)
and that has important consequences for our application.
*its* package.json and that has important consequences for our application.
在“快速起步”的`package.json`文件中,并没有*peerDependencies*区。
但是Angular本身在[*它自己的* package.json](https://github.com/angular/angular/blob/master/modules/angular2/package.json)中有,

View File

@ -969,9 +969,11 @@ a(id="one-time-initialization")
### Property binding or interpolation?
### 属性绑定还是插值表达式?
We often have a choice between interpolation and property binding. The following binding pairs do the same thing:
We often have a choice between interpolation and property binding.
The following binding pairs do the same thing:
我们通常得在插值表达式和属性绑定之间做出选择。下列这几对绑定做的事情完全相同:
我们通常得在插值表达式和属性绑定之间做出选择。
下列这几对绑定做的事情完全相同:
+makeExample('template-syntax/ts/app/app.component.html', 'property-binding-vs-interpolation')(format=".")
:marked
Interpolation is a convenient alternative for property binding in many cases.
@ -989,6 +991,26 @@ a(id="one-time-initialization")
我们倾向于可读性,所以倾向于插值表达式。
我们建议建立组织级的代码风格规定,然后选择一种形式,既能遵循规则,又能让手头的任务做起来更自然。
:marked
#### Content Security
#### 内容安全
Imagine the following *malicious content*.
假设下面的*恶毒内容*
+makeExample('template-syntax/ts/app/app.component.ts', 'evil-title')(format=".")
:marked
Fortunately, Angular data binding is on alert for dangerous HTML.
It *sanitizes* the values before displaying them.
It **will not** allow HTML with script tags to leak into the browser, neither with interpolation
nor property binding.
+makeExample('template-syntax/ts/app/app.component.html', 'property-binding-vs-interpolation-sanitization')(format=".")
:marked
Interpolation handles the script tags differently than property binding but both approaches render the
content harmlessly.
figure.image-display
img(src='/resources/images/devguide/template-syntax/evil-title.png' alt="evil title made safe" width='500px')
.l-main-section
:marked
<a id="other-bindings"></a>

View File

@ -368,7 +368,7 @@ a(id="common-configuration")
但是大多数`import`语句完全不会去引用扩展名。
所以我们要告诉Webpack如何通过查找匹配的文件来_解析_模块文件的加载请求
* an explicit extention (signified by the empty extension string, `''`) or
* an explicit extension (signified by the empty extension string, `''`) or
* 一个明确的扩展名(通过一个空白的扩展名字符串`''`标记出来),或者
* `.js` extension (for regular JavaScript files and pre-compiled TypeScript files) or
* `.js`扩展名(为了查找标准的JavaScript文件和预编译过的TypeScript文件),或者
@ -512,7 +512,7 @@ a(id="development-configuration")
我们这些CSS默认情况下被埋没在JavaScript包儿中。`ExtractTextPlugin`会把它们提取成外部`.css`文件,
这样`HtmlWebpackPlugin`插件就会转而把一个&lt;link&gt;标签写进`index.html`了。
Refer to the Webpack documentation for details on these and other configuation options in this file
Refer to the Webpack documentation for details on these and other configuration options in this file
要了解本文件中这些以及其它配置项的详情请参阅Webpack文档。

View File

@ -5,9 +5,6 @@ block includes
- var _prereq = 'Node.js'
- var _angular_browser_uri = '@angular/platform-browser-dynamic'
- var _angular_core_uri = '@angular/core'
- var _appDir = 'app'
- var _indexHtmlDir = 'project root'
- var _indexHtmlDirCn = '项目的根'
:marked
Our QuickStart goal is to build and run a super-simple

View File

@ -468,11 +468,11 @@ code-example(format="." language="bash").
:marked
We specify the path _all the way back to the application root_ &mdash; `app/` in this case &mdash;
because Angular doesn't support relative paths _by default_.
We _can_ switch to [component-relative paths](../cookbook/component-relative-paths) if we prefer.
We _can_ switch to [component-relative paths](../cookbook/component-relative-paths.html) if we prefer.
我们指定的所有路径_都是相对于该应用的根目录这里是`app/`的_。
因为Angular_默认_不支持使用相对于当前模块的路径。
只要喜欢我们也_可以_切换成[相对于组件的路径](../cookbook/component-relative-paths)模式。
只要喜欢我们也_可以_切换成[相对于组件的路径](../cookbook/component-relative-paths.html)模式。
:marked
Create that file with these contents:
@ -719,9 +719,10 @@ code-example(format='').
这段代码的问题在于`HeroService`并没有一个叫`getHero`的方法,我们最好在别人报告应用出问题之前赶快修复它。
Open `HeroService` and add the `getHero` method. It's trivial given that we're still faking data access:
Open `HeroService` and add a `getHero` method that filters the heroes list from `getHeroes` by `id`:
打开`HeroService`,并添加一个`getHero`方法,用来通过`id`从`getHeros`过滤英雄列表:
打开`HeroService`,并添加一个`getHero`方法。对于我们的假数据存取逻辑来说,这点修改是微不足道的:
+makeExample('toh-5/ts/app/hero.service.ts', 'get-hero', 'app/hero.service.ts (getHero)')(format=".")
:marked
Return to the `HeroDetailComponent` to clean up loose ends.

View File

@ -218,7 +218,10 @@ code-example(format="." language="bash").
In the following section we will update our components to use our new methods to add, edit and delete heroes.
### Add/Edit in the *HeroDetailComponent*
We already have `HeroDetailComponent` for viewing details about a specific hero. Add and Edit are natural extensions of the detail view, so we are able to reuse `DetailHeroComponent` with a few tweaks. The original component was created to render existing data, but to add new data we have to initialize the `hero` property to an empty `Hero` object.
We already have `HeroDetailComponent` for viewing details about a specific hero.
Add and Edit are natural extensions of the detail view, so we are able to reuse `HeroDetailComponent` with a few tweaks.
The original component was created to render existing data, but to add new data we have to initialize the `hero` property to an empty `Hero` object.
+makeExample('toh-6/ts/app/hero-detail.component.ts', 'ngOnInit', 'app/hero-detail.component.ts (ngOnInit)')(format=".")
@ -364,4 +367,3 @@ figure.image-display
hero-detail.comp...html,
hero.service.ts`
)

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -198,7 +198,7 @@ var createShredMapPackage = function(mapOptions) {
.config(function(readFilesProcessor, extractPathsReader ) {
readFilesProcessor.fileReaders = [ extractPathsReader];
})
// default configs - may be overriden
// default configs - may be overridden
.config(function(readFilesProcessor) {
// Specify the base path used when resolving relative paths to source and output files
readFilesProcessor.basePath = '/';