From 1b126181db24f06c4e54b998245004d698dda877 Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Mon, 15 Oct 2018 18:57:03 +0200 Subject: [PATCH] build: run chrome and firefox headless tests in circleci * Moves the `travis_required` TravisCI job to CircleCI. Our `ngcontainer` image already comes with Chrome and Firefox installed. --- .circleci/config.yml | 31 +++++++++++++- .travis.yml | 1 - package.json | 2 +- test/browser-providers.js | 85 +++++++++++++++++++-------------------- test/karma.conf.js | 9 ++++- 5 files changed, 78 insertions(+), 50 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 01f55518f382..038cf87e7657 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,6 +1,5 @@ # Configuration file for https://circleci.com/gh/angular/material2 -# # Note: YAML anchors allow an object to be re-used, reducing duplication. # The ampersand declares an alias for an object, then later the `<<: *name` # syntax dereferences it. @@ -81,6 +80,30 @@ jobs: - *save_cache + # ------------------------------------------------------------------------------------------ + # Job that runs the unit tests on locally installed browsers (Chrome and Firefox headless). + # The available browsers are installed through the angular/ngcontainer Docker image. + # ------------------------------------------------------------------------------------------ + tests_local_browsers: + docker: + # TODO(devversion): Temporarily use a image that includes Firefox 62 because the + # ngcontainer image does include an old Firefox version that does not support headless. + # See the PR that fixes this: https://github.com/angular/angular/pull/26435 + - image: circleci/node:10.12-browsers + resource_class: xlarge + environment: + TEST_PLATFORM: local + steps: + - *checkout_code + - *restore_cache + - *yarn_install + + # Launches the unit tests. The platform is determined by the "TEST_PLATFORM" environment + # variable which has been configured above + - run: yarn gulp ci:test + + - *save_cache + # ---------------------------------- # Lint job. Runs the gulp lint task. # ---------------------------------- @@ -91,7 +114,7 @@ jobs: - *restore_cache - *yarn_install - - run: yarn ci:lint + - run: yarn gulp ci:lint - *save_cache @@ -108,6 +131,10 @@ workflows: jobs: - bazel_build_test + unit_tests: + jobs: + - tests_local_browsers + # Lint workflow. As we want to lint in one job, this is a workflow with just one job. lint: jobs: diff --git a/.travis.yml b/.travis.yml index e980d6a40847..2c64bf0c5a17 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,6 @@ jobs: - env: "MODE=e2e" - env: "MODE=saucelabs_required" - env: "MODE=browserstack_required" - - env: "MODE=travis_required" - env: "DEPLOY_MODE=build-artifacts" if: type = push - env: "DEPLOY_MODE=docs-content" diff --git a/package.json b/package.json index ac2d7a73ee8d..3cb1e477b6a1 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "docs": "gulp docs", "api": "gulp api-docs", "breaking-changes": "gulp breaking-changes", - "ci:lint": "gulp ci:lint" + "gulp": "gulp" }, "version": "7.0.0-rc.1", "requiredAngularVersion": ">=7.0.0-rc.0", diff --git a/test/browser-providers.js b/test/browser-providers.js index 479e7b10504a..a97d3dcb1775 100644 --- a/test/browser-providers.js +++ b/test/browser-providers.js @@ -2,67 +2,64 @@ /* * Browser Configuration for the different jobs in the CI. - * Target can be either: BS (Browserstack) | SL (Saucelabs) | TC (Travis CI) | null (To not run) + * + * - local: Launches the browser locally on the current operating system. + * - BS: Launches the browser within BrowserStack + * - SL: Launches the browser within Saucelabs + * + * TODO(devversion): rename this to "browserstack" and "saucelabs". */ const browserConfig = { - 'ChromeHeadlessCI': { unitTest: {target: 'TC', required: true }}, - 'FirefoxHeadless': { unitTest: {target: 'TC', required: true }}, - 'ChromeBeta': { unitTest: {target: null, required: false }}, - 'FirefoxBeta': { unitTest: {target: null, required: false }}, - 'ChromeDev': { unitTest: {target: null, required: false }}, - 'FirefoxDev': { unitTest: {target: null, required: false }}, - 'IE9': { unitTest: {target: null, required: false }}, - 'IE10': { unitTest: {target: null, required: false }}, - 'IE11': { unitTest: {target: null, required: false }}, - 'Edge': { unitTest: {target: 'BS', required: true }}, - 'Android4.1': { unitTest: {target: null, required: false }}, - 'Android4.2': { unitTest: {target: null, required: false }}, - 'Android4.3': { unitTest: {target: null, required: false }}, - 'Android4.4': { unitTest: {target: null, required: false }}, - 'Android5': { unitTest: {target: null, required: false }}, - 'Safari7': { unitTest: {target: null, required: false }}, - 'Safari8': { unitTest: {target: null, required: false }}, - 'Safari9': { unitTest: {target: null, required: false }}, - 'Safari10': { unitTest: {target: 'BS', required: true }}, - 'iOS7': { unitTest: {target: null, required: false }}, - 'iOS8': { unitTest: {target: null, required: false }}, - 'iOS9': { unitTest: {target: null, required: false }}, - 'iOS10': { unitTest: {target: null, required: false }}, + 'ChromeHeadlessCI': { unitTest: {target: 'local', }}, + 'FirefoxHeadless': { unitTest: {target: 'local', }}, + 'ChromeBeta': { unitTest: {target: null, }}, + 'FirefoxBeta': { unitTest: {target: null, }}, + 'ChromeDev': { unitTest: {target: null, }}, + 'FirefoxDev': { unitTest: {target: null, }}, + 'IE9': { unitTest: {target: null, }}, + 'IE10': { unitTest: {target: null, }}, + 'IE11': { unitTest: {target: null, }}, + 'Edge': { unitTest: {target: 'BS', }}, + 'Android4.1': { unitTest: {target: null, }}, + 'Android4.2': { unitTest: {target: null, }}, + 'Android4.3': { unitTest: {target: null, }}, + 'Android4.4': { unitTest: {target: null, }}, + 'Android5': { unitTest: {target: null, }}, + 'Safari7': { unitTest: {target: null, }}, + 'Safari8': { unitTest: {target: null, }}, + 'Safari9': { unitTest: {target: null, }}, + 'Safari10': { unitTest: {target: 'BS', }}, + 'iOS7': { unitTest: {target: null, }}, + 'iOS8': { unitTest: {target: null, }}, + 'iOS9': { unitTest: {target: null, }}, + 'iOS10': { unitTest: {target: null, }}, // Don't use Browserstack until our open-source license includes automate testing on // mobile devices. For now, we need to use Saucelabs to keep our coverage. - 'iOS11': { unitTest: {target: 'SL', required: true }}, - 'WindowsPhone': { unitTest: {target: null, required: false }} + 'iOS11': { unitTest: {target: 'SL', }}, + 'WindowsPhone': { unitTest: {target: null, }} }; /** Exports all available remote browsers. */ exports.customLaunchers = require('./remote_browsers.json'); -/** Exports a map of configured browsers, which should run on the CI. */ +/** Exports a map of configured browsers, which should run in the given platform. */ exports.platformMap = { - 'saucelabs': { - required: buildConfiguration('unitTest', 'SL', true), - optional: buildConfiguration('unitTest', 'SL', false) - }, - 'browserstack': { - required: buildConfiguration('unitTest', 'BS', true), - optional: buildConfiguration('unitTest', 'BS', false) - }, - 'travis': { - required: buildConfiguration('unitTest', 'TC', true), - optional: buildConfiguration('unitTest', 'TC', false) - } + 'saucelabs': buildConfiguration('unitTest', 'SL'), + 'browserstack': buildConfiguration('unitTest', 'BS'), + 'local': buildConfiguration('unitTest', 'local'), }; /** Build a list of configuration (custom launcher names). */ -function buildConfiguration(type, target, required) { +function buildConfiguration(type, target) { const targetBrowsers = Object.keys(browserConfig) .map(browserName => [browserName, browserConfig[browserName][type]]) - .filter(([, config]) => config.required === required && config.target === target) + .filter(([, config]) => config.target === target) .map(([browserName]) => browserName); - // For browsers that run on Travis CI the browser name shouldn't be prefixed with the shortcut - // of Travis. The different Karma launchers only work with the plain browser name (e.g Firefox) - if (target === 'TC') { + // For browsers that run locally, the browser name shouldn't be prefixed with the target + // platform. We only prefix the external platforms in order to distinguish between + // local and remote browsers in our "customLaunchers" for Karma. + if (target === 'local') { return targetBrowsers; } diff --git a/test/karma.conf.js b/test/karma.conf.js index ef4c51259161..a8ae3f9b2e3c 100644 --- a/test/karma.conf.js +++ b/test/karma.conf.js @@ -100,6 +100,10 @@ module.exports = (config) => { }, }); + if (process.env['CIRCLECI']) { + config.browsers = platformMap[process.env['TEST_PLATFORM']]; + } + if (process.env['TRAVIS']) { const buildId = `TRAVIS #${process.env.TRAVIS_BUILD_NUMBER} (${process.env.TRAVIS_BUILD_ID})`; @@ -114,7 +118,8 @@ module.exports = (config) => { // It will look like _, where platform is one of 'saucelabs', 'browserstack' // or 'travis'. The target is a reference to different collections of browsers that can run // in the previously specified platform. - const [platform, target] = process.env.MODE.split('_'); + // TODO(devversion): when moving Saucelabs and Browserstack to Circle, remove the target part. + const [platform] = process.env.MODE.split('_'); if (platform === 'saucelabs') { config.sauceLabs.build = buildId; @@ -132,6 +137,6 @@ module.exports = (config) => { config.concurrency = 1; } - config.browsers = platformMap[platform][target.toLowerCase()]; + config.browsers = platformMap[platform]; } };