2018-05-01 13:40:35 -04:00
|
|
|
const path = require('path');
|
|
|
|
const glob = require('glob');
|
|
|
|
const chalk = require('chalk');
|
|
|
|
const webpack = require('webpack');
|
|
|
|
const argumentsParser = require('commander');
|
|
|
|
const webpackConfig = require('./webpack.config.js');
|
2019-04-25 05:48:54 -04:00
|
|
|
const IS_EE = require('./helpers/is_ee_env');
|
2018-05-01 13:40:35 -04:00
|
|
|
|
|
|
|
const ROOT_PATH = path.resolve(__dirname, '..');
|
2019-03-13 15:38:06 -04:00
|
|
|
const SPECS_PATH = /^(?:\.[\\\/])?(ee[\\\/])?spec[\\\/]javascripts[\\\/]/;
|
2018-05-01 13:40:35 -04:00
|
|
|
|
2019-05-10 08:14:53 -04:00
|
|
|
function exitError(message) {
|
2018-05-01 13:40:35 -04:00
|
|
|
console.error(chalk.red(`\nError: ${message}\n`));
|
|
|
|
process.exit(1);
|
|
|
|
}
|
2016-12-29 16:42:48 -05:00
|
|
|
|
2019-05-10 08:14:53 -04:00
|
|
|
function exitWarn(message) {
|
|
|
|
console.error(chalk.yellow(`\nWarn: ${message}\n`));
|
|
|
|
process.exit(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
function exit(message, isError = true) {
|
|
|
|
const fn = isError ? exitError : exitWarn;
|
|
|
|
|
|
|
|
fn(message);
|
|
|
|
}
|
|
|
|
|
2018-03-02 16:12:49 -05:00
|
|
|
// disable problematic options
|
|
|
|
webpackConfig.entry = undefined;
|
|
|
|
webpackConfig.mode = 'development';
|
2018-06-21 13:36:17 -04:00
|
|
|
webpackConfig.optimization.nodeEnv = false;
|
2018-03-02 16:12:49 -05:00
|
|
|
webpackConfig.optimization.runtimeChunk = false;
|
|
|
|
webpackConfig.optimization.splitChunks = false;
|
|
|
|
|
|
|
|
// use quicker sourcemap option
|
|
|
|
webpackConfig.devtool = 'cheap-inline-source-map';
|
2017-03-02 17:35:36 -05:00
|
|
|
|
2018-10-02 17:24:44 -04:00
|
|
|
// set BABEL_ENV to indicate when we're running code coverage
|
2018-10-01 23:09:43 -04:00
|
|
|
webpackConfig.plugins.push(
|
2018-10-02 16:12:04 -04:00
|
|
|
new webpack.DefinePlugin({
|
2018-10-02 17:24:44 -04:00
|
|
|
'process.env.BABEL_ENV': JSON.stringify(process.env.BABEL_ENV || process.env.NODE_ENV || null),
|
2019-03-08 11:59:15 -05:00
|
|
|
}),
|
2018-10-01 23:09:43 -04:00
|
|
|
);
|
|
|
|
|
2019-05-10 08:14:53 -04:00
|
|
|
const options = argumentsParser
|
|
|
|
.option('--no-fail-on-empty-test-suite')
|
2018-04-10 18:34:18 -04:00
|
|
|
.option(
|
|
|
|
'-f, --filter-spec [filter]',
|
|
|
|
'Filter run spec files by path. Multiple filters are like a logical OR.',
|
2018-05-01 13:40:35 -04:00
|
|
|
(filter, memo) => {
|
|
|
|
memo.push(filter, filter.replace(/\/?$/, '/**/*.js'));
|
2018-04-10 18:34:18 -04:00
|
|
|
return memo;
|
|
|
|
},
|
2019-03-08 11:59:15 -05:00
|
|
|
[],
|
2018-04-10 18:34:18 -04:00
|
|
|
)
|
2019-05-10 08:14:53 -04:00
|
|
|
.parse(process.argv);
|
|
|
|
|
|
|
|
const specFilters = options.filterSpec;
|
2018-04-10 05:12:24 -04:00
|
|
|
|
2019-03-13 15:38:06 -04:00
|
|
|
const createContext = (specFiles, regex, suffix) => {
|
|
|
|
const newContext = specFiles.reduce((context, file) => {
|
|
|
|
const relativePath = file.replace(SPECS_PATH, '');
|
|
|
|
context[file] = `./${relativePath}`;
|
|
|
|
return context;
|
|
|
|
}, {});
|
|
|
|
|
|
|
|
webpackConfig.plugins.push(
|
|
|
|
new webpack.ContextReplacementPlugin(regex, path.join(ROOT_PATH, suffix), newContext),
|
|
|
|
);
|
|
|
|
};
|
2018-05-01 13:40:35 -04:00
|
|
|
|
2019-03-13 15:38:06 -04:00
|
|
|
if (specFilters.length) {
|
2018-05-01 13:40:35 -04:00
|
|
|
// resolve filters
|
2020-12-23 16:10:24 -05:00
|
|
|
let filteredSpecFiles = specFilters.map((filter) =>
|
2018-05-01 13:40:35 -04:00
|
|
|
glob
|
|
|
|
.sync(filter, {
|
|
|
|
root: ROOT_PATH,
|
|
|
|
matchBase: true,
|
|
|
|
})
|
2020-12-23 16:10:24 -05:00
|
|
|
.filter((path) => path.endsWith('spec.js')),
|
2018-05-01 13:40:35 -04:00
|
|
|
);
|
|
|
|
|
|
|
|
// flatten
|
|
|
|
filteredSpecFiles = Array.prototype.concat.apply([], filteredSpecFiles);
|
|
|
|
|
|
|
|
// remove duplicates
|
|
|
|
filteredSpecFiles = [...new Set(filteredSpecFiles)];
|
|
|
|
|
|
|
|
if (filteredSpecFiles.length < 1) {
|
2019-05-10 08:14:53 -04:00
|
|
|
const isError = options.failOnEmptyTestSuite;
|
|
|
|
|
|
|
|
exit('Your filter did not match any test files.', isError);
|
2018-05-01 13:40:35 -04:00
|
|
|
}
|
|
|
|
|
2020-12-23 16:10:24 -05:00
|
|
|
if (!filteredSpecFiles.every((file) => SPECS_PATH.test(file))) {
|
2019-05-10 08:14:53 -04:00
|
|
|
exitError('Test files must be located within /spec/javascripts.');
|
2018-05-01 13:40:35 -04:00
|
|
|
}
|
|
|
|
|
2020-12-23 16:10:24 -05:00
|
|
|
const CE_FILES = filteredSpecFiles.filter((file) => !file.startsWith('ee'));
|
2019-03-13 15:38:06 -04:00
|
|
|
createContext(CE_FILES, /[^e]{2}[\\\/]spec[\\\/]javascripts$/, 'spec/javascripts');
|
2018-05-01 13:40:35 -04:00
|
|
|
|
2020-12-23 16:10:24 -05:00
|
|
|
const EE_FILES = filteredSpecFiles.filter((file) => file.startsWith('ee'));
|
2019-03-13 15:38:06 -04:00
|
|
|
createContext(EE_FILES, /ee[\\\/]spec[\\\/]javascripts$/, 'ee/spec/javascripts');
|
2018-05-01 13:40:35 -04:00
|
|
|
}
|
2017-12-21 18:01:51 -05:00
|
|
|
|
2016-12-29 16:42:48 -05:00
|
|
|
// Karma configuration
|
2020-12-23 07:10:26 -05:00
|
|
|
module.exports = function (config) {
|
2018-01-21 01:16:25 -05:00
|
|
|
process.env.TZ = 'Etc/UTC';
|
|
|
|
|
2019-07-17 18:47:33 -04:00
|
|
|
const fixturesPath = `tmp/tests/frontend/fixtures${IS_EE ? '-ee' : ''}`;
|
2019-07-18 15:11:09 -04:00
|
|
|
const staticFixturesPath = 'spec/frontend/fixtures/static';
|
2019-04-25 05:48:54 -04:00
|
|
|
|
2018-05-01 13:40:35 -04:00
|
|
|
const karmaConfig = {
|
2016-12-29 16:42:48 -05:00
|
|
|
basePath: ROOT_PATH,
|
2017-06-14 14:58:10 -04:00
|
|
|
browsers: ['ChromeHeadlessCustom'],
|
2018-09-11 17:03:05 -04:00
|
|
|
client: {
|
2018-10-02 16:12:04 -04:00
|
|
|
color: !process.env.CI,
|
2018-09-11 17:03:05 -04:00
|
|
|
},
|
2017-06-13 13:37:36 -04:00
|
|
|
customLaunchers: {
|
2017-06-14 14:58:10 -04:00
|
|
|
ChromeHeadlessCustom: {
|
2017-06-13 13:37:36 -04:00
|
|
|
base: 'ChromeHeadless',
|
2017-06-14 14:58:10 -04:00
|
|
|
displayName: 'Chrome',
|
|
|
|
flags: [
|
|
|
|
// chrome cannot run in sandboxed mode inside a docker container unless it is run with
|
|
|
|
// escalated kernel privileges (e.g. docker run --cap-add=CAP_SYS_ADMIN)
|
|
|
|
'--no-sandbox',
|
2019-05-15 19:44:11 -04:00
|
|
|
// https://bugs.chromium.org/p/chromedriver/issues/detail?id=2870
|
|
|
|
'--enable-features=NetworkService,NetworkServiceInProcess',
|
2017-06-14 14:58:10 -04:00
|
|
|
],
|
2018-03-23 12:52:54 -04:00
|
|
|
},
|
2017-06-13 13:37:36 -04:00
|
|
|
},
|
2017-01-06 18:21:54 -05:00
|
|
|
frameworks: ['jasmine'],
|
2016-12-29 16:42:48 -05:00
|
|
|
files: [
|
2017-01-07 02:38:36 -05:00
|
|
|
{ pattern: 'spec/javascripts/test_bundle.js', watched: false },
|
2019-07-17 18:47:33 -04:00
|
|
|
{ pattern: `${fixturesPath}/**/*`, included: false },
|
|
|
|
{ pattern: `${staticFixturesPath}/**/*`, included: false },
|
2016-12-29 16:42:48 -05:00
|
|
|
],
|
2019-07-17 18:47:33 -04:00
|
|
|
proxies: {
|
|
|
|
'/fixtures/': `/base/${fixturesPath}/`,
|
|
|
|
'/fixtures/static/': `/base/${staticFixturesPath}/`,
|
|
|
|
},
|
2016-12-29 16:42:48 -05:00
|
|
|
preprocessors: {
|
2017-03-15 19:31:01 -04:00
|
|
|
'spec/javascripts/**/*.js': ['webpack', 'sourcemap'],
|
2019-03-13 15:38:06 -04:00
|
|
|
'ee/spec/javascripts/**/*.js': ['webpack', 'sourcemap'],
|
2016-12-29 16:42:48 -05:00
|
|
|
},
|
2019-03-11 09:18:24 -04:00
|
|
|
reporters: ['mocha'],
|
2017-03-20 18:29:45 -04:00
|
|
|
webpack: webpackConfig,
|
|
|
|
webpackMiddleware: { stats: 'errors-only' },
|
2019-03-12 19:29:08 -04:00
|
|
|
plugins: [
|
|
|
|
'karma-chrome-launcher',
|
|
|
|
'karma-coverage-istanbul-reporter',
|
|
|
|
'karma-jasmine',
|
|
|
|
'karma-junit-reporter',
|
|
|
|
'karma-mocha-reporter',
|
|
|
|
'karma-sourcemap-loader',
|
|
|
|
'karma-webpack',
|
|
|
|
],
|
2017-03-20 18:29:45 -04:00
|
|
|
};
|
|
|
|
|
2018-09-11 17:03:05 -04:00
|
|
|
if (process.env.CI) {
|
2019-03-11 09:18:24 -04:00
|
|
|
karmaConfig.reporters.push('junit');
|
2018-09-11 17:03:05 -04:00
|
|
|
karmaConfig.junitReporter = {
|
|
|
|
outputFile: 'junit_karma.xml',
|
|
|
|
useBrowserName: false,
|
|
|
|
};
|
2019-03-12 19:29:08 -04:00
|
|
|
} else {
|
|
|
|
// ignore 404s in local environment because we are not fixing them and they bloat the log
|
|
|
|
function ignore404() {
|
|
|
|
return (request, response /* next */) => {
|
|
|
|
response.writeHead(404);
|
|
|
|
return response.end('NOT FOUND');
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
karmaConfig.middleware = ['ignore-404'];
|
|
|
|
karmaConfig.plugins.push({
|
|
|
|
'middleware:ignore-404': ['factory', ignore404],
|
|
|
|
});
|
2018-09-11 17:03:05 -04:00
|
|
|
}
|
|
|
|
|
2018-10-02 16:12:04 -04:00
|
|
|
if (process.env.BABEL_ENV === 'coverage' || process.env.NODE_ENV === 'coverage') {
|
2017-03-20 18:29:45 -04:00
|
|
|
karmaConfig.reporters.push('coverage-istanbul');
|
|
|
|
karmaConfig.coverageIstanbulReporter = {
|
2020-06-23 11:08:41 -04:00
|
|
|
reports: ['html', 'text-summary', 'cobertura'],
|
2017-02-10 13:29:03 -05:00
|
|
|
dir: 'coverage-javascript/',
|
|
|
|
subdir: '.',
|
2018-03-23 12:52:54 -04:00
|
|
|
fixWebpackSourcePaths: true,
|
2017-03-20 18:29:45 -04:00
|
|
|
};
|
2017-06-16 16:40:28 -04:00
|
|
|
karmaConfig.browserNoActivityTimeout = 60000; // 60 seconds
|
2017-03-20 18:29:45 -04:00
|
|
|
}
|
|
|
|
|
2017-06-14 14:58:10 -04:00
|
|
|
if (process.env.DEBUG) {
|
|
|
|
karmaConfig.logLevel = config.LOG_DEBUG;
|
|
|
|
process.env.CHROME_LOG_FILE = process.env.CHROME_LOG_FILE || 'chrome_debug.log';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (process.env.CHROME_LOG_FILE) {
|
|
|
|
karmaConfig.customLaunchers.ChromeHeadlessCustom.flags.push('--enable-logging', '--v=1');
|
|
|
|
}
|
|
|
|
|
2017-03-20 18:29:45 -04:00
|
|
|
config.set(karmaConfig);
|
2016-12-29 16:42:48 -05:00
|
|
|
};
|