mocha test client and server side - javascript

I'm evaluating mocha but I cant get around some basic problems, I wrote an example test and I'd like to run it both with node.js and in a browser using an html file but I cannot find a way to write only one test that works for both, if I add the require(s) in the test file it's fine for node.js and I get a "Uncaught ReferenceError: require is not defined" in the browser, deleting the require(s) I get "chai is not defined" in node js
this is the code
(function(exports) {
"use strict";
function Cow(name) {
this.name = name || "Anon cow";
}
exports.Cow = Cow;
})(this);
this is the test
var chai = require('chai'),
cowobj = require ("../cow"),
expect = chai.expect;
describe("Cow", function() {
describe("constructor", function() {
it("should have a default name", function() {
var cow = new cowobj.Cow();
expect(cow.name).to.equal("Anon cow");
});
});
this is the html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Cow tests</title>
<link rel="stylesheet" media="all" href="node_modules/mocha/mocha.css">
</head>
<body>
<div id="mocha"><p>Index</p></div>
<div id="messages"></div>
<div id="fixtures"></div>
<script src="node_modules/mocha/mocha.js"></script>
<script src="node_modules/chai/chai.js"></script>
<script src="cow.js"></script>
<script>mocha.setup('bdd')</script>
<script src="./test/cow_test.js"></script>
<script>mocha.run();</script>
</body>
</html>
any Idea on how to fix that?

checking if exports is defined in the test file did the job
if(typeof(exports) !== "undefined"){
var Cow = require ("../cow").Cow,
chai = require('chai');
}
var
expect = chai.expect;
after that I can simply do
var cow = new Cow();

Related

test html page with jest

I'm trying to setup a test for prototype.js.
I would like to avoid starting a local server to use cypress / puppeteer / etc. My goal here is just use jest.
My idea was to have for each test a minimal index.html like the following:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/prototype/1.7.2.0/prototype.js"></script>
</head>
<body>
<span id="el">foo foo</span>
</body>
</html>
and I tried first to run jest as
const fs = require('fs');
const path = require('path');
const html = fs.readFileSync(path.resolve(__dirname, './index.html'), 'utf8');
jest.dontMock('fs');
describe('$', function () {
beforeEach(() => {
document.documentElement.innerHTML = html.toString();
});
afterEach(jest.resetModules);
it('finds a node', function () {
expect($('el')).toBeInTheDocument()
});
});
but $ as all the prototype.js global stuff is not available.
ouhhh .... looks like wrapping the expect into a window.onload is enough, which makes also sense.

Import functions from another js file. Javascript

I have a question about including a file in javascript.
I have a very simple example:
--> index.html
--> models
--> course.js
--> student.js
course.js:
function Course() {
this.id = '';
this.name = '';
}
A student has a course property. like this:
import './course';
function Student() {
this.firstName = '';
this.lastName = '';
this.course = new Course();
}
and the index.html is like:
<html>
<head>
<script src="./models/student.js" type="text/javascript"></script>
</head>
<body>
<div id="myDiv">
</div>
<script>
window.onload= function() {
var x = new Student();
x.course.id = 1;
document.getElementById('myDiv').innerHTML = x.course.id;
}
</script>
</body>
</html>
But I am getting an error on the line "var x = new Student();":
Student is not defined
When I remove the import from Student, I don't receive the error anymore.
I have tried to use (require, import, include, create a custom function, export) and none has worked for me.
Anybody knows why? and how to fix that?
P.S. the path is correct, it comes from the autocomplete in VS Code
The following works for me in Firefox and Chrome. In Firefox it even works from file:///
models/course.js
export function Course() {
this.id = '';
this.name = '';
};
models/student.js
import { Course } from './course.js';
export function Student() {
this.firstName = '';
this.lastName = '';
this.course = new Course();
};
index.html
<div id="myDiv">
</div>
<script type="module">
import { Student } from './models/student.js';
window.onload = function () {
var x = new Student();
x.course.id = 1;
document.getElementById('myDiv').innerHTML = x.course.id;
}
</script>
You can try as follows:
//------ js/functions.js ------
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
//------ js/main.js ------
import { square, diag } from './functions.js';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5
You can also import completely:
//------ js/main.js ------
import * as lib from './functions.js';
console.log(lib.square(11)); // 121
console.log(lib.diag(4, 3)); // 5
Normally we use ./fileName.js for importing own js file/module and fileName.js is used for importing package/library module
When you will include the main.js file to your webpage you must set the type="module" attribute as follows:
<script type="module" src="js/main.js"></script>
For more details please check ES6 modules
By default, scripts can't handle imports like that directly. You're probably getting another error about not being able to get Course or not doing the import.
If you add type="module" to your <script> tag, and change the import to ./course.js (because browsers won't auto-append the .js portion), then the browser will pull down course for you and it'll probably work.
import './course.js';
function Student() {
this.firstName = '';
this.lastName = '';
this.course = new Course();
}
<html>
<head>
<script src="./models/student.js" type="module"></script>
</head>
<body>
<div id="myDiv">
</div>
<script>
window.onload= function() {
var x = new Student();
x.course.id = 1;
document.getElementById('myDiv').innerHTML = x.course.id;
}
</script>
</body>
</html>
If you're serving files over file://, it likely won't work. Some IDEs have a way to run a quick sever.
You can also write a quick express server to serve your files (install Node if you don't have it):
//package.json
{
"scripts": { "start": "node server" },
"dependencies": { "express": "latest" }
}
// server/index.js
const express = require('express');
const app = express();
app.use('/', express.static('PATH_TO_YOUR_FILES_HERE');
app.listen(8000);
With those two files, run npm install, then npm start and you'll have a server running over http://localhost:8000 which should point to your files.
//In module.js add below code
export function multiply() {
return 2 * 3;
}
// Consume the module in calc.js
import { multiply } from './modules.js';
const result = multiply();
console.log(`Result: ${result}`);
// Module.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Module</title>
</head>
<body>
<script type="module" src="./calc.js"></script>
</body>
</html>
Its a design pattern same code can be found below, please use a live server to test it else you will get CORS error
https://github.com/rohan12patil/JSDesignPatterns/tree/master/Structural%20Patterns/module

Uncaught Error: Module name "antlr4/index" has not been loaded yet for context on require.js

I try to use antlr4 on javascript, then read https://tomassetti.me/antlr-and-the-web/ and make but error has occurred.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="lib/require.js"></script>
<script type="text/javascript">
var antlr4 = require('antlr4/index');
var QueryLexer = require('gram/queryLexer');
var QueryParser = require('gram/queryParser');
document.getElementById("parse").addEventListener("click", function() {
var input = document.getElementById("code").value;
var chars = new antlr4.InputStream(input);
var lexer = new QueryLexer.queryLexer(chars);
var tokens = new antlr4.CommonTokenStream(lexer);
var parser = new QueryParser.queryParser(tokens);
parser.buildParseTrees = true;
var tree = parser.query();
console.log("Parsed: "+ tree);
});
</script>
</head>
<body>
<div id="inputs">
<textarea id="code">
* play with antlr4
* write a tutorial
</textarea>
<br/>
<button id="parse">Parse</button>
</div>
</body>
</html>
The error may cause on "var antlr4 = require('antlr4/index');".
I downloaded antlr4 from http://www.antlr.org/download/index.html and put same tier of "index.html". In lib directory there exist "require.js".
index.js
exports.atn = require('./atn/index');
exports.codepointat = require('./polyfills/codepointat');
exports.dfa = require('./dfa/index');
exports.fromcodepoint = require('./polyfills/fromcodepoint');
exports.tree = require('./tree/index');
exports.error = require('./error/index');
exports.Token = require('./Token').Token;
exports.CharStreams = require('./CharStreams').CharStreams;
exports.CommonToken = require('./Token').CommonToken;
exports.InputStream = require('./InputStream').InputStream;
exports.FileStream = require('./FileStream').FileStream;
exports.CommonTokenStream = require('./CommonTokenStream').CommonTokenStream;
exports.Lexer = require('./Lexer').Lexer;
exports.Parser = require('./Parser').Parser;
var pc = require('./PredictionContext');
exports.PredictionContextCache = pc.PredictionContextCache;
exports.ParserRuleContext = require('./ParserRuleContext').ParserRuleContext;
exports.Interval = require('./IntervalSet').Interval;
exports.Utils = require('./Utils');
I think there are no problems, because require path('antlr4/index') is not wrong.
But error has occurred. Please give me some idea.
The code you show in your question cannot work as-is with RequireJS. You'd have to write the require calls differently, or wrap all the require calls you have in a define so as to use the CommonJS support that RequireJS provides.
But the tutorial is not asking you to use RequireJS. if you go to the github repo that the writer of the tutorial provided, you'll see:
Require.js was obtained from https://github.com/letorbi/smoothie/blob/master/standalone/require.js
You have to use that file, which is not RequireJS, but something similar to it in the sense that it also loads scripts, and yet different from RequireJS in the sense that it seems to support the CommonJS module format as-is, which RequireJS doesn't.

Javascript mocha testing "it" function never entered

I want to Test my JavaScript Code with the mocha and chai Library. I'm working from this tutorial.
I want to test the code at work, but i am not able to use node.js (security stuff).
The problem is that the describe function is entered but never called.
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="IST-8859-1">
<title>Insert Title Here</title>
<link rel="stylesheet" type="text/css" ref="./mocha.css">
</head>
<body>
<div id="mocha"></div>
<script type="text/javascript" src="./mocha.js"></script>
<script type="text/javascript" src="./chai.js"></script>
<script>mocha.setup('bdd');</script>
<script type="text/javascript" src="./testmocha.js"></script>
<script>mocha.run</script>
</body>
</html>
JS
var assert = chai.assert;
describe('Array', function(){
console.log("inside2");
it("teest", function() {
console.log("it 01");
var arr = [];
assert.equal(arr.length, 0);
});
it("teests", function(){
var arr = [];
assert.equal(arr.length, 1);
});
console.log("inside3");
})
The console log "it 01" will never be shown.. but the "inside 2" and the "inside 3".
the html files stays empty.
Have anyone a idea?
You forgot the parentheses to invoke the .run function. Try this instead:
<script>mocha.run();</script>

BlanketJS + Jasmine 2.0 not working

I have been testing with Jasmine 2.0.0 and it works without any problem.
But there's a problem when I append BlanketJS to my code.
I used a specRunner(https://github.com/alex-seville/blanket/blob/master/test/jasmine-requirejs/runner.html) that works with Jasmine 1.3.1. But It does not work when I replace Jasmine 1.3.1 with Jasmine 2.0.0,
Here's original code from BlanketJS repo:
<html>
<head>
<title>Jasmine Spec Runner</title>
<link rel="stylesheet" type="text/css" href="../vendor/jasmine.css">
<script type="text/javascript" src="../vendor/jasmine.js"></script>
<script type="text/javascript" src="../vendor/jasmine-html.js"></script>
<script type="text/javascript" src="../helpers/console_runner.js"></script>
<script type="text/javascript" src="../../node_modules/requirejs/require.js"></script>
<script type="text/javascript" data-cover-only="code/" data-cover-never="['all.tests','code/tests']"
src="../../dist/qunit/blanket.js"> </script>
<script type="text/javascript" src="../../src/adapters/jasmine-blanket.js"></script>
<script type="text/javascript">
if (window.require && typeof (window.require.config) === 'function') {
require.config({
baseUrl: './code'
});
}
</script>
<script type="text/javascript" src="code/all.tests.jasmine.js"></script>
<script type="text/javascript">
(function () {
window.blanketTestJasmineExpected=2;
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000;
var htmlReporter = new jasmine.HtmlReporter();
var oldResult = htmlReporter.reportRunnerResults;
jasmineEnv.addReporter(htmlReporter);
/* this is just for our automated tests */
window.jasmine_phantom_reporter = new jasmine.ConsoleReporter;
jasmineEnv.addReporter(jasmine_phantom_reporter);
/* */
jasmineEnv.specFilter = function (spec) {
return htmlReporter.specFilter(spec);
};
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
execJasmine();
};
function execJasmine() {
jasmineEnv.execute();
}
})();
</script>
</head>
<body>
</body>
</html>
and I added Jasmine 2.0.0 files and changed this code like below:
....
<title>Jasmine Spec Runner</title>
<link rel="stylesheet" type="text/css" href="../vendor/jasmine.css">
<script type="text/javascript" src="../vendor/jasmine-2.0.0/jasmine.js"></script>
<script type="text/javascript" src="../vendor/jasmine-2.0.0/jasmine-html.js"></script>
<script type="text/javascript" src="../vendor/jasmine-2.0.0/boot.js"></script>
<script type="text/javascript" src="../helpers/console_runner.js"></script>
....
The error messages printed:
Uncaught TypeError: Cannot read property 'env' of undefined jasmine-html.js:38
Uncaught TypeError: Object #<Env> has no method 'currentRunner' jasmine-blanket.js:76
How can I run this specRunner page without problems? Please give me a solution. thanks.
the Blanket adapter uses currentRunner but that doesn't exist in 2.0 anymore.
The Blanket Jasmine adapter needs to be updated as both this and the reporter interface has changed.
Open up your jasmine-blanket.js file and replace the code at the bottom with this:
BlanketReporter.prototype = {
specStarted: function(spec) {
blanket.onTestStart();
},
specDone: function(result) {
var passed = result.status === "passed" ? 1 : 0;
blanket.onTestDone(1,passed);
},
jasmineDone: function() {
blanket.onTestsDone();
},
log: function(str) {
var console = jasmine.getGlobal().console;
if (console && console.log) {
console.log(str);
}
}
};
// export public
jasmine.BlanketReporter = BlanketReporter;
//override existing jasmine execute
var originalJasmineExecute = jasmine.getEnv().execute;
jasmine.getEnv().execute = function(){ console.log("waiting for blanket..."); };
blanket.beforeStartTestRunner({
checkRequirejs:true,
callback:function(){
jasmine.getEnv().addReporter(new jasmine.BlanketReporter());
jasmine.getEnv().execute = originalJasmineExecute;
jasmine.getEnv().execute();
}
});
Then it will should as intended.
ETA - personally I'd switch to Istanbul instead, as Blanket seems to be sparsely updated (if at all) right now. Istanbul has more complete coverage stats (not just lines - branches, etc) and can export to lcov for tools like Code Climate. It works with Jasmine, or any test framework, flawlessly.
So now there is actually an adapter for 2.x version of jasmine. But I still had some trouble configuring it. Eventually I did configure everything right, so that is what I got:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Tests</title>
<link rel="stylesheet" href="components/jasmine.css">
<script src="components/jasmine.js"></script>
<script src="components/jasmine-html.js"></script>
<script src="components/boot.js"></script>
<script type="text/javascript" data-cover-only="app/" src="components/blanket.js" data-cover-adapter="components/jasmine-2.x-blanket.js"></script>
<script src="components/blanket_browser.js"></script>
<script src="components/jasmine-2.x-blanket.js"></script>
<!-- sources -->
<script src="components/angular.js"></script>
<script src="components/angular-mocks.js"></script>
<script src="app/custom-forms.js"></script>
<script src="app/route-selector.js"></script>
<!-- tests -->
<script src="tests/custom-forms-tests.js"></script>
<script src="tests/route-selector-tests.js"></script>
</head>
<body>
</body>
</html>
Note: I used bower to retrieve jasmine and blanket, but there is some confusion towards what blanket files I had to reference, so:
"components/blanket.js" -> I got this file from dist/qunit/blanket.js
"components/blanket_browser.js" -> src/blanket_browser.js
"components/jasmine-2.x-blanket.js" -> src/adapters/jasmine-2.x-blanket.js
Note that I also use boot.js that comes with jasmine and it works fine. Hope this information helps someone.

Categories