From 5a847298e556d1be7f766f18964081e316b6f6c8 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Thu, 3 Jan 2019 15:27:50 +0000 Subject: [PATCH] ci: use puppeteer --- .appveyor.yml | 2 +- .buildkite/pipeline.yml | 2 +- .circleci/config.yml | 2 +- Dockerfile | 2 + package.json | 4 +- .../core/src/json/schema/registry_spec.ts | 2 +- .../hello-world-app/angular.json | 2 +- .../hello-world-app/karma.conf.js | 6 ++ .../hello-world-app/protractor.conf.js | 3 +- .../build_ng_packagr/ng-packaged/angular.json | 2 +- .../ng-packaged/projects/lib/karma.conf.js | 6 ++ .../generate/application/application-basic.ts | 2 +- .../tests/generate/library/library-basic.ts | 2 +- tests/legacy-cli/e2e/utils/project.ts | 84 ++++++++++--------- yarn.lock | 64 +++++++++++++- 15 files changed, 132 insertions(+), 53 deletions(-) create mode 100644 Dockerfile diff --git a/.appveyor.yml b/.appveyor.yml index c7d7537d1596..19fa94a43d83 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -11,7 +11,7 @@ install: - ps: Install-Product node $env:nodejs_version # --network-timeout is a workaround for https://github.com/yarnpkg/yarn/issues/6221 - yarn --frozen-lockfile --network-timeout=500000 - - yarn webdriver-update-appveyor + - yarn webdriver-update test_script: - node --version diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index 411de648250b..6ef51ff92554 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -11,7 +11,7 @@ steps: # Actual CI commands # --network-timeout is a workaround for https://github.com/yarnpkg/yarn/issues/6221 - yarn install --frozen-lockfile --non-interactive --network-timeout 500000 - - yarn webdriver-update-appveyor + - yarn webdriver-update - node --version - yarn --version - yarn test diff --git a/.circleci/config.yml b/.circleci/config.yml index 98faf1532252..e01c902c4cfc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -74,7 +74,7 @@ jobs: parallelism: 4 steps: - attach_workspace: *attach_options - - run: npm run webdriver-update-circleci + - run: npm run webdriver-update - run: npm run test-large -- --full --nb-shards=${CIRCLE_NODE_TOTAL} --shard=${CIRCLE_NODE_INDEX} e2e-cli: diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000000..8fef94100787 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,2 @@ +FROM node:10.12 +ENTRYPOINT [ "sh" ] diff --git a/package.json b/package.json index b35897b54be8..cfa310a58f7a 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,7 @@ "validate-commits": "./bin/devkit-admin validate-commits", "prepush": "node ./bin/devkit-admin hooks/pre-push", "preinstall": "node ./tools/yarn/check-yarn.js", - "webdriver-update-appveyor": "webdriver-manager update --standalone false --gecko false --versions.chrome 2.37", - "webdriver-update-circleci": "webdriver-manager update --standalone false --gecko false --versions.chrome $CHROMEDRIVER_VERSION_ARG " + "webdriver-update": "webdriver-manager update --standalone false --gecko false --versions.chrome 2.45" }, "repository": { "type": "git", @@ -66,6 +65,7 @@ "dependencies": { "glob": "^7.0.3", "node-fetch": "^2.2.0", + "puppeteer": "1.11.0", "quicktype-core": "^6.0.15", "temp": "^0.9.0", "tslint": "^5.11.0", diff --git a/packages/angular_devkit/core/src/json/schema/registry_spec.ts b/packages/angular_devkit/core/src/json/schema/registry_spec.ts index c20fb276e11a..fa512977605f 100644 --- a/packages/angular_devkit/core/src/json/schema/registry_spec.ts +++ b/packages/angular_devkit/core/src/json/schema/registry_spec.ts @@ -14,7 +14,7 @@ import { addUndefinedDefaults } from './transforms'; describe('CoreSchemaRegistry', () => { it('works asynchronously', done => { - if (process.env.BUILDKITE === 'true') { + if (process.platform.startsWith('win')) { // This test consistently fails on Windows BuildKite, but doesn't fail on local Windows // or in Appveyor. Many tests test the async behaviour of the registry, but this is the only // one that also fetches an async ref. Perhaps that is why. diff --git a/tests/angular_devkit/build_angular/hello-world-app/angular.json b/tests/angular_devkit/build_angular/hello-world-app/angular.json index a5ea30273883..25e2f12f40e5 100644 --- a/tests/angular_devkit/build_angular/hello-world-app/angular.json +++ b/tests/angular_devkit/build_angular/hello-world-app/angular.json @@ -97,7 +97,7 @@ "polyfills": "src/polyfills.ts", "tsConfig": "src/tsconfig.spec.json", "karmaConfig": "karma.conf.js", - "browsers": "ChromeHeadless", + "browsers": "ChromeHeadlessCI", "progress": false, "watch": false, "styles": [ diff --git a/tests/angular_devkit/build_angular/hello-world-app/karma.conf.js b/tests/angular_devkit/build_angular/hello-world-app/karma.conf.js index deec58129cdd..29b0a92e1fde 100644 --- a/tests/angular_devkit/build_angular/hello-world-app/karma.conf.js +++ b/tests/angular_devkit/build_angular/hello-world-app/karma.conf.js @@ -35,6 +35,12 @@ module.exports = function (config) { logLevel: config.LOG_INFO, autoWatch: true, browsers: ['Chrome'], + customLaunchers: { + ChromeHeadlessCI: { + base: 'ChromeHeadless', + flags: ['--disable-gpu'] + } + }, singleRun: false }); }; diff --git a/tests/angular_devkit/build_angular/hello-world-app/protractor.conf.js b/tests/angular_devkit/build_angular/hello-world-app/protractor.conf.js index 445801606d60..5ae5970f346e 100644 --- a/tests/angular_devkit/build_angular/hello-world-app/protractor.conf.js +++ b/tests/angular_devkit/build_angular/hello-world-app/protractor.conf.js @@ -19,7 +19,8 @@ exports.config = { capabilities: { 'browserName': 'chrome', chromeOptions: { - args: ["--headless", "--disable-gpu", "--window-size=800,600"] + args: ['--headless', '--disable-gpu', '--window-size=800,600'], + binary: require('puppeteer').executablePath() } }, directConnect: true, diff --git a/tests/angular_devkit/build_ng_packagr/ng-packaged/angular.json b/tests/angular_devkit/build_ng_packagr/ng-packaged/angular.json index 57961ebcc962..4f23a860aec1 100644 --- a/tests/angular_devkit/build_ng_packagr/ng-packaged/angular.json +++ b/tests/angular_devkit/build_ng_packagr/ng-packaged/angular.json @@ -19,7 +19,7 @@ "main": "projects/lib/src/test.ts", "tsConfig": "projects/lib/tsconfig.spec.json", "karmaConfig": "projects/lib/karma.conf.js", - "browsers": "ChromeHeadless", + "browsers": "ChromeHeadlessCI", "progress": false, "watch": false } diff --git a/tests/angular_devkit/build_ng_packagr/ng-packaged/projects/lib/karma.conf.js b/tests/angular_devkit/build_ng_packagr/ng-packaged/projects/lib/karma.conf.js index 0a81bfc617a5..2f49ecb6df61 100644 --- a/tests/angular_devkit/build_ng_packagr/ng-packaged/projects/lib/karma.conf.js +++ b/tests/angular_devkit/build_ng_packagr/ng-packaged/projects/lib/karma.conf.js @@ -33,6 +33,12 @@ module.exports = function (config) { logLevel: config.LOG_INFO, autoWatch: true, browsers: ['Chrome'], + customLaunchers: { + ChromeHeadlessCI: { + base: 'ChromeHeadless', + flags: ['--disable-gpu'] + } + }, singleRun: false }); }; diff --git a/tests/legacy-cli/e2e/tests/generate/application/application-basic.ts b/tests/legacy-cli/e2e/tests/generate/application/application-basic.ts index ff96506e53df..340f4ac4807b 100644 --- a/tests/legacy-cli/e2e/tests/generate/application/application-basic.ts +++ b/tests/legacy-cli/e2e/tests/generate/application/application-basic.ts @@ -8,5 +8,5 @@ export default function() { .then(() => expectFileToMatch('angular.json', /\"app2\":/)) .then(() => useCIChrome('projects/app2')) .then(() => useCIChrome('projects/app2-e2e')) - .then(() => ng('test', 'app2', '--watch=false')); + .then(() => ng('test', 'app2', '--watch=false', '--browsers=ChromeHeadlessCI')); } diff --git a/tests/legacy-cli/e2e/tests/generate/library/library-basic.ts b/tests/legacy-cli/e2e/tests/generate/library/library-basic.ts index 8e5f10848de7..a4a29f2be493 100644 --- a/tests/legacy-cli/e2e/tests/generate/library/library-basic.ts +++ b/tests/legacy-cli/e2e/tests/generate/library/library-basic.ts @@ -7,5 +7,5 @@ export default function () { .then(() => expectFileToMatch('angular.json', /\"my-lib\":/)) .then(() => useCIChrome('projects/my-lib')) .then(() => ng('build', 'my-lib')) - .then(() => ng('test', 'my-lib', '--watch=false')); + .then(() => ng('test', 'my-lib', '--watch=false', '--browsers=ChromeHeadlessCI')); } diff --git a/tests/legacy-cli/e2e/utils/project.ts b/tests/legacy-cli/e2e/utils/project.ts index ca292e3c682e..c86868dc7026 100644 --- a/tests/legacy-cli/e2e/utils/project.ts +++ b/tests/legacy-cli/e2e/utils/project.ts @@ -1,4 +1,5 @@ -import { readFile, writeFile, replaceInFile } from './fs'; +import * as fs from 'fs-extra'; +import { readFile, writeFile, replaceInFile, prependToFile } from './fs'; import { execAndWaitForOutputToMatch, npm, silentNpm, ng } from './process'; import { getGlobalVariable } from './env'; @@ -186,58 +187,61 @@ export function useCIDefaults(projectName = 'test-project') { const appTargets = project.targets || project.architect; appTargets.build.options.progress = false; appTargets.test.options.progress = false; + // Use the CI chrome setup in karma. + appTargets.test.options.browsers = 'ChromeHeadlessCI'; // Disable auto-updating webdriver in e2e. const e2eProject = workspaceJson.projects[projectName + '-e2e']; const e2eTargets = e2eProject.targets || e2eProject.architect; e2eTargets.e2e.options.webdriverUpdate = false; }) .then(() => updateJsonFile('package.json', json => { - // We want to always use the same version of webdriver but can only do so on CircleCI. - // Appveyor and Travis will use latest Chrome stable. - // CircleCI (via ngcontainer:0.1.1) uses Chrome 63.0.3239.84. - // Appveyor (via chocolatey) cannot use older versions of Chrome at all: - // https://github.com/chocolatey/chocolatey-coreteampackages/tree/master/automatic/googlechrome - // webdriver 2.33 matches Chrome 63.0.3239.84. - // webdriver 2.37 matches Chrome 65.0.3325.18100 (latest stable). - // The webdriver versions for latest stable will need to be manually updated. - const webdriverVersion = process.env['CIRCLECI'] ? '2.33' : '2.37'; - const driverOption = process.env['CHROMEDRIVER_VERSION_ARG'] - || `--versions.chrome ${webdriverVersion}`; + // Use matching versions of Chrome and Webdriver. json['scripts']['webdriver-update'] = 'webdriver-manager update' + - ` --standalone false --gecko false ${driverOption}`; + ` --standalone false --gecko false --versions.chrome 2.45`; // Supports Chrome v70-72 + })) .then(() => npm('run', 'webdriver-update')); } export function useCIChrome(projectDir: string) { - // There's a race condition happening in Chrome. Enabling logging in chrome used by - // protractor actually fixes it. Logging is piped to a file so it doesn't affect our setup. - // --no-sandbox is needed for Circle CI. - // Travis can use headless chrome, but not appveyor. + const protractorConf = `${projectDir}/protractor.conf.js`; + const karmaConf = `${projectDir}/karma.conf.js`; + return Promise.resolve() - .then(() => replaceInFile(`${projectDir}/protractor.conf.js`, - `'browserName': 'chrome'`, - `'browserName': 'chrome', - chromeOptions: { - args: [ - "--enable-logging", - // "--no-sandbox", - // "--headless" - ] - } - `)) - // Not a problem if the file can't be found. - // .catch(() => null) - // .then(() => replaceInFile(`${projectDir}/karma.conf.js`, `browsers: ['Chrome'],`, - // `browsers: ['ChromeCI'], - // customLaunchers: { - // ChromeCI: { - // base: 'ChromeHeadless', - // flags: ['--no-sandbox'] - // } - // }, - // `)) - .catch(() => null); + .then(() => updateJsonFile('package.json', json => { + // Use matching versions of Chrome and Webdriver. + json['devDependencies']['puppeteer'] = '1.11.0'; // Chromium 72.0.3618.0 (r609904) + json['devDependencies']['karma-chrome-launcher'] = '~2.2.0'; // Minimum for ChromeHeadless. + })) + // Use Pupeteer in protractor if a config is found on the project. + .then(() => { + if (fs.existsSync(protractorConf)) { + return replaceInFile(protractorConf, + `'browserName': 'chrome'`, + `'browserName': 'chrome', + chromeOptions: { + args: ['--headless'], + binary: require('puppeteer').executablePath() + } + `); + } + }) + // Use Pupeteer in karma if a config is found on the project. + .then(() => { + if (fs.existsSync(karmaConf)) { + return prependToFile(karmaConf, + `process.env.CHROME_BIN = require('puppeteer').executablePath();`) + .then(() => replaceInFile(karmaConf, + `browsers: ['Chrome']`, + `browsers: ['Chrome'], + customLaunchers: { + ChromeHeadlessCI: { + base: 'ChromeHeadless', + } + } + `)); + } + }); } // Convert a Angular 5 project to Angular 2. diff --git a/yarn.lock b/yarn.lock index 5049a8baeca2..462a3149589f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2293,7 +2293,7 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concat-stream@^1.5.0, concat-stream@^1.5.2, concat-stream@~1.6.0: +concat-stream@1.6.2, concat-stream@^1.5.0, concat-stream@^1.5.2, concat-stream@~1.6.0: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== @@ -3610,6 +3610,16 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" +extract-zip@^1.6.6: + version "1.6.7" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.7.tgz#a840b4b8af6403264c8db57f4f1a74333ef81fe9" + integrity sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k= + dependencies: + concat-stream "1.6.2" + debug "2.6.9" + mkdirp "0.5.1" + yauzl "2.4.1" + extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" @@ -3674,6 +3684,13 @@ faye-websocket@~0.11.1: dependencies: websocket-driver ">=0.5.1" +fd-slicer@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" + integrity sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU= + dependencies: + pend "~1.2.0" + fecha@^2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd" @@ -6328,6 +6345,11 @@ mime@^1.3.4, mime@^1.4.1: resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== +mime@^2.0.3: + version "2.4.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.0.tgz#e051fd881358585f3279df333fe694da0bcffdd6" + integrity sha512-ikBcWwyqXQSHKtciCcctu9YfPbFYZ4+gbHEmE0Q8jzcTYQg5dHCr3g2wwAZjPoJfQVXZq6KXAjpXOTf5/cjT7w== + mime@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/mime/-/mime-2.3.1.tgz#b1621c54d63b97c47d3cfe7f7215f7d64517c369" @@ -6470,7 +6492,7 @@ mixin-object@^2.0.1: for-in "^0.1.3" is-extendable "^0.1.1" -mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: +mkdirp@0.5.1, mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: version "0.5.1" resolved "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -7520,6 +7542,11 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -7703,6 +7730,11 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= +progress@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" @@ -7870,6 +7902,20 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +puppeteer@1.11.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-1.11.0.tgz#63cdbe12b07275cd6e0b94bce41f3fcb20305770" + integrity sha512-iG4iMOHixc2EpzqRV+pv7o3GgmU2dNYEMkvKwSaQO/vMZURakwSOn/EYJ6OIRFYOque1qorzIBvrytPIQB3YzQ== + dependencies: + debug "^4.1.0" + extract-zip "^1.6.6" + https-proxy-agent "^2.2.1" + mime "^2.0.3" + progress "^2.0.1" + proxy-from-env "^1.0.0" + rimraf "^2.6.1" + ws "^6.1.0" + q@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" @@ -10641,6 +10687,13 @@ write-file-atomic@^2.0.0: imurmurhash "^0.1.4" signal-exit "^3.0.2" +ws@^6.1.0: + version "6.1.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" + integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw== + dependencies: + async-limiter "~1.0.0" + ws@~3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" @@ -10810,6 +10863,13 @@ yargs@^7.0.0: y18n "^3.2.1" yargs-parser "^5.0.0" +yauzl@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" + integrity sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU= + dependencies: + fd-slicer "~1.0.1" + yeast@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"