How do I get node.js & Mocha to run (test) in browser? - javascript

In Win10.64 I'm running the test on the command line with expected results:
>mocha test
Array
#indexOf()
√ should return -1 when the value is not present
1 passing (16ms)
But in Chrome, console error is: Uncaught ReferenceError: require is not defined(anonymous function) # test.lead-helper.js:1
test.lead-helper.js:
var assert = require("assert");
describe('Array', function() {
describe('#indexOf()', function () {
it('should return -1 when the value is not present', function () {
assert.equal(-1, [1,2,3].indexOf(5));
assert.equal(-1, [1,2,3].indexOf(0));
});
});
});
and the HTML test runner:
<html>
<head>
<meta charset="utf-8">
<title>Mocha Tests</title>
<link href="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.css" rel="stylesheet" />
</head>
<body>
<div id="mocha"></div>
<div id="messages"></div>
<div id="fixtures"></div>
<script src="https://cdn.rawgit.com/jquery/jquery/2.1.4/dist/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/Automattic/expect.js/0.3.1/index.js"></script>
<script src="https://cdn.rawgit.com/mochajs/mocha/2.2.5/mocha.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.3.0/chai.js"></script>
<script src="lead-helper.js"></script>
<script>mocha.setup('bdd')</script>
<script src="test/test.lead-helper.js"></script>
<script>
mocha.checkLeaks();
mocha.globals(['jQuery']);
mocha.run();
</script>
</body>
</html>

Your code seems to be working at cross-purpose. You load Chai:
<script src="https://cdnjs.cloudflare.com/ajax/libs/chai/3.3.0/chai.js"></script>
which is a full-featured assertion library but then you use require("assert") which seems to be an attempt at loading Node's assert library into your browser. There may be a way to get this to load by using Browserify but I don't see why you'd do that, seeing as you already load Chai, and there is no indication that the rest of your code needs Browserify.
I would just remove the require call and instead have:
var assert = chai.assert;

This happens because there is no require() method in browser environment by default, so you have to make some changes in your script moduling. There are some ways you can go:
Use other method to load scripts, for example with the help
<script> tag.
Use CommonJS implementation, like Browserify, or Component.
Use AMD implementation like RequireJs.

Related

function is not defined, when it is

today i was working on a project, and i got this error.
Uncaught ReferenceError: launch is not defined
at HTMLInputElement.onclick (home.html:77)
i don't understand what i did wrong here..
Here is the index.js file:
function launch() {
console.log('test');
}
module.exports.launch = launch;
and home.html:
<script>
let func = require('./index');
let launch = func.launch();
document.getElementById('lanBTN').addEventListener('click', () => {
launch();
});
<input type="button" value="Launch!" id="lanBTN" onclick="launch()">
</script>
Any ideas why this is happening..?
Require is a commonjs module specification, it doesn't work on the browser unless you use some bundler like webpack or browserify to resolve the dependencies between all of you modules and bundles one single js file to include in your html
As #mehdi-belbal mentioned you can not use CommonJS in HTML files expect if when using module bundlers like Webpack.
Besides of that module.exports is useless here, try to link your javascript module in the head of the document. and the declared function after. that will attach to the window object and you can use them both by using window.func() and ‍func()
<head>
<script src="./index.js"></script>
</head>
<body>
...
<script>
func();
</script>
</body>

No test output from mocha-phantomjs

I'm having trouble getting the simplest mocha-phantomjs test to work on Windows, from the command-line. It seems to run the javascript - as I can see some output from console.log, but I'm not seeing any test output.
I did npm install on the following packages
mocha-phantomjs (4.0.2)
phantomjs (2.1.3)
mocha (2.4.4)
chai (3.5.0)
test\cow-test.js:
console.log("fred1");
describe("OnePlusFour", function() {
it("should be able to add two numbers", function() {
chai = require('chai');
var expect = chai.expect;
var first = 1;
var second = 4;
expect(first + second).to.equal(5);
});
});
console.log("fred2");
cow.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"></div>
<script src="./node_modules/mocha/mocha.js"></script>
<script src="./node_modules/chai/chai.js"></script>
<script>
mocha.setup('bdd');
</script>
<script src="test/cow-test.js"></script>
<script>
mocha.run();
</script>
</body>
</html>
When I run mocha on the javascript file, I get the correct test output:
D:\Sandbox\GummyBear>mocha test\cow-test.js
fred1
fred2
OnePlusFour
√ should be able to add two numbers
1 passing (10ms)
Yay! But when I run mocha-phantomjs on the HTML file, I only get console output and nothing from the test:
D:\Sandbox\GummyBear>mocha-phantomjs cow.html
fred1
fred2
^CTerminate batch job (Y/N)? y
and I have to use Ctrl+Break to terminate it, or it will stay there forever. Boo.
What am I doing wrong?
BTW eventually I want to get this working with gulp. I used the MVC Boilerplate templates to create a project structure with ASP.NET Core, bower and gulp etc, but I got stuck at the javascript unit test stage (gulp-mocha-phantomjs gave the error "mocha was not found in the page within 10000ms of the page loading."). So in order to solve that, I wanted to get my head around the basics of JS unit testing first.

Protractor cannot find angular

I am trying to set up unit/e2e tests for the angular app. Following the instructions on the protractor web site and numerous other samples I have set it up and being able to run tests unless they are referring to the angular objects.
Here is the sample html page I want to have tests for:
<!DOCTYPE html>
<html ng-app="app">
<head>
<script type="text/javascript" src="libraries/angular.js"></script>
<script type="text/javascript" src="libraries/angular-route.js"></script>
<script type="text/javascript" src="libraries/angular-touch.js"></script>
<script type="text/javascript" src="libraries/angular-sanitize.js"></script>
<script type="text/javascript" src="libraries/angular-mocks.js"></script>
.....
</head>
<body ng-controller="DefaultController">
...
The test:
describe('Logon page', function ()
{
beforeEach(function ()
{
browser.get('default.html');
angular.module("app");
});
it('should have a title', function ()
{
expect(browser.getTitle()).toEqual('Logon');
});
});
as soon as I run it I got an exception: "ReferenceEror: angular is not defined".
If I remove line "angular.module("app");" - it works fine.
By looking at console output of the protractor it looks like Protractor.waitForAngular() is internally called after I try to access "angular" object. But as far as I understand browser.get - should load it before?
I use angular 1.3.4 and protractor 1.4.0.
Thanks in advance.
Why do you need the angular.module("app"); part? The code you write in a Protractor test does not run in the browser. It uses the browser API (through Selenium) but you don't have direct access to angular modules or other structures on the page you're testing.
I think you may have mixed up the concepts of unit tests and E2E tests. You'll need angular.module("app"); just for unit tests.

RequireJS paths not work

I'm new to RequireJS and trying to use it. I followed an example in RequireJS docs but there is some problem. I can load the jquery but not app/shell.
Root
|__index.html
|__javascripts
|__main.js
|__libs
| |__jquery.js
| |__require.js
|__app
|__shell.js
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<script data-main="javascripts/main.js" src="javascripts/libs/require.js"></script>
</head>
<body>
</body>
</html>
main.js
requirejs.config({
baseUrl:'javascripts/libs',
paths:{
app:'../app'
}
});
require(['jquery','app/shell'],function($,shell){
if($ && shell){
console.info('Scripts loaded');
}
});
shell.js
define(function(){
"use strict";
return{
initModule:function(){
console.info('Module init');
}
}
});
Web Console Errors
"NetworkError: 404 Not Found - http://localhost:3000/javascripts/app../default.htmshell.js"
Error: Script error for: app/shell http://requirejs.org/docs/errors.html#scripterror
Node.js Express Console Error
GET /javascripts/app../default.htmshell.js 404
Because you have multiple folder levels, you have to set your baseUrl as the root of your application. If you want to use require(['jquery']) instead of require(['libs/jquery']), you have to specify the "alias" of it in your configuration.
requirejs.config({
baseUrl:'javascripts',
paths:{
jquery: 'libs/jquery'
}
});
Try adding your main.js file explicitly after your requirejs script tag:
<script src="javascripts/libs/require.js"></script>
<script src="javascripts/main.js"></script>
This will load your configuration file synchronously after loading requirejs thus making sure the paths are set before a module is called.
Hope it helps.

Check Backbone/requireJs project with Jasmine

I have a project loaded using RequireJS and I would like to test the models.
I have the following test :
require(['../../js/models/lead_sharing'], function(Lead_sharing_Model) {
describe('when instantiated', function () {
it('should exhibit attributes', function() {
var test = new Lead_sharing_Model({
attribute : 3
});
expect(test.get('attribute')).toEqual(3);
});
});
});
But I have a error " failed with error: SyntaxError: Unexpected token"...
In reality , I don't know if it's possible to test a backbone/requireJs project with Jasmine. Indeed, how can I include my views/Models... without require config (like definition of the paths...)
Thanks you
Ps : just a small edit to specify that I would like test with a a js cmd. no in a browser. :)
It is certainly possible to test a backbone/requirejs project with jasmine. Pull the same require config used by the app into the html page that drives the unit tests. For example:
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="vendor/jasmine.css">
</head>
<body>
<script src="vendor/jasmine.js"></script>
<script src="vendor/jasmine-html.js"></script>
<script src="../assets/js/libs/jquery.js"></script>
<script src="../assets/js/libs/underscore.js"></script>
<script src="../assets/js/libs/backbone.js"></script>
<!-- This points to the require config that is also used by the main app. -->
<script data-main="../app/config" src="../assets/js/libs/require.js"></script>
<script>
require({ paths: { spec: "../test/spec" } }, [
// Pull in all your modules containing unit tests here.
"spec/lead-sharing-specs"
], function() {
jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
jasmine.getEnv().execute();
});
</script>
</body>
</html>
Since you want to run this outside of the browser, check out PhantomJS, grunt, and grunt-jasmine-task.

Categories