Visual Studio Code Mocha ProblemMatcher - mocha.js

I'm searching for the configuration of a problem matcher for Mocha in Visual Studio Code. Problem matchers inspect the terminal output for errors and add them in the Problems view.
Problem matchers in VS Code are described here: https://code.visualstudio.com/docs/editor/tasks#_processing-task-output-with-problem-matchers

Seems like all built-in reporters describe the error with variable number of lines. And building vscode problem matcher for such kind of reporting is not supported - multiline support is extremely limited.
But we can build our own reporter with whatever format we like and then match on it with ease!
Here is a simple reporter which extends default Spec reporter with outputting errors with $tsc-watch matcher compatible format:
// my-reporter.js
var StackTraceParser = require('stacktrace-parser');
var path = require('path');
var mocha = require('mocha');
module.exports = MyReporter;
function MyReporter(runner) {
mocha.reporters.Spec.call(this, runner);
runner.on('fail', function(test, err){
var lines = StackTraceParser.parse(err.stack)
// we are only interested in the place in the test which originated the error
var line = lines.find(line => line.file.startsWith('test'))
if (line) {
console.log(`${line.file}(${line.lineNumber},${line.column}): error TS0000: ${err.message.split('\n')[0]}`)
}
});
}
// To have this reporter "extend" a built-in reporter uncomment the following line:
mocha.utils.inherits(MyReporter, mocha.reporters.Spec);
Add command to scripts section in package.json:
"test": "mocha --reporter my-reporter.js"
You then add to your tasks.json:
{
"type": "npm",
"script": "test",
"problemMatcher": [
{
"applyTo": "allDocuments",
"fileLocation": "relative",
"base": "$tsc-watch",
"source": "mocha"
}
],
"group": {
"kind": "test",
"isDefault": true
}
}

Related

Printing output to terminal from 'cypress run'

I'd like to print arbitrary outputs to the terminal per each test after calling cypress run. The outputs should appear regardless of each test's success/failure. I've followed the instructions from dozens of online answers - nothing worked for me.
I'm using Cypress 8.7.0. Thanks!
It's pretty much what #nozik linked to. In your cypress.config.js add:
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
on('task', {
log(message) {
// Then to see the log messages in the terminal
// cy.task("log", "my message");
console.log(message +'\n\n');
return null;
},
});
},
},
});
which can then be called in your tests with:
cy.task('log', 'Display some logging');

Detailed Reporting Cypress/Mochawesome

Has anyone had much experience of generating good detailed reports from Cypress tests using Mochawesome as the report engine?
I've followed the info on the Mochawesome GIT page but what I get is rather dull!!
I'd like to be able to include the odd screen-shot and the output from the assertions - here's the current cypress.json file......
{
"projectId": "haw8v6",
"baseUrl": "https://obmng.dbm.guestline.net/",
"chromeWebSecurity": false,
"reporter" : "mochawesome",
"reporterOptions" : {
"reportFilename" : "DBM Smoke-Test",
"overwrite": true,
"inline": true
}
}
I've been toying with var addContext = require('mochawesome/addContext'); but with little joy.
Suggestions gratefully received.
Thanks
As per request below - very basic example of addContext
var addContext = require('mochawesome/addContext');
describe('DBM Smoketests', function() {
it('E2E Hotel2 WorldPay System', function() {
cy.visit('https://obmng.dbm.guestline.net/');
cy.url().should('include','/obmng.dbm');
addContext(this,'URL is correct');
//loads hotel 2
cy.get('.jss189 > div > .jss69 > .jss230').click();
After much hacking about, I found a way to use Mochawesome addContext in Cypress.
Note, you can only make one addContext call per test (this is a Mochawesome limitation).
describe('DBM Smoketests', function() {
it('E2E Hotel2 WorldPay System', function() {
cy.visit('https://obmng.dbm.guestline.net/');
cy.url().should('include','/obmng.dbm');
Cypress.on('test:after:run', (test) => {
addContext({ test }, {
title: 'This is my context title',
value: 'This is my context value'
})
});
});
});
The second param is the context to be attached to the test, and it must have non-empty title and a value properties.
What you get in the mochawesome.json output is
...
"suites": [
{
...
"tests": [
{
"title": "E2E Hotel2 WorldPay System",
...
"context": "{\n \"title\": \"This is my context title\",\n \"value\": \"This is my context value\"\n}",
"code": "...",
...
}
],
In mochawesome.html, on clicking the test you get
Additional Test Context
This is my context title:
This is my context value
I have not tried it out with value types other than string.
Note for anyone starting out with Mochawesome in Cypress, it looks like you can only get a Mochawesome report with running cypress run, not with cypress open - although there may be a way around this using mocha's multiple reporter functionality.
Yes confirmed work! It's possible to call once in each test like this:
it('Should shine the test report!!!', () => {
cy.get('li').should('have.length.greaterThan', 0);
addTestContext('String','giphy');
addTestContext('Link','https://giphy.com');
addTestContext('Image','https://media.giphy.com/media/tIIdsiWAaBNYY/giphy.gif');
addTestContext('Image','https://media.giphy.com/media/tIIdsiWAaBNYY/giphy.gif');
});
function addTestContext(title, value) {
cy.once('test:after:run', test => addContext({ test }, { title, value }));
}

How to generate HTML report while using Nightwatch with Mocha

I'm using Nightwatch JS to run my e2e tests with the Mocha runner.
I want to integrate an HTML reporter that with the suite.
I'm trying to use the nightwatch-html-reporter package. But as far as I understand there is a problem with the CLI commands (it's written in the Nightwatch docs that --reporter will not work when using mocha).
I also copied the code sample from nightwatch-html-reporter to my globals.js but it doesn't seem to work either.
The tests run but there is no output anywhere.
Here is my folder structure:
project
src
spec
e2e
globals
globals.js
tests
smoke
testFile.js
nightwatch.conf.js
Here is my conf file:
const seleniumServer = require('selenium-server-standalone-jar');
const chromeDriver = require('chromedriver');
module.exports = {
src_folders: ['src/spec/e2e/tests'],
output_folder: 'report',
page_objects_path: [
'src/spec/e2e/pageObjects'
],
globals_path: 'src/spec/e2e/globals/globals.js',
custom_commands_path: 'src/spec/e2e/customCommands',
selenium: {
start_process: true,
server_path: seleniumServer.path,
host: '127.0.0.1',
port: 4444,
cli_args: {
'webdriver.chrome.driver': chromeDriver.path
}
},
test_runner: {
type: 'mocha',
options: {
ui: 'bdd',
reporter: 'list'
}
},
test_settings: {
default: {
launch_url: 'http://URL',
silent: true,
desiredCapabilities: {
browserName: 'chrome',
javascriptEnabled: true,
acceptSslCerts: true,
chromeOptions: {
args: [
"--no-sandbox",
"start-fullscreen"
]
}
}
}
}
};
And here is my global.js file:
var HtmlReporter = require('nightwatch-html-reporter');
var reporter = new HtmlReporter({
openBrowser: true,
reportsDirectory: __dirname + '/reports'
});
module.exports = {
reporter: reporter.fn
};
I don't think it will work with nightwatch-html-reporter as it is probably not a mocha reporter (but correct me if I'm wrong).
You want to use built in or custom mocha reporters when using nightwatch with mocha.
You can use a custom mocha html reporter like mochawesome but you'll have to hack around a bit and I offer no guarantees as I only tested those hacks lightly.
Here are the instructions to use mochawesome
(tested with
"mocha": "^5.2.0",
"mochawesome": "^3.1.1",
"nightwatch": "^0.9.21")
npm install mochawesome
Modify mochawesome node_modules\mochawesome *.js files to require mocha-nightwatch instead of mocha. (See instructions/explanations towards the end of the answer)
Presuming you're using a nightwatch.conf.js, configure your test runner to the equivalent of
test_runner : {
type : "mocha",
options : {
ui : "bdd",
reporter : require("mochawesome") // Please observe that you can pass a custom report constructor function here, not just reporter names
}
}
Run tests and observe that you still see the default console reporter (spec) but that at the end of the run you also see an output like:
[mochawesome] Report HTML saved to C:\projects\myWebApp\mochawesome-report\mochawesome.html
Open the html report.
This solution is hackish and fragile because nightwatch comes with it's own version of mocha.
When you install nightwatch you will see in your node_modules a mocha-nightwatch folder. This is the mocha that is being used by nightwatch.
However mochawesome doesn't use mocha-nightwatch. If you look at node_modules\mochawsome\dist\mochawesome.js you will see lines of code like:
var Base = require('mocha/lib/reporters/base');
var Spec = require('mocha/lib/reporters/spec');
This means is requires mocha, not mocha-nightwatch.
Those lines should ideally be: require('mocha-nightwatch/...).
So please change them in all *.js files that need fixing.
You could also fork mochawesome and make them like that ;)
Debugging notes:
Try putting some additional console.logs in node_modules\mocha-nightwatch\lib\mocha.js in the Mocha.prototype.reporter function. That's how I figured out what's going on.
If you use Mocha you can always go with mochawsome: https://www.npmjs.com/package/mochawesome
I haven't tried it myself but it looks pretty neat.

How to set up Browserify with Elixir and Browserify Shim on Laravel 5?

I am trying to set up Browserify with Elixir and Browserify Shim on Laravel 5.2 to use Gulp with my JavaScript files, but I didn't have much luck so far. This should be pretty straightforward to do, but it isn't.
Here is my package.json
{
"private": true,
"devDependencies": {
"gulp": "^3.8.8"
},
"dependencies": {
"bootstrap-sass": "^3.0.0",
"browserify-shim": "^3.8.12",
"jquery": "^2.2.0",
"jquery-ui": "^1.10.5",
"laravel-elixir": "^4.0.0"
},
"browser": {
"app": "./resources/assets/js/app.js",
"utils": "./resources/assets/js/utils.js",
},
"browserify": {
"transform": [
"browserify-shim"
]
},
"browserify-shim": {
"app": {
"depends": [
"jquery:$",
"utils:Utils"
]
},
"utils": {
"depends": [
"jquery:$"
]
},
}
}
gulpfile.js
var elixir = require('laravel-elixir');
elixir(function (mix) {
mix.browserify('main.js', './public/js/bundle.js');
});
Entry script main.js looks like this:
var $ = require('jquery');
var Utils = require('utils');
var App = require('app');
app.js
var App = {
init: function(){
console.log(Utils);
Utils.doSomething();
}
//other methods
};
In short: Utils depends on $, and App depends on both $ and Utils.
When I hit gulp from terminal, bundle.js is correctly created. All scripts are wrapped up in Browserify code (as expected). Each script has all included dependencies, like I configured in package.json so this part looks good as well.
The problem is that all my included dependencies are empty objects. For example, Utils in app.js is empty, and I get an error when I try to call its method "doSomething". Console log prints out an empty object "{}" instead of real object. The only correctly included script is jQuery and it's not an empty object.
What could be wrong here? Do I need to make some changes in my JS files or in configuration to make this work? It looks like I'm pretty close to the solution, but it still does not work and I can't use it at all.
It is the easiest solution to directly use 'exports' from browserify-shim property:
"browserify-shim": {
"app": {
"exports": "App",
"depends": [
"jquery:$",
"utils:Utils"
]
},
"utils": {
"exports": "Utils",
"depends": [
"jquery:$"
]
},
}
Take a look at this repo which I believe shows the fixed version of your app. The issue is that your app.js and utils.js modules aren't exporting anything to their respective require calls. One option is to add a line like:
module.exports = App;
to the bottom of your app.js file, and the equivalent to the bottom of your utils.js file. You'll see if you test the repo that badapp doesn't have this line and produces the exact behavior you're describing.
See this answer for an explanation of the issue.

How to load OBJ model with three.js in TypeScript

I am using TypeScript and three.d.ts from definitely typed. I have no problems using THREE.JSONLoader, but how do I use an OBJLoader from here in a TypeScript project. I probably need to create an OBJLoader.d.ts file, but I have no idea how to do it and then how to use the created definition. I tried to simply copy the THREE.JSONLoader definition and rename it to OBJLoader, but that didn't work.
The latest Three.js now has ES Module versions of all the classes in the examples/ folder, along with type declaration files. So, now you can:
import {OBJLoader} from 'three/examples/jsm/loaders/OBJLoader'
And it will be typed in TypeScript as expected (hover on it to see tooltips in VS Code).
This answer was correct at the time of posting, but it's out of date now in 2019. See #trusktr's response below for a better solution today.
Having looked at the source of the OBJLoader here, (and with reference to three.d.ts) a simple objloader.d.ts file might look like this:
/// <reference path="three.d.ts" />
export class OBJLoader extends EventDispatcher {
constructor();
load(url: string, callback?: (response:any) => any): void;
parse(data:any):any; // Not sure if the return value can be typed. Seems to be a group but I can't find a definition for that in three.d.ts?
}
Caveat: this is quickly hacked together and not tested, but may help you to get started.
You would then reference your objloader.d.ts in the same way you are currently using three.d.ts. Don't forget to include both the three.js and OBJLoader.js files in your html page, or import them if you are working with external modules.
Add the libraries to your index.html or to your angular-cli.json if you're using angular2 cli:
$ cat angular-cli.json
{
"project": {
"version": "1.0.0-beta.16",
"name": "ssp"
},
"apps": [
{
"root": "src",
"outDir": "dist",
"assets": "assets",
"index": "index.html",
"main": "main.ts",
"test": "test.ts",
"tsconfig": "tsconfig.json",
"prefix": "app",
"mobile": false,
"styles": [
"styles.css"
],
"scripts": [
"../node_modules/three/build/three.js",
"../node_modules/three/examples/js/controls/VRControls.js",
"../node_modules/three/examples/js/effects/VREffect.js",
"../node_modules/webvr-boilerplate/build/webvr-manager.js",
"../node_modules/dat-gui/vendor/dat.gui.js",
"../node_modules/stats-js/build/stats.min.js",
"../node_modules/three/examples/js/controls/OrbitControls.js",
"../node_modules/three/examples/js/loaders/OBJLoader.js", <-- add
"../node_modules/three/examples/js/loaders/MTLLoader.js" <-- add
],
"environments": {
"source": "environments/environment.ts",
"dev": "environments/environment.ts",
"prod": "environments/environment.prod.ts"
}
}
],
Then reference the libraries like "var mtlLoader = new (THREE as any).MTLLoader( );":
var mtlLoader = new (THREE as any).MTLLoader( );
mtlLoader.setPath( '../../assets/models' );
mtlLoader.load( 'myProject.mtl', function( materials ) {
materials.preload();
var loader = new (THREE as any).OBJLoader();
loader.setMaterials(materials);
loader.load( '../../assets/models/myProject.obj', function(object) {
... do stuff
You won't get type checking, but it's a quick way to get started until someone adds an entry for the loaders to definitely typed.

Resources