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'];
// --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
// 'foo' in their folder names.
/**
* 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.
*
* --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() {
var spawnInfo = spawnExt('npm', ['install'], { cwd: EXAMPLES_PATH});
return spawnInfo.promise.then(function() {
copyExampleBoilerplate();
var exePath = path.join(process.cwd(), "./node_modules/.bin/");
spawnInfo = spawnExt('webdriver-manager', ['update'], {cwd: exePath});
return spawnInfo.promise;
}).then(function() {
var exePath = path.join(process.cwd(), "./node_modules/.bin/");
var promise;
if (argv.fast) {
// fast; skip all setup
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);
}).then(function(status) {
reportStatus(status);
}).fail(function(e) {
}).catch(function(e) {
gutil.log(e);
return e;
});
});
@ -114,10 +139,13 @@ function findAndRunE2eTests(filter) {
var startTime = new Date().getTime();
// create an output file with header.
var outputFile = path.join(process.cwd(), 'protractor-results.txt');
var header = "Protractor example results for " + lang + " on " + (new Date()).toLocaleString() + "\n\n";
if (filter) {
header += ' Filter: ' + filter.toString() + '\n\n';
}
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
@ -175,25 +203,32 @@ function runE2eTsTests(appDir, protractorConfigFilename, outputFile) {
}
function runProtractor(prepPromise, appDir, appRunSpawnInfo, protractorConfigFilename, outputFile) {
return prepPromise.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 exePath = path.join(process.cwd(), "./node_modules/.bin/");
var spawnInfo = spawnExt('protractor',
[ pcFilename, '--params.appDir=' + appDir, '--params.outputFile=' + outputFile], { cwd: exePath });
return spawnInfo.promise;
}).then(function(data) {
// kill the app now that protractor has completed.
// Ugh... proc.kill does not work properly on windows with child processes.
// appRun.proc.kill();
treeKill(appRunSpawnInfo.proc.pid);
return !data;
}).fail(function(err) {
// Ugh... proc.kill does not work properly on windows with child processes.
// appRun.proc.kill();
treeKill(appRunSpawnInfo.proc.pid);
return false;
});
return prepPromise
.catch(function(){
var emsg = `AppDir failed during compile: ${appDir}\n\n`;
gutil.log(emsg);
fs.appendFileSync(outputFile, emsg);
return Promise.reject(emsg);
})
.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 exePath = path.join(process.cwd(), "./node_modules/.bin/");
var spawnInfo = spawnExt('protractor',
[ pcFilename, '--params.appDir=' + appDir, '--params.outputFile=' + outputFile], { cwd: exePath });
return spawnInfo.promise
})
.then(
function() { return finish(true);},
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
@ -252,9 +287,11 @@ function spawnExt(command, args, options) {
proc.stderr.on('data', function (data) {
gutil.log(data.toString());
});
proc.on('close', function (data) {
proc.on('close', function (returnCode) {
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) {
gutil.log('completed with error:' + descr);

View File

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

View File

@ -1,27 +1,32 @@
// gulp run-e2e-tests --filter=cb-set-document-title
describe('Set Document Title', function () {
describe('Cookbook: component-relative paths', function () {
beforeAll(function () {
browser.get('');
});
it('should set the document title', function () {
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 ] );
}
);
function getPageStruct() {
return {
title: element( by.tagName( 'h1' )),
absComp: element( by.css( 'absolute-path div' ) ),
relComp: element( by.css( 'relative-path div' ) )
}
}
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 { InMemoryBackendService,
SEED_DATA } from 'angular2-in-memory-web-api/core';
SEED_DATA } from 'angular2-in-memory-web-api';
import { AppComponent } from './app.component';

View File

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

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@
import { provide } from '@angular/core';
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';
// The usual bootstrapping imports

View File

@ -84,7 +84,7 @@ module.exports = function () {
var packages = {
'app': { main: 'main.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
'angular2-in-memory-web-api': { defaultExtension: 'js' },
'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
};
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/app.component.ts`,
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
.l-main-section