docs(e2e-tests): improve gulp e2e tasks and fix samples that were failing

This commit is contained in:
Ward Bell 2016-05-20 19:07:01 -07:00
parent f9fea00824
commit e188e472f1
11 changed files with 113 additions and 71 deletions

View File

@ -86,21 +86,46 @@ var _exampleBoilerplateFiles = [
var _exampleDartWebBoilerPlateFiles = ['styles.css']; var _exampleDartWebBoilerPlateFiles = ['styles.css'];
// --filter may be passed in to filter/select _example app subdir names /**
// i.e. gulp run-e2e-tests --filter=foo ; would select all example apps with * Run Protractor End-to-End Tests for Doc Samples
// 'foo' in their folder names. *
* 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.
*
* --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
*
* --lang to filter by code language
* e.g. gulp run-e2e-tests --lang=ts // only TypeScript apps
* default is (ts|js)
* all means (ts|js|dart)
*/
gulp.task('run-e2e-tests', function() { gulp.task('run-e2e-tests', function() {
var spawnInfo = spawnExt('npm', ['install'], { cwd: EXAMPLES_PATH});
return spawnInfo.promise.then(function() { var exePath = path.join(process.cwd(), "./node_modules/.bin/");
copyExampleBoilerplate();
var exePath = path.join(process.cwd(), "./node_modules/.bin/"); var promise;
spawnInfo = spawnExt('webdriver-manager', ['update'], {cwd: exePath}); if (argv.fast) {
return spawnInfo.promise; // fast; skip all setup
}).then(function() { promise = Promise.resolve(true);
} else {
// Not 'fast'; do full setup
var spawnInfo = spawnExt('npm', ['install'], { cwd: EXAMPLES_PATH});
promise = spawnInfo.promise.then(function() {
copyExampleBoilerplate();
spawnInfo = spawnExt('webdriver-manager', ['update'], {cwd: exePath});
return spawnInfo.promise;
});
}
promise.then(function() {
return findAndRunE2eTests(argv.filter); return findAndRunE2eTests(argv.filter);
}).then(function(status) { }).then(function(status) {
reportStatus(status); reportStatus(status);
}).fail(function(e) { }).catch(function(e) {
gutil.log(e);
return e; return e;
}); });
}); });
@ -114,10 +139,13 @@ function findAndRunE2eTests(filter) {
var startTime = new Date().getTime(); var startTime = new Date().getTime();
// create an output file with header. // create an output file with header.
var outputFile = path.join(process.cwd(), 'protractor-results.txt'); var outputFile = path.join(process.cwd(), 'protractor-results.txt');
var header = "Protractor example results for " + lang + " on " + (new Date()).toLocaleString() + "\n\n";
if (filter) { var header = `Doc Sample Protractor Results for ${lang} on ${new Date().toLocaleString()}\n`;
header += ' Filter: ' + filter.toString() + '\n\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); fs.writeFileSync(outputFile, header);
// create an array of combos where each // create an array of combos where each
@ -175,25 +203,32 @@ function runE2eTsTests(appDir, protractorConfigFilename, outputFile) {
} }
function runProtractor(prepPromise, appDir, appRunSpawnInfo, protractorConfigFilename, outputFile) { function runProtractor(prepPromise, appDir, appRunSpawnInfo, protractorConfigFilename, outputFile) {
return prepPromise.then(function (data) { return prepPromise
// start protractor .catch(function(){
var pcFilename = path.resolve(protractorConfigFilename); // need to resolve because we are going to be running from a different dir var emsg = `AppDir failed during compile: ${appDir}\n\n`;
var exePath = path.join(process.cwd(), "./node_modules/.bin/"); gutil.log(emsg);
var spawnInfo = spawnExt('protractor', fs.appendFileSync(outputFile, emsg);
[ pcFilename, '--params.appDir=' + appDir, '--params.outputFile=' + outputFile], { cwd: exePath }); return Promise.reject(emsg);
return spawnInfo.promise; })
}).then(function(data) { .then(function (data) {
// kill the app now that protractor has completed. // start protractor
// Ugh... proc.kill does not work properly on windows with child processes. var pcFilename = path.resolve(protractorConfigFilename); // need to resolve because we are going to be running from a different dir
// appRun.proc.kill(); var exePath = path.join(process.cwd(), "./node_modules/.bin/");
treeKill(appRunSpawnInfo.proc.pid); var spawnInfo = spawnExt('protractor',
return !data; [ pcFilename, '--params.appDir=' + appDir, '--params.outputFile=' + outputFile], { cwd: exePath });
}).fail(function(err) { return spawnInfo.promise
// Ugh... proc.kill does not work properly on windows with child processes. })
// appRun.proc.kill(); .then(
treeKill(appRunSpawnInfo.proc.pid); function() { return finish(true);},
return false; function() { return finish(false);}
}); )
function finish(ok){
// Ugh... proc.kill does not work properly on windows with child processes.
// appRun.proc.kill();
treeKill(appRunSpawnInfo.proc.pid);
return ok;
}
} }
// start the server in appDir/build/web; then run protractor with the specified // start the server in appDir/build/web; then run protractor with the specified
@ -252,9 +287,11 @@ function spawnExt(command, args, options) {
proc.stderr.on('data', function (data) { proc.stderr.on('data', function (data) {
gutil.log(data.toString()); gutil.log(data.toString());
}); });
proc.on('close', function (data) { proc.on('close', function (returnCode) {
gutil.log('completed: ' + descr); gutil.log('completed: ' + descr);
deferred.resolve(data); // Many tasks (e.g., tsc) complete but are actually errors;
// Confirm return code is zero.
returnCode === 0 ? deferred.resolve(0) : deferred.reject(returnCode);
}); });
proc.on('error', function (data) { proc.on('error', function (data) {
gutil.log('completed with error:' + descr); gutil.log('completed with error:' + descr);

View File

@ -2,7 +2,7 @@
import { Component, OnDestroy, OnInit } from '@angular/core'; import { Component, OnDestroy, OnInit } from '@angular/core';
@Component({ @Component({
selector:'countdown-timer', selector: 'countdown-timer',
template: '<p>{{message}}</p>' template: '<p>{{message}}</p>'
}) })
export class CountdownTimerComponent implements OnInit, OnDestroy { export class CountdownTimerComponent implements OnInit, OnDestroy {
@ -24,12 +24,12 @@ export class CountdownTimerComponent implements OnInit, OnDestroy {
private countDown() { private countDown() {
this.clearTimer(); this.clearTimer();
this.intervalId = setInterval(()=>{ this.intervalId = window.setInterval(() => {
this.seconds -= 1; this.seconds -= 1;
if (this.seconds == 0) { if (this.seconds === 0) {
this.message = "Blast off!"; this.message = 'Blast off!';
} else { } else {
if (this.seconds < 0) { this.seconds = 10;} // reset if (this.seconds < 0) { this.seconds = 10; } // reset
this.message = `T-${this.seconds} seconds and counting`; this.message = `T-${this.seconds} seconds and counting`;
} }
}, 1000); }, 1000);

View File

@ -1,27 +1,32 @@
// gulp run-e2e-tests --filter=cb-set-document-title describe('Cookbook: component-relative paths', function () {
describe('Set Document Title', function () {
beforeAll(function () { function getPageStruct() {
browser.get(''); return {
}); title: element( by.tagName( 'h1' )),
absComp: element( by.css( 'absolute-path div' ) ),
it('should set the document title', function () { relComp: element( by.css( 'relative-path div' ) )
}
var titles = [ }
'Good morning!',
'Good afternoon!',
'Good evening!'
];
element.all( by.css( 'ul li a' ) ).each(
function iterator( element, i ) {
element.click();
expect( browser.getTitle() ).toEqual( titles[ i ] );
}
);
var page;
beforeAll(function () {
browser.get('');
page = getPageStruct();
}); });
it('should display title of the sample', function () {
expect(element(by.tagName('h1')).getText()).toContain('Paths');
});
it('should have absolute-path element', function () {
expect(page.absComp.isPresent()).toBe(true, 'no <absolute-path> element');
});
it('should display the absolute path text', function () {
expect(page.absComp.getText()).toContain('Absolute');
});
it('should display the component-relative path text', function () {
expect(page.relComp.getText()).toContain('Component-relative');
});
}); });

View File

@ -8,7 +8,7 @@ import { LocationStrategy,
import { HeroData } from './hero-data'; import { HeroData } from './hero-data';
import { InMemoryBackendService, import { InMemoryBackendService,
SEED_DATA } from 'angular2-in-memory-web-api/core'; SEED_DATA } from 'angular2-in-memory-web-api';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';

View File

@ -38,7 +38,7 @@ var map = {
var packages = { var packages = {
'app': { main: 'main.js', defaultExtension: 'js' }, 'app': { main: 'main.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' }, 'rxjs': { defaultExtension: 'js' },
'angular2-in-memory-web-api': { defaultExtension: 'js' }, 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
}; };
var ngPackageNames = [ var ngPackageNames = [

View File

@ -5,7 +5,7 @@ import { provide } from '@angular/core';
import { XHRBackend } from '@angular/http'; import { XHRBackend } from '@angular/http';
import { InMemoryBackendService, import { InMemoryBackendService,
SEED_DATA } from 'angular2-in-memory-web-api/core'; SEED_DATA } from 'angular2-in-memory-web-api';
import { HeroData } from './hero-data'; import { HeroData } from './hero-data';
// The usual bootstrapping imports // The usual bootstrapping imports

View File

@ -17,7 +17,7 @@
var packages = { var packages = {
'app': { main: 'main.js', defaultExtension: 'js' }, 'app': { main: 'main.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' }, 'rxjs': { defaultExtension: 'js' },
'angular2-in-memory-web-api': { defaultExtension: 'js' }, 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
}; };
var ngPackageNames = [ var ngPackageNames = [

View File

@ -22,7 +22,7 @@
var packages = { var packages = {
'app': { main: 'main.ts', defaultExtension: 'ts' }, 'app': { main: 'main.ts', defaultExtension: 'ts' },
'rxjs': { defaultExtension: 'js' }, 'rxjs': { defaultExtension: 'js' },
'angular2-in-memory-web-api': { defaultExtension: 'js' }, 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
}; };
var ngPackageNames = [ var ngPackageNames = [

View File

@ -4,7 +4,7 @@
import { provide } from '@angular/core'; import { provide } from '@angular/core';
import { XHRBackend } from '@angular/http'; import { XHRBackend } from '@angular/http';
import { InMemoryBackendService, SEED_DATA } from 'angular2-in-memory-web-api/core'; import { InMemoryBackendService, SEED_DATA } from 'angular2-in-memory-web-api';
import { InMemoryDataService } from './in-memory-data.service'; import { InMemoryDataService } from './in-memory-data.service';
// The usual bootstrapping imports // The usual bootstrapping imports

View File

@ -84,7 +84,7 @@ module.exports = function () {
var packages = { var packages = {
'app': { main: 'main.js', defaultExtension: 'js' }, 'app': { main: 'main.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' }, 'rxjs': { defaultExtension: 'js' },
'angular2-in-memory-web-api': { defaultExtension: 'js' }, 'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
}; };
var ngPackageNames = [ var ngPackageNames = [

View File

@ -84,7 +84,7 @@ include ../_util-fns
cb-component-relative-paths/ts/app/some.component.css, cb-component-relative-paths/ts/app/some.component.css,
cb-component-relative-paths/ts/app/app.component.ts`, cb-component-relative-paths/ts/app/app.component.ts`,
null, null,
`app/some.component.ts, app/some.html, app/some.component.css, app/app.component.ts`) `app/some.component.ts, app/some.component.html, app/some.component.css, app/app.component.ts`)
a#why-default a#why-default
.l-main-section .l-main-section