From c31b4fd94c298b81bb4a666e6dbcc1d672701a5b Mon Sep 17 00:00:00 2001 From: bryk Date: Mon, 8 Feb 2016 16:58:57 +0100 Subject: [PATCH] Run tests that require a browser on saucelabs (FF/Chrome/IE) Sample report from an integration test: https://saucelabs.com/beta/tests/7e6958fd51d44abfbb7a5e7a1efe132a/commands See, e.g., screencast that you can play or see history. --- .travis.yml | 12 ++++---- build/cluster.js | 2 +- build/conf.js | 11 ++++++++ build/karma.conf.js | 44 +++++++++++++++++++---------- build/protractor.conf.js | 60 ++++++++++++++++++++++++++++++++-------- build/test.js | 3 +- package.json | 1 + 7 files changed, 98 insertions(+), 35 deletions(-) diff --git a/.travis.yml b/.travis.yml index cfee884a7439..afc30c4960bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,16 +30,16 @@ language: node_js node_js: - 4.2.2 +addons: + # Run tests that require a browser on SauceLabs CI provider. Learn more at: https://saucelabs.com + sauce_connect: + username: k8s-dashboard-ci + access_key: "18b7e71b-60e9-4177-9a7f-e769977dbb39" + # Docker is required to set up a simple, single node Kubernetes cluster. # Local Docker-based cluster is the simplest way to create kubernetes on the host machine. services: - docker -before_script: - # Prepare environment for the Chrome browser. - - export CHROME_BIN=chromium-browser - - export DISPLAY=:99.0 - - sh -e /etc/init.d/xvfb start - script: ./node_modules/.bin/gulp check:local-cluster after_script: ./node_modules/.bin/gulp coverage-codecov-upload diff --git a/build/cluster.js b/build/cluster.js index a7731c4198a2..b405f13d9441 100644 --- a/build/cluster.js +++ b/build/cluster.js @@ -149,7 +149,7 @@ gulp.task('wait-for-cluster', function(doneFn) { // constantly query the cluster until it is properly running clusterHealthCheck(function(result) { - if (result === 'ok') { + if (result === 'ok' && isRunningSetIntervalHandler !== null) { gulpUtil.log(gulpUtil.colors.magenta('Kubernetes cluster is up and running.')); clearTimeout(isRunningSetIntervalHandler); isRunningSetIntervalHandler = null; diff --git a/build/conf.js b/build/conf.js index 83500d90709e..8eb2e8f4af34 100644 --- a/build/conf.js +++ b/build/conf.js @@ -85,6 +85,17 @@ export default { rootModuleName: 'kubernetesDashboard', }, + /** + * Configuration for tests. + */ + test: { + /** + * Whether to use sauce labs for running tests that require a browser. + */ + useSauceLabs: + !!process.env.SAUCE_USERNAME && !!process.env.SAUCE_ACCESS_KEY && !!process.env.TRAVIS, + }, + /** * Absolute paths to known directories, e.g., to source directory. */ diff --git a/build/karma.conf.js b/build/karma.conf.js index c0afd77c21c3..71a386fb5bcc 100644 --- a/build/karma.conf.js +++ b/build/karma.conf.js @@ -57,20 +57,9 @@ module.exports = function(config) { frameworks: ['jasmine', 'browserify'], - browsers: ['Chrome'], - browserNoActivityTimeout: 60 * 1000, // 60 seconds. - customLaunchers: { - // Custom launcher for Travis CI. It is required because Travis environment cannot use - // sandbox. - chromeTravis: { - base: 'Chrome', - flags: ['--no-sandbox'], - }, - }, - - reporters: ['progress', 'coverage'], + reporters: ['dots', 'coverage'], coverageReporter: { dir: conf.paths.coverage, @@ -89,6 +78,7 @@ module.exports = function(config) { 'karma-ng-html2js-preprocessor', 'karma-sourcemap-loader', 'karma-browserify', + 'karma-sauce-launcher', ], // karma-browserify plugin config. @@ -115,8 +105,34 @@ module.exports = function(config) { }; // Use custom browser configuration when running on Travis CI. - if (process.env.TRAVIS) { - configuration.browsers = ['chromeTravis']; + if (conf.test.useSauceLabs) { + configuration.reporters.push('saucelabs'); + + let testName; + if (process.env.TRAVIS) { + testName = `Karma tests ${process.env.TRAVIS_REPO_SLUG}, build ` + + `${process.env.TRAVIS_BUILD_NUMBER}`; + if (process.env.TRAVIS_PULL_REQUEST !== 'false') { + testName += `, PR: https://github.com/${process.env.TRAVIS_REPO_SLUG}/pull/` + + `${process.env.TRAVIS_PULL_REQUEST}`; + } + } else { + testName = 'Local karma tests'; + } + + configuration.sauceLabs = { + testName: testName, + connectOptions: {port: 5757, logfile: 'sauce_connect.log'}, + public: 'public', + }, + configuration.customLaunchers = { + sl_chrome: {base: 'SauceLabs', browserName: 'chrome'}, + sl_firefox: {base: 'SauceLabs', browserName: 'firefox'}, + sl_ie: {base: 'SauceLabs', browserName: 'internet explorer'}, + }; + configuration.browsers = Object.keys(configuration.customLaunchers); + } else { + configuration.browsers = ['Chrome']; } // Convert all JS code written ES6 with modules to ES5 bundles that browsers can digest. diff --git a/build/protractor.conf.js b/build/protractor.conf.js index 04c3e2e6d126..6d9de4eb9157 100644 --- a/build/protractor.conf.js +++ b/build/protractor.conf.js @@ -17,25 +17,61 @@ * * TODO(bryk): Start using ES6 modules in this file when supported. */ +/* eslint strict: [0] */ +'use strict'; require('babel-core/register'); const conf = require('./conf').default; const path = require('path'); /** - * Exported protractor config required by the framework. - * * Schema can be found here: https://github.com/angular/protractor/blob/master/docs/referenceConf.js + * @return {!Object} */ -exports.config = { - baseUrl: `http://localhost:${conf.frontend.serverPort}`, +function createConfig() { + const config = { + baseUrl: `http://localhost:${conf.frontend.serverPort}`, + + framework: 'jasmine', + + specs: [path.join(conf.paths.integrationTest, '**/*.js')], + }; + + if (conf.test.useSauceLabs) { + let name = `Integration tests ${process.env.TRAVIS_REPO_SLUG}, build ` + + `${process.env.TRAVIS_BUILD_NUMBER}`; + if (process.env.TRAVIS_PULL_REQUEST !== 'false') { + name += `, PR: https://github.com/${process.env.TRAVIS_REPO_SLUG}/pull/` + + `${process.env.TRAVIS_PULL_REQUEST}`; + } - capabilities: { - // Firefox is used instead of Chrome, because that's what Travis supports best. - // The browser that is used in the integration tests should not affect the results, anyway. - 'browserName': 'firefox', - }, + config.sauceUser = process.env.SAUCE_USERNAME; + config.sauceKey = process.env.SAUCE_ACCESS_KEY; + config.multiCapabilities = [ + { + 'browserName': 'chrome', + 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER, + 'name': name, + }, + { + 'browserName': 'firefox', + 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER, + 'name': name, + }, + { + 'browserName': 'internet explorer', + 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER, + 'name': name, + }, + ]; - framework: 'jasmine', + } else { + config.capabilities = {'browserName': 'chrome'}; + } - specs: [path.join(conf.paths.integrationTest, '**/*.js')], -}; + return config; +} + +/** + * Exported protractor config required by the framework. + */ +exports.config = createConfig(); diff --git a/build/test.js b/build/test.js index ec4172dff58f..4d4233f20b8b 100644 --- a/build/test.js +++ b/build/test.js @@ -138,8 +138,7 @@ gulp.task('integration-test:prod', ['serve:prod', 'webdriver-update'], runProtra * Runs application integration tests. Uses production version of the application. */ gulp.task( - 'local-cluster-integration-test:prod', ['serve:prod', 'webdriver-update', 'local-up-cluster'], - runProtractorTests); + 'local-cluster-integration-test:prod', ['serve:prod', 'local-up-cluster'], runProtractorTests); /** * Downloads and updates webdriver. Required to keep it up to date. diff --git a/package.json b/package.json index 94adaab82e09..06318a03eb1a 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "karma-coverage": "~0.5.3", "karma-jasmine": "~0.3.6", "karma-ng-html2js-preprocessor": "~0.2.0", + "karma-sauce-launcher": "^0.3.0", "karma-sourcemap-loader": "~0.3.6", "lodash": "~4.1.0", "proxy-middleware": "~0.15.0",