Skip to content

Commit a656ed7

Browse files
committed
wip
1 parent a391c9b commit a656ed7

File tree

5 files changed

+114
-30
lines changed

5 files changed

+114
-30
lines changed

package.json

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"bin": "dist/cli.js",
88
"scripts": {
99
"prepare": "npm t",
10-
"build": "microbundle --target node --external all -f cjs --no-compress src/*.js",
10+
"build": "microbundle --target node -f cjs --no-compress src/*.js",
1111
"test:build": "node ./dist/cli.js run",
1212
"test:watch": "node ./dist/cli.js watch --headless false",
1313
"test": "eslint src test && npm run -s build && npm run -s test:build",
@@ -30,26 +30,28 @@
3030
"devDependencies": {
3131
"eslint": "^4.16.0",
3232
"eslint-config-developit": "^1.1.1",
33-
"microbundle": "^0.4.3",
33+
"microbundle": "^0.11.0",
3434
"webpack": "^4.14.0",
35-
"workerize-loader": "^1.0.1"
35+
"workerize-loader": "^1.0.4"
3636
},
3737
"dependencies": {
38-
"babel-core": "^6.26.0",
39-
"babel-loader": "^7.1.2",
38+
"@babel/core": "^7.4.3",
39+
"@babel/plugin-proposal-object-rest-spread": "^7.4.3",
40+
"@babel/plugin-transform-react-jsx": "^7.3.0",
41+
"@babel/polyfill": "^7.4.3",
42+
"@babel/preset-env": "^7.4.3",
43+
"@babel/preset-stage-0": "^7.0.0",
44+
"babel-loader": "^8.0.5",
4045
"babel-plugin-istanbul": "^5.1.0",
41-
"babel-plugin-transform-object-rest-spread": "^6.26.0",
42-
"babel-plugin-transform-react-jsx": "^6.24.1",
43-
"babel-polyfill": "^6.26.0",
44-
"babel-preset-env": "^1.6.1",
45-
"babel-preset-stage-0": "^6.24.1",
4646
"chalk": "^2.3.0",
4747
"dlv": "^1.1.1",
4848
"jasmine-core": "^3.3.0",
4949
"karma": "^3.1.1",
5050
"karma-chrome-launcher": "^2.2.0",
5151
"karma-coverage": "^1.1.2",
52+
"karma-firefox-launcher": "^1.1.0",
5253
"karma-jasmine": "^2.0.1",
54+
"karma-sauce-launcher": "^2.0.2",
5355
"karma-sourcemap-loader": "^0.3.7",
5456
"karma-spec-reporter": "0.0.32",
5557
"karma-webpack": "2.0.7",

src/cli.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ import './lib/patch';
66
import karmatic from '.';
77
import { cleanStack } from './lib/util';
88

9+
// @ts-ignore
910
const { version } = require('../package.json');
1011

11-
let toArray = val => Array.isArray(val) ? val : val == null ? [] : [val];
12+
let toArray = val => typeof val === 'string' ? val.split(/\s*,\s*/) : val == null ? [] : [].concat(val);
1213

1314
let prog = sade('karmatic');
1415

@@ -32,6 +33,7 @@ prog
3233
.command('debug [...files]')
3334
.describe('Open a headful Puppeteer instance for debugging your tests')
3435
.option('--headless', 'Run using Chrome Headless', false) // Override default to false
36+
.option('--browsers', 'Run in specific browsers', null)
3537
.option('--coverage', 'Report code coverage of tests', false) // Override default to false
3638
.action( (str, opts) => run(str, opts, true) );
3739

@@ -40,6 +42,8 @@ prog.parse(process.argv);
4042
function run(str, opts, isWatch) {
4143
opts.watch = !!isWatch;
4244
opts.files = toArray(str || opts.files).concat(opts._);
45+
const b = opts.browsers || opts.browser;
46+
opts.browsers = b ? toArray(b) : null;
4347
karmatic(opts)
4448
.then( output => {
4549
if (output!=null) process.stdout.write(output + '\n');

src/configure.js

Lines changed: 78 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
import path from 'path';
22
import puppeteer from 'puppeteer';
3+
import chalk from 'chalk';
34
import delve from 'dlv';
4-
import { moduleDir, tryRequire, dedupe, cleanStack, readFile, readDir } from './lib/util';
5+
import { tryRequire, dedupe, cleanStack, readFile, readDir } from './lib/util';
56
import babelLoader from './lib/babel-loader';
67
import cssLoader from './lib/css-loader';
78

89
const WEBPACK_VERSION = String(require('webpack').version || '3.0.0');
9-
const WEBPACK_MAJOR = WEBPACK_VERSION.split('.')[0]|0;
10+
const WEBPACK_MAJOR = parseInt(WEBPACK_VERSION.split('.')[0], 10);
1011

12+
/**
13+
* @param {Object} options
14+
* @param {Array} options.files - Test files to run
15+
* @param {Array} [options.browsers] - Custom list of browsers to run in
16+
* @param {Boolean} [options.headless=false] - Run in Headless Chrome?
17+
* @param {Boolean} [options.watch=false] - Start a continuous test server and retest when files change
18+
* @param {Boolean} [options.coverage=false] - Instrument and collect code coverage statistics
19+
* @param {Object} [options.webpackConfig] - Custom webpack configuration
20+
*/
1121
export default function configure(options) {
1222
let cwd = process.cwd(),
1323
res = file => path.resolve(cwd, file);
@@ -17,7 +27,9 @@ export default function configure(options) {
1727

1828
process.env.CHROME_BIN = puppeteer.executablePath();
1929

20-
let gitignore = (readFile(path.resolve(cwd, '.gitignore'), 'utf8') || '').replace(/(^\s*|\s*$|#.*$)/g, '').split('\n').filter(Boolean);
30+
let gitignore = (
31+
readFile(path.resolve(cwd, '.gitignore')) || ''
32+
).replace(/(^\s*|\s*$|#.*$)/g, '').split('\n').filter(Boolean);
2133
let repoRoot = (readDir(cwd) || []).filter( c => c[0]!=='.' && c!=='node_modules' && gitignore.indexOf(c)===-1 );
2234
let rootFiles = '{' + repoRoot.join(',') + '}';
2335

@@ -31,6 +43,56 @@ export default function configure(options) {
3143
options.coverage ? 'karma-coverage' : []
3244
);
3345

46+
// Custom launchers to be injected:
47+
const launchers = {};
48+
let useSauceLabs = false;
49+
50+
let browsers;
51+
if (options.browsers) {
52+
browsers = options.browsers.map(browser => {
53+
if (/^chrome$/i.test(browser)) {
54+
return 'Chrome';
55+
}
56+
if (/^firefox$/i.test(browser)) {
57+
PLUGINS.push('karma-firefox-launcher');
58+
return 'Firefox';
59+
}
60+
if (/^sauce-/.test(browser)) {
61+
if (!useSauceLabs) {
62+
useSauceLabs = true;
63+
PLUGINS.push('karma-sauce-launcher');
64+
}
65+
const parts = browser.toLowerCase().split('-');
66+
const name = parts.join('_');
67+
launchers[name] = {
68+
base: 'SauceLabs',
69+
browserName: parts[1].replace(/^ie$/gi, 'Internet Explorer'),
70+
version: parts[2] || undefined,
71+
platform: parts[3] ? parts[3].replace(/^win(dows)?[ -]+/gi, 'Windows ').replace(/^(macos|mac ?os ?x|os ?x)[ -]+/gi, 'OS X ') : undefined
72+
};
73+
return name;
74+
}
75+
return browser;
76+
});
77+
}
78+
else {
79+
browsers = [options.headless===false ? 'KarmaticChrome' : 'KarmaticChromeHeadless'];
80+
}
81+
82+
if (useSauceLabs) {
83+
let missing = ['SAUCE_USERNAME', 'SAUCE_ACCESS_KEY'].filter(x => !process.env[x])[0];
84+
if (missing) {
85+
throw (
86+
'\n' +
87+
chalk.bold.bgRed.white('Error:') + ' Missing SauceLabs auth configuration.' +
88+
'\n ' + chalk.white(`A SauceLabs browser was requested, but no ${chalk.magentaBright(missing)} environment variable provided.`) +
89+
'\n ' + chalk.white('Try prepending it to your test command:') +
90+
' ' + chalk.greenBright(missing + '=... npm test') +
91+
'\n'
92+
);
93+
}
94+
}
95+
3496
const WEBPACK_CONFIGS = [
3597
'webpack.config.babel.js',
3698
'webpack.config.js'
@@ -109,22 +171,27 @@ export default function configure(options) {
109171

110172
let generatedConfig = {
111173
basePath: cwd,
112-
plugins: PLUGINS.map(require.resolve),
174+
plugins: PLUGINS.map(req => require.resolve(req)),
113175
frameworks: ['jasmine'],
114176
reporters: ['spec'].concat(
115-
options.coverage ? 'coverage' : []
177+
options.coverage ? 'coverage' : [],
178+
useSauceLabs ? 'saucelabs' : []
116179
),
117-
browsers: [options.headless===false ? 'KarmaticChrome' : 'KarmaticChromeHeadless'],
180+
browsers,
181+
sauceLabs: {
182+
testName: pkg && pkg.name || undefined
183+
},
118184

119-
customLaunchers: {
185+
customLaunchers: Object.assign({
120186
KarmaticChrome: {
121-
base: 'Chrome'
187+
base: 'Chrome',
188+
flags: ['--no-sandbox']
122189
},
123190
KarmaticChromeHeadless: {
124191
base: 'ChromeHeadless',
125192
flags: ['--no-sandbox']
126193
}
127-
},
194+
}, launchers),
128195

129196
coverageReporter: {
130197
reporters: [
@@ -149,7 +216,8 @@ export default function configure(options) {
149216
}],
150217

151218
files: [
152-
{ pattern: moduleDir('babel-polyfill')+'/dist/polyfill.js', watched: false, included: true, served: true }
219+
// @TODO remove me
220+
// { pattern: moduleDir('babel-polyfill')+'/dist/polyfill.js', watched: false, included: true, served: true }
153221
].concat( ...files.map( pattern => {
154222
// Expand '**/xx' patterns but exempt node_modules and gitignored directories
155223
let matches = pattern.match(/^\*\*\/(.+)$/);

src/lib/babel-loader.js

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,33 @@ export default function babelLoader(options) {
22
return {
33
test: /\.jsx?$/,
44
exclude: /node_modules/,
5-
loader: 'babel-loader',
5+
loader: require.resolve('babel-loader'),
66
query: {
77
presets: [
8-
[require.resolve('babel-preset-env'), {
8+
[require.resolve('@babel/preset-env'), {
99
targets: {
10-
browsers: 'last 2 Chrome versions'
10+
browsers: [
11+
'last 2 Chrome versions',
12+
'last 2 Firefox versions',
13+
options.browsers && String(options.browsers).match(/(\bie(\b|\d)|internet.explorer)/gi) && 'ie>=9'
14+
].filter(Boolean)
1115
},
16+
corejs: 2,
17+
useBuiltIns: 'usage',
1218
modules: false,
1319
loose: true
14-
}],
15-
require.resolve('babel-preset-stage-0')
20+
}]
1621
],
1722
plugins: [
18-
[require.resolve('babel-plugin-transform-object-rest-spread')],
19-
[require.resolve('babel-plugin-transform-react-jsx'), { pragma: options.pragma || 'h' }]
23+
[require.resolve('@babel/plugin-proposal-object-rest-spread'), {
24+
loose: true,
25+
useBuiltIns: true
26+
}],
27+
[require.resolve('@babel/plugin-transform-react-jsx'), {
28+
pragma: options.pragma || 'h'
29+
}]
2030
].concat(
21-
options.coverage ? require.resolve('babel-plugin-istanbul') : []
31+
options.coverage ? [require.resolve('babel-plugin-istanbul')] : []
2232
)
2333
}
2434
};

src/lib/css-loader.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
export default function cssLoader() {
1+
export default function cssLoader(options) {
22
return {
33
test: /\.css$/,
44
loader: 'style-loader!css-loader'

0 commit comments

Comments
 (0)