From 516977adbb603133ad79d1f8fd7083e13c190998 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Thu, 25 Nov 2021 20:07:49 +0100 Subject: [PATCH 1/7] ci: attempt to increase stability of saucelabs legacy job This is an attempt to increase the stability of the Saucelabs legacy job by using an emulator recommended by the Saucelabs platform configurator, explicitly specifying the appium server version etc. --- browser-providers.conf.js | 102 ++++++------------------------ karma-js.conf.js | 24 +++++-- package.json | 7 +- yarn.lock | 130 ++++++++++++++++++++++++++++++++------ 4 files changed, 156 insertions(+), 107 deletions(-) diff --git a/browser-providers.conf.js b/browser-providers.conf.js index 4b3c95b2b53a..d8dc2b5e7824 100644 --- a/browser-providers.conf.js +++ b/browser-providers.conf.js @@ -10,98 +10,36 @@ // If the target is set to null, then the browser is not run anywhere during CI. // If a category becomes empty (e.g. BS and required), then the corresponding job must be commented // out in the CI configuration. -var CIconfiguration = { - // Chrome and Firefox run as part of the Bazel browser tests, so we do not run them as - // part of the legacy Saucelabs tests. - 'Chrome': {unitTest: {target: null, required: false}, e2e: {target: null, required: true}}, - 'Firefox': {unitTest: {target: null, required: false}, e2e: {target: null, required: true}}, - // Set ESR as a not required browser as it fails for Ivy acceptance tests. - 'FirefoxESR': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}}, - // Disabled because using the "beta" channel of Chrome can cause non-deterministic CI results. - // e.g. a new chrome beta version has been released, but the Saucelabs selenium server does - // not provide a chromedriver version that is compatible with the new beta. - 'ChromeBeta': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: false}}, - 'ChromeDev': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}}, - // FirefoxBeta and FirefoxDev should be target:'BS' or target:'SL', and required:true - // Currently deactivated due to https://github.com/angular/angular/issues/7560 - 'FirefoxBeta': {unitTest: {target: null, required: true}, e2e: {target: null, required: false}}, - 'FirefoxDev': {unitTest: {target: null, required: true}, e2e: {target: null, required: true}}, - 'Edge': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}}, - 'Android10': {unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}}, - 'Android11': {unitTest: {target: 'SL', required: true}, e2e: {target: null, required: true}}, - 'Safari12': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}}, - 'Safari13': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}}, - 'iOS12': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}}, - 'iOS13': {unitTest: {target: 'SL', required: false}, e2e: {target: null, required: true}}, - 'WindowsPhone': {unitTest: {target: 'BS', required: false}, e2e: {target: null, required: true}} +const config = { + 'Android10': {unitTest: {target: 'SL', required: true}}, + 'Android11': {unitTest: {target: 'SL', required: true}}, }; -var customLaunchers = { - 'DartiumWithWebPlatform': - {base: 'Dartium', flags: ['--enable-experimental-web-platform-features']}, - 'ChromeNoSandbox': {base: 'Chrome', flags: ['--no-sandbox']}, - 'SL_CHROME': {base: 'SauceLabs', browserName: 'chrome', version: '81'}, - 'SL_CHROMEBETA': {base: 'SauceLabs', browserName: 'chrome', version: 'beta'}, - 'SL_CHROMEDEV': {base: 'SauceLabs', browserName: 'chrome', version: 'dev'}, - 'SL_FIREFOX': {base: 'SauceLabs', browserName: 'firefox', version: '76'}, - // Firefox 68 is the current ESR vesion - 'SL_FIREFOXESR': {base: 'SauceLabs', browserName: 'firefox', version: '68'}, - 'SL_FIREFOXBETA': - {base: 'SauceLabs', platform: 'Windows 10', browserName: 'firefox', version: 'beta'}, - 'SL_FIREFOXDEV': - {base: 'SauceLabs', platform: 'Windows 10', browserName: 'firefox', version: 'dev'}, - 'SL_SAFARI12': - {base: 'SauceLabs', browserName: 'safari', platform: 'macOS 10.13', version: '12.1'}, - 'SL_SAFARI13': - {base: 'SauceLabs', browserName: 'safari', platform: 'macOS 10.15', version: '13.0'}, - 'SL_IOS12': { - base: 'SauceLabs', - browserName: 'Safari', - platform: 'iOS', - version: '12.0', - device: 'iPhone 7 Simulator' - }, - 'SL_IOS13': { - base: 'SauceLabs', - browserName: 'Safari', - platform: 'iOS', - version: '13.0', - device: 'iPhone 11 Simulator' - }, - 'SL_EDGE': { - base: 'SauceLabs', - browserName: 'MicrosoftEdge', - platform: 'Windows 10', - version: '14.14393' - }, +/** Whether browsers should be remotely acquired in debug mode. */ +const debugMode = false; + +const customLaunchers = { 'SL_ANDROID10': { base: 'SauceLabs', browserName: 'Chrome', - platform: 'Android', - version: '10.0', - device: 'Android GoogleAPI Emulator' + platformName: 'Android', + platformVersion: '10.0', + deviceName: 'Google Pixel 3a GoogleAPI Emulator', + appiumVersion: '1.20.2', + extendedDebugging: debugMode, }, 'SL_ANDROID11': { base: 'SauceLabs', browserName: 'Chrome', - platform: 'Android', - version: '11.0', - device: 'Android GoogleAPI Emulator' + platformName: 'Android', + platformVersion: '11.0', + deviceName: 'Google Pixel 3a GoogleAPI Emulator', + appiumVersion: '1.20.2', + extendedDebugging: debugMode, }, }; -var sauceAliases = { - 'ALL': Object.keys(customLaunchers).filter(function(item) { - return customLaunchers[item].base == 'SauceLabs'; - }), - 'DESKTOP': ['SL_CHROME', 'SL_FIREFOX', 'SL_EDGE', 'SL_SAFARI12', 'SL_SAFARI13', 'SL_FIREFOXESR'], - 'MOBILE': ['SL_ANDROID10', 'SL_ANDROID11', 'SL_IOS12', 'SL_IOS13'], - 'ANDROID': ['SL_ANDROID10', 'SL_ANDROID11'], - 'FIREFOX': ['SL_FIREFOXESR'], - 'IOS': ['SL_IOS12', 'SL_IOS13'], - 'SAFARI': ['SL_SAFARI12', 'SL_SAFARI13'], - 'BETA': ['SL_CHROMEBETA', 'SL_FIREFOXBETA'], - 'DEV': ['SL_CHROMEDEV', 'SL_FIREFOXDEV'], +const sauceAliases = { 'CI_REQUIRED': buildConfiguration('unitTest', 'SL', true), 'CI_OPTIONAL': buildConfiguration('unitTest', 'SL', false) }; @@ -112,9 +50,9 @@ module.exports = { }; function buildConfiguration(type, target, required) { - return Object.keys(CIconfiguration) + return Object.keys(config) .filter((item) => { - var conf = CIconfiguration[item][type]; + const conf = config[item][type]; return conf.required === required && conf.target === target; }) .map((item) => target + '_' + item.toUpperCase()); diff --git a/karma-js.conf.js b/karma-js.conf.js index 3ca73627a2de..575e202b31a9 100644 --- a/karma-js.conf.js +++ b/karma-js.conf.js @@ -10,8 +10,6 @@ const browserProvidersConf = require('./browser-providers.conf'); const {generateSeed} = require('./tools/jasmine-seed-generator'); const {hostname} = require('os'); -// Karma configuration -// Generated on Thu Sep 25 2014 11:52:02 GMT-0700 (PDT) module.exports = function(config) { const conf = { frameworks: ['jasmine'], @@ -21,7 +19,7 @@ module.exports = function(config) { random: true, seed: generateSeed('karma-js.conf'), }, - captureConsole: process.env.CI ? false : true, + captureConsole: true, }, files: [ @@ -133,8 +131,8 @@ module.exports = function(config) { maxDuration: 5400, }, - // Try "websocket" for a faster transmission first. Fallback to "polling" if necessary. - transports: ['websocket', 'polling'], + // Always use `polling` for increased communication stability. + transports: ['polling'], port: 9876, captureTimeout: 180000, @@ -151,6 +149,15 @@ module.exports = function(config) { set: () => {}, }); + if (process.env.CIRCLECI) { + conf.frameworks.unshift('parallel'); + conf.plugins.unshift(require('karma-parallel')); + conf.parallelOptions = { + executors: 2, + shardStrategy: 'round-robin', + }; + } + if (process.env['SAUCE_TUNNEL_IDENTIFIER']) { console.log(`SAUCE_TUNNEL_IDENTIFIER: ${process.env.SAUCE_TUNNEL_IDENTIFIER}`); @@ -159,6 +166,13 @@ module.exports = function(config) { // Setup the Saucelabs plugin so that it can launch browsers using the proper tunnel. conf.sauceLabs.build = tunnelIdentifier; conf.sauceLabs.tunnelIdentifier = tunnelIdentifier; + + // Patch the `saucelabs` package so that `karma-sauce-launcher` does not attempt downloading + // the test logs from upstream and tries re-uploading them with the Karma enhanced details. + // This slows-down tests/browser restarting and can decrease stability. + // https://github.com/karma-runner/karma-sauce-launcher/blob/59b0c5c877448e064ad56449cd906743721c6b62/src/launcher/launcher.ts#L72-L79. + require('saucelabs').default.prototype.downloadJobAsset = + () => Promise.resolve(''); } // For SauceLabs jobs, we set up a domain which resolves to the machine which launched diff --git a/package.json b/package.json index d6e74ec10297..c1fd799fe47c 100644 --- a/package.json +++ b/package.json @@ -176,9 +176,10 @@ "gulp-conventional-changelog": "^2.0.35", "husky": "7.0.4", "inquirer": "^8.0.0", + "karma-parallel": "^0.3.1", "karma-sauce-launcher": "^4.3.6", "madge": "^5.0.0", - "sauce-connect": "https://saucelabs.com/downloads/sc-4.6.2-linux.tar.gz", + "sauce-connect": "https://saucelabs.com/downloads/sc-4.7.1-linux.tar.gz", "semver": "^7.3.5", "ts-node": "^10.0.0", "tsec": "0.2.0", @@ -192,6 +193,7 @@ "// 5": "Ensure a single version of webdriver-manager so it is hoisted as the integration tests depend on it being found at ../../node_modules/webdriver-manager", "// 6": "Ensure that `@babel/*` packages match the below versions to avoid conflicts with `types/babel__*`", "// 7": "Ensure that transitive dependencies on `https-proxy-agent` are at minimum v5 as older versions patch NodeJS directly, breaking tools like webdriver which is used by the karma-sauce-launcher as an example.", + "// 8": "Ensure that a single instance of the `saucelabs` package is used. Protractor and the Karma sauce launcher pull this package as dependency. A single instance allows for e.g. easier patching in the Karma config.", "resolutions": { "**/graceful-fs": "4.2.8", "**/webdriver-manager": "12.1.8", @@ -202,6 +204,7 @@ "@babel/template": "7.8.6", "@babel/traverse": "7.8.6", "@babel/types": "7.8.6", - "**/https-proxy-agent": "5.0.0" + "**/https-proxy-agent": "5.0.0", + "**/saucelabs": "4.7.8" } } diff --git a/yarn.lock b/yarn.lock index c8be1dae5953..8d86c0dd8f3e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -236,7 +236,6 @@ "@angular/dev-infra-private@https://github.com/angular/dev-infra-private-builds.git#74fb4de008fde297fb83393ff076de10532f82a9": version "0.0.0-c2fb49a44ad9fa77f508010f950524ee97f5e8d5" - uid "74fb4de008fde297fb83393ff076de10532f82a9" resolved "https://github.com/angular/dev-infra-private-builds.git#74fb4de008fde297fb83393ff076de10532f82a9" dependencies: "@actions/core" "^1.4.0" @@ -2604,6 +2603,11 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abbrev@1.0.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -2723,6 +2727,11 @@ ajv@^8.0.0: require-from-string "^2.0.2" uri-js "^4.2.2" +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + "angular-1.5@npm:angular@1.5": version "1.5.11" resolved "https://registry.yarnpkg.com/angular/-/angular-1.5.11.tgz#8c5ba7386f15965c9acf3429f6881553aada30d6" @@ -3164,7 +3173,7 @@ async@0.9.x: resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= -async@^1.3.0, async@^1.5.2: +async@1.x, async@^1.3.0, async@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= @@ -5884,6 +5893,18 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +escodegen@1.8.x: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + escodegen@^1.8.1: version "1.14.3" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" @@ -5921,6 +5942,11 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== +esprima@2.7.x, esprima@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= + esprima@4.0.1, esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -5933,6 +5959,11 @@ esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= + estraverse@^4.1.1, estraverse@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" @@ -7088,6 +7119,17 @@ glob@7.2.0, glob@^7.0.0, glob@^7.0.3, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, glo once "^1.3.0" path-is-absolute "^1.0.0" +glob@^5.0.15: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + global-agent@^2.1.12: version "2.2.0" resolved "https://registry.yarnpkg.com/global-agent/-/global-agent-2.2.0.tgz#566331b0646e6bf79429a16877685c4a1fbf76dc" @@ -7428,7 +7470,7 @@ handle-thing@^2.0.0: resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== -handlebars@^4.7.6: +handlebars@^4.0.1, handlebars@^4.7.6: version "4.7.7" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== @@ -7465,6 +7507,11 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + has-flag@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" @@ -8526,6 +8573,26 @@ istanbul-reports@^3.0.2: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +istanbul@^0.4.5: + version "0.4.5" + resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" + integrity sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs= + dependencies: + abbrev "1.0.x" + async "1.x" + escodegen "1.8.x" + esprima "2.7.x" + glob "^5.0.15" + handlebars "^4.0.1" + js-yaml "3.x" + mkdirp "0.5.x" + nopt "3.x" + once "1.x" + resolve "1.1.x" + supports-color "^3.1.0" + which "^1.1.1" + wordwrap "^1.0.0" + isurl@^1.0.0-alpha5: version "1.0.0" resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" @@ -8636,7 +8703,7 @@ js-levenshtein@^1.1.6: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.13.1: +js-yaml@3.x, js-yaml@^3.13.1: version "3.14.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== @@ -8869,6 +8936,14 @@ karma-jasmine@^4.0.1: dependencies: jasmine-core "^3.6.0" +karma-parallel@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/karma-parallel/-/karma-parallel-0.3.1.tgz#781876e5992b2781619e762f3e04dcbf85f47fa1" + integrity sha512-64jxNYamYi/9Y67h4+FfViSYhwDgod3rLuq+ZdZ0c3XeZFp/3q3v3HVkd8b5Czp3hCB+LLF8DIv4zlR4xFqbRw== + dependencies: + istanbul "^0.4.5" + lodash "^4.17.11" + karma-requirejs@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/karma-requirejs/-/karma-requirejs-1.1.0.tgz#fddae2cb87d7ebc16fb0222893564d7fee578798" @@ -9783,7 +9858,7 @@ minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@3.0.4, minimatch@^3.0.3, minimatch@^3.0.4: +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.3, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -9894,7 +9969,7 @@ mkdirp-classic@^0.5.2: resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== -"mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5: +mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -10179,6 +10254,13 @@ nodejs-websocket@^1.7.2: resolved "https://registry.yarnpkg.com/nodejs-websocket/-/nodejs-websocket-1.7.2.tgz#94abd1e248f57d4d1c663dec3831015c6dad98a6" integrity sha512-PFX6ypJcCNDs7obRellR0DGTebfUhw1SXGKe2zpB+Ng1DQJhdzbzx1ob+AvJCLzy2TJF4r8cCDqMQqei1CZdPQ== +nopt@3.x: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + nopt@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" @@ -10467,7 +10549,7 @@ on-headers@^1.0.0, on-headers@~1.0.2: resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== -once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: +once@1.x, once@^1.3.0, once@^1.3.1, once@^1.3.2, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -12280,6 +12362,11 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= +resolve@1.1.x: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + resolve@1.20.0, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.3.2, resolve@^1.4.0: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" @@ -12555,18 +12642,11 @@ sass@1.43.4: dependencies: chokidar ">=3.0.0 <4.0.0" -"sauce-connect@https://saucelabs.com/downloads/sc-4.6.2-linux.tar.gz": +"sauce-connect@https://saucelabs.com/downloads/sc-4.7.1-linux.tar.gz": version "0.0.0" - resolved "https://saucelabs.com/downloads/sc-4.6.2-linux.tar.gz#7b7f35433af9c3380758e048894d7b9aecf3754e" + resolved "https://saucelabs.com/downloads/sc-4.7.1-linux.tar.gz#e5d7f82ad98251a653d1b0537f1103e49eda5e11" -saucelabs@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/saucelabs/-/saucelabs-1.5.0.tgz#9405a73c360d449b232839919a86c396d379fd9d" - integrity sha512-jlX3FGdWvYf4Q3LFfFWS1QvPg3IGCGWxIc8QBFdPTbpTJnt/v17FHXYVAn7C8sHf1yUXo2c7yIM0isDryfYtHQ== - dependencies: - https-proxy-agent "^2.2.1" - -saucelabs@^4.6.3: +saucelabs@4.7.8, saucelabs@^1.5.0, saucelabs@^4.6.3: version "4.7.8" resolved "https://registry.yarnpkg.com/saucelabs/-/saucelabs-4.7.8.tgz#099a7ddacee297b34420acd5ddc155eb1ad0efde" integrity sha512-K2qaRUixc7+8JiAwpTvEsIQVzzUkYwa0mAfs0akGagRlWXUR1JrsmgJRyz28qkwpERW1KDuByn3Ju96BuW1V7Q== @@ -13121,6 +13201,13 @@ source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.6: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= + dependencies: + amdefine ">=0.0.4" + sourcemap-codec@1.4.8, sourcemap-codec@^1.4.4, sourcemap-codec@^1.4.8: version "1.4.8" resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" @@ -13497,6 +13584,13 @@ supports-color@^2.0.0: resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= +supports-color@^3.1.0: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + supports-color@^5.0.0, supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -14806,7 +14900,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.2.1, which@^1.2.14, which@^1.2.9: +which@^1.1.1, which@^1.2.1, which@^1.2.14, which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== From d78bfd03e1f9786671eaaad69f98a5a6d0906057 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Fri, 26 Nov 2021 15:24:04 +0100 Subject: [PATCH 2/7] build: bundle spec files for saucelabs legacy job Bundle spec files similar to how it is done within the Angular Components repo. This should simplify the setup and also speed up the Saucelab job as only a single spec bundle would need to be downloaded, compared to having to load hundreds of files through the Saucelabs tunnel. Also makes a couple of tests more robust with the emulators/and accounts for ES2015 test runner changes. The tests should be less reluctant to such build process changes. Note for reviewers: Some imports have been simplified here. This work came from Joey's original WIP for this. It's unclear to me whether this is still needed, but it sounded like this was necessary for the ESBuild bundling to work. I have robusted the module resolution plugin though, so I doubt it's still needed. At the same time though: Not worth reverting/trying as these changes are nice to have anyway! Co-Authored-By: Joey Perrott Co-Authored-By: Paul Gschwendtner --- .circleci/config.yml | 14 +- .pullapprove.yml | 1 + karma-js.conf.js | 58 +--- .../src/old/compiler/compiler_benchmark.ts | 2 +- package.json | 2 +- packages/core/test/acceptance/content_spec.ts | 5 +- .../core/test/acceptance/directive_spec.ts | 3 +- .../test/acceptance/discover_utils_spec.ts | 4 +- packages/core/test/acceptance/text_spec.ts | 3 +- .../acceptance/view_container_ref_spec.ts | 3 +- ...ns_with_web_animations_integration_spec.ts | 3 +- packages/core/test/debug/debug_node_spec.ts | 3 +- .../directive_lifecycle_integration_spec.ts | 3 +- packages/core/test/linker/integration_spec.ts | 3 +- packages/core/test/render3/i18n_debug_spec.ts | 12 +- packages/core/test/render3/ivy/jit_spec.ts | 6 +- packages/router/test/router_preloader.spec.ts | 1 - packages/tsconfig-legacy-saucelabs.json | 32 ++- .../test/integration/downgrade_module_spec.ts | 15 +- test-main.js | 213 -------------- .../build-saucelabs-test-bundle.mjs | 267 ++++++++++++++++++ .../downlevel_decorator_transform.ts | 27 ++ tools/legacy-saucelabs/tsconfig.json | 10 + yarn.lock | 120 +------- 24 files changed, 388 insertions(+), 422 deletions(-) delete mode 100644 test-main.js create mode 100644 tools/legacy-saucelabs/build-saucelabs-test-bundle.mjs create mode 100644 tools/legacy-saucelabs/downlevel_decorator_transform.ts create mode 100644 tools/legacy-saucelabs/tsconfig.json diff --git a/.circleci/config.yml b/.circleci/config.yml index a98c188f04e7..8645548431c2 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -614,9 +614,9 @@ jobs: //packages/common/locales # Needed for the ES5 downlevel reflector test in `packages/core/test/reflection`. - mkdir -p dist/all/@angular/core/test/reflection/ + mkdir -p dist/legacy-test-out/core/test/reflection/ cp dist/bin/packages/core/test/reflection/es5_downleveled_inheritance_fixture.js \ - dist/all/@angular/core/test/reflection/es5_downleveled_inheritance_fixture.js + dist/legacy-test-out/core/test/reflection/es5_downleveled_inheritance_fixture.js # Locale files are needed for i18n tests running within Saucelabs. These are added # directly as sources so that the TypeScript compilation of `/packages/tsconfig.json` # can succeed. Note that the base locale and currencies files are checked-in, so @@ -624,11 +624,10 @@ jobs: mkdir -p packages/common/locales/extra cp dist/bin/packages/common/locales/*.ts packages/common/locales cp dist/bin/packages/common/locales/extra/*.ts packages/common/locales/extra - # add module umd tsc compile option so the test can work - # properly in the legacy browsers - - run: yarn tsc -p packages/tsconfig-legacy-saucelabs.json --module UMD - - run: yarn tsc -p modules --module UMD + # Build ZoneJS so that it can be loaded globally in the Karma tests. - run: yarn bazel build //packages/zone.js:npm_package + # Build the bundle for all tests to run within Saucelabs + - run: node tools/legacy-saucelabs/build-saucelabs-test-bundle.mjs - run: # Waiting on ready ensures that we don't run tests too early without Saucelabs not being ready. name: Waiting for Saucelabs tunnel to connect @@ -636,8 +635,7 @@ jobs: - run: name: Running tests on Saucelabs. command: | - browsers=$(node -e 'console.log(require("./browser-providers.conf").sauceAliases.CI_REQUIRED.join(","))') - yarn karma start ./karma-js.conf.js --single-run --browsers=${browsers} + KARMA_WEB_TEST_MODE=SL_REQUIRED yarn karma start ./karma-js.conf.js --single-run - run: name: Stop Saucelabs tunnel service command: ./tools/saucelabs/sauce-service.sh stop diff --git a/.pullapprove.yml b/.pullapprove.yml index 648739d8cb07..55498a1847fa 100644 --- a/.pullapprove.yml +++ b/.pullapprove.yml @@ -1196,6 +1196,7 @@ groups: 'tools/circular_dependency_test/**', 'tools/contributing-stats/**', 'tools/gulp-tasks/**', + 'tools/legacy-saucelabs/**', 'tools/npm/**', 'tools/npm_integration_test/**', 'tools/rxjs/**', diff --git a/karma-js.conf.js b/karma-js.conf.js index 575e202b31a9..98588131ce58 100644 --- a/karma-js.conf.js +++ b/karma-js.conf.js @@ -23,10 +23,6 @@ module.exports = function(config) { }, files: [ - // Sources and specs. - // Loaded through the System loader, in `test-main.js`. - {pattern: 'dist/all/@angular/**/*.js', included: false, watched: true}, - // Serve AngularJS for `ngUpgrade` testing. {pattern: 'node_modules/angular-1.5/angular?(.min).js', included: false, watched: false}, {pattern: 'node_modules/angular-mocks-1.5/angular-mocks.js', included: false, watched: false}, @@ -46,10 +42,9 @@ module.exports = function(config) { 'dist/bin/packages/zone.js/npm_package/bundles/zone-testing.umd.js', 'dist/bin/packages/zone.js/npm_package/bundles/task-tracking.umd.js', - // Including systemjs because it defines `__eval`, which produces correct stack traces. - 'test-events.js', - 'third_party/shims_for_internal_tests.js', - 'node_modules/systemjs/dist/system.src.js', + // Static test assets. + {pattern: 'packages/platform-browser/test/static_assets/**/*', included: false}, + {pattern: 'packages/platform-browser/test/browser/static_assets/**/*', included: false}, // Serve polyfills necessary for testing the `elements` package. { @@ -58,42 +53,9 @@ module.exports = function(config) { watched: false }, - {pattern: 'node_modules/rxjs/**', included: false, watched: false, served: true}, 'node_modules/reflect-metadata/Reflect.js', - 'tools/build/file2modulename.js', - 'test-main.js', - {pattern: 'dist/all/@angular/empty.*', included: false, watched: false}, - {pattern: 'packages/platform-browser/test/static_assets/**', included: false, watched: false}, - { - pattern: 'packages/platform-browser/test/browser/static_assets/**', - included: false, - watched: false, - }, - ], - exclude: [ - 'dist/all/@angular/_testing_init/**', - 'dist/all/@angular/**/e2e_test/**', - 'dist/all/@angular/**/*node_only_spec.js', - 'dist/all/@angular/benchpress/**', - 'dist/all/@angular/compiler-cli/**', - 'dist/all/@angular/compiler-cli/src/ngtsc/**', - 'dist/all/@angular/compiler-cli/test/compliance/**', - 'dist/all/@angular/compiler-cli/test/ngtsc/**', - 'dist/all/@angular/compiler/test/aot/**', - 'dist/all/@angular/compiler/test/render3/**', - 'dist/all/@angular/core/test/bundling/**', - 'dist/all/@angular/core/test/render3/ivy/**', - 'dist/all/@angular/core/test/render3/jit/**', - 'dist/all/@angular/core/test/render3/perf/**', - 'dist/all/@angular/elements/schematics/**', - 'dist/all/@angular/examples/**/e2e_test/*', - 'dist/all/@angular/language-service/**', - 'dist/all/@angular/localize/**/test/**', - 'dist/all/@angular/localize/schematics/**', - 'dist/all/@angular/router/**/test/**', - 'dist/all/@angular/platform-browser/testing/e2e_util.js', - 'dist/examples/**/e2e_test/**', + 'dist/legacy-test-bundle.spec.js', ], customLaunchers: browserProvidersConf.customLaunchers, @@ -149,15 +111,6 @@ module.exports = function(config) { set: () => {}, }); - if (process.env.CIRCLECI) { - conf.frameworks.unshift('parallel'); - conf.plugins.unshift(require('karma-parallel')); - conf.parallelOptions = { - executors: 2, - shardStrategy: 'round-robin', - }; - } - if (process.env['SAUCE_TUNNEL_IDENTIFIER']) { console.log(`SAUCE_TUNNEL_IDENTIFIER: ${process.env.SAUCE_TUNNEL_IDENTIFIER}`); @@ -171,8 +124,7 @@ module.exports = function(config) { // the test logs from upstream and tries re-uploading them with the Karma enhanced details. // This slows-down tests/browser restarting and can decrease stability. // https://github.com/karma-runner/karma-sauce-launcher/blob/59b0c5c877448e064ad56449cd906743721c6b62/src/launcher/launcher.ts#L72-L79. - require('saucelabs').default.prototype.downloadJobAsset = - () => Promise.resolve(''); + require('saucelabs').default.prototype.downloadJobAsset = () => Promise.resolve(''); } // For SauceLabs jobs, we set up a domain which resolves to the machine which launched diff --git a/modules/benchmarks/src/old/compiler/compiler_benchmark.ts b/modules/benchmarks/src/old/compiler/compiler_benchmark.ts index 88b135b5609b..4f57f7aa4b4a 100644 --- a/modules/benchmarks/src/old/compiler/compiler_benchmark.ts +++ b/modules/benchmarks/src/old/compiler/compiler_benchmark.ts @@ -8,7 +8,7 @@ import {CompilerConfig, DirectiveResolver} from '@angular/compiler'; import {Component, ComponentResolver, Directive, ViewContainerRef,} from '@angular/core'; -import {ViewMetadata} from '@angular/core/src/metadata/view'; +import {ViewMetadata} from '@angular/core/view'; import {PromiseWrapper} from '@angular/facade/src/async'; import {print, Type} from '@angular/facade/src/lang'; import {bootstrap} from '@angular/platform-browser'; diff --git a/package.json b/package.json index c1fd799fe47c..d72555bf16a8 100644 --- a/package.json +++ b/package.json @@ -176,9 +176,9 @@ "gulp-conventional-changelog": "^2.0.35", "husky": "7.0.4", "inquirer": "^8.0.0", - "karma-parallel": "^0.3.1", "karma-sauce-launcher": "^4.3.6", "madge": "^5.0.0", + "multimatch": "^6.0.0", "sauce-connect": "https://saucelabs.com/downloads/sc-4.7.1-linux.tar.gz", "semver": "^7.3.5", "ts-node": "^10.0.0", diff --git a/packages/core/test/acceptance/content_spec.ts b/packages/core/test/acceptance/content_spec.ts index c30171fc2bc8..2b264f4b4050 100644 --- a/packages/core/test/acceptance/content_spec.ts +++ b/packages/core/test/acceptance/content_spec.ts @@ -7,8 +7,7 @@ */ import {CommonModule} from '@angular/common'; -import {ChangeDetectorRef, Component, Directive, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core'; -import {Input} from '@angular/core/src/metadata'; +import {ChangeDetectorRef, Component, Directive, Input, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core'; import {TestBed} from '@angular/core/testing'; import {By} from '@angular/platform-browser'; import {expect} from '@angular/platform-browser/testing/src/matchers'; @@ -322,7 +321,7 @@ describe('projection', () => { @Component( {selector: 'comp', template: ``}) class Comp { - @ViewChild(TemplateRef, {static: true}) template !: TemplateRef; + @ViewChild(TemplateRef, {static: true}) template!: TemplateRef; } @Directive({selector: '[trigger]'}) diff --git a/packages/core/test/acceptance/directive_spec.ts b/packages/core/test/acceptance/directive_spec.ts index 135e92274f17..b2dce9f02419 100644 --- a/packages/core/test/acceptance/directive_spec.ts +++ b/packages/core/test/acceptance/directive_spec.ts @@ -7,8 +7,7 @@ */ import {CommonModule} from '@angular/common'; -import {Component, Directive, ElementRef, EventEmitter, NgModule, Output, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core'; -import {Input} from '@angular/core/src/metadata'; +import {Component, Directive, ElementRef, EventEmitter, Input, NgModule, Output, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core'; import {TestBed} from '@angular/core/testing'; import {By} from '@angular/platform-browser'; diff --git a/packages/core/test/acceptance/discover_utils_spec.ts b/packages/core/test/acceptance/discover_utils_spec.ts index f7c0450c312b..6ce5b4b81a32 100644 --- a/packages/core/test/acceptance/discover_utils_spec.ts +++ b/packages/core/test/acceptance/discover_utils_spec.ts @@ -6,10 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ import {CommonModule} from '@angular/common'; -import {Component, Directive, HostBinding, InjectionToken, ViewChild} from '@angular/core'; -import {ChangeDetectionStrategy} from '@angular/core/src/change_detection'; +import {ChangeDetectionStrategy, Component, Directive, HostBinding, InjectionToken, Input, Output, ViewChild, ViewEncapsulation} from '@angular/core'; import {EventEmitter} from '@angular/core/src/event_emitter'; -import {Input, Output, ViewEncapsulation} from '@angular/core/src/metadata'; import {isLView} from '@angular/core/src/render3/interfaces/type_checks'; import {CONTEXT} from '@angular/core/src/render3/interfaces/view'; import {ComponentFixture, TestBed} from '@angular/core/testing'; diff --git a/packages/core/test/acceptance/text_spec.ts b/packages/core/test/acceptance/text_spec.ts index 952006c5a9a2..c08efd47a5e1 100644 --- a/packages/core/test/acceptance/text_spec.ts +++ b/packages/core/test/acceptance/text_spec.ts @@ -127,7 +127,8 @@ describe('text instructions', () => { fixture.detectChanges(); const div = fixture.nativeElement.querySelector('div'); - expect(div.innerHTML).toBe('function foo() { }'); + expect(div.innerHTML).toBe(fixture.componentInstance.test.toString()); + expect(div.innerHTML).toContain('foo'); }); it('should stringify an object using its toString method', () => { diff --git a/packages/core/test/acceptance/view_container_ref_spec.ts b/packages/core/test/acceptance/view_container_ref_spec.ts index 1baae1ea6bfc..f8ebadd50d91 100644 --- a/packages/core/test/acceptance/view_container_ref_spec.ts +++ b/packages/core/test/acceptance/view_container_ref_spec.ts @@ -8,8 +8,7 @@ import {CommonModule, DOCUMENT} from '@angular/common'; import {computeMsgId} from '@angular/compiler'; -import {Compiler, Component, ComponentFactoryResolver, Directive, DoCheck, ElementRef, EmbeddedViewRef, ErrorHandler, InjectionToken, Injector, NgModule, NgModuleRef, NO_ERRORS_SCHEMA, OnDestroy, OnInit, Pipe, PipeTransform, QueryList, RendererFactory2, RendererType2, Sanitizer, TemplateRef, ViewChild, ViewChildren, ViewContainerRef, ɵsetDocument} from '@angular/core'; -import {Input} from '@angular/core/src/metadata'; +import {Compiler, Component, ComponentFactoryResolver, Directive, DoCheck, ElementRef, EmbeddedViewRef, ErrorHandler, InjectionToken, Injector, Input, NgModule, NgModuleRef, NO_ERRORS_SCHEMA, OnDestroy, OnInit, Pipe, PipeTransform, QueryList, RendererFactory2, RendererType2, Sanitizer, TemplateRef, ViewChild, ViewChildren, ViewContainerRef, ɵsetDocument} from '@angular/core'; import {ngDevModeResetPerfCounters} from '@angular/core/src/util/ng_dev_mode'; import {ComponentFixture, TestBed, TestComponentRenderer} from '@angular/core/testing'; import {clearTranslations, loadTranslations} from '@angular/localize'; diff --git a/packages/core/test/animation/animations_with_web_animations_integration_spec.ts b/packages/core/test/animation/animations_with_web_animations_integration_spec.ts index a4f1f526654b..c38ae02d3a69 100644 --- a/packages/core/test/animation/animations_with_web_animations_integration_spec.ts +++ b/packages/core/test/animation/animations_with_web_animations_integration_spec.ts @@ -249,7 +249,8 @@ describe('animation integration tests using web animations', function() { overflow:hidden; } .list .inner { - line-height:50px; + box-sizing: border-box; + height: 50px; } `], template: ` diff --git a/packages/core/test/debug/debug_node_spec.ts b/packages/core/test/debug/debug_node_spec.ts index f9f4427f4f34..41360e75a6ce 100644 --- a/packages/core/test/debug/debug_node_spec.ts +++ b/packages/core/test/debug/debug_node_spec.ts @@ -8,8 +8,7 @@ import {CommonModule, NgIfContext, ɵgetDOM as getDOM} from '@angular/common'; -import {Component, DebugElement, DebugNode, Directive, ElementRef, EmbeddedViewRef, EventEmitter, HostBinding, Injectable, Input, NO_ERRORS_SCHEMA, OnInit, Output, Renderer2, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core'; -import {NgZone} from '@angular/core/src/zone'; +import {Component, DebugElement, DebugNode, Directive, ElementRef, EmbeddedViewRef, EventEmitter, HostBinding, Injectable, Input, NgZone, NO_ERRORS_SCHEMA, OnInit, Output, Renderer2, TemplateRef, ViewChild, ViewContainerRef} from '@angular/core'; import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing'; import {By} from '@angular/platform-browser/src/dom/debug/by'; import {createMouseEvent, hasClass} from '@angular/platform-browser/testing/src/browser_util'; diff --git a/packages/core/test/directive_lifecycle_integration_spec.ts b/packages/core/test/directive_lifecycle_integration_spec.ts index 1bddcba6c7e0..b9408fae4ef2 100644 --- a/packages/core/test/directive_lifecycle_integration_spec.ts +++ b/packages/core/test/directive_lifecycle_integration_spec.ts @@ -6,8 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, DoCheck, OnChanges, OnInit} from '@angular/core'; -import {Component, Directive} from '@angular/core/src/metadata'; +import {AfterContentChecked, AfterContentInit, AfterViewChecked, AfterViewInit, Component, Directive, DoCheck, OnChanges, OnInit} from '@angular/core'; import {inject, TestBed} from '@angular/core/testing'; import {Log} from '@angular/core/testing/src/testing_internal'; diff --git a/packages/core/test/linker/integration_spec.ts b/packages/core/test/linker/integration_spec.ts index 0d7863351db7..75c5afa52cfd 100644 --- a/packages/core/test/linker/integration_spec.ts +++ b/packages/core/test/linker/integration_spec.ts @@ -7,7 +7,7 @@ */ import {CommonModule, DOCUMENT, ɵgetDOM as getDOM} from '@angular/common'; -import {Compiler, ComponentFactory, ComponentRef, EventEmitter, Host, Inject, Injectable, InjectionToken, Injector, NgModule, NgModuleRef, NO_ERRORS_SCHEMA, OnDestroy, SkipSelf, ViewChild, ViewRef} from '@angular/core'; +import {Attribute, Compiler, Component, ComponentFactory, ComponentRef, ContentChildren, Directive, EventEmitter, Host, HostBinding, HostListener, Inject, Injectable, InjectionToken, Injector, Input, NgModule, NgModuleRef, NO_ERRORS_SCHEMA, OnDestroy, Output, Pipe, SkipSelf, ViewChild, ViewRef} from '@angular/core'; import {ChangeDetectionStrategy, ChangeDetectorRef, PipeTransform} from '@angular/core/src/change_detection/change_detection'; import {ComponentFactoryResolver} from '@angular/core/src/linker/component_factory_resolver'; import {ElementRef} from '@angular/core/src/linker/element_ref'; @@ -15,7 +15,6 @@ import {QueryList} from '@angular/core/src/linker/query_list'; import {TemplateRef} from '@angular/core/src/linker/template_ref'; import {ViewContainerRef} from '@angular/core/src/linker/view_container_ref'; import {EmbeddedViewRef} from '@angular/core/src/linker/view_ref'; -import {Attribute, Component, ContentChildren, Directive, HostBinding, HostListener, Input, Output, Pipe} from '@angular/core/src/metadata'; import {fakeAsync, getTestBed, TestBed, tick, waitForAsync} from '@angular/core/testing'; import {createMouseEvent, dispatchEvent, el, isCommentNode} from '@angular/platform-browser/testing/src/browser_util'; import {expect} from '@angular/platform-browser/testing/src/matchers'; diff --git a/packages/core/test/render3/i18n_debug_spec.ts b/packages/core/test/render3/i18n_debug_spec.ts index 5d1f2d7766d6..5ddcf7151fdc 100644 --- a/packages/core/test/render3/i18n_debug_spec.ts +++ b/packages/core/test/render3/i18n_debug_spec.ts @@ -29,6 +29,13 @@ describe('i18n debug', () => { }); it('should print Attribute opCode', () => { + // The `sanitizeFn` is written as actual function, compared to it being an arrow function. + // This is done to make this test less reluctant to build process changes where e.g. an + // arrow function might be transformed to a function declaration in ES5. + const sanitizeFn = function(v: any) { + return v; + }; + expect(i18nUpdateOpCodesToString([ 0b01, 8, 'pre ', -4, @@ -39,11 +46,12 @@ describe('i18n debug', () => { 'pre ', -4, ' in ', -3, ' post', 1 << I18nUpdateOpCode.SHIFT_REF | I18nUpdateOpCode.Attr, - 'title', (v: any) => v, + 'title', sanitizeFn, ] as unknown as I18nUpdateOpCodes)) .toEqual([ 'if (mask & 0b1) { (lView[1] as Element).setAttribute(\'title\', `pre ${lView[i-4]} in ${lView[i-3]} post`); }', - 'if (mask & 0b10) { (lView[1] as Element).setAttribute(\'title\', (function (v) { return v; })(`pre ${lView[i-4]} in ${lView[i-3]} post`)); }' + `if (mask & 0b10) { (lView[1] as Element).setAttribute('title', (${ + sanitizeFn.toString()})(\`pre $\{lView[i-4]} in $\{lView[i-3]} post\`)); }` ]); }); diff --git a/packages/core/test/render3/ivy/jit_spec.ts b/packages/core/test/render3/ivy/jit_spec.ts index c26f12478af8..d1a0bfd6f7d5 100644 --- a/packages/core/test/render3/ivy/jit_spec.ts +++ b/packages/core/test/render3/ivy/jit_spec.ts @@ -7,14 +7,10 @@ */ import 'reflect-metadata'; -import {ElementRef, QueryList} from '@angular/core'; +import {Component, ContentChild, ContentChildren, Directive, ElementRef, HostBinding, HostListener, Input, NgModule, Pipe, QueryList, ViewChild, ViewChildren, ɵNgModuleDef as NgModuleDef} from '@angular/core'; import {Injectable} from '@angular/core/src/di/injectable'; import {setCurrentInjector, ɵɵinject} from '@angular/core/src/di/injector_compatibility'; import {ɵɵdefineInjectable, ɵɵInjectorDef} from '@angular/core/src/di/interface/defs'; -import {ContentChild, ContentChildren, ViewChild, ViewChildren} from '@angular/core/src/metadata/di'; -import {Component, Directive, HostBinding, HostListener, Input, Pipe} from '@angular/core/src/metadata/directives'; -import {NgModule} from '@angular/core/src/metadata/ng_module'; -import {NgModuleDef} from '@angular/core/src/metadata/ng_module_def'; import {FactoryFn} from '@angular/core/src/render3/definition_factory'; import {ComponentDef, PipeDef} from '@angular/core/src/render3/interfaces/definition'; diff --git a/packages/router/test/router_preloader.spec.ts b/packages/router/test/router_preloader.spec.ts index 94d5c620b6ec..03dc0c2f6ab7 100644 --- a/packages/router/test/router_preloader.spec.ts +++ b/packages/router/test/router_preloader.spec.ts @@ -7,7 +7,6 @@ */ import {Compiler, Component, Injector, NgModule, NgModuleFactory, NgModuleRef, Type} from '@angular/core'; -import {resolveComponentResources} from '@angular/core/src/metadata/resource_loading'; import {fakeAsync, inject, TestBed, tick} from '@angular/core/testing'; import {PreloadAllModules, PreloadingStrategy, RouterPreloader} from '@angular/router'; import {BehaviorSubject, Observable, of, throwError} from 'rxjs'; diff --git a/packages/tsconfig-legacy-saucelabs.json b/packages/tsconfig-legacy-saucelabs.json index ec661240ab6f..7d73f05d065d 100644 --- a/packages/tsconfig-legacy-saucelabs.json +++ b/packages/tsconfig-legacy-saucelabs.json @@ -1,13 +1,37 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "target": "ES5", - "module": "commonjs", + "outDir": "../dist/legacy-test-out", + "target": "ES2015", + "module": "ES2020", + "importHelpers": true, // The project uses Bazel for TypeScript compilation. Unlike with Bazel, we build all // sources as part of a single TypeScript compilation. This results in `@internal` // declarations not being omitted between the logical as defined per the Bazel targets. // This can cause issues where the `override` keyword is needed for the legacy TS // compilation, but not within Bazel where the overridden member has `@internal`. - "noImplicitOverride": false - } + "noImplicitOverride": false, + // We run the decorator downlevel transform when compiling the sources and tests. + // Given that is the case, we do not need additional `design` metadata being emitted. + // The default TS decorator metadata would also not work with ES2015 JIT. + // https://github.com/angular/angular/issues/30106. + "emitDecoratorMetadata": false + }, + "exclude": [ + // Exclusions from the parent `tsconfig` need to be merged manually here. + "bazel", + "common/locales", + "compiler-cli/integrationtest", + "compiler-cli/test/compliance", + "core/schematics", + "elements/schematics", + "examples/**", + "http/**", + "platform-server/integrationtest", + "router/test/aot_ngsummary_test", + + // Additional exclusion since tests for the language-service never run within the + // Saucelabs job and the package is not compatible with ESM TS compilation anyway. + "language-service/**", + ] } diff --git a/packages/upgrade/static/test/integration/downgrade_module_spec.ts b/packages/upgrade/static/test/integration/downgrade_module_spec.ts index 8b314dfd7d5e..e930b3a357dd 100644 --- a/packages/upgrade/static/test/integration/downgrade_module_spec.ts +++ b/packages/upgrade/static/test/integration/downgrade_module_spec.ts @@ -622,7 +622,9 @@ withEachNg1Version(() => { angular.module_('ng1', [lazyModuleName]) .directive( 'ng2', downgradeComponent({component: Ng2AComponent, propagateDigest})) - .run(($rootScope: angular.IRootScopeService) => $rootScope.value = 0); + .run([ + '$rootScope', ($rootScope: angular.IRootScopeService) => $rootScope.value = 0 + ]); const element = html('
'); const $injector = angular.bootstrap(element, [ng1Module.name]); @@ -811,10 +813,13 @@ withEachNg1Version(() => { const ng1Module = angular.module_('ng1', [lazyModuleName]) .directive('ng2', downgradeComponent({component: Ng2Component, propagateDigest})) - .run(($rootScope: angular.IRootScopeService) => { - $rootScope.attrVal = 'bar'; - $rootScope.propVal = 'bar'; - }); + .run([ + '$rootScope', + ($rootScope: angular.IRootScopeService) => { + $rootScope.attrVal = 'bar'; + $rootScope.propVal = 'bar'; + } + ]); const element = html(''); const $injector = angular.bootstrap(element, [ng1Module.name]); diff --git a/test-main.js b/test-main.js deleted file mode 100644 index 6e8ca29aa7dc..000000000000 --- a/test-main.js +++ /dev/null @@ -1,213 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.io/license - */ - -// Tun on full stack traces in errors to help debugging -Error.stackTraceLimit = Infinity; - -jasmine.DEFAULT_TIMEOUT_INTERVAL = 15000; - -// Cancel Karma's synchronous start, -// we will call `__karma__.start()` later, once all the specs are loaded. -__karma__.loaded = function() {}; - -window.isNode = false; -window.isBrowser = true; - -System.config({ - baseURL: '/base', - defaultJSExtensions: true, - map: { - 'benchpress/*': 'dist/js/dev/es5/benchpress/*.js', - '@angular': 'dist/all/@angular', - 'domino': 'dist/all/@angular/empty.js', - 'url': 'dist/all/@angular/empty.js', - 'xhr2': 'dist/all/@angular/empty.js', - '@angular/platform-server/src/domino_adapter': 'dist/all/@angular/empty.js', - 'angular-in-memory-web-api': 'dist/all/@angular/misc/angular-in-memory-web-api', - 'rxjs': 'node_modules/rxjs', - }, - packages: { - '@angular/core/src/render3': {main: 'index.js', defaultExtension: 'js'}, - '@angular/core/testing': {main: 'index.js', defaultExtension: 'js'}, - '@angular/core': {main: 'index.js', defaultExtension: 'js'}, - '@angular/animations/browser/testing': {main: 'index.js', defaultExtension: 'js'}, - '@angular/animations/browser': {main: 'index.js', defaultExtension: 'js'}, - '@angular/animations/testing': {main: 'index.js', defaultExtension: 'js'}, - '@angular/animations': {main: 'index.js', defaultExtension: 'js'}, - '@angular/compiler/testing': {main: 'index.js', defaultExtension: 'js'}, - '@angular/compiler': {main: 'index.js', defaultExtension: 'js'}, - '@angular/common/testing': {main: 'index.js', defaultExtension: 'js'}, - '@angular/common/http/testing': {main: 'index.js', defaultExtension: 'js'}, - '@angular/common/http': {main: 'index.js', defaultExtension: 'js'}, - '@angular/common': {main: 'index.js', defaultExtension: 'js'}, - '@angular/forms': {main: 'index.js', defaultExtension: 'js'}, - '@angular/misc/angular-in-memory-web-api': {main: 'index.js', defaultExtension: 'js'}, - // remove after all tests imports are fixed - '@angular/facade': {main: 'index.js', defaultExtension: 'js'}, - '@angular/router/testing': {main: 'index.js', defaultExtension: 'js'}, - '@angular/router': {main: 'index.js', defaultExtension: 'js'}, - '@angular/localize/src/utils': {main: 'index.js', defaultExtension: 'js'}, - '@angular/localize/src/localize': {main: 'index.js', defaultExtension: 'js'}, - '@angular/localize/init': {main: 'index.js', defaultExtension: 'js'}, - '@angular/localize': {main: 'index.js', defaultExtension: 'js'}, - '@angular/upgrade/static/testing': {main: 'index.js', defaultExtension: 'js'}, - '@angular/upgrade/static': {main: 'index.js', defaultExtension: 'js'}, - '@angular/upgrade': {main: 'index.js', defaultExtension: 'js'}, - '@angular/platform-browser/animations/testing': {main: 'index.js', defaultExtension: 'js'}, - '@angular/platform-browser/animations': {main: 'index.js', defaultExtension: 'js'}, - '@angular/platform-browser/testing': {main: 'index.js', defaultExtension: 'js'}, - '@angular/platform-browser': {main: 'index.js', defaultExtension: 'js'}, - '@angular/platform-browser-dynamic/testing': {main: 'index.js', defaultExtension: 'js'}, - '@angular/platform-browser-dynamic': {main: 'index.js', defaultExtension: 'js'}, - '@angular/platform-server/init': {main: 'index.js', defaultExtension: 'js'}, - '@angular/platform-server/testing': {main: 'index.js', defaultExtension: 'js'}, - '@angular/platform-server': {main: 'index.js', defaultExtension: 'js'}, - '@angular/private/testing': {main: 'index.js', defaultExtension: 'js'}, - '@angular/elements': {main: 'index.js', defaultExtension: 'js'}, - 'rxjs/ajax': {main: 'index.js', defaultExtension: 'js'}, - 'rxjs/operators': {main: 'index.js', defaultExtension: 'js'}, - 'rxjs/testing': {main: 'index.js', defaultExtension: 'js'}, - 'rxjs/websocket': {main: 'index.js', defaultExtension: 'js'}, - 'rxjs': {main: 'index.js', defaultExtension: 'js'}, - } -}); - - -// Load browser-specific CustomElement polyfills, set up the test injector, import all the specs, -// execute their `main()` method and kick off Karma (Jasmine). -Promise - .resolve() - - // Load browser-specific polyfills for custom elements. - .then(function() { - return loadCustomElementsPolyfills(); - }) - - // Load necessary testing packages. - .then(function() { - return Promise.all([ - System.import('@angular/core/testing'), - System.import('@angular/platform-browser-dynamic/testing'), - System.import('@angular/platform-browser/animations') - ]); - }) - - // Set up the test injector. - .then(function(mods) { - var coreTesting = mods[0]; - var pbdTesting = mods[1]; - var pbAnimations = mods[2]; - - coreTesting.TestBed.initTestEnvironment( - [pbdTesting.BrowserDynamicTestingModule, pbAnimations.NoopAnimationsModule], - pbdTesting.platformBrowserDynamicTesting()); - }) - - // Import all the specs and execute their `main()` method. - .then(function() { - return Promise.all(Object - .keys(window.__karma__.files) // All files served by Karma. - .filter(onlySpecFiles) - .map(window.file2moduleName) // Normalize paths to module names. - .map(function(path) { - return System.import(path).then(function(module) { - if (module.hasOwnProperty('main')) { - throw new Error('main() in specs are no longer supported'); - } - }); - })); - }) - - // Kick off karma (Jasmine). - .then( - function() { - __karma__.start(); - }, - function(error) { - console.error(error); - }); - - -function loadCustomElementsPolyfills() { - // The custom elements polyfill will patch properties and methods on `(HTML)Element` and `Node` - // (among others), including `(HTML)Element#innerHTML` and `Node#removeChild()`: - // https://github.com/webcomponents/custom-elements/blob/4f7072c0dbda4beb505d16967acfffd33337b325/src/Patch/Element.js#L28-L73 - // https://github.com/webcomponents/custom-elements/blob/4f7072c0dbda4beb505d16967acfffd33337b325/src/Patch/Node.js#L105-L120 - // The patched `innerHTML` setter and `removeChild()` method will try to traverse the DOM (via - // `nextSibling` and `parentNode` respectively), which leads to infinite loops when testing - // `HtmlSanitizer` with cloberred elements on browsers that do not support the `