How to include karma reporter without publishing it as npm package - karma-runner

I want to use a self-written karma reporter which, however, is not intended to be published as a separate npm module. After reading both documentation and source code I'm still having hard times to figure out how exactly this should be done.
From code I see now this is sort of hardcoded in that sense that there's a one-to-one correspondence between the name of the reporter (say, "somereporter") and the name of npm package karma tries to refer to - in this case it's gonna be karma-somereporter-reporter.

So, I finally figured it out. In order to add a local reported you need to include it as plugin, for instance:
module.exports = function (config) {
config.set({
plugins: [
require('../../MyReporter.js')
],
reporters: ['myreporter']
})
}

Related

Babel: root programmatic options

I seem to absolutely not grasp where to put root programmatic options for the babel.
If I have a monorepo and need to tell the different sub packages that they shall look upwards for my babel.config.js then I should put rootMode: "upwards" into the .babelrc of the sub packages, correct? This does not work, because of the resulting error
Error: .rootMode is only allowed in root programmatic options
Somehow I simply can't find any example of where to put/use root programmatic options... Can anyone point me to the right direction?
If you are using Webpack, you need to put it there.
module: {
[..]
rules: [
// Transpile ES6 Javascript into ES5 with babel loader
{
test: /\.jsx?$/,
exclude: [/node_modules/, /json/],
loader: 'babel-loader',
options: {
rootMode: 'upward'
},
},
[..]
],
[..]
},
Otherwise I had the same issue than you, I can't put it in the package.json file using the key babel.
Any API-related options are called programmatic options. Take a look at my discussion with the primary maintainer of Babel: https://github.com/babel/babel/discussions/14405.
It's when you specify them directly to Babel (babel.transformSync(code, programmaticOptions) or to the Babel integration you are using (e.g. babel-loader, which can pass them to its internal babel.transform call). In other words, not in presets or config files. [...]
by #nicolo-ribaudo - Babel core team.
I got this error using my (probably non-standard) monorepo setup where I have top-level subdirectories for each of my packages. No top-level package. When I upgraded to Babel 7, my Jest tests were no longer transforming packages that were yarn linked into the package where I was running Jest.
I added a top-level babel.config.js as part of Babel's monorepo instructions. I had rootMode: "upwards" in these three places:
ui-package/webpack.config.js for transforming the app.
ui-package/babel-jest.js for the tests, where it appeared like:
module.exports = require("babel-jest").createTransformer({
rootMode: "upward",
})
and was referenced from jest.config.js in that same dir like:
transform: {
"^.+\\.jsx?$": "./babel-jest.js",
},
And in /babel.config.js, the newly added top-level babel conf file.
Removing it from the last one removed the error.

Change what directory Babel plugins are resolved against?

I'm getting this error:
Unknown plugin "transform-class-properties" specified in "base" at 0, attempted to resolve relative to "/home/me/Projects/myproj/src"
The message is pretty clear, so I know why it's happening, but I want to change where Babel looks for the plugins/presets/packages.
I'm using Babel with rollup via rollup-plugin-babel.
The options I'm giving it are:
{ plugins: [ 'transform-class-properties', 'transform-object-rest-spread' ],
babelrc: false }
However, I can't find an option to change where Babel looks for the plugins. Is there no way to do this without rewriting my plugins list to use absolute paths?
I also can't find a public API method for extracting the dependencies from .babelrc, so it's pretty hard to manually rewrite the file to use full paths. N.B. Babel configs might also be stored in package.json, and there's been some talk about adding support for .babelrc.js too -- I really don't want to maintain my own project that searches for all the different places a babel config might be hiding, parse the file(s), and scan it for all the plugins, with and without the arbitrary babel-plugin- prefixes.
You can use NODE_PATH to do the same.
$ npx babel test.js
Unknown plugin "external-helpers" specified in "/Users/tarun.lalwani/Desktop/babeltest/.babelrc" at 0, attempted to resolve relative to "/Users/tarun.lalwani/Desktop/babeltest"
After specifying the path for modules in a different location
$ NODE_PATH=/Users/tarun.lalwani/Desktop/babeltest2/node_modules npx babel test.js
function test() {
this.abc = function (url) {
return console.log(url);
};
}
NODE_PATH environment variable allows you to specify additional locations where the modules can be searched for

babel-jest doesn't handle ES6 within modules

I am trying to set up Jest on a React based project which uses ES6 modules. However I seem to be having issues with ES6 modules, I am using babel-jest and believe I have this set up properly (Jest detects it automatically).
Jest doesn't seem to have a problem using ES6 imports however as soon as it hits on an import statement within one of the imported modules it chokes. It's as if it is only transpiling the initial test script and not any of the imported modules. I have tried various configurations and tried searching Google with no luck. Running tests without any imports works fine.
Here is the error:
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import Predications from './predications';
^^^^^^
SyntaxError: Unexpected token import
Here are the relevant bits of config:
jest.conf.json
{
"testRegex": "\/test\/spec\/.*\\.js$",
}
.babelrc
{
"presets": ["es2015", "stage-0", "react"]
}
Test script
import React from 'react';
import { mount, shallow } from 'enzyme';
import Slider from 'react-slick';
import Carousel from '../../client/components/carousel/carousel.js'; // test chokes on when I include this module
describe('carousel component', () => {
it('is a test test case', () => {
expect(1 + 2).toEqual(3);
});
});
Update:
As suggested, I have tried running the test without jest.conf.js, however the testRegex is needed in order for Jest to find my tests, I tried moving tests to the default test directory and they still fail.
I would like to clarify that tests themselves are running fine, the issue seems to be where one of my imported modules uses ES6, in my example above, if I don't import my carousel component the test runs fine, as soon as I import that the test chokes on the import statement within that file. It seems as though the imported modules are not getting transpiled.
Update #2
After some investigation it appears the issue is that babel is not transpiling ES6 within node_modules. I have created an example repo to demonstrate this here: https://github.com/jamiedust/babel-jest-example
I understand that third party modules should be handling their own transpiling, however we have a number of modules which are hosted on our own npm registry and are re-used between projects, in these cases Webpack handles transpiling, for the Jest tests we need these node_modules to be transpiled by Babel, or a way of leveraging our webpack set up to do this for us.
Solution
Add the following config in package.json (or Jest config file).
"jest": {
"transformIgnorePatterns": [
"/node_modules/(?!test-component).+\\.js$"
]
}
By default any code in node_modules is ignored by babel-jest, see the Jest config option transformIgnorePatterns. I've also created a PR on your example repo, so you can see it working.
While this works, I've found it to be extremely slow in real applications that have a lot of dependencies containing ES modules. The Jest codebase has a slightly different approach to this as you can find in babel-jest transforming dependencies. This can also take much longer on Windows, see Taking 10 seconds on an empty repo.
If doing "unit" testing, mocking is probably the better way to go.
You could try adding the transform-es2015-modules-commonjs plugin to your babel config file for testing only. Here is an example config file which tells babel to transpile modules only when in a testing environment. You can put it underneath your presets:
{
"presets": [
"react",
["es2015", {"modules": false, "loose": true}]
],
"env": {
"test": {
"plugins": ["transform-es2015-modules-commonjs"]
}
}
}
You can read about the plugin here:
https://www.npmjs.com/package/babel-plugin-transform-es2015-modules-commonjs
Then, when running your Jest tests on the command line specify NODE_ENV=test (you may need to add the --no-cache flag to the command the first time after making the change to the babel config because Jest caches babel output, but after that you can leave it off:
NODE_ENV=test jest --no-cache
I learned about this issue in a React seminar by Brian Holt at Frontend Masters. https://frontendmasters.com/courses/
faced the same issue, followed the steps to resolve,
install babel-jest
in jest config add this configuration
transform: {
'^.+\\.js?$': require.resolve('babel-jest')
}
make sure you have babel.config.js present (your config might be different than provided below)
module.exports = {
"env": {
"test": {
presets: [
[
'#babel/preset-env',
{
targets: {
node: 'current',
},
},
],
]
}
}
};
I faced the same problem (node_module not transpiled by babel-jest), without being able to solve it.
Instead, I finally succeed by mocking the node_module, like described here https://facebook.github.io/jest/docs/manual-mocks.html
NB: setting mocks in __mocks__ subfolders did not work for me. So I passed the mock as the second parameter of the jest.mock() function. Something like :
jest.mock('your_node_module', () => {})
Another possible cause. Babel now ignores your .babelrc inside node_modules and uses the one provided by the dependency. If you have control of the dependency you would have to add a .babelrc to it and babel would use those settings for it.
this can cause problems though if your dependency and your project use different babel versions or modules.

my coffeescript file compiles but mocha gives an error

I have a project that uses "coffee-script": "^1.7.1" in its package.json.
The code has this line in it:
[{id: id, name: name}, ...] = result.rows
This compiles fine using coffeescript version 1.7.1
The problem is that I am trying to use mocha for unit tests and it gives me an error on this line:
Parse error on line xyz: Unexpected '...'
Apparently mocha uses an older coffeescript. Is there a way to make it work without adjusting the source for mocha?
EDIT:
my Gruntfile.coffee:
'use strict'
module.exports = ->
#initConfig
cafemocha:
src: ['test/*.coffee']
options:
reporter: 'spec'
ui: 'bdd'
coffee:
compile:
files:
'lib/mylib.js': ['src/*.coffee']
#loadNpmTasks 'grunt-cafe-mocha'
#loadNpmTasks 'grunt-contrib-coffee'
#registerTask 'default', ['coffee', 'cafemocha']
I added mocha.opts to the test directory:
--require coffee-script/register
--compilers coffee:coffee-script/register
--reporter spec
--ui bdd
but, still, when I run grunt, it gives me the same error. I am new to this environment, and I find it too complicated, please help.
Starting from version 1.7.x CoffeeScript compiler should be explicitly registered (see change log for version 1.7.0).
So, the problem is that CoffeeScript compiler is not registered when you're running your mocha tests, so node.js treats all your .coffee files as .js files.
The best possible solution is to specify --compilers option for your mocha tests:
--compilers coffee:coffee-script/register
If you don't want to include it to every mocha call, you could set it up using mocha.opts file.
Here are some useful links:
issue about it on github
reference in mocha docs
the reason behind this breaking change in CoffeeScript engine
Update
Looks like your issue is much deeper then I thought.
First, grunt-cafe-mocha doesn't respect mocha.opts because it's running tests by requireing mocha as a dependency, instead of calling mocha test runner.
So, it would've been enough to add require('coffee-script/register') to the top of your gruntfile, if not for this old grunt issue.
In short, grunt uses coffee-script 1.3.x, forcing all its tasks to use the same version of coffee. I had the same problem with grunt-contrib-connect, being unable to use latest coffee-script in my express app.
So, the only help I can offer you is a small grunt task I wrote to solve similar problem in one of my projects. It runs mocha in a separate child process, thus completely isolating it from grunt.
N.B. I had a thought about releasing this task to npm, but considered it too minor.

Test coverage with Karma, browserify and Coffeescript

I'm having troubles to add test code coverage, I'm using Karma and files added to Karma are already bundled with browserify, so in karma.conf.coffee it looks like that:
files: [
{ pattern:'bin/public/client/app.js', served:yes: included:yes }
{ pattern:'src/lib/vendor/angular-mocks/angular-mocks.js', served:yes: included:yes }
{ pattern:'bin/tests.js', served:yes: included:no }
]
And that works for running the test, but not coverage
I'm using karma-coverage npm package, and this:
preprocessors: 'bin/public/client/app.js':['coverage']
reporters: ['progress','coverage']
Actually does create coverage stat files, but those are completely wrong, because it reddens parts that browserify brought from node_modules (because I don't have tests to cover those)
Ideally I have to gather source maps that browserify generates, and run coverage against those, but browserify embeds source maps into .js files. Using karma-sourcemap-loader lets me see original coffeescript files of tests, when debugging (for some reason it works only in ChromeCanary, nevertheless it works)
I tried to do preprocessors: 'src/client/**/*.coffee':['coverage'], but that yields no stats at all saying 'No data to display'
Do you have any ideas?
upd:
I've figured by running browserify-istanbul transform right after coffeeify and that gave me nice diagram like this:
Now, I need somehow to remove app.js from it, because really it doesn't matter and really confuses
upd:
Oh, instead of javascript I have to supply coffee files:
preprocessors : {
'bin/tests.js': ['sourcemap']
'src/client/**/*.coffee': ['coverage']
}
Seems I answered my own question. Also it seems there's a bug in current version of karma-coverage - it throws an error when coverageReporter.type is html (which is by default html). I'm glad I've figured it out. It's always nice to see how much code covered by tests