No coverage information is generated for vscode extension using nyc - node.js

To generate the code coverage report for vscode extension, i am using nyc and running those via vscode test runner.
Source : https://code.visualstudio.com/api/working-with-extensions/testing-extension
Project structure:
out
-test
-unit
-testcases.js
-index.js
- runTest.js
``
"test": "rm -rf .nyc_output/ && nyc node ./out/test/runTest.js",
"nyc": {
"extends": "#istanbuljs/nyc-config-typescript",
"require": [
"ts-node/register",
"source-map-support/register"
],
"report-dir": ".",
"reporter": [
"text",
"html",
"lcov"
],
"exclude": ["out/test/**"],
"include": [ "out/**/*.js" ],
"check-coverage": true
},
index.ts file:
import * as path from 'path';
import * as Mocha from 'mocha';
import * as glob from 'glob';
export function run(): Promise<void> {
const mocha = new Mocha({
ui: 'tdd',
color: true,
timeout: 20000,});
const testsRoot = path.resolve(__dirname, '../unit');
return new Promise((c, e) => {
glob('**/**.test.js', { cwd: testsRoot }, (err, files) => {
if (err) {
return e(err);
}
// Add files to the test suite
files.forEach(f => {
mocha.addFile(path.resolve(testsRoot, f));
});
try {
// Run the mocha test
mocha.run(failures => {
if (failures > 0) {
e(new Error(`${failures} tests failed.`));
} else {
c();
}
});
} catch (err) {
// eslint-disable-next-line no-console
console.error(err);
e(err);
}
});
});
}
runTest.ts file:
import * as path from 'path';
import { runTests } from 'vscode-test';
async function main() {
try {
// The folder containing the Extension Manifest package.json
// Passed to `--extensionDevelopmentPath`
const extensionDevelopmentPath = path.resolve(__dirname, '../../');
// The path to test runner
// Passed to --extensionTestsPath
//const extensionTestsPath = path.resolve(__dirname, './unit/index-coverage');
const extensionTestsPath = path.resolve(__dirname, './unit/index');
// Download VS Code, unzip it and run the integration test
await runTests({ extensionDevelopmentPath, extensionTestsPath });
} catch (err) {
//console.error('Failed to run tests');
process.exit(1);
}
}
main();
I was not able to generate code coverage report.It generates report but without any information.
What i am doing wrong here??

There are couple of ways to do this. I found some valuable information while checking below link:
How do a generate vscode TypeScript extension coverage report
Seems the easiest one is from user frenya. but the other two also gives valuable information.

Related

Unable to get jest to load a module (pdf.js) in a component test

I am building tests using jest that makes use of the pdf.js node library, but keep getting the following error due to jest not picking up the library properly
TypeError: Cannot set property 'workerSrc' of undefined
Here is pdfParser.js:
import * as pdfJs from 'pdfjs-dist/legacy/build/pdf'
import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'
pdfJs.GlobalWorkerOptions.workerSrc = pdfjsWorker
export const readPdf = async theFile => {
... (*it doesn't even get this far)
}
Here is my test (pdfParser.test.js):
import { readPdf } from '../../../../src/utils/pdfParser.js'
describe('PDF Parser', () => {
it('returns error when no file submitted', () => {
expect(1).toEqual(1)
})
})
I've tried setting the following in package.json
"jest": {
"moduleNameMapper": {
"pdfjs-dist": "<rootDir>/node_modules/pdfjs-dist/legacy/build/pdf.js"
},
"moduleDirectories": [
".",
"src",
"src/util",
"node_modules"
]
What am I doing wrong?

Problems initiating Web API File object in test with Babel and Jest

While trying to upgrade babel to v7 in an existing test setup with Jest and Enzyme, I have encountered a problem where Web API File is empty. Although it responds to methods like myFile.name.
Packages used:
babel => 7.6.4
jest => 24.9.0
babel-jest => 24.9.0
Not really an expert with babel, but this is my config
Babe config
const env = process.env.NODE_ENV;
const isProd = () => env === 'production';
const isDev = () => env === 'development';
const isTest = () => env === 'test';
const babelPresetEnvOptions = () => {
const options = {};
if (isTest()) {
options.targets = { node: 'current' };
} else {
// Disable polyfill transforms
options.useBuiltIns = false;
// Do not transform modules to CommonJS
options.modules = false;
}
if (isProd()) {
options.forceAllTransforms = true;
}
return options;
};
const presets = [
[require.resolve('#babel/preset-env'), babelPresetEnvOptions()],
[require.resolve('#babel/preset-react'), { development: isDev() }],
];
const plugins = [
[require.resolve('#babel/plugin-proposal-decorators'), { legacy: true }],
[require.resolve('#babel/plugin-proposal-class-properties'), { loose: true }],
require.resolve('#babel/plugin-proposal-object-rest-spread'),
require.resolve('#babel/plugin-transform-react-jsx'),
require.resolve('#babel/plugin-transform-runtime'),
];
if (isTest()) {
// Compiles import() to a deferred require()
plugins.push(require.resolve('babel-plugin-dynamic-import-node'));
} else {
// Adds syntax support for import()
plugins.push(require.resolve('#babel/plugin-syntax-dynamic-import'));
}
module.exports = api => {
api.assertVersion('^7.6');
return {
presets,
plugins,
};
};
Jest setup
"jest": {
"rootDir": "./webpack",
"setupFiles": [
"<rootDir>/test/jestsetup.js"
],
"snapshotSerializers": [
"enzyme-to-json/serializer"
],
"moduleNameMapper": {
"^.+\\.(css|scss)$": "identity-obj-proxy"
},
"transform": {
"^.+\\.(js|jsx)?$": "babel-jest"
}
},
Problem:
When I try to initiate a file object
const lastModified = 1511256180536;
const myImageFile = new File([''], 'pixel.gif', { type: 'image/gif', lastModified });
console.log(myImageFile); // Also results in => File {}
console.log(imageFile.name); // return 'pixel.gif'
The test snapshot fails as shown below, which I can't explain why.
- file={
- File {
- Symbol(impl): FileImpl {
- "_buffer": Object {
- "data": Array [],
- "type": "Buffer",
- },
- "isClosed": false,
- "lastModified": 1511256180536,
- "name": "pixel.gif",
- "type": "image/gif",
- Symbol(wrapper): [Circular],
- },
- }
- }
+ file={File {}}
Even a hint on this would be great.
Babel debug
#babel/preset-env: `DEBUG` option
Using targets:
{
"node": "12.11"
}
Using modules transform: auto
Using plugins:
syntax-async-generators { "node":"12.11" }
syntax-object-rest-spread { "node":"12.11" }
syntax-json-strings { "node":"12.11" }
syntax-optional-catch-binding { "node":"12.11" }
transform-modules-commonjs { "node":"12.11" }
proposal-dynamic-import { "node":"12.11" }
Using polyfills: No polyfills were added, since the `useBuiltIns` option was not set.

Different builds based on targeting client vs server code

I currently have 2 separate webpack builds for server rendered vs client rendered code. Is there an easy way to change the build output based on server/client build?
For example something like this:
// Have some code like this
if(is_client){
console.log('x.y.z')
} else {
server.log('x.y.z')
}
// Webpack outputs:
// replaced code in client.js
console.log('x.y.z')
// replaced code in server.js
server.log('x.y.z')
Have you tried anything like this?
// webpack.config.js
module.exports = () => ['web', 'node'].map(target => {
const config = {
target,
context: path.resolve('__dirname', 'src'),
entry: {
[target]: ['./application.js'],
},
output: {
path: path.resolve(__dirname, 'dist', target),
filename: '[name].js'
},
modules: { rules: ... },
plugins: [
new webpack.DefinePlugin({
IS_NODE: JSON.stringify(target === 'node'),
IS_WEB: JSON.stringify(target === 'web'),
}),
],
};
return config;
});
// later in your code
import logger from 'logger';
if (IS_NODE) {
logger.log('this is node js');
}
if (IS_WEB) {
console.log('this is web');
}
how the compilation works?
// client.bundle.js
import logger from 'logger';
// DefinePlugin creates a constant expression which causes the code below to be unreachable
if (false) {
logger.log('this is node js');
}
if (true) {
console.log('this is web');
}
Finally you will produce your build in production mode, so webpack will include a plugin called UglifyJS, this has a feature called dead code removal (aka tree shaking), so it will delete any unused/unreachable code.
and the final result will look like:
// node.bundle.js
import logger from 'logger';
console.log('this is node js');
//web.bundle.js
console.log('this is node js');

running e2e testing with aurelia cli

I'm trying to implement a few e2e tests in my aurelia-cli app. I've tried looking for docs or blogs but haven't found anything on e2e setup for the cli. I've made the following adjustments to the project.
first I added this to aurelia.json
"e2eTestRunner": {
"id": "protractor",
"displayName": "Protractor",
"source": "test/e2e/src/**/*.ts",
"dist": "test/e2e/dist/",
"typingsSource": [
"typings/**/*.d.ts",
"custom_typings/**/*.d.ts"
]
},
Also added the e2e tasks on aurelia_project/tasks:
e2e.ts
import * as project from '../aurelia.json';
import * as gulp from 'gulp';
import * as del from 'del';
import * as typescript from 'gulp-typescript';
import * as tsConfig from '../../tsconfig.json';
import {CLIOptions} from 'aurelia-cli';
import { webdriver_update, protractor } from 'gulp-protractor';
function clean() {
return del(project.e2eTestRunner.dist + '*');
}
function build() {
var typescriptCompiler = typescriptCompiler || null;
if ( !typescriptCompiler ) {
delete tsConfig.compilerOptions.lib;
typescriptCompiler = typescript.createProject(Object.assign({}, tsConfig.compilerOptions, {
// Add any special overrides for the compiler here
module: 'commonjs'
}));
}
return gulp.src(project.e2eTestRunner.typingsSource.concat(project.e2eTestRunner.source))
.pipe(typescript(typescriptCompiler))
.pipe(gulp.dest(project.e2eTestRunner.dist));
}
// runs build-e2e task
// then runs end to end tasks
// using Protractor: http://angular.github.io/protractor/
function e2e() {
return gulp.src(project.e2eTestRunner.dist + '**/*.js')
.pipe(protractor({
configFile: 'protractor.conf.js',
args: ['--baseUrl', 'http://127.0.0.1:9000']
}))
.on('end', function() { process.exit(); })
.on('error', function(e) { throw e; });
}
export default gulp.series(
webdriver_update,
clean,
build,
e2e
);
and the e2e.json
{
"name": "e2e",
"description": "Runs all e2e tests and reports the results.",
"flags": []
}
I've added a protractor.conf file and aurelia.protractor to the root of my project
protractor.conf.js
exports.config = {
directConnect: true,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
//seleniumAddress: 'http://0.0.0.0:4444',
specs: ['test/e2e/dist/*.js'],
plugins: [{
path: 'aurelia.protractor.js'
}],
// Options to be passed to Jasmine-node.
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000
}
};
aurelia.protractor.js
/* Aurelia Protractor Plugin */
function addValueBindLocator() {
by.addLocator('valueBind', function (bindingModel, opt_parentElement) {
var using = opt_parentElement || document;
var matches = using.querySelectorAll('*[value\\.bind="' + bindingModel +'"]');
var result;
if (matches.length === 0) {
result = null;
} else if (matches.length === 1) {
result = matches[0];
} else {
result = matches;
}
return result;
});
}
function loadAndWaitForAureliaPage(pageUrl) {
browser.get(pageUrl);
return browser.executeAsyncScript(
'var cb = arguments[arguments.length - 1];' +
'document.addEventListener("aurelia-composed", function (e) {' +
' cb("Aurelia App composed")' +
'}, false);'
).then(function(result){
console.log(result);
return result;
});
}
function waitForRouterComplete() {
return browser.executeAsyncScript(
'var cb = arguments[arguments.length - 1];' +
'document.querySelector("[aurelia-app]")' +
'.aurelia.subscribeOnce("router:navigation:complete", function() {' +
' cb(true)' +
'});'
).then(function(result){
return result;
});
}
/* Plugin hooks */
exports.setup = function(config) {
// Ignore the default Angular synchronization helpers
browser.ignoreSynchronization = true;
// add the aurelia specific valueBind locator
addValueBindLocator();
// attach a new way to browser.get a page and wait for Aurelia to complete loading
browser.loadAndWaitForAureliaPage = loadAndWaitForAureliaPage;
// wait for router navigations to complete
browser.waitForRouterComplete = waitForRouterComplete;
};
exports.teardown = function(config) {};
exports.postResults = function(config) {};
and I added a sample test in my test/e2e/src folder it doesn't get executed. I've also tried implementing a e2e test within the unit test folder since when I run au test I see that a chrome browser opens up.
describe('aurelia homepage', function() {
it('should load page', function() {
browser.get('http://www.aurelia.io');
expect(browser.getTitle()).toEqual('Home | Aurelia');
});
});
But this throws the error browser is undefined. Am I missing something with e2e testing with the cli? I know aurelia-protractor comes pre-installed but I don't see any way to run it.
I know this is a very late answer, but perhaps for others looking for an answer, you could try to import from the aurelia-protractor plugin
import {browser} from 'aurelia-protractor-plugin/protractor';

React unit test with jest in es6

I am pretty new in react world and trying to write simple friendslist application. I wrote my friends store in es6 style and using babel as transpiler from es5 to es6.
import AppDispatcher from '../dispatcher/app_dispatcher';
import { EventEmitter } from 'events';
import FRIENDS_CONST from '../constants/friends';
const CHANGE_EVENT = 'CHANGE';
let friendsList = [];
let add = (name) => {
let counter = friendsList.length + 1;
let newFriend = {
id: counter,
name: name
};
friendsList.push(newFriend);
}
let remove = (id) => {
let index = friendsList.findIndex(e => e.id == id);
delete friendsList[index];
}
let FriendsStore = Object.assign({}, EventEmitter.prototype, {
getAll: () => {
return friendsList;
},
emitChange: () => {
this.emit(CHANGE_EVENT);
},
addChangeListener: (callback) => {
this.on(CHANGE_EVENT, callback);
},
removeChangeListener: (callback) => {
this.removeListener(CHANGE_EVENT, callback);
}
});
AppDispatcher.register((action) => {
switch (action.actionType) {
case FRIENDS_CONST.ADD_FRIENDS:
add(action.name);
FriendsStore.emitChange();
break;
case FRIENDS_CONST.REMOVE_FRIENDS:
remove(action.id);
FriendsStore.emitChange();
break;
}
});
export default FriendsStore;
Now I want to test my store and wrote the unit test also in es6
jest.dontMock('../../constants/friends');
jest.dontMock('../friends_store');
describe('FriendsStore', () => {
import FRIENDS from '../../constants/friends';
import AppDispatcher from '../../dispatcher/AppDispatcher';
import FriendsStore from '../friends_store';
let FakeAppDispatcher;
let FakeFriendsStore;
let callback;
let addFriends = {
actionType: FRIENDS.ADD_FRIENDS,
name: 'Many'
};
let removeFriend = {
actionType: FRIENDS.REMOVE_FRIENDS,
id: '3'
};
beforeEach(function() {
FakeAppDispatcher = AppDispatcher;
FakeFriendsStore = FriendsStore;
callback = AppDispatcher.register.mock.calls[0][0];
});
it('Should initialize with no friends items', function() {
var all = FriendsStore.getAll();
expect(all).toEqual([]);
});
});
When I execute the test with statement npm test, I've got the error message:
> react-starterify#0.0.9 test /Volumes/Developer/reactjs/app5
> echo "Error: no test specified"
Error: no test specified
What am I doing wrong? The file structure looks as follow:
I did it following the tutorial:
npm install --save-dev jest babel-jest babel-preset-es2015 babel-preset-react react-test-renderer
then
add to package.json
"scripts": {
"test": "jest"
},
"jest": {
"testPathDirs": [
"src/main/resources/web_pages/__tests__"
]
},
Result:
PASS src/main/resources/web_pages/__tests__/modules/utils/ValidationUtil.spec.js (5.214s)
✓ ValidateEmail (5ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 6.092s, estimated 7s
Ran all test suites.
To test ES6 syntax and JSX files, they need to be transformed for Jest. Jest has a config variable where you can define a preprocessor (scriptPreprocessor). You can use the babel-jest preprocessor:
Make the following changes to package.json:
{
"devDependencies": {
"babel-jest": "*",
"jest-cli": "*"
},
"scripts": {
"test": "jest"
},
"jest": {
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
"testFileExtensions": ["es6", "js"],
"moduleFileExtensions": ["js", "json", "es6"]
}
}
And run:
$ npm install

Resources