From 3c68d91e7512c0fff3dda9d6cc2007ec344a06fa Mon Sep 17 00:00:00 2001 From: Paul Gschwendtner Date: Wed, 14 Jun 2017 19:06:13 +0200 Subject: [PATCH] build: run chrome headless in travis * No longer runs Chrome inside of Saucelabs or Browserstack. * Chrome will now run directly in Travis in headless mode. --- .travis.yml | 5 ++- scripts/ci/env.sh | 20 ++++++----- scripts/ci/sources/mode.sh | 12 +++---- test/browser-providers.js | 68 ++++++++++++++++++++++---------------- test/karma.conf.js | 14 ++++---- test/remote_browsers.json | 6 ++-- 6 files changed, 71 insertions(+), 54 deletions(-) diff --git a/.travis.yml b/.travis.yml index 69bb84724129..bdb0dde978c5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: node_js sudo: false +dist: trusty node_js: - '--lts' @@ -9,6 +10,7 @@ addons: # SAUCE_ACCESS_KEY<=secret for FIREBASE_ACCESS_TOKEN to work around travis-ci/travis-ci#7223, unencrypted value in valentine as FIREBASE_ACCESS_TOKEN> # we alias FIREBASE_ACCESS_TOKEN to $SAUCE_ACCESS_KEY in env.sh and set the SAUCE_ACCESS_KEY there - secure: "PKts/IbxuJRWWOEeiGbl8Z9zds0M+hIdCH/g/E4WbQ9yzSvSbdwzfmRfFccQFjxjsrY7+SJMVjsURZy+xUyBpzqgWYHUItnSVqjZb8DlyAU2IXyg8TM9BVLkGGe6k5k4PIFVmfMMMzQwWMM0X0W9w3oYmfHL5egxwSHvf9HIqLolLNXg8sqamIdS5d5KoCXf1c+oRjN/IMBktzNBR6N4OFOZQXVoepXNiIvTWAcTtOPBvFWdKP2n7RVioHKdm4a85aCUpDJp+LYGaLqiQZoRzmzfVTnAhTAPdd4ao5w/+jojrfZIHV55bqYF9rLnQMTneKsiyVNVYJzOLuxmARa/EEKfZld+J3rX4/o4cogrU38YSZF+T7J9g/7CTsnIZ3F6W6m+8iJbIBh55nGOQi5PVe458Q/nGb3fgQd2Z4+6lK9k479H4Ssh/Y7hbVQbepqEVIXzZKqWX6/ZE4iWoR/Q2dm0hySFmmB/R2etixX5JxhnHvgobTYIQ+1liJVp/3YFW1ru64Yg6yz/V291Bhh9g31znmTROCJ/usAmZZaLUqW1TDKnLIMP+M74MF9XERqcWKywXRFwxP4E5uDnx/vAyN49gL+SDfrBUxUtXrTkKZAlglwo9SgA7cOYEPWrionvKcGm87gCBYHFUmXZNQVzh212fpuJYXb/vy0sPDj8La4=" + chrome: stable branches: only: @@ -17,13 +19,14 @@ branches: jobs: include: - env: "MODE=lint" - - env: "MODE=e2e" - env: "MODE=aot" - env: "MODE=payload" - env: "MODE=prerender" - env: "MODE=closure-compiler" + - env: "MODE=e2e" - env: "MODE=saucelabs_required" - env: "MODE=browserstack_required" + - env: "MODE=travis_required" - stage: Deploy script: ./scripts/ci/publish-artifacts.sh env: "MODE=release" diff --git a/scripts/ci/env.sh b/scripts/ci/env.sh index d981c4625818..465457f73edd 100644 --- a/scripts/ci/env.sh +++ b/scripts/ci/env.sh @@ -1,12 +1,14 @@ -#!/usr/bin/env bash +#!/bin/bash +if [[ -z "${TRAVIS}" ]]; then + echo "This script can only setup the environment inside of Travis builds" + exit 0 +fi -if [[ ${TRAVIS:-} ]]; then - # If FIREBASE_ACCESS_TOKEN not set yet, export the FIREBASE_ACCESS_TOKEN using the JWT token that Travis generated and exported for SAUCE_ACCESS_KEY. - # This is a workaround for travis-ci/travis-ci#7223 - # WARNING: FIREBASE_ACCESS_TOKEN should NOT be printed - export FIREBASE_ACCESS_TOKEN=${FIREBASE_ACCESS_TOKEN:-$SAUCE_ACCESS_KEY} +# If FIREBASE_ACCESS_TOKEN not set yet, export the FIREBASE_ACCESS_TOKEN using the JWT token that Travis generated and exported for SAUCE_ACCESS_KEY. +# This is a workaround for travis-ci/travis-ci#7223 +# WARNING: FIREBASE_ACCESS_TOKEN should NOT be printed +export FIREBASE_ACCESS_TOKEN=${FIREBASE_ACCESS_TOKEN:-$SAUCE_ACCESS_KEY} - # - we overwrite the value set by Travis JWT addon here to work around travis-ci/travis-ci#7223 for FIREBASE_ACCESS_TOKEN - export SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987 -fi +# - we overwrite the value set by Travis JWT addon here to work around travis-ci/travis-ci#7223 for FIREBASE_ACCESS_TOKEN +export SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987 diff --git a/scripts/ci/sources/mode.sh b/scripts/ci/sources/mode.sh index b4090a2f202e..6b40a7f5e68b 100644 --- a/scripts/ci/sources/mode.sh +++ b/scripts/ci/sources/mode.sh @@ -2,27 +2,27 @@ source ./scripts/ci/sources/tunnel.sh is_e2e() { - [[ "$MODE" = e2e ]] + [[ "${MODE}" = e2e ]] } is_lint() { - [[ "$MODE" = lint ]] + [[ "${MODE}" = lint ]] } is_aot() { - [[ "$MODE" = aot ]] + [[ "${MODE}" = aot ]] } is_closure_compiler() { - [[ "$MODE" = closure-compiler ]] + [[ "${MODE}" = closure-compiler ]] } is_payload() { - [[ "$MODE" = payload ]] + [[ "${MODE}" = payload ]] } is_unit() { - [[ "$MODE" = saucelabs_required || "$MODE" = browserstack_required ]] + [[ "${MODE}" =~ ^.*_(optional|required)$ ]] } is_prerender() { diff --git a/test/browser-providers.js b/test/browser-providers.js index a857454c38a4..e181fdcc3acf 100644 --- a/test/browser-providers.js +++ b/test/browser-providers.js @@ -2,32 +2,32 @@ /* * Browser Configuration for the different jobs in the CI. - * Target can be either: BS (Browserstack) | SL (Saucelabs) | null (To not run at all) + * Target can be either: BS (Browserstack) | SL (Saucelabs) | TC (Travis CI) | null (To not run) */ const browserConfig = { - 'Chrome': { unitTest: {target: 'BS', required: true }}, - 'Firefox': { unitTest: {target: 'BS', required: true }}, - 'ChromeBeta': { unitTest: {target: null, required: false }}, - 'FirefoxBeta': { unitTest: {target: null, required: false }}, - 'ChromeDev': { unitTest: {target: null, required: true }}, - 'FirefoxDev': { unitTest: {target: null, required: true }}, - 'IE9': { unitTest: {target: null, required: false }}, - 'IE10': { unitTest: {target: null, required: true }}, - 'IE11': { unitTest: {target: 'SL', required: true }}, - 'Edge': { unitTest: {target: 'SL', 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: 'SL', required: true }}, - 'Safari10': { unitTest: {target: 'BS', required: true }}, - 'iOS7': { unitTest: {target: null, required: false }}, - 'iOS8': { unitTest: {target: null, required: false }}, - 'iOS9': { unitTest: {target: 'BS', required: true }}, - 'WindowsPhone': { unitTest: {target: null, required: false }} + 'ChromeHeadless_CI': { unitTest: {target: 'TC', required: true }}, + 'Firefox': { unitTest: {target: 'BS', required: true }}, + 'ChromeBeta': { unitTest: {target: null, required: false }}, + 'FirefoxBeta': { unitTest: {target: null, required: false }}, + 'ChromeDev': { unitTest: {target: null, required: true }}, + 'FirefoxDev': { unitTest: {target: null, required: true }}, + 'IE9': { unitTest: {target: null, required: false }}, + 'IE10': { unitTest: {target: null, required: true }}, + 'IE11': { unitTest: {target: 'SL', required: true }}, + 'Edge': { unitTest: {target: 'SL', 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: 'SL', required: true }}, + 'Safari10': { unitTest: {target: 'BS', required: true }}, + 'iOS7': { unitTest: {target: null, required: false }}, + 'iOS8': { unitTest: {target: null, required: false }}, + 'iOS9': { unitTest: {target: 'BS', required: true }}, + 'WindowsPhone': { unitTest: {target: null, required: false }} }; /** Exports all available remote browsers. */ @@ -43,14 +43,26 @@ exports.platformMap = { required: buildConfiguration('unitTest', 'BS', true), optional: buildConfiguration('unitTest', 'BS', false) }, + 'travis': { + required: buildConfiguration('unitTest', 'TC', true), + optional: buildConfiguration('unitTest', 'TC', false) + } }; /** Build a list of configuration (custom launcher names). */ function buildConfiguration(type, target, required) { - return Object.keys(browserConfig) - .map(item => [item, browserConfig[item][type]]) - .filter(([, conf]) => conf.required === required && conf.target === target) - .map(([item]) => `${target}_${item.toUpperCase()}`); + const targetBrowsers = Object.keys(browserConfig) + .map(browserName => [browserName, browserConfig[browserName][type]]) + .filter(([, config]) => config.required === required && 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') { + return targetBrowsers; + } + + return targetBrowsers.map(browserName => `${target}_${browserName.toUpperCase()}`); } /** Decode the token for Travis to use. */ diff --git a/test/karma.conf.js b/test/karma.conf.js index edb466bd453a..5e22ca0099ad 100644 --- a/test/karma.conf.js +++ b/test/karma.conf.js @@ -92,7 +92,7 @@ module.exports = (config) => { }); if (process.env['TRAVIS']) { - let buildId = `TRAVIS #${process.env.TRAVIS_BUILD_NUMBER} (${process.env.TRAVIS_BUILD_ID})`; + const buildId = `TRAVIS #${process.env.TRAVIS_BUILD_NUMBER} (${process.env.TRAVIS_BUILD_ID})`; if (process.env['TRAVIS_PULL_REQUEST'] === 'false' && process.env['MODE'] === "browserstack_required") { @@ -102,10 +102,10 @@ module.exports = (config) => { } // The MODE variable is the indicator of what row in the test matrix we're running. - // It will look like _, where platform is one of 'saucelabs' or 'browserstack', - // and alias is one of the keys in the CI configuration variable declared in - // browser-providers.ts. - let [platform, alias] = process.env.MODE.split('_'); + // 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('_'); if (platform === 'saucelabs') { config.sauceLabs.build = buildId; @@ -113,10 +113,10 @@ module.exports = (config) => { } else if (platform === 'browserstack') { config.browserStack.build = buildId; config.browserStack.tunnelIdentifier = process.env.TRAVIS_JOB_ID; - } else { + } else if (platform !== 'travis') { throw new Error(`Platform "${platform}" unknown, but Travis specified. Exiting.`); } - config.browsers = platformMap[platform][alias.toLowerCase()]; + config.browsers = platformMap[platform][target.toLowerCase()]; } }; diff --git a/test/remote_browsers.json b/test/remote_browsers.json index 75858361a590..83816d2adfa2 100644 --- a/test/remote_browsers.json +++ b/test/remote_browsers.json @@ -1,8 +1,8 @@ { - "ChromeNoSandbox": { - "base": "Chrome", + "ChromeHeadless_CI": { + "base": "ChromeHeadless", "flags": [ - "--no-sandbox" + "--window-size=1024,768" ] }, "Chrome_1024x768": {