| // TODO Specify echarts path |
| |
| const fs = require('fs'); |
| const globby = require('globby'); |
| const {buildExampleCode, collectDeps} = require('../common/buildCode'); |
| const nodePath = require('path'); |
| const { runTasks } = require('../common/task'); |
| const fse = require('fs-extra'); |
| const prettier = require('prettier'); |
| const ts = require('typescript'); |
| const chalk = require('chalk'); |
| const nStatic = require('node-static'); |
| const webpack = require('webpack'); |
| const {RawSource} = require('webpack-sources'); |
| const argparse = require('argparse'); |
| const esbuild = require('esbuild'); |
| const puppeteer = require('puppeteer'); |
| const config = require('./config'); |
| const {compareImage} = require('../common/compareImage'); |
| const shell = require('shelljs'); |
| const downloadGit = require('download-git-repo'); |
| const {promisify} = require('util'); |
| const matter = require('gray-matter'); |
| const minimatch = require('minimatch'); |
| |
| const parser = new argparse.ArgumentParser({ |
| addHelp: true |
| }); |
| parser.addArgument(['--bundler'], { |
| help: 'Bundler, can be webpack or esbuild' |
| }); |
| parser.addArgument(['-m', '--minify'], { |
| action: 'storeTrue', |
| help: 'If minify' |
| }); |
| parser.addArgument(['--local'], { |
| action: 'storeTrue', |
| help: `If use local repos. If so, don't forget to update the location of local repo in config.js.` |
| }); |
| parser.addArgument(['--skip'], { |
| help: 'If skip some stages to speed up the test. Can be npm,bundle,render,compare' |
| }); |
| parser.addArgument(['-t', '--tests'], { |
| help: 'If use pattern to specify which tests to run' |
| }); |
| const args = parser.parseArgs(); |
| |
| const EXAMPLE_DIR = `${__dirname}/../public/`; |
| const TMP_DIR = `${__dirname}/tmp`; |
| const RUN_CODE_DIR = `${TMP_DIR}/tests`; |
| const BUNDLE_DIR = `${TMP_DIR}/bundles`; |
| const SCREENSHOTS_DIR = `${TMP_DIR}/screenshots`; |
| const REPO_DIR = `${TMP_DIR}/repos`; |
| const PACKAGE_DIR = `${TMP_DIR}/packages`; |
| |
| const MINIMAL_POSTFIX = 'minimal'; |
| const MINIMAL_LEGACY_POSTFIX = 'minimal.legacy'; |
| |
| const MINIFY_BUNDLE = args.minify; |
| // const TEST_THEME = 'dark-blue'; |
| const TEST_THEME = ''; |
| const USE_WEBPACK = !(args.bundler === 'esbuild'); |
| |
| let testsPattern = args.tests; |
| if (testsPattern) { |
| testsPattern = testsPattern.split(','); |
| } |
| |
| // Create a server |
| const port = 3322; |
| const baseUrl = `http://localhost:${port}`; |
| |
| const TEMPLATE_CODE = ` |
| // @ts-ignore |
| echarts.registerPreprocessor(function (option) { |
| option.animation = false; |
| if (option.series) { |
| if (!(option.series instanceof Array)) { |
| option.series = [option.series]; |
| } |
| // @ts-ignore |
| option.series.forEach(function (seriesOpt) { |
| if (seriesOpt.type === 'graph') { |
| seriesOpt.force = seriesOpt.force || {}; |
| seriesOpt.force.layoutAnimation = false; |
| } |
| seriesOpt.progressive = 1e5; |
| seriesOpt.animation = false; |
| }); |
| } |
| }); |
| ` |
| |
| function buildPrepareCode(isESM, lang) { |
| return ` |
| // @ts-ignore |
| ${isESM |
| ? `import _seedrandom from 'seedrandom';` |
| : `const _seedrandom = require('seedrandom');` |
| } |
| |
| // Check if i18n will break the minimal imports. |
| ${lang |
| ? isESM |
| ? `import 'echarts/i18n/${lang}';` |
| : `require('echarts/i18n/${lang}');` |
| : '' |
| } |
| // @ts-ignore |
| const _myrng = _seedrandom('echarts'); |
| // @ts-ignore |
| Math.random = function () { |
| // @ts-ignore |
| return _myrng(); |
| }; |
| ${TEMPLATE_CODE} |
| `; |
| } |
| |
| async function prepare() { |
| fse.removeSync(TMP_DIR); |
| fse.removeSync(RUN_CODE_DIR); |
| fse.removeSync(BUNDLE_DIR); |
| fse.removeSync(SCREENSHOTS_DIR); |
| |
| fse.removeSync(REPO_DIR); |
| fse.removeSync(PACKAGE_DIR); |
| |
| fse.ensureDirSync(TMP_DIR); |
| fse.ensureDirSync(RUN_CODE_DIR); |
| fse.ensureDirSync(BUNDLE_DIR); |
| fse.ensureDirSync(SCREENSHOTS_DIR); |
| |
| fse.ensureDirSync(REPO_DIR); |
| fse.ensureDirSync(PACKAGE_DIR); |
| } |
| |
| async function downloadPackages(config) { |
| for (let pkg of config.packages) { |
| const pkgDownloadPath = nodePath.join(REPO_DIR, pkg.name); |
| console.log(chalk.gray(`Downloading ${pkg.git}`)) |
| await promisify(downloadGit)(pkg.git, pkgDownloadPath); |
| // Override the path |
| pkg.dir = pkgDownloadPath; |
| } |
| } |
| |
| async function installPackages(config) { |
| |
| const publishedPackages = {}; |
| |
| function checkFolder(pkg) { |
| const dir = pkg.dir; |
| if (!fs.existsSync(dir)) { |
| console.warn(chalk.yellow(`${dir} not exists. Please update it in e2e/config.js.`)); |
| return false; |
| } |
| if (!nodePath.isAbsolute(dir)) { |
| console.warn(chalk.yellow(`${dir} is not an absolute path. Please update it in e2e/config.js.`)); |
| return false; |
| } |
| return true; |
| } |
| |
| function publishPackage(pkg) { |
| console.log(chalk.gray(`Publishing ${pkg.dir}`)) |
| |
| shell.cd(pkg.dir); |
| |
| const packageJson = JSON.parse(fs.readFileSync(nodePath.join(pkg.dir, 'package.json'))); |
| const tgzFileName = `${packageJson.name}-${packageJson.version}.tgz`; |
| const targetTgzFilePath = nodePath.join(PACKAGE_DIR, tgzFileName); |
| |
| if (packageJson.dependencies) { |
| for (let depPkgName in packageJson.dependencies) { |
| if (!publishedPackages[depPkgName]) { |
| const depPkg = config.packages.find(a => a.name === depPkgName); |
| if (depPkg) { |
| publishPackage(depPkg); |
| // Come back. |
| shell.cd(pkg.dir); |
| } |
| } |
| |
| shell.exec(`npm install`); |
| shell.exec(`npm install ${publishedPackages[depPkgName]} --no-save`); |
| } |
| } |
| |
| shell.exec(`npm pack`); |
| fs.renameSync(nodePath.join(pkg.dir, tgzFileName), targetTgzFilePath); |
| publishedPackages[packageJson.name] = targetTgzFilePath; |
| } |
| |
| for (let pkg of config.packages) { |
| if (!checkFolder(pkg)) { |
| return; |
| } |
| |
| publishPackage(pkg); |
| }; |
| |
| shell.cd(__dirname); |
| for (let pkg of config.packages) { |
| console.log(chalk.gray(`Installing ${pkg.name}`)) |
| shell.exec(`npm install ${publishedPackages[pkg.name]}`); |
| } |
| |
| // Come back. |
| shell.cd(process.cwd()); |
| } |
| |
| async function buildRunCode() { |
| const files = await globby([ |
| `${EXAMPLE_DIR}/data/option/*.json`, |
| `${EXAMPLE_DIR}/data-gl/option/*.json` |
| ]); |
| |
| if (!files.length) { |
| throw new Error('You need to run `node tool/build-example.js` before run this test.'); |
| } |
| |
| async function addTestCase(testName, testCode, deps, checkTs, extraImports, extraRequire) { |
| const ROOT_PATH = `${baseUrl}/public`; |
| |
| const fullCode = buildExampleCode(buildPrepareCode(true) + testCode, deps, { |
| minimal: false, |
| ts: checkTs, |
| // Check if theme will break the minimal imports. |
| theme: TEST_THEME, |
| ROOT_PATH, |
| extraImports |
| }); |
| const minimalCode = buildExampleCode(buildPrepareCode(true) + testCode, deps, { |
| minimal: true, |
| ts: checkTs, |
| theme: TEST_THEME, |
| ROOT_PATH, |
| extraImports |
| }); |
| const legacyCode = buildExampleCode(buildPrepareCode(false) + testCode, deps, { |
| minimal: true, |
| esm: false, |
| ts: false, |
| theme: TEST_THEME, |
| ROOT_PATH, |
| extraImports: extraRequire |
| }); |
| |
| await fse.writeFile( |
| nodePath.join(RUN_CODE_DIR, testName + (checkTs ? '.ts' : '.js')), |
| prettier.format(fullCode, { |
| singleQuote: true, |
| parser: checkTs ? 'typescript' : 'babel' |
| }), 'utf-8' |
| ); |
| await fse.writeFile( |
| nodePath.join(RUN_CODE_DIR, testName + `.${MINIMAL_POSTFIX}.${checkTs ? 'ts' : 'js'}`), |
| prettier.format(minimalCode, { |
| singleQuote: true, |
| parser: checkTs ? 'typescript' : 'babel' |
| }), 'utf-8' |
| ); |
| await fse.writeFile( |
| nodePath.join(RUN_CODE_DIR, testName + `.${MINIMAL_LEGACY_POSTFIX}.js`), |
| prettier.format(legacyCode, { |
| singleQuote: true, |
| parser: 'babel' |
| }), 'utf-8' |
| ); |
| console.log( |
| chalk.green('Generated: ', testName) |
| ); |
| } |
| |
| const builtinTestCases = await runTasks(files, async (fileName) => { |
| const isGL = fileName.startsWith(`${EXAMPLE_DIR}/data-gl`); |
| const testName = nodePath.basename(fileName, '.json'); |
| |
| if (testsPattern && !testsPattern.some(pattern => minimatch(testName, pattern))) { |
| return; |
| } |
| |
| const optionCode = await fse.readFile(fileName, 'utf-8'); |
| const option = JSON.parse(optionCode); |
| const testCode = await fse.readFile(nodePath.join( |
| EXAMPLE_DIR, isGL ? 'data-gl' : 'data', testName + '.js' |
| ), 'utf-8'); |
| |
| // TODO Ignore case with extension. |
| |
| const deps = collectDeps(option).concat([ |
| // TODO SVG |
| 'CanvasRenderer' |
| ]); |
| |
| if (deps.includes('MapChart') |
| || deps.includes('GeoComponent') |
| || option.bmap) { |
| console.warn(chalk.yellow(`Ignored map tests.${fileName}`)); |
| return; |
| } |
| |
| // TODO: Don't support TypeScript in GL |
| await addTestCase(testName, testCode, deps, !isGL); |
| |
| return testName; |
| }, 20); |
| const extensionTestCases = await runTasks(await globby(__dirname + '/cases/*.js'), async (fileName) => { |
| const testName = nodePath.basename(fileName, '.js'); |
| if (testsPattern && !testsPattern.some(pattern => minimatch(testName, pattern))) { |
| return; |
| } |
| |
| const testCode = await fse.readFile(fileName, 'utf-8'); |
| let importsCode = ''; |
| let requireCode = ''; |
| try { |
| const fmResult = matter(testCode, { |
| delimiters: ['/*', '*/'] |
| }); |
| const extension = fmResult.data.extension; |
| if (extension) { |
| importsCode = `import '${extension}';`; |
| requireCode = `require('${extension}');`; |
| } |
| } |
| catch (e) { |
| } |
| await addTestCase(testName, testCode, [], false, importsCode, requireCode); |
| |
| return testName; |
| }, 20); |
| |
| return builtinTestCases.concat(extensionTestCases).filter(a => !!a); |
| } |
| |
| async function compileTs(tsTestFiles, result) { |
| const config = JSON.parse(fs.readFileSync(nodePath.join(__dirname, 'tsconfig.json'), 'utf-8')); |
| |
| const compilerOptions = { |
| ...config.compilerOptions |
| }; |
| |
| const {options, errors} = ts.convertCompilerOptionsFromJson(compilerOptions, nodePath.resolve(__dirname)); |
| |
| if (errors.length) { |
| let errMsg = 'tsconfig parse failed: ' |
| + errors.map(error => error.messageText).join('. ') |
| + '\n compilerOptions: \n' + JSON.stringify(config.compilerOptions, null, 4); |
| assert(false, errMsg); |
| } |
| |
| // Generate this config file for checking the source code in vscode. |
| fs.writeFileSync(nodePath.join(RUN_CODE_DIR, 'tsconfig.json'), JSON.stringify({ |
| compilerOptions |
| }, null, 2), 'utf-8'); |
| |
| // See: https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API |
| let program = ts.createProgram(tsTestFiles, options); |
| let emitResult = program.emit(); |
| |
| let allDiagnostics = ts |
| .getPreEmitDiagnostics(program) |
| .concat(emitResult.diagnostics); |
| |
| allDiagnostics.forEach(diagnostic => { |
| if (diagnostic.file) { |
| let {line, character} = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); |
| let message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); |
| |
| const compilerError = { |
| location: [line + 1, character + 1], |
| message |
| }; |
| if (diagnostic.file.fileName.endsWith(`${MINIMAL_POSTFIX}.ts`)) { |
| const basename = nodePath.basename(diagnostic.file.fileName, `.${MINIMAL_POSTFIX}.ts`); |
| result[basename].compileErrors.minimal.push(compilerError); |
| } |
| else { |
| const basename = nodePath.basename(diagnostic.file.fileName, `.ts`); |
| result[basename].compileErrors.full.push(compilerError); |
| } |
| // console.log(chalk.red(`${diagnostic.file.fileName} (${line + 1},${character + 1})`)); |
| // console.log(chalk.gray(message)); |
| } |
| else { |
| console.log(chalk.red(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'))); |
| } |
| }); |
| // assert(!emitResult.emitSkipped, 'ts compile failed.'); |
| } |
| |
| async function webpackBundle(esbuildService, entry, result) { |
| return new Promise((resolve) => { |
| webpack({ |
| entry, |
| output: { |
| path: BUNDLE_DIR, |
| filename: '[name].js' |
| }, |
| // Use esbuild as minify, terser is tooooooo slow for so much tests. |
| optimization: { |
| minimizer: MINIFY_BUNDLE ? [{ |
| apply(compiler) { |
| compiler.hooks.compilation.tap( |
| 'ESBuild Minify', |
| (compilation) => { |
| compilation.hooks.optimizeChunkAssets.tapPromise( |
| 'ESBuild Minify', |
| async (chunks) => { |
| for (const chunk of chunks) { |
| for (const file of chunk.files) { |
| const asset = compilation.assets[file]; |
| const { source } = asset.sourceAndMap(); |
| const result = await esbuildService.transform(source, { |
| minify: true, |
| sourcemap: false |
| }); |
| compilation.updateAsset(file, () => { |
| return new RawSource(result.code || ''); |
| }); |
| } |
| } |
| } |
| ); |
| }, |
| ); |
| |
| } |
| }] : [] |
| } |
| }, (err, stats) => { |
| if (err || stats.hasErrors()) { |
| if (err) { |
| console.error(err.stack || err); |
| if (err.details) { |
| console.error(err.details); |
| } |
| resolve(); |
| return; |
| } |
| |
| const info = stats.toJson(); |
| |
| if (stats.hasErrors()) { |
| console.error(info.errors); |
| } |
| |
| if (stats.hasWarnings()) { |
| console.warn(info.warnings); |
| } |
| } |
| else { |
| console.log(chalk.green(`${Object.values(entry).map(a => `Bundled ${a}`).join('\n')}`)); |
| } |
| |
| resolve(); |
| }); |
| }) |
| } |
| |
| function esbuildBundle(entry, result, minify) { |
| return esbuild.build({ |
| entryPoints: entry, |
| bundle: true, |
| minify: minify, |
| define: { |
| 'process.env.NODE_ENV': JSON.stringify(minify ? 'production' : 'development') |
| }, |
| outdir: BUNDLE_DIR |
| }); |
| } |
| |
| async function bundle(entryFiles, result) { |
| if (USE_WEBPACK) { |
| // Split to multiple buckets to seepup bundle |
| // TODO Multiple entry may have effects on the final bundle. |
| const BUCKET_SIZE = 1; |
| const buckets = []; |
| const esbuildService = await esbuild.startService(); |
| let count = 0; |
| outer: while (true) { |
| const bucket = {}; |
| for (let i = 0; i < BUCKET_SIZE; i++) { |
| const filePath = entryFiles[count++]; |
| if (!filePath) { |
| break outer; |
| } |
| const basename = nodePath.basename(filePath, '.js'); |
| bucket[basename] = filePath; |
| } |
| buckets.push(bucket); |
| } |
| |
| // TODO Multiple thread. |
| for (let bucket of buckets) { |
| await webpackBundle(esbuildService, bucket, result); |
| } |
| |
| esbuildService.stop(); |
| } |
| else { |
| for (let file of entryFiles) { |
| await esbuildBundle([file], result, MINIFY_BUNDLE); |
| console.log(chalk.green(`Bundled ${file}`)); |
| } |
| } |
| } |
| |
| function waitTime(time) { |
| return new Promise((resolve) => setTimeout(resolve, time)); |
| } |
| async function runExamples(jsFiles, result) { |
| const fileServer = new nStatic.Server(__dirname + '/../'); |
| const server = require('http').createServer(function (request, response) { |
| request.addListener('end', function () { |
| fileServer.serve(request, response); |
| }).resume(); |
| }) |
| server.listen(port); |
| |
| try { |
| const IGNORE_LOG = [ |
| 'A cookie associated with a cross-site resource at', |
| 'A parser-blocking, cross site', |
| // For ECharts GL |
| 'RENDER WARNING', |
| 'GL ERROR', |
| 'GL_INVALID_OPERATION' |
| ]; |
| |
| const browser = await puppeteer.launch({ |
| headless: false, |
| args: [ |
| '--headless', |
| '--hide-scrollbars', |
| // https://github.com/puppeteer/puppeteer/issues/4913 |
| '--use-gl=egl', |
| '--mute-audio' |
| ] |
| }); |
| |
| await runTasks(jsFiles, async (file) => { |
| const page = await browser.newPage(); |
| const basename = nodePath.basename(file, '.js'); |
| await page.setViewport({ width: 800, height: 600 }); |
| |
| page.on('pageerror', function (err) { |
| // TODO Record pageerror |
| console.error(chalk.red(`[PAGE ERROR] [${basename}]`)); |
| console.error(chalk.red(err.toString())); |
| }); |
| page.on('console', msg => { |
| const text = msg.text(); |
| if (!IGNORE_LOG.find(a => text.indexOf(a) >= 0)) { |
| console.log(chalk.gray(`[PAGE LOG] [${basename}]: ${text}`)); |
| } |
| }); |
| |
| await page.goto(`${baseUrl}/e2e/template.html`, { |
| waitUntil: 'networkidle0', |
| timeout: 10000 |
| }); |
| await page.addScriptTag({ |
| url: `${baseUrl}/e2e/tmp/bundles/${basename}.js` |
| }); |
| await waitTime(200); |
| |
| await page.screenshot({ |
| type: 'png', |
| path: nodePath.resolve(SCREENSHOTS_DIR, basename + '.png') |
| }); |
| |
| await page.close(); |
| |
| console.log(chalk.green(`Rendered ${file}`)); |
| }, 8); |
| } |
| catch (e) { |
| server.close(); |
| throw e; |
| } |
| } |
| |
| |
| async function compareExamples(testNames, result) { |
| |
| function writePNG(png, diffPath) { |
| return new Promise(resolve => { |
| const writer = fs.createWriteStream(diffPath); |
| png.pack().pipe(writer); |
| writer.on('finish', () => { resolve(); }); |
| }); |
| } |
| |
| for (let testName of testNames) { |
| const diffMinimal = await compareImage( |
| nodePath.resolve(SCREENSHOTS_DIR, testName + '.png'), |
| nodePath.resolve(SCREENSHOTS_DIR, `${testName}.${MINIMAL_POSTFIX}.png`) |
| ); |
| const diffMinimalLegacy = await compareImage( |
| nodePath.resolve(SCREENSHOTS_DIR, testName + '.png'), |
| nodePath.resolve(SCREENSHOTS_DIR, `${testName}.${MINIMAL_LEGACY_POSTFIX}.png`) |
| ); |
| |
| const diffMinimalPNGPath = nodePath.resolve(SCREENSHOTS_DIR, `${testName}.${MINIMAL_POSTFIX}.diff.png`); |
| const diffMinimalLegacyPNGPath = nodePath.resolve(SCREENSHOTS_DIR, `${testName}.${MINIMAL_LEGACY_POSTFIX}.diff.png`); |
| |
| writePNG(diffMinimal.diffPNG, diffMinimalPNGPath); |
| writePNG(diffMinimalLegacy.diffPNG, diffMinimalLegacyPNGPath); |
| |
| result[testName].screenshotDiff = { |
| minimal: { |
| ratio: diffMinimal.diffRatio, |
| png: nodePath.basename(diffMinimalPNGPath) |
| }, |
| minimalLegacy: { |
| ratio: diffMinimalLegacy.diffRatio, |
| png: nodePath.basename(diffMinimalLegacyPNGPath) |
| } |
| } |
| |
| if (diffMinimal.diffRatio > 0 || diffMinimalLegacy.diffRatio > 0) { |
| console.log(chalk.red(`Failed ${testName}`)); |
| } |
| else { |
| console.log(chalk.green(`Passed ${testName}`)); |
| } |
| } |
| } |
| |
| |
| async function main() { |
| let result; |
| |
| if (!args.skip && !args.tests) { |
| // Don't clean up if skipping some of the stages. |
| await prepare(); |
| result = {}; |
| } |
| else { |
| // Read result. |
| try { |
| result = JSON.parse(fs.readFileSync(__dirname + '/tmp/result.json', 'utf-8')); |
| } |
| catch (e) { |
| console.error(e); |
| throw 'Must run full e2e test without --skip and --tests at least once.'; |
| } |
| } |
| |
| function isNotSkipped(stage) { |
| return !((args.skip || '').indexOf(stage) >= 0); |
| } |
| |
| // We don't have to test the npm if bundle is also skipped. |
| if (isNotSkipped('npm') && isNotSkipped('bundle')) { |
| if (!args.local) { |
| console.log(chalk.gray('Downloading packages')); |
| await downloadPackages(config); |
| } |
| |
| console.log(chalk.gray('Installing packages')); |
| await installPackages(config); |
| } |
| else { |
| console.log(chalk.yellow('Skipped NPM.')); |
| } |
| |
| |
| console.log(chalk.gray('Generating codes')); |
| // Always build code. |
| const testNames = await buildRunCode(); |
| |
| for (let key of testNames) { |
| result[key] = result[key] || {}; |
| } |
| |
| Object.keys(result).forEach(key => { |
| // Always do TS check on all tests. So reset all compile errors. |
| result[key].compileErrors = { |
| full: [], |
| minimal: [], |
| minimalLegacy: [] |
| }; |
| }); |
| |
| console.log('Compiling TypeScript'); |
| // Always run typescript check to generate the js code. |
| await compileTs( |
| (await globby(nodePath.join(RUN_CODE_DIR, '*.ts'))) |
| // No need to check types of the minimal legacy imports |
| .filter(a => !a.endsWith(`${MINIMAL_LEGACY_POSTFIX}.ts`)), |
| result |
| ); |
| |
| if (isNotSkipped('bundle')) { |
| console.log(`Bundling with ${USE_WEBPACK ? 'webpack' : 'esbuild'}`); |
| const jsFiles = []; |
| for (let testName of testNames) { |
| jsFiles.push( |
| nodePath.join(RUN_CODE_DIR, `${testName}.js`), |
| nodePath.join(RUN_CODE_DIR, `${testName}.${MINIMAL_POSTFIX}.js`), |
| nodePath.join(RUN_CODE_DIR, `${testName}.${MINIMAL_LEGACY_POSTFIX}.js`) |
| ); |
| } |
| await bundle(jsFiles, result); |
| } |
| else { |
| console.log(chalk.yellow('Skipped Bundle.')); |
| } |
| |
| if (isNotSkipped('render')) { |
| console.log('Running examples'); |
| const bundleFiles = []; |
| for (let testName of testNames) { |
| bundleFiles.push( |
| nodePath.join(BUNDLE_DIR, `${testName}.js`), |
| nodePath.join(BUNDLE_DIR, `${testName}.${MINIMAL_POSTFIX}.js`), |
| nodePath.join(BUNDLE_DIR, `${testName}.${MINIMAL_LEGACY_POSTFIX}.js`) |
| ); |
| } |
| await runExamples(bundleFiles, result); |
| } |
| else { |
| console.log(chalk.yellow('Skipped Render.')); |
| } |
| |
| if (isNotSkipped('compare')) { |
| console.log('Comparing Results'); |
| await compareExamples(testNames, result); |
| } |
| else { |
| console.log(chalk.yellow('Skipped Compare.')); |
| } |
| |
| fs.writeFileSync(__dirname + '/tmp/result.json', JSON.stringify( |
| result, null, 2 |
| ), 'utf-8'); |
| } |
| |
| main().catch(e => { |
| console.error(e); |
| process.exit(); |
| }).then(() => { |
| process.exit(); |
| }); |
| |
| process.on('SIGINT', function() { |
| console.log('Closing'); |
| // Close through ctrl + c; |
| process.exit(); |
| }); |