Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

Commit 8a5df4c

Browse files
committed
chore: support e2e-specs written in TypeScript
Update gulpfile and project to add a tsconfig to protractor test folders Change all sample e2e-spec.js -> e2e-spec.ts Split typings between e2e-spec & app code Use same config for all e2e tests Only 1/3 e2e specs truly converted. Most don't pass because they fail TS transpile by Protractor due to missing type annotations
1 parent ae2d8f2 commit 8a5df4c

File tree

44 files changed

+954
-693
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+954
-693
lines changed

.travis.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ before_script:
1818
install:
1919
- npm install --no-optional
2020
- npm install --prefix public/docs/_examples
21-
- npm run webdriver:update --prefix public/docs/_examples
21+
- npm install --prefix public/docs/_examples/_protractor
22+
- npm run webdriver:update --prefix public/docs/_examples/_protractor
2223
- gulp add-example-boilerplate
2324
script:
2425
- gulp $SCRIPT

gulpfile.js

Lines changed: 104 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ var TEMP_PATH = './_temp';
3838
var DOCS_PATH = path.join(PUBLIC_PATH, 'docs');
3939

4040
var EXAMPLES_PATH = path.join(DOCS_PATH, '_examples');
41+
var EXAMPLES_PROTRACTOR_PATH = path.join(EXAMPLES_PATH, '_protractor');
4142
var NOT_API_DOCS_GLOB = path.join(PUBLIC_PATH, './{docs/*/latest/!(api),!(docs)}/**/*');
4243
var RESOURCES_PATH = path.join(PUBLIC_PATH, 'resources');
4344
var LIVE_EXAMPLES_PATH = path.join(RESOURCES_PATH, 'live-examples');
@@ -86,123 +87,150 @@ var _exampleBoilerplateFiles = [
8687

8788
var _exampleDartWebBoilerPlateFiles = ['styles.css'];
8889

90+
var _exampleProtractorBoilerplateFiles = [
91+
'tsconfig.json'
92+
];
93+
94+
/**
95+
* Run Protractor End-to-End Specs for Doc Samples
96+
* Alias for 'run-e2e-tests'
97+
*/
98+
gulp.task('e2e', runE2e);
99+
100+
gulp.task('run-e2e-tests', runE2e);
101+
89102
/**
90103
* Run Protractor End-to-End Tests for Doc Samples
91104
*
92105
* Flags
93106
* --filter to filter/select _example app subdir names
94-
* e.g. gulp run-e2e-tests --filter=foo // all example apps with 'foo' in their folder names.
107+
* e.g. gulp e2e --filter=foo // all example apps with 'foo' in their folder names.
95108
*
96109
* --fast by-passes the npm install and webdriver update
97110
* Use it for repeated test runs (but not the FIRST run)
98-
* e.g. gulp run-e2e-tests --fast
111+
* e.g. gulp e2e --fast
99112
*
100113
* --lang to filter by code language
101-
* e.g. gulp run-e2e-tests --lang=ts // only TypeScript apps
114+
* e.g. gulp e2e --lang=ts // only TypeScript apps
102115
* default is (ts|js)
103116
* all means (ts|js|dart)
104117
*/
105-
gulp.task('run-e2e-tests', function() {
118+
function runE2e() {
106119
var promise;
107120
if (argv.fast) {
108121
// fast; skip all setup
109122
promise = Promise.resolve(true);
110123
} else {
111-
// Not 'fast'; do full setup
124+
/*
125+
// Not 'fast'; do full setup
112126
var spawnInfo = spawnExt('npm', ['install'], { cwd: EXAMPLES_PATH});
113127
promise = spawnInfo.promise.then(function() {
114128
copyExampleBoilerplate();
115129
spawnInfo = spawnExt('npm', ['run', 'webdriver:update'], {cwd: EXAMPLES_PATH});
116130
return spawnInfo.promise;
117131
});
118-
}
132+
*/
133+
// Not 'fast'; do full setup
134+
gutil.log('runE2e: install _protractor stuff');
135+
var spawnInfo = spawnExt('npm', ['install'], { cwd: EXAMPLES_PROTRACTOR_PATH});
136+
promise = spawnInfo.promise
137+
.then(function() {
138+
gutil.log('runE2e: install _examples stuff');
139+
spawnInfo = spawnExt('npm', ['install'], { cwd: EXAMPLES_PATH})
140+
return spawnInfo.promise;
141+
})
142+
.then(function() {
143+
copyExampleBoilerplate();
144+
gutil.log('runE2e: update webdriver');
145+
spawnInfo = spawnExt('npm', ['run', 'webdriver:update'], {cwd: EXAMPLES_PROTRACTOR_PATH});
146+
return spawnInfo.promise;
147+
});
148+
};
149+
150+
var outputFile = path.join(process.cwd(), 'protractor-results.txt');
119151

120152
promise.then(function() {
121-
return findAndRunE2eTests(argv.filter);
153+
return findAndRunE2eTests(argv.filter, outputFile);
122154
}).then(function(status) {
123-
reportStatus(status);
155+
reportStatus(status, outputFile);
124156
if (status.failed.length > 0){
125157
return Promise.reject('Some test suites failed');
126158
}
127159
}).catch(function(e) {
128160
gutil.log(e);
129-
process.exit(1);
161+
process.exitCode = 1;
130162
});
131-
});
163+
return promise;
164+
}
132165

133166
// finds all of the *e2e-spec.tests under the _examples folder along
134167
// with the corresponding apps that they should run under. Then run
135168
// each app/spec collection sequentially.
136-
function findAndRunE2eTests(filter) {
169+
function findAndRunE2eTests(filter, outputFile) {
170+
171+
// create an output file with header.
137172
var lang = (argv.lang || '(ts|js)').toLowerCase();
138173
if (lang === 'all') { lang = '(ts|js|dart)'; }
139174
var startTime = new Date().getTime();
140-
// create an output file with header.
141-
var outputFile = path.join(process.cwd(), 'protractor-results.txt');
142-
143175
var header = `Doc Sample Protractor Results for ${lang} on ${new Date().toLocaleString()}\n`;
144176
header += argv.fast ?
145177
' Fast Mode (--fast): no npm install, webdriver update, or boilerplate copy\n' :
146178
' Slow Mode: npm install, webdriver update, and boilerplate copy\n';
147179
header += ` Filter: ${filter ? filter : 'All tests'}\n\n`;
148-
149180
fs.writeFileSync(outputFile, header);
150181

151182
// create an array of combos where each
152183
// combo consists of { examplePath: ... , protractorConfigFilename: ... }
153-
var exeConfigs = [];
184+
var examplePaths = [];
154185
var e2eSpecPaths = getE2eSpecPaths(EXAMPLES_PATH);
155-
var srcConfig = path.join(EXAMPLES_PATH, 'protractor.config.js');
156-
e2eSpecPaths.forEach(function(specPath) {
186+
e2eSpecPaths.forEach(function(specPath) {
157187
var destConfig = path.join(specPath, 'protractor.config.js');
158-
fsExtra.copySync(srcConfig, destConfig);
159188
// get all of the examples under each dir where a pcFilename is found
160-
examplePaths = getExamplePaths(specPath, true);
189+
localExamplePaths = getExamplePaths(specPath, true);
161190
// Filter by language
162-
examplePaths = examplePaths.filter(function (fn) {
191+
localExamplePaths = localExamplePaths.filter(function (fn) {
163192
return fn.match('/'+lang+'$') != null;
164193
});
165194
if (filter) {
166-
examplePaths = examplePaths.filter(function (fn) {
195+
localExamplePaths = localExamplePaths.filter(function (fn) {
167196
return fn.match(filter) != null;
168197
})
169198
}
170-
examplePaths.forEach(function(exPath) {
171-
exeConfigs.push( { examplePath: exPath, protractorConfigFilename: destConfig });
199+
localExamplePaths.forEach(function(examplePath) {
200+
examplePaths.push(examplePath);
172201
})
173202
});
174203

175204
// run the tests sequentially
176205
var status = { passed: [], failed: [] };
177-
return exeConfigs.reduce(function (promise, combo) {
206+
return examplePaths.reduce(function (promise, examplePath) {
178207
return promise.then(function () {
179-
var isDart = combo.examplePath.indexOf('/dart') > -1;
208+
var isDart = examplePath.indexOf('/dart') > -1;
180209
var runTests = isDart ? runE2eDartTests : runE2eTsTests;
181-
return runTests(combo.examplePath, combo.protractorConfigFilename, outputFile).then(function(ok) {
210+
return runTests(examplePath, outputFile).then(function(ok) {
182211
var arr = ok ? status.passed : status.failed;
183-
arr.push(combo.examplePath);
212+
arr.push(examplePath);
184213
})
185214
});
186215
}, Q.resolve()).then(function() {
187216
var stopTime = new Date().getTime();
188217
status.elapsedTime = (stopTime - startTime)/1000;
189-
fs.appendFileSync(outputFile, '\nElaped Time: ' + status.elapsedTime + ' seconds');
190218
return status;
191219
});
192220
}
193221

194222
// start the example in appDir; then run protractor with the specified
195223
// fileName; then shut down the example. All protractor output is appended
196224
// to the outputFile.
197-
function runE2eTsTests(appDir, protractorConfigFilename, outputFile) {
225+
function runE2eTsTests(appDir, outputFile) {
198226
// start the app
199227
var appRunSpawnInfo = spawnExt('npm',['run','http-server:e2e', '--', '-s' ], { cwd: appDir });
200228
var tscRunSpawnInfo = spawnExt('npm',['run','tsc'], { cwd: appDir });
201229

202-
return runProtractor(tscRunSpawnInfo.promise, appDir, appRunSpawnInfo, protractorConfigFilename, outputFile);
230+
return runProtractor(tscRunSpawnInfo.promise, appDir, appRunSpawnInfo, outputFile);
203231
}
204232

205-
function runProtractor(prepPromise, appDir, appRunSpawnInfo, protractorConfigFilename, outputFile) {
233+
function runProtractor(prepPromise, appDir, appRunSpawnInfo, outputFile) {
206234
return prepPromise
207235
.catch(function(){
208236
var emsg = `AppDir failed during compile: ${appDir}\n\n`;
@@ -212,10 +240,10 @@ function runProtractor(prepPromise, appDir, appRunSpawnInfo, protractorConfigFil
212240
})
213241
.then(function (data) {
214242
// start protractor
215-
var pcFilename = path.resolve(protractorConfigFilename); // need to resolve because we are going to be running from a different dir
216-
var spawnInfo = spawnExt('npm', [ 'run', 'protractor', '--', pcFilename,
217-
'--params.appDir=' + appDir, '--params.outputFile=' + outputFile], { cwd: EXAMPLES_PATH });
218-
return spawnInfo.promise
243+
var specFilename = path.resolve(`${appDir}/../e2e-spec.ts`);
244+
var spawnInfo = spawnExt('npm', [ 'run', 'protractor', '--', 'protractor.config.js',
245+
`--specs=${specFilename}`, '--params.appDir=' + appDir, '--params.outputFile=' + outputFile], { cwd: EXAMPLES_PROTRACTOR_PATH });
246+
return spawnInfo.promise;
219247
})
220248
.then(
221249
function() { return finish(true);},
@@ -233,7 +261,7 @@ function runProtractor(prepPromise, appDir, appRunSpawnInfo, protractorConfigFil
233261
// start the server in appDir/build/web; then run protractor with the specified
234262
// fileName; then shut down the example. All protractor output is appended
235263
// to the outputFile.
236-
function runE2eDartTests(appDir, protractorConfigFilename, outputFile) {
264+
function runE2eDartTests(appDir, outputFile) {
237265
var deployDir = path.resolve(path.join(appDir, 'build/web'));
238266
gutil.log('AppDir for Dart e2e: ' + appDir);
239267
gutil.log('Deploying from: ' + deployDir);
@@ -247,24 +275,28 @@ function runE2eDartTests(appDir, protractorConfigFilename, outputFile) {
247275
var prepPromise = pubUpgradeSpawnInfo.promise.then(function (data) {
248276
return spawnExt('pub', ['build'], { cwd: appDir }).promise;
249277
});
250-
return runProtractor(prepPromise, appDir, appRunSpawnInfo, protractorConfigFilename, outputFile);
278+
return runProtractor(prepPromise, appDir, appRunSpawnInfo, outputFile);
251279
}
252280

253-
function reportStatus(status) {
254-
gutil.log('Suites passed:');
281+
function reportStatus(status, outputFile) {
282+
var log = [''];
283+
log.push('Suites passed:');
255284
status.passed.forEach(function(val) {
256-
gutil.log(' ' + val);
285+
log.push(' ' + val);
257286
});
258287

259288
if (status.failed.length == 0) {
260-
gutil.log('All tests passed');
289+
log.push('All tests passed');
261290
} else {
262-
gutil.log('Suites failed:');
291+
log.push('Suites failed:');
263292
status.failed.forEach(function (val) {
264-
gutil.log(' ' + val);
293+
log.push(' ' + val);
265294
});
266295
}
267-
gutil.log('Elapsed time: ' + status.elapsedTime + ' seconds');
296+
log.push('\nElapsed time: ' + status.elapsedTime + ' seconds');
297+
var log = log.join('\n');
298+
gutil.log(log);
299+
fs.appendFileSync(outputFile, log);
268300
}
269301

270302
// 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) {
312344
return shouldRemove;
313345
}));
314346

315-
// requires admin access
347+
// requires admin access because it adds symlinks
316348
gulp.task('add-example-boilerplate', function() {
317349
var realPath = path.join(EXAMPLES_PATH, '/node_modules');
318350
var nodeModulesPaths = getNodeModulesPaths(EXAMPLES_PATH);
@@ -332,11 +364,18 @@ gulp.task('add-example-boilerplate', function() {
332364
return copyExampleBoilerplate();
333365
});
334366

367+
368+
// copies boilerplate files to locations
369+
// where an example app is found
370+
gulp.task('_copy-example-boilerplate', copyExampleBoilerplate);
371+
372+
335373
// copies boilerplate files to locations
336374
// where an example app is found
337375
// also copies certain web files (e.g., styles.css) to ~/_examples/**/dart/**/web
338376
// also copies protractor.config.js file
339377
function copyExampleBoilerplate() {
378+
gutil.log('Copying example boilerplate files');
340379
var sourceFiles = _exampleBoilerplateFiles.map(function(fn) {
341380
return path.join(EXAMPLES_PATH, fn);
342381
});
@@ -351,12 +390,14 @@ function copyExampleBoilerplate() {
351390
.then(function() {
352391
return copyFiles(dartWebSourceFiles, dartExampleWebPaths);
353392
})
354-
// copy protractor.config.js from _examples dir to each subdir that
393+
// copy files from _examples/_protractor dir to each subdir that
355394
// contains a e2e-spec file.
356395
.then(function() {
357-
var sourceFiles = [ path.join(EXAMPLES_PATH, 'protractor.config.js') ];
396+
var protractorSourceFiles =
397+
_exampleProtractorBoilerplateFiles
398+
.map(function(name) {return path.join(EXAMPLES_PROTRACTOR_PATH, name);});;
358399
var e2eSpecPaths = getE2eSpecPaths(EXAMPLES_PATH);
359-
return copyFiles(sourceFiles, e2eSpecPaths);
400+
return copyFiles(protractorSourceFiles, e2eSpecPaths);
360401
});
361402
}
362403

@@ -371,6 +412,15 @@ gulp.task('remove-example-boilerplate', function() {
371412
fsUtils.removeSymlink(linkPath);
372413
});
373414

415+
deleteExampleBoilerPlate();
416+
});
417+
418+
// deletes boilerplate files that were added by copyExampleBoilerplate
419+
// from locations where an example app is found
420+
gulp.task('_delete-example-boilerplate', deleteExampleBoilerPlate);
421+
422+
function deleteExampleBoilerPlate() {
423+
gutil.log('Deleting example boilerplate files');
374424
var examplePaths = getExamplePaths(EXAMPLES_PATH);
375425
var dartExampleWebPaths = getDartExampleWebPaths(EXAMPLES_PATH);
376426

@@ -379,10 +429,11 @@ gulp.task('remove-example-boilerplate', function() {
379429
return deleteFiles(_exampleDartWebBoilerPlateFiles, dartExampleWebPaths);
380430
})
381431
.then(function() {
432+
var protractorFiles = _exampleProtractorBoilerplateFiles;
382433
var e2eSpecPaths = getE2eSpecPaths(EXAMPLES_PATH);
383-
return deleteFiles(['protractor.config.js'], e2eSpecPaths);
384-
})
385-
});
434+
return deleteFiles(protractorFiles, e2eSpecPaths);
435+
});
436+
}
386437

387438
gulp.task('serve-and-sync', ['build-docs'], function (cb) {
388439
// watchAndSync({devGuide: true, apiDocs: true, apiExamples: true, localFiles: true}, cb);
@@ -744,7 +795,7 @@ function deleteFiles(baseFileNames, destPaths) {
744795
// TODO: filter out all paths that are subdirs of another
745796
// path in the result.
746797
function getE2eSpecPaths(basePath) {
747-
var paths = getPaths(basePath, '*e2e-spec.js', true);
798+
var paths = getPaths(basePath, '*e2e-spec.+(js|ts)', true);
748799
return _.uniq(paths);
749800
}
750801

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/// <reference path="typings/index.d.ts" />
2+
3+
// Defined in protractor.config.js
4+
declare function setProtractorToNg1Mode(): void;
5+
declare function sendKeys(element: protractor.ElementFinder, str: string): webdriver.promise.Promise<void>;
6+
declare function describeIf(cond: boolean, name: string, func: Function): void;
7+
declare function itIf(cond: boolean, name: string, func: Function): void;
8+
9+
declare namespace protractor {
10+
interface IBrowser {
11+
appIsTs: boolean;
12+
appIsJs: boolean;
13+
}
14+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "angular2-examples-protractor",
3+
"version": "1.0.0",
4+
"description": "Manage _protractor folder installations",
5+
"scripts": {
6+
"postinstall": "typings install",
7+
"typings": "typings",
8+
"protractor": "protractor",
9+
"webdriver:update": "webdriver-manager update"
10+
},
11+
"keywords": [],
12+
"author": "",
13+
"license": "ISC",
14+
"devDependencies": {
15+
"protractor": "^3.3.0",
16+
"typings": "^1.0.4"
17+
},
18+
"repository": {}
19+
}

0 commit comments

Comments
 (0)