mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 04:14:21 +08:00
chore(gulp): update e2e and snapshot (#8846)
* chore(e2e): add livereload server and clean task for e2e * chore(e2e): refactor to use gulp connect and open * chore(e2e): WIP remove open, add formatting, add reload task * wip(e2e): use SystemJS for faster dev e2e rebuilds * chore(e2e): wip removing old gulp file, old e2e task update template for e2e and port number * chore(e2e): wip add SystemJS for dev build of e2e, use those tasks instead * chore(e2e): uncomment out range components * chore(e2e): wip fix paths for the e2e tempate * chore(scripts): update README back to the old way * chore(e2e): code cleanup * chore(e2e): split tasks into dev and prod, put common tasks in e2e * chore(e2e): rename e2e templates and add to readme * chore(e2e): fix dev build so it will work with snapshot * chore(snapshot): get snapshot working with dev and prod builds
This commit is contained in:
committed by
Manu Mtz.-Almeida
parent
981e95d034
commit
d93070a7d5
@ -45,4 +45,4 @@ export const NPM_VENDOR_FILES = [
|
||||
|
||||
|
||||
// SERVER
|
||||
export const LOCAL_SERVER_PORT = 8080;
|
||||
export const LOCAL_SERVER_PORT = 8000;
|
||||
|
||||
9
scripts/gulp/declarations.d.ts
vendored
9
scripts/gulp/declarations.d.ts
vendored
@ -2,18 +2,25 @@ declare module 'conventional-changelog';
|
||||
declare module 'dgeni';
|
||||
declare module 'event-stream';
|
||||
declare module 'github';
|
||||
declare module 'gulp-babel';
|
||||
declare module 'gulp-cached';
|
||||
declare module 'gulp-concat';
|
||||
declare module 'gulp-connect';
|
||||
declare module 'gulp-if';
|
||||
declare module 'gulp-open';
|
||||
declare module 'gulp-remember';
|
||||
declare module 'gulp-rename';
|
||||
declare module 'gulp-scss-lint';
|
||||
declare module 'gulp-server-livereload';
|
||||
declare module 'gulp-tslint';
|
||||
declare module 'gulp-typescript';
|
||||
declare module 'html-entities';
|
||||
declare module 'path';
|
||||
declare module 'rollup';
|
||||
declare module 'rollup-plugin-commonjs';
|
||||
declare module 'rollup-plugin-multi-entry';
|
||||
declare module 'rollup-plugin-node-resolve';
|
||||
declare module 'rollup-plugin-uglify';
|
||||
declare module 'through2';
|
||||
declare module 'semver';
|
||||
declare module 'vinyl';
|
||||
declare module 'yargs';
|
||||
|
||||
@ -4,6 +4,8 @@ import './tasks/default';
|
||||
import './tasks/demos';
|
||||
import './tasks/docs';
|
||||
import './tasks/e2e';
|
||||
import './tasks/e2e.dev';
|
||||
import './tasks/e2e.prod';
|
||||
import './tasks/lint';
|
||||
import './tasks/release';
|
||||
import './tasks/snapshot';
|
||||
|
||||
226
scripts/gulp/tasks/e2e.dev.ts
Normal file
226
scripts/gulp/tasks/e2e.dev.ts
Normal file
@ -0,0 +1,226 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { dirname, join, sep } from 'path';
|
||||
|
||||
import { dest, src, start, task } from 'gulp';
|
||||
import * as babel from 'gulp-babel';
|
||||
import * as cache from 'gulp-cached';
|
||||
import * as concat from 'gulp-concat';
|
||||
import * as connect from 'gulp-connect';
|
||||
import * as gulpif from 'gulp-if';
|
||||
import * as remember from 'gulp-remember';
|
||||
import * as rename from 'gulp-rename';
|
||||
import * as tsc from 'gulp-typescript';
|
||||
import * as watch from 'gulp-watch';
|
||||
import { template } from 'lodash';
|
||||
import * as merge from 'merge2';
|
||||
import * as runSequence from 'run-sequence';
|
||||
import { obj } from 'through2';
|
||||
import * as VinylFile from 'vinyl';
|
||||
|
||||
import { DIST_E2E_ROOT, DIST_NAME, E2E_NAME, ES5, ES_2015, SCRIPTS_ROOT } from '../constants';
|
||||
|
||||
const buildConfig = require('../../build/config');
|
||||
|
||||
/**
|
||||
* Builds Ionic e2e tests to dist/e2e and creates the necessary files for tests
|
||||
* to run.
|
||||
*/
|
||||
task('e2e', e2eBuild);
|
||||
|
||||
function e2eBuild(done: (err: any) => void) {
|
||||
runSequence(
|
||||
'e2e.clean',
|
||||
'e2e.build',
|
||||
'e2e.polyfill',
|
||||
'e2e.copyExternalDependencies',
|
||||
'e2e.sass',
|
||||
'e2e.fonts',
|
||||
'e2e.bundle',
|
||||
done);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds Ionic e2e tests to dist/e2e.
|
||||
*/
|
||||
task('e2e.build', function () {
|
||||
var indexTemplate = template(
|
||||
readFileSync(`${SCRIPTS_ROOT}/${E2E_NAME}/e2e.template.dev.html`).toString()
|
||||
)({
|
||||
buildConfig: buildConfig
|
||||
});
|
||||
|
||||
// Get each test folder with src
|
||||
var tsResult = src([
|
||||
'src/components/*/test/*/**/*.ts',
|
||||
'!src/components/*/test/*/**/*.spec.ts'
|
||||
])
|
||||
.pipe(cache('e2e.ts'))
|
||||
.pipe(tsc(getTscOptions(), undefined, tscReporter))
|
||||
.on('error', function (error) {
|
||||
console.log(error.message);
|
||||
})
|
||||
.pipe(gulpif(/app-module.js$/, createIndexHTML()))
|
||||
.pipe(gulpif(/e2e.js$/, createPlatformTests()));
|
||||
|
||||
var testFiles = src([
|
||||
'src/components/*/test/*/**/*',
|
||||
'!src/components/*/test/*/**/*.ts'
|
||||
])
|
||||
.pipe(cache('e2e.files'));
|
||||
|
||||
return merge([
|
||||
tsResult,
|
||||
testFiles
|
||||
])
|
||||
.pipe(rename(function (file) {
|
||||
file.dirname = file.dirname.replace(sep + 'test' + sep, sep);
|
||||
}))
|
||||
.pipe(dest(DIST_E2E_ROOT))
|
||||
.pipe(connect.reload());
|
||||
|
||||
function createIndexHTML() {
|
||||
return obj(function (file, enc, next) {
|
||||
this.push(new VinylFile({
|
||||
base: file.base,
|
||||
contents: new Buffer(indexTemplate),
|
||||
path: join(dirname(file.path), 'index.html'),
|
||||
}));
|
||||
next(null, file);
|
||||
});
|
||||
}
|
||||
|
||||
function createPlatformTests() {
|
||||
let platforms = [
|
||||
'android',
|
||||
'ios',
|
||||
'windows'
|
||||
];
|
||||
|
||||
let testTemplate = template(readFileSync(`${SCRIPTS_ROOT}/${E2E_NAME}/e2e.template.js`).toString());
|
||||
|
||||
return obj(function (file, enc, next) {
|
||||
let self = this;
|
||||
|
||||
let relativePath = dirname(file.path.replace(/^.*?src(\/|\\)components(\/|\\)/, ''));
|
||||
relativePath = relativePath.replace('/test/', '/');
|
||||
|
||||
let contents = file.contents.toString();
|
||||
platforms.forEach(function (platform) {
|
||||
let platformContents = testTemplate({
|
||||
contents: contents,
|
||||
buildConfig: buildConfig,
|
||||
relativePath: relativePath,
|
||||
platform: platform
|
||||
});
|
||||
self.push(new VinylFile({
|
||||
base: file.base,
|
||||
contents: new Buffer(platformContents),
|
||||
path: file.path.replace(/e2e.js$/, platform + '.e2e.js')
|
||||
}));
|
||||
});
|
||||
next();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Creates SystemJS bundle from Ionic source files.
|
||||
*/
|
||||
task('e2e.bundle', function () {
|
||||
var tsResult = tsCompile(getTscOptions('es6'), 'system')
|
||||
.pipe(babel(babelOptions));
|
||||
|
||||
var swiper = src('src/components/slides/swiper-widget.system.js');
|
||||
|
||||
return merge([tsResult, swiper])
|
||||
.pipe(remember('system'))
|
||||
.pipe(concat('ionic.system.js'))
|
||||
.pipe(dest(`${DIST_NAME}/bundles`))
|
||||
.pipe(connect.reload());
|
||||
});
|
||||
|
||||
function tsCompile(options, cacheName) {
|
||||
return src([
|
||||
'typings/main.d.ts',
|
||||
'src/**/*.ts',
|
||||
'!src/**/*.d.ts',
|
||||
'!src/components/*/test/**/*',
|
||||
'!src/util/test/*',
|
||||
'!src/config/test/*',
|
||||
'!src/platform/test/*',
|
||||
'!src/**/*.spec.ts'
|
||||
])
|
||||
.pipe(cache(cacheName, { optimizeMemory: true }))
|
||||
.pipe(tsc(options, undefined, tscReporter));
|
||||
}
|
||||
|
||||
function getTscOptions(name?: string) {
|
||||
var opts = {
|
||||
emitDecoratorMetadata: true,
|
||||
experimentalDecorators: true,
|
||||
target: ES5,
|
||||
module: 'commonjs',
|
||||
isolatedModules: true,
|
||||
typescript: require('typescript'),
|
||||
declaration: false
|
||||
};
|
||||
|
||||
if (name === 'typecheck') {
|
||||
opts.declaration = true;
|
||||
delete opts.isolatedModules;
|
||||
} else if (name === 'es6') {
|
||||
opts.target = 'es6';
|
||||
delete opts.module;
|
||||
}
|
||||
return opts;
|
||||
}
|
||||
|
||||
var tscReporter = {
|
||||
error: function (error) {
|
||||
console.error(error.message);
|
||||
}
|
||||
};
|
||||
|
||||
// We use Babel to easily create named System.register modules
|
||||
// See: https://github.com/Microsoft/TypeScript/issues/4801
|
||||
// and https://github.com/ivogabe/gulp-typescript/issues/211
|
||||
const babelOptions = {
|
||||
moduleIds: true,
|
||||
getModuleId: function (name) {
|
||||
return 'ionic-angular/' + name;
|
||||
},
|
||||
plugins: ['transform-es2015-modules-systemjs'],
|
||||
presets: [ES_2015]
|
||||
};
|
||||
|
||||
/**
|
||||
* Builds e2e tests to dist/e2e and watches for changes. Runs 'e2e.bundle' or
|
||||
* 'sass' on Ionic source changes and 'e2e.build' for e2e test changes.
|
||||
*/
|
||||
task('e2e.watch', ['e2e'], function () {
|
||||
watchTask('e2e.bundle');
|
||||
|
||||
watch('src/components/*/test/**/*', function (file) {
|
||||
start('e2e.build');
|
||||
});
|
||||
});
|
||||
|
||||
function watchTask(task) {
|
||||
watch([
|
||||
'src/**/*.ts',
|
||||
'!src/components/*/test/**/*',
|
||||
'!src/util/test/*'
|
||||
],
|
||||
function (file) {
|
||||
if (file.event !== 'unlink') {
|
||||
start(task);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
watch('src/**/*.scss', function () {
|
||||
start('e2e.sass');
|
||||
});
|
||||
|
||||
start('e2e.serve');
|
||||
}
|
||||
279
scripts/gulp/tasks/e2e.prod.ts
Normal file
279
scripts/gulp/tasks/e2e.prod.ts
Normal file
@ -0,0 +1,279 @@
|
||||
import { accessSync, F_OK, readFileSync, writeFileSync } from 'fs';
|
||||
import { dirname, join } from 'path';
|
||||
|
||||
import * as glob from 'glob';
|
||||
import { dest, src, start, task } from 'gulp';
|
||||
import * as gulpif from 'gulp-if';
|
||||
import * as watch from 'gulp-watch';
|
||||
import { template } from 'lodash';
|
||||
import * as rollup from 'rollup';
|
||||
import * as nodeResolve from 'rollup-plugin-node-resolve';
|
||||
import * as commonjs from 'rollup-plugin-commonjs';
|
||||
import * as runSequence from 'run-sequence';
|
||||
import { obj } from 'through2';
|
||||
import * as VinylFile from 'vinyl';
|
||||
import { argv } from 'yargs';
|
||||
|
||||
import { DIST_E2E_COMPONENTS_ROOT, DIST_E2E_ROOT, DIST_NAME, E2E_NAME, ES5, ES_2015, LOCAL_SERVER_PORT, PROJECT_ROOT, SCRIPTS_ROOT, SRC_COMPONENTS_ROOT, SRC_ROOT } from '../constants';
|
||||
import { createTempTsConfig, deleteFiles, runNgc } from '../util';
|
||||
|
||||
task('e2e.prod', e2eBuild);
|
||||
|
||||
function e2eBuild(done: (err: any) => void) {
|
||||
runSequence(
|
||||
'e2e.clean',
|
||||
'e2e.polyfill',
|
||||
'e2e.copySource',
|
||||
'e2e.compileTests',
|
||||
'e2e.copyExternalDependencies',
|
||||
'e2e.sass',
|
||||
'e2e.fonts',
|
||||
'e2e.bundleProd',
|
||||
done);
|
||||
}
|
||||
|
||||
task('e2e.copySource', (done: Function) => {
|
||||
|
||||
const buildConfig = require('../../build/config');
|
||||
|
||||
const stream = src([`${SRC_ROOT}/**/*`, `!${SRC_ROOT}/**/*.spec.ts`])
|
||||
.pipe(gulpif(/app-module.ts$/, createIndexHTML()))
|
||||
.pipe(gulpif(/e2e.ts$/, createPlatformTests()))
|
||||
.pipe(dest(DIST_E2E_ROOT));
|
||||
|
||||
stream.on('end', done);
|
||||
|
||||
function createIndexHTML() {
|
||||
const indexTemplate = readFileSync(`${SCRIPTS_ROOT}/${E2E_NAME}/e2e.template.prod.html`);
|
||||
const indexTs = readFileSync(`${SCRIPTS_ROOT}/${E2E_NAME}/entry.ts`);
|
||||
|
||||
return obj(function (file, enc, next) {
|
||||
this.push(new VinylFile({
|
||||
base: file.base,
|
||||
contents: new Buffer(indexTemplate),
|
||||
path: join(dirname(file.path), 'index.html'),
|
||||
}));
|
||||
this.push(new VinylFile({
|
||||
base: file.base,
|
||||
contents: new Buffer(indexTs),
|
||||
path: join(dirname(file.path), 'entry.ts'),
|
||||
}));
|
||||
next(null, file);
|
||||
});
|
||||
}
|
||||
|
||||
// TODO this is almost the same as dev, diff and combine
|
||||
function createPlatformTests() {
|
||||
let platforms = [
|
||||
'android',
|
||||
'ios',
|
||||
'windows'
|
||||
];
|
||||
|
||||
let testTemplate = template(readFileSync(`${SCRIPTS_ROOT}/${E2E_NAME}/e2e.template.js`).toString());
|
||||
|
||||
return obj(function (file, enc, next) {
|
||||
let self = this;
|
||||
|
||||
let relativePath = dirname(file.path.replace(/^.*?src(\/|\\)/, ''));
|
||||
|
||||
let contents = file.contents.toString();
|
||||
platforms.forEach(function (platform) {
|
||||
let platformContents = testTemplate({
|
||||
contents: contents,
|
||||
buildConfig: buildConfig,
|
||||
relativePath: relativePath,
|
||||
platform: platform
|
||||
});
|
||||
self.push(new VinylFile({
|
||||
base: file.base,
|
||||
contents: new Buffer(platformContents),
|
||||
path: file.path.replace(/e2e.ts$/, platform + '.e2e.js')
|
||||
}));
|
||||
});
|
||||
next();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
task('e2e.compileTests', (done: Function) => {
|
||||
let folderInfo = getFolderInfo();
|
||||
buildE2ETests(folderInfo, done);
|
||||
});
|
||||
|
||||
function buildE2ETests(folderInfo: any, done: Function) {
|
||||
let includeGlob = ['./components/*/test/*/app-module.ts', './components/*/test/*/entry.ts'];
|
||||
if (folderInfo.componentName && folderInfo.componentTest) {
|
||||
includeGlob = [
|
||||
`./components/${folderInfo.componentName}/test/${folderInfo.componentTest}/app-module.ts`,
|
||||
`./components/${folderInfo.componentName}/test/${folderInfo.componentTest}/entry.ts`,
|
||||
];
|
||||
}
|
||||
createTempTsConfig(includeGlob, ES5, ES_2015, `${DIST_E2E_ROOT}/tsconfig.json`);
|
||||
runNgc(`${DIST_E2E_ROOT}/tsconfig.json`, (err) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
return;
|
||||
}
|
||||
// clean up any .ts files that remain
|
||||
deleteFiles([`${DIST_E2E_ROOT}/**/*.ts`, `!${DIST_E2E_ROOT}/**/*.ngfactory.ts`, `!${DIST_E2E_ROOT}/**/*.d.ts`], done);
|
||||
});
|
||||
}
|
||||
|
||||
task('e2e.bundleProd', (done) => {
|
||||
let includeGlob = `${DIST_E2E_ROOT}/components/*/test/*/entry.js`;
|
||||
let folderInfo = getFolderInfo();
|
||||
if (folderInfo.componentName && folderInfo.componentTest) {
|
||||
includeGlob = `${DIST_E2E_ROOT}/components/${folderInfo.componentName}/test/${folderInfo.componentTest}/entry.js`;
|
||||
}
|
||||
glob(includeGlob, {}, function (er, files) {
|
||||
var directories = files.map(function (file) {
|
||||
return dirname(file);
|
||||
});
|
||||
|
||||
let indexFileContents = directories.map(function (dir) {
|
||||
let testName = dir.replace(`${DIST_E2E_ROOT}/components/`, '');
|
||||
let fileName = dir.replace(`${PROJECT_ROOT}`, '');
|
||||
return `<p><a href="${fileName}/index.html">${testName}</a></p>`;
|
||||
}, []);
|
||||
|
||||
writeFileSync(`${DIST_E2E_ROOT}/index.html`,
|
||||
'<!DOCTYPE html><html lang="en"><head></head><body style="width: 500px; margin: 100px auto">\n' +
|
||||
indexFileContents.join('\n') +
|
||||
'</center></body></html>'
|
||||
);
|
||||
|
||||
createBundles(files).then(() => {
|
||||
done();
|
||||
}).catch(err => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function createBundles(files: string[]) {
|
||||
let start;
|
||||
if (!files) {
|
||||
return Promise.reject(new Error('list of files is null'));
|
||||
} else if (files.length === 0) {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
const outputFileName = join(dirname(files[0]), 'app.bundle.js');
|
||||
start = Date.now();
|
||||
return bundle(files[0], outputFileName).then(() => {
|
||||
const end = Date.now();
|
||||
const seconds = (end - start) / 1000;
|
||||
console.log(`Took ${seconds} seconds to process ${files[0]}`);
|
||||
const remainingFiles = files.concat();
|
||||
remainingFiles.shift();
|
||||
return createBundles(remainingFiles);
|
||||
}).catch(err => {
|
||||
return Promise.reject(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function bundle(inputFile: string, outputFile: string): Promise<any> {
|
||||
console.log(`Starting rollup on ${inputFile} ... writing to ${outputFile}`);
|
||||
return rollup.rollup({
|
||||
entry: inputFile,
|
||||
plugins: [
|
||||
commonjs(),
|
||||
nodeResolve({
|
||||
module: true,
|
||||
jsnext: true,
|
||||
main: true,
|
||||
extensions: ['.js']
|
||||
})
|
||||
]
|
||||
}).then(bundle => {
|
||||
return bundle.write({
|
||||
format: 'iife',
|
||||
dest: outputFile,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
task('e2e.watchProd', ['e2e.copyExternalDependencies', 'e2e.sass', 'e2e.fonts'], (done: Function) => {
|
||||
const folderInfo = getFolderInfo();
|
||||
let e2eTestPath = SRC_COMPONENTS_ROOT;
|
||||
|
||||
if (folderInfo.componentName && folderInfo.componentTest) {
|
||||
e2eTestPath = join(SRC_COMPONENTS_ROOT, folderInfo.componentName, 'test', folderInfo.componentTest, 'app-module.ts');
|
||||
}
|
||||
|
||||
try {
|
||||
accessSync(e2eTestPath, F_OK);
|
||||
} catch (e) {
|
||||
done(new Error(`Could not find e2e test: ${e2eTestPath}`));
|
||||
return;
|
||||
}
|
||||
|
||||
if (e2eComponentsExists()) {
|
||||
// already generated the e2e directory
|
||||
e2eWatch(folderInfo.componentName, folderInfo.componentTest);
|
||||
|
||||
} else {
|
||||
// generate the e2e directory
|
||||
console.log('Generated e2e builds first...');
|
||||
e2eBuild(() => {
|
||||
e2eWatch(folderInfo.componentName, folderInfo.componentTest);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function e2eWatch(componentName: string, componentTest: string) {
|
||||
// If any tests change within components then run e2e.resources.
|
||||
watch([
|
||||
'src/components/*/test/**/*'
|
||||
],
|
||||
function (file) {
|
||||
console.log('start e2e.resources - ' + JSON.stringify(file.history, null, 2));
|
||||
start('e2e.copyAndCompile');
|
||||
});
|
||||
|
||||
// If any src files change except for tests then transpile only the source ionic files
|
||||
watch([
|
||||
'src/**/*.ts',
|
||||
'!src/components/*/test/**/*',
|
||||
'!src/util/test/*'
|
||||
],
|
||||
function (file) {
|
||||
console.log('start e2e.ngcSource - ' + JSON.stringify(file.history, null, 2));
|
||||
start('e2e.copyAndCompile');
|
||||
});
|
||||
|
||||
// If any scss files change then recompile all sass
|
||||
watch(['src/**/*.scss'], (file) => {
|
||||
console.log('start sass - ' + JSON.stringify(file.history, null, 2));
|
||||
start('e2e.sass');
|
||||
});
|
||||
|
||||
console.log(`http://localhost:${LOCAL_SERVER_PORT}/${DIST_NAME}/${E2E_NAME}/components/${componentName}/test/${componentTest}/`);
|
||||
|
||||
start('e2e.serve');
|
||||
}
|
||||
|
||||
function e2eComponentsExists(): boolean {
|
||||
try {
|
||||
accessSync(DIST_E2E_COMPONENTS_ROOT, F_OK);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function getFolderInfo() {
|
||||
let componentName: string = null;
|
||||
let componentTest: string = null;
|
||||
const folder: string = argv.folder || argv.f;
|
||||
if (folder && folder.length) {
|
||||
const folderSplit = folder.split('/');
|
||||
componentName = folderSplit[0];
|
||||
componentTest = (folderSplit.length > 1 ? folderSplit[1] : 'basic');
|
||||
}
|
||||
return {
|
||||
componentName: componentName,
|
||||
componentTest: componentTest
|
||||
};
|
||||
}
|
||||
@ -1,32 +1,11 @@
|
||||
import { accessSync, F_OK, readFileSync, writeFileSync } from 'fs';
|
||||
import { dirname, join } from 'path';
|
||||
|
||||
import * as glob from 'glob';
|
||||
import {dest, src, start, task} from 'gulp';
|
||||
import { dest, src, task } from 'gulp';
|
||||
import * as connect from 'gulp-connect';
|
||||
import * as gulpif from 'gulp-if';
|
||||
import * as open from 'gulp-open';
|
||||
import * as watch from 'gulp-watch';
|
||||
import { template } from 'lodash';
|
||||
import * as rollup from 'rollup';
|
||||
import * as nodeResolve from 'rollup-plugin-node-resolve';
|
||||
import * as commonjs from 'rollup-plugin-commonjs';
|
||||
import * as del from 'del';
|
||||
import * as runSequence from 'run-sequence';
|
||||
import { obj } from 'through2';
|
||||
import * as VinylFile from 'vinyl';
|
||||
import { argv } from 'yargs';
|
||||
|
||||
import { DIST_E2E_COMPONENTS_ROOT, DIST_E2E_ROOT, DIST_NAME, E2E_NAME, ES5, ES_2015, LOCAL_SERVER_PORT, PROJECT_ROOT, SCRIPTS_ROOT, SRC_COMPONENTS_ROOT, SRC_ROOT } from '../constants';
|
||||
import { compileSass, copyFonts, createTempTsConfig, createTimestamp, deleteFiles, runNgc, setSassIonicVersion, writePolyfills } from '../util';
|
||||
import { DIST_E2E_ROOT, LOCAL_SERVER_PORT, SCRIPTS_ROOT } from '../constants';
|
||||
import { compileSass, copyFonts, createTimestamp, setSassIonicVersion, writePolyfills } from '../util';
|
||||
|
||||
task('e2e', e2eBuild);
|
||||
|
||||
function e2eBuild(done: (err: any) => void) {
|
||||
runSequence('e2e.polyfill', 'e2e.copySource', 'e2e.compileTests', 'e2e.copyExternalDependencies', 'e2e.sass', 'e2e.fonts', 'e2e.bundle', done);
|
||||
}
|
||||
|
||||
// TODO this should run when building all of e2e, not when folder passed
|
||||
task('e2e.clean', (done: Function) => {
|
||||
del(['dist/e2e/**']).then(() => {
|
||||
done();
|
||||
@ -44,110 +23,13 @@ task('e2e.polyfill', (done: Function) => {
|
||||
});
|
||||
|
||||
task('e2e.copyAndCompile', (done: (err: any) => void) => {
|
||||
runSequence('e2e.copySource', 'e2e.compileTests', 'e2e.bundle', done);
|
||||
runSequence(
|
||||
'e2e.copySource',
|
||||
'e2e.compileTests',
|
||||
'e2e.bundle',
|
||||
done);
|
||||
});
|
||||
|
||||
task('e2e.copySource', (done: Function) => {
|
||||
|
||||
const buildConfig = require('../../build/config');
|
||||
|
||||
const stream = src([`${SRC_ROOT}/**/*`, `!${SRC_ROOT}/**/*.spec.ts`])
|
||||
.pipe(gulpif(/app-module.ts$/, createIndexHTML()))
|
||||
.pipe(gulpif(/e2e.ts$/, createPlatformTests()))
|
||||
.pipe(dest(DIST_E2E_ROOT));
|
||||
|
||||
stream.on('end', done);
|
||||
|
||||
function createIndexHTML() {
|
||||
const indexTemplate = readFileSync('scripts/e2e/index.html');
|
||||
const indexTs = readFileSync('scripts/e2e/entry.ts');
|
||||
|
||||
return obj(function(file, enc, next) {
|
||||
this.push(new VinylFile({
|
||||
base: file.base,
|
||||
contents: new Buffer(indexTemplate),
|
||||
path: join(dirname(file.path), 'index.html'),
|
||||
}));
|
||||
this.push(new VinylFile({
|
||||
base: file.base,
|
||||
contents: new Buffer(indexTs),
|
||||
path: join(dirname(file.path), 'entry.ts'),
|
||||
}));
|
||||
next(null, file);
|
||||
});
|
||||
}
|
||||
|
||||
function createPlatformTests() {
|
||||
let platforms = [
|
||||
'android',
|
||||
'ios',
|
||||
'windows'
|
||||
];
|
||||
|
||||
let testTemplate = template(readFileSync('scripts/e2e/e2e.template.js').toString());
|
||||
|
||||
return obj(function(file, enc, next) {
|
||||
let self = this;
|
||||
let relativePath = dirname(file.path.replace(/^.*?src(\/|\\)components(\/|\\)/, ''));
|
||||
|
||||
let contents = file.contents.toString();
|
||||
platforms.forEach(function(platform) {
|
||||
let platformContents = testTemplate({
|
||||
contents: contents,
|
||||
buildConfig: buildConfig,
|
||||
relativePath: relativePath,
|
||||
platform: platform
|
||||
});
|
||||
self.push(new VinylFile({
|
||||
base: file.base,
|
||||
contents: new Buffer(platformContents),
|
||||
path: file.path.replace(/e2e.ts$/, platform + '.e2e.js')
|
||||
}));
|
||||
});
|
||||
next();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
task('e2e.compileTests', (done: Function) => {
|
||||
let folderInfo = getFolderInfo();
|
||||
buildE2ETests(folderInfo, done);
|
||||
});
|
||||
|
||||
function buildE2ETests(folderInfo: any, done: Function) {
|
||||
let includeGlob = ['./components/*/test/*/app-module.ts', './components/*/test/*/entry.ts'];
|
||||
if (folderInfo.componentName && folderInfo.componentTest) {
|
||||
includeGlob = [
|
||||
`./components/${folderInfo.componentName}/test/${folderInfo.componentTest}/app-module.ts`,
|
||||
`./components/${folderInfo.componentName}/test/${folderInfo.componentTest}/entry.ts`,
|
||||
];
|
||||
}
|
||||
createTempTsConfig(includeGlob, ES5, ES_2015, `${DIST_E2E_ROOT}/tsconfig.json`);
|
||||
runNgc(`${DIST_E2E_ROOT}/tsconfig.json`, (err) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
return;
|
||||
}
|
||||
// clean up any .ts files that remain
|
||||
deleteFiles([`${DIST_E2E_ROOT}/**/*.ts`, `!${DIST_E2E_ROOT}/**/*.ngfactory.ts`, `!${DIST_E2E_ROOT}/**/*.d.ts`], done);
|
||||
});
|
||||
}
|
||||
|
||||
function getFolderInfo() {
|
||||
let componentName: string = null;
|
||||
let componentTest: string = null;
|
||||
const folder: string = argv.folder || argv.f;
|
||||
if (folder && folder.length) {
|
||||
const folderSplit = folder.split('/');
|
||||
componentName = folderSplit[0];
|
||||
componentTest = (folderSplit.length > 1 ? folderSplit[1] : 'basic');
|
||||
}
|
||||
return {
|
||||
componentName: componentName,
|
||||
componentTest: componentTest
|
||||
};
|
||||
}
|
||||
|
||||
task('e2e.copyExternalDependencies', () => {
|
||||
src([`${SCRIPTS_ROOT}/e2e/*.css`]).pipe(dest(`${DIST_E2E_ROOT}/css`));
|
||||
});
|
||||
@ -162,154 +44,12 @@ task('e2e.fonts', () => {
|
||||
return copyFonts(`${DIST_E2E_ROOT}/fonts`);
|
||||
});
|
||||
|
||||
task('e2e.bundle', (done) => {
|
||||
let includeGlob = `${DIST_E2E_ROOT}/components/*/test/*/entry.js`;
|
||||
let folderInfo = getFolderInfo();
|
||||
if (folderInfo.componentName && folderInfo.componentTest) {
|
||||
includeGlob = `${DIST_E2E_ROOT}/components/${folderInfo.componentName}/test/${folderInfo.componentTest}/entry.js`;
|
||||
}
|
||||
glob(includeGlob, {}, function(er, files) {
|
||||
var directories = files.map(function(file) {
|
||||
return dirname(file);
|
||||
});
|
||||
|
||||
let indexFileContents = directories.map(function(dir) {
|
||||
let testName = dir.replace(`${DIST_E2E_ROOT}/components/`, '');
|
||||
let fileName = dir.replace(`${PROJECT_ROOT}`, '');
|
||||
return `<p><a href="${fileName}/index.html">${testName}</a></p>`;
|
||||
}, []);
|
||||
|
||||
writeFileSync(`${DIST_E2E_ROOT}/index.html`,
|
||||
'<!DOCTYPE html><html lang="en"><head></head><body style="width: 500px; margin: 100px auto">\n' +
|
||||
indexFileContents.join('\n') +
|
||||
'</center></body></html>'
|
||||
);
|
||||
|
||||
createBundles(files).then(() => {
|
||||
done();
|
||||
}).catch(err => {
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function createBundles(files: string[]) {
|
||||
let start;
|
||||
if (!files) {
|
||||
return Promise.reject(new Error('list of files is null'));
|
||||
} else if ( files.length === 0) {
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
const outputFileName = join(dirname(files[0]), 'app.bundle.js');
|
||||
start = Date.now();
|
||||
return bundle(files[0], outputFileName).then(() => {
|
||||
const end = Date.now();
|
||||
const seconds = (end - start) / 1000;
|
||||
console.log(`Took ${seconds} seconds to process ${files[0]}`);
|
||||
const remainingFiles = files.concat();
|
||||
remainingFiles.shift();
|
||||
return createBundles(remainingFiles);
|
||||
}).catch(err => {
|
||||
return Promise.reject(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function bundle(inputFile: string, outputFile: string): Promise<any> {
|
||||
console.log(`Starting rollup on ${inputFile} ... writing to ${outputFile}`);
|
||||
return rollup.rollup({
|
||||
entry: inputFile,
|
||||
plugins: [
|
||||
commonjs(),
|
||||
nodeResolve({
|
||||
module: true,
|
||||
jsnext: true,
|
||||
main: true,
|
||||
extensions: ['.js']
|
||||
})
|
||||
]
|
||||
}).then(bundle => {
|
||||
return bundle.write({
|
||||
format: 'iife',
|
||||
dest: outputFile,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
task('e2e.watch', ['e2e.copyExternalDependencies', 'e2e.sass', 'e2e.fonts'], (done: Function) => {
|
||||
const folderInfo = getFolderInfo();
|
||||
if (! folderInfo.componentName || ! folderInfo.componentTest) {
|
||||
done(new Error('Passing in a folder to watch is required for this command. Use the --folder or -f option.'));
|
||||
return;
|
||||
}
|
||||
|
||||
const e2eTestPath = join(SRC_COMPONENTS_ROOT, folderInfo.componentName, 'test', folderInfo.componentTest, 'app-module.ts');
|
||||
|
||||
try {
|
||||
accessSync(e2eTestPath, F_OK);
|
||||
} catch (e) {
|
||||
done(new Error(`Could not find e2e test: ${e2eTestPath}`));
|
||||
return;
|
||||
}
|
||||
|
||||
if (e2eComponentsExists()) {
|
||||
// already generated the e2e directory
|
||||
e2eWatch(folderInfo.componentName, folderInfo.componentTest);
|
||||
|
||||
} else {
|
||||
// generate the e2e directory
|
||||
console.log('Generated e2e builds first...');
|
||||
e2eBuild(() => {
|
||||
e2eWatch(folderInfo.componentName, folderInfo.componentTest);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function e2eWatch(componentName: string, componentTest: string) {
|
||||
// If any tests change within components then run e2e.resources.
|
||||
watch([
|
||||
'src/components/*/test/**/*'
|
||||
],
|
||||
function(file) {
|
||||
console.log('start e2e.resources - ' + JSON.stringify(file.history, null, 2));
|
||||
start('e2e.copyAndCompile');
|
||||
});
|
||||
|
||||
// If any src files change except for tests then transpile only the source ionic files
|
||||
watch([
|
||||
'src/**/*.ts',
|
||||
'!src/components/*/test/**/*',
|
||||
'!src/util/test/*'
|
||||
],
|
||||
function(file) {
|
||||
console.log('start e2e.ngcSource - ' + JSON.stringify(file.history, null, 2));
|
||||
start('e2e.copyAndCompile');
|
||||
});
|
||||
|
||||
// If any scss files change then recompile all sass
|
||||
watch(['src/**/*.scss'], (file) => {
|
||||
console.log('start sass - ' + JSON.stringify(file.history, null, 2));
|
||||
start('e2e.sass');
|
||||
});
|
||||
|
||||
console.log(`http://localhost:${LOCAL_SERVER_PORT}/${DIST_NAME}/${E2E_NAME}/components/${componentName}/test/${componentTest}/`);
|
||||
|
||||
task('e2e.serve', function() {
|
||||
connect.server({
|
||||
root: './',
|
||||
port: LOCAL_SERVER_PORT,
|
||||
livereload: true
|
||||
livereload: {
|
||||
port: 35700
|
||||
}
|
||||
});
|
||||
|
||||
src('dist').pipe(
|
||||
open({uri: `http://localhost:${LOCAL_SERVER_PORT}/${DIST_NAME}/${E2E_NAME}`})
|
||||
);
|
||||
}
|
||||
|
||||
function e2eComponentsExists(): boolean {
|
||||
try {
|
||||
accessSync(DIST_E2E_COMPONENTS_ROOT, F_OK);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
@ -7,23 +7,27 @@ import { task } from 'gulp';
|
||||
import * as serveStatic from 'serve-static';
|
||||
import { argv } from 'yargs';
|
||||
|
||||
import { DIST_E2E_COMPONENTS_ROOT, PROJECT_ROOT, SCRIPTS_ROOT } from '../constants';
|
||||
import { DIST_E2E_ROOT, DIST_E2E_COMPONENTS_ROOT, PROJECT_ROOT, SCRIPTS_ROOT } from '../constants';
|
||||
import { mergeObjects } from '../util';
|
||||
|
||||
|
||||
task('snapshot', ['e2e'], (done: Function) => {
|
||||
snapshot(false, done);
|
||||
task('snapshot', ['e2e.clean', 'e2e.prod'], (done: Function) => {
|
||||
snapshot(false, false, done);
|
||||
});
|
||||
|
||||
task('snapshot.skipBuild', ['e2e.sass'], (done: Function) => {
|
||||
snapshot(false, done);
|
||||
snapshot(false, false, done);
|
||||
});
|
||||
|
||||
task('snapshot.dev', ['e2e.clean', 'e2e'], (done: Function) => {
|
||||
snapshot(false, true, done);
|
||||
});
|
||||
|
||||
task('snapshot.quick', ['e2e.sass'], (done: Function) => {
|
||||
snapshot(true, done);
|
||||
snapshot(true, true, done);
|
||||
});
|
||||
|
||||
function snapshot(quickMode: boolean, callback: Function) {
|
||||
function snapshot(quickMode: boolean, devMode: boolean, callback: Function) {
|
||||
const snapshotConfig = require('../../snapshot/snapshot.config').config;
|
||||
const protractorConfigFile = resolve(SCRIPTS_ROOT, 'snapshot/protractor.config.js');
|
||||
|
||||
@ -45,7 +49,10 @@ function snapshot(quickMode: boolean, callback: Function) {
|
||||
e2eSpecs = folderArgPaths[1];
|
||||
}
|
||||
}
|
||||
const specs = join(DIST_E2E_COMPONENTS_ROOT, component, 'test', e2eSpecs, '*e2e.js');
|
||||
var specs = join(DIST_E2E_COMPONENTS_ROOT, component, 'test', e2eSpecs, '*e2e.js');
|
||||
if (devMode) specs = join(DIST_E2E_ROOT, component, e2eSpecs, '*e2e.js');
|
||||
|
||||
console.log('[snapshot] Running with', devMode ? 'Development' : 'Production', 'build');
|
||||
console.log(`[snapshot] Specs: ${specs}`);
|
||||
|
||||
const testId = generateTestId();
|
||||
@ -64,6 +71,7 @@ function snapshot(quickMode: boolean, callback: Function) {
|
||||
'--params.height=' + snapshotValues.params.height,
|
||||
'--params.test_id=' + snapshotValues.params.test_id,
|
||||
'--params.upload=' + snapshotValues.params.upload,
|
||||
'--params.dev=' + devMode,
|
||||
'--specs=' + specs
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user