From cc040210157251a929647450296390bdb2e8f60b Mon Sep 17 00:00:00 2001 From: Huafu Gandon Date: Sun, 5 Aug 2018 13:21:11 +0200 Subject: [PATCH] perf: improves speed of local test after 1st run --- e2e/README.md | 1 + e2e/__helpers__/test-case.ts | 36 +++++++++++++++++++++++++++++------- package.json | 3 ++- scripts/e2e.js | 8 +++++++- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/e2e/README.md b/e2e/README.md index 8d847e77c6..7a4081e46a 100644 --- a/e2e/README.md +++ b/e2e/README.md @@ -40,6 +40,7 @@ The returned value is an object with those properties and methods: - `stdout`, _string_: the data written to stdout during the run - `stderr`, _string_: the data written to stderr during the run - `output`, _string_: the data written to stdout and stderr during the run + - `outputForSnapshot`, _string_: same as `output`, expect it's sanitized for jest snapshot (time values are replaced with static values, ...) **Note**: _You can optionally pass the expected status code as the first argument of `run()`. In the case it's not the correct one, it'll write in the console the actual `output` so that you can debug the test case._ diff --git a/e2e/__helpers__/test-case.ts b/e2e/__helpers__/test-case.ts index 1453ab34c8..c9eeb51773 100644 --- a/e2e/__helpers__/test-case.ts +++ b/e2e/__helpers__/test-case.ts @@ -49,11 +49,14 @@ class TestCaseRunDescriptor { ...this._options, template: this.templateName, }); - if (logOutputUnlessStatusIs != null) { + if ( + logOutputUnlessStatusIs != null && + logOutputUnlessStatusIs !== result.status + ) { console.log( `Output of test run in "${this.name}" using template "${ this.templateName - }":\n\n`, + } (exit code: ${result.status})":\n\n`, result.output.trim(), ); } @@ -72,6 +75,7 @@ export interface TestRunResult { stdout: string; stderr: string; output: string; + outputForSnapshot: string; } export default function configureTestCase( @@ -111,8 +115,24 @@ export function run( const output = result.output ? stripAnsiColors(result.output.join('\n\n')) : ''; + const outputForSnapshot = output + .trim() + // removes total and estimated time(s) + .replace( + /^(\s*Time\s*:\s*)[\d.]+m?s(?:(,\s*estimated\s+)[\d.]+m?s)?(\s*)$/gm, + (_, start, estimatedPrefix, end) => { + return `${start}XXs${ + estimatedPrefix ? `${estimatedPrefix}YYs` : '' + }${end}`; + }, + ) + // removes each test time(s) + .replace( + /^(\s*(?:✕|✓)\s+.+\s+\()[\d.]+m?s(\)\s*)$/gm, + (_, start, end) => `${start}XXms${end}`, + ); - return { status: result.status, stderr, stdout, output }; + return { status: result.status, stderr, stdout, output, outputForSnapshot }; } // from https://stackoverflow.com/questions/25245716/remove-all-ansi-colors-styles-from-strings @@ -136,10 +156,12 @@ function prepareTest(name: string, template: string): string { fs.copySync(sourceDir, caseDir); // link the node_modules dir - fs.symlinkSync( - join(templateDir, 'node_modules'), - join(caseDir, 'node_modules'), - ); + if (!fs.existsSync(join(caseDir, 'node_modules'))) { + fs.symlinkSync( + join(templateDir, 'node_modules'), + join(caseDir, 'node_modules'), + ); + } // copy all other files from the template to the case dir fs.readdirSync(templateDir).forEach(item => { diff --git a/package.json b/package.json index ad3735c52e..9aaed2d9bf 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,8 @@ "test": "npm run test:e2e && npm run test:unit", "tslint": "tslint 'src/**/*.ts'", "doc": "doctoc .", - "prepublish": "npm run clean-build", + "prepare": "npm run build", + "prepublishOnly": "npm run clean-build", "precommit": "lint-staged", "postcommit": "git reset", "format": "prettier --single-quote --trailing-comma all --write \"{src,scripts,tests}/**/*.ts\" && prettier --single-quote --trailing-comma es5 --write \"{src,scripts,tests}/**/*.js\"" diff --git a/scripts/e2e.js b/scripts/e2e.js index 56c993a943..ae1eb97196 100755 --- a/scripts/e2e.js +++ b/scripts/e2e.js @@ -41,12 +41,18 @@ function setupE2e() { ); // link locally so we could find it easily - fs.symlinkSync(Paths.e2eWorkDir, Paths.e2eWotkDirLink); + if (!fs.existsSync(Paths.e2eWotkDirLink)) { + fs.symlinkSync(Paths.e2eWorkDir, Paths.e2eWotkDirLink, 'dir'); + } // install with `npm ci` in each template, this is the fastest but needs a package lock file, // that is why we end with the npm install of our bundle getDirectories(Paths.e2eWorkTemplatesDir).forEach(tmplDir => { const dir = path.join(Paths.e2eWorkTemplatesDir, tmplDir); + // TODO: create a hash of package-lock.json as well as the bundle, and test it over one copied in each + // template dir, to know if we should re-install or not + if (fs.existsSync(path.join(dir, 'node_modules'))) return; + if (NodeVersion.major >= 8) { spawnSync('npm', ['ci'], { cwd: dir, stdio: 'inherit' }); } else {