requirejs throws a 404 trying to load a file from karma runner - javascript

I am trying to load a test helper module using requirejs, but it fails even when it has been already loaded as a dependency at the start of karma run, and I can't figure out what's the problem, I always get
There is no timestamp for /base/spec/helpers/testHelpers!'
Tests run fine, inside them I require any module of the app without problem, it only fails when I require specifically something from spec folder.
I have checked all karma related questions and none of them apply to these case.
My karma.conf file:
module.exports = function (config) {
'use strict';
config.set({
basePath: '',
frameworks: ['jasmine', 'requirejs'],
files: [
'bootstrapTests.js',
{
pattern: 'app/**/*.js',
included: false
},
{
pattern: 'entities/**/*.js',
included: false
},
{
pattern: 'config/**/*.js',
included: false
},
{
pattern: 'libs/**/*.js',
included: false
},
{
pattern: 'spec/**/*Spec.js',
included: false
},
{
pattern: 'spec/helpers/**/*.js',
included: false
}
],
exclude: [
'bootstrap.js',
'bootstrap.built.js'
],
preprocessors: {
'app/**/*.js': ['coverage'],
'entities/**/*.js': ['coverage']
},
coverageReporter: {
reporters: [
{
type: 'text-summary'
}
]
},
reporters: ['progress', 'coverage'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['PhantomJS'],
singleRun: false
});
};
My bootstrapTests.js file:
var tests = [];
for (var file in window.__karma__.files) {
if (window.__karma__.files.hasOwnProperty(file)) {
// Add all spec files and helpers
if (/spec\/.+.js$/.test(file)) {
tests.push(file);
}
}
}
require.config({
baseUrl: '/base',
paths: {
'backbone': 'libs/backbone',
'marionette': 'libs/backbone.marionette',
'jquery': 'libs/jquery-2.1.1',
'json2': 'libs/json2',
'underscore': 'libs/underscore',
'twig': 'libs/twig',
'editor': 'app/editor',
'widgets': 'app/widgets',
'menu': 'app/menu',
'helpers': 'spec/helpers'
},
map: {
'*': {
'jquery': 'config/jquery/jqueryPrivate'
},
'config/jquery/jqueryPrivate': { 'jquery': 'jquery' }
},
deps: tests,
callback: window.__karma__.start
});
so in my tests,
define([
'app/app',
'backbone',
'editor/editorController',
'editor/editorApp',
], function (
myApp,
Backbone,
editorController
) {
'use strict';
describe('editorApp', function () {
.....
works like a charm, but when I try
define([
'app/common/routerUtilities',
'backbone',
'helpers/testHelpers'
], function (
routerUtilities,
Backbone,
testHelpers
) {
'use strict';
describe('routerUtilities', function () {
...
it fails trying to fetch testHelpers, always get the error even when the module is already loaded. I tried specifying the path in all possible ways besides the shortened one: spec/helpers/testHelpers, /base/spec/helpers/testHelpers, /spec/helpers/testHelpers, ../../helpers/testHelpers, etc...
The file is included in tests array as a dependency (checked), so it's loaded (checked with console.log) along my tests and other test setup modules:
LOG: ['/base/spec/app/appSpec.js',
'/base/spec/app/common/routerUtilitiesSpec.js',
'/base/spec/app/editor/EditorLayoutViewSpec.js',
'/base/spec/app/editor/editorAppSpec.js',
'/base/spec/app/editor/editorControllerSpec.js',
'/base/spec/app/menu/menuControllerSpec.js',
'/base/spec/helpers/envSetup.js',
'/base/spec/helpers/testHelpers.js']
I've checked that is included in window._ karma _.files as well (edited for brevity):
LOG: Object{
/base/bootstrapTests.js: 'c389a1d36d1c48f2879d434b10fd5a25b6b07758',
/base/app/app.js: '7ad39554809146effd20dd1db908fc068f8119ba',
/base/app/common/routerUtilities.js: '4da0e1d1794cccc727b544cacbc6d672c0d9965a',
...
/base/config/marionette/renderer.js: '34a5e729f6133aa13841c5e949307cd437ca331b',
/base/config/marionette/templateCache.js: '9f1901d4c6f43f5f90dadacb1c4ac179efd14b15',
/base/spec/app/appSpec.js: 'e01f4fea3533e25cfcd4f7621e1c1c5559e0eed8',
/base/spec/app/common/routerUtilitiesSpec.js: 'a06b9793a635633d053142dff24d1ba4427dd365',
/base/spec/app/editor/EditorLayoutViewSpec.js: 'a24c7e8742e38b86d626bd6f3e45baacfa6af5eb',
/base/spec/app/editor/editorAppSpec.js: '800c0e8e82840ebd0d1af07c3ec4556a24ee0b04',
/base/spec/app/editor/editorControllerSpec.js: 'd2e259a477da85b6a2f742f5c6c3a4a34b7e340b',
/base/spec/helpers/envSetup.js: '297aa1e59477d967aa210bece1726e8a372cb630',
/base/spec/helpers/testHelpers.js: '5266065d344ca69f8f5980db16bf6d131492ebd0'
}
The content of spec/helpers/testHelpers.js is:
define([
'backbone'
], function (
Backbone
) {
'use strict';
var testHelpers = {
setupRoutingTest: function () {
Backbone.history.start();
Backbone.history.navigate('');
},
teardownRoutingTest: function () {
Backbone.history.navigate('');
Backbone.history.stop();
}
};
return testHelpers;
});
My folder structure is:
|-app
|---common
|---editor
|---menu
|---widgets
|-config
|---jquery
|---marionette
|-entities
|-features
|-gruntTasks
|---lib
|-spec
|---app
|-----common
|-----editor
|-----menu
|-----widgets
|---entities
|---helpers
|-tmp

Hi it looks like the karma-requirejs doesn't like the resources to be loaded into the tests array.
Try to modify the code to exclude the helper files and it could help
var tests = [];
for (var file in window.__karma__.files) {
if (window.__karma__.files.hasOwnProperty(file)) {
// Add all spec files and helpers
if (/spec\/.+.js$/.test(file)) {
tests.push(file);
}
}
}

This drove me a little nuts a while back. Make sure you're using karma-requirejs, not just requirejs.
https://www.npmjs.org/package/karma-requirejs
On that note, don't also load the production version of requirejs.

Related

Karma unit test for ES6 modules with babel

I'm following instructions from karma-babel-preprocessor to set up unit tests in a project I'm currently working, but I always the error
'require is not defined'
My karma.conf.js is as follows:
files: [
{ pattern: './test/unit/*.spec.js', watched: true },
{ pattern: './src/js/es6_modules/*.js', watched: false },
],
preprocessors: {
'./src/js/es6_modules/*.js': ['babel'],
'./test/unit/*.spec.js': ['babel'] //, 'coverage'
},
babelPreprocessor: {
options: {
presets: ['es2015'],
sourceMap: 'inline'
},
filename: function (file) {
return file.originalPath.replace(/\.js$/, '.es5.js');
},
sourceFileName: function (file) {
return file.originalPath;
}
}
The scripts in src/js/es6_modules jave ES6 classes exported. Something like:
export default class MyClass {
}
And my spec file would need to import this
import { MyClass } from "../../src/js/es6_modules/myclass";
I have seen some thread here at SO that said I would need to use browserify, but I can't find any doc (or example) on how to use it together with babel in karma. Does anyone know to configure this properly?
I fixed it using browserify instead of babel, and using a babelify transform
preprocessors: {
'./src/js/es6_modules/*.js': ['browserify'],
'./test/unit/*.spec.js': ['browserify']
},
browserify: {
debug: true,
"transform": [
[
"babelify",
{
presets: ["es2015"]
}
]
]
},

The generated AMD file is not including required files inside anonymous function and pollute the global namespace

The generated AMD file is not including required files inside anonymous function and pollute the global namespace
I got Uncaught ReferenceError: define is not defined
The generated js file https://dadasay.com/plugin/v1/js/dadasay.min.js is not including required files require.js
The js file generated by runninggulp minify_plugin_js
However, the expected export js file should be like this https://gist.github.com/anonymous/32894a4065ce338fb0416f4eb2b884dd
How could I do that in Gulp js and require.js
require.js config
'use strict';
var vendor_paths = {
require: './vendor/require',
jquery: './vendor/js/jquery-2.1.1.min',
...
}
require.config({
paths: vendor_paths,
hbs: { // optional
helpers: true, // default: true
templateExtension: 'hbs', // default: 'hbs'
partialsUrl: '' // default: ''
},
shim: {
handlebars: {
exports: 'Handlebars'
},
backbone: {
deps: [
'jquery',
'underscore'
],
exports: 'Backbone'
},
underscore: {
exports: '_'
}
},
});
require(["app"],function(App){
define(["app"], function (App) {
$("#dadasay_comments_plugin").hide();
$('head').append('<link rel="stylesheet" href='+cfg.css_style_link+' type="text/css" />');
return App.initialize();
});
});
Gulp config
var v1_assets = {
css: ['public/plugin/v1/css/*.css'],
js: ['public/plugin/v1/src/**/*.js'],
require_manifest_file: "public/plugin/v1/src/main.js"
}
gulp.task('minify_plugin_js',function(){
gulp.src(v1_assets.js)
.pipe(amdOptimize("main",{
configFile: v1_assets.require_manifest_file,
findNestedDependencies: true,
include: true
}))
.pipe(concatFile('dadasay.min.js'))
})
Exported js min file
https://dadasay.com/plugin/v1/js/dadasay.min.js
define('app_config', [], function () {
return {
server_host: SERVER_HOST,
hideCommentsThreshouldNumber: 3,
comments_req_prefix: SERVER_HOST + '/api/v1/comments/load?og_url=',
css_style_link: [
SERVER_HOST,
PLUGIN_LOCATION,
'style.min.css'
].join('/')
};
});
....
The line:
define(["app"], function (App) {
is unnecessary. You required your application asynchronously already.
I believe that you could try to use the requirejs optimizer directly within gulp instead, here's how my build task looks like:
"use strict";
const requirejs = require("requirejs");
const path = require("path");
const _ = require("underscore");
module.exports = function (options, callback) {
// RequireJS Optimizer Build Configuration
// See this: https://github.com/jrburke/r.js/blob/master/build/example.build.js
// as an example file that details all of the allowed optimizer configuration options.
var buildConfig = {
appDir: options.dest,
baseUrl: "./",
optimize: "uglify2",
optimizeCss: "standard",
findNestedDependencies: true,
dir: options.build,
removeCombined: true,
fileExclusionRegExp: options.exclude || /test/,
modules: options.modules || [{
name: "runner"
}],
allowSourceOverwrites: true
};
var config = path.join(__dirname + "/../../", options.config);
var requireConfig = require(config);
_.extend(buildConfig, requireConfig);
requirejs.optimize(buildConfig, function (text) {
callback(null, text);
}, callback);
};
And then later in gulp:
const gulp = require("gulp");
const build = require("../task/build.task");
gulp.task("build", function (callback) {
build({ some: "options" }, callback);
});

How do I integrate with AMD format with brunch.js

According to brunch docs AMD format can be configured so that modules are wrapped in AMD:
https://github.com/brunch/brunch/blob/master/docs/config.md#modules
Here is my brunch config:
exports.config = {
paths: {
watched: [
'src/styles/',
'src/scripts/'
],
public: 'public'
},
files: {
javascripts: {
joinTo: {
'scripts/vendor.js': /^src\/vendor/,
'scripts/head.js': /^src\/scripts\/head/,
'scripts/foot.js': /^src\/scripts\/foot/
}
}
},
modules: {
definition: 'amd',
wrapper: 'amd'
}
};
what I'm expecting is to see any files under src/scripts wrapped with a define wrapper:
define(['mymodule'] , function ($) {
return function () {};
});
Am I missing some part of the configuration?

angularjs, karma and requirejs test case error

I am using requirejs for my angularjs application. For TDD i am using mocha. As per this article, I am writing my test cases but there is always this error that comes while executing a test case
Error: [$injector:modulerr] Failed to instantiate module sampleapp due to:
Error: [$injector:nomod] Module 'sampleapp' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
Test Case:
define([
'angular',
'angular-mocks'
], function() {
describe('main controller todo app', function() {
var scope, ctrl;
beforeEach(module('sampleapp',[]));
beforeEach(inject(function($rootScope, $controller) {
scope = $rootScope.$new();
ctrl = $controller('mainCtrl', {$scope: scope});
}));
it('is todo added', function() {
scope.todo = 'My new Todo';
scope.addTodo();
assert.equal(scope.todos.length, 1);
});
})
});
Karma Conf:
module.exports = function(config) {
'use strict';
config.set({
basePath: './',
frameworks: [
'requirejs',
'mocha',
'chai'
],
files: [{
pattern: 'test/test-main.js',
watched: true
}, {
pattern: 'app/angular/**/*.js',
included: false
}, {
pattern: 'app/*.js',
included: false
}, {
pattern: 'app/scripts/additional/**/*.js',
included: false
}, {
pattern: 'test/spec/**/*.js',
included: false,
watched: true
}],
exclude: [
'app/main.js'
],
reporters: ['spec'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
captureTimeout: 20000,
singleRun: false,
plugins: [
'karma-chai',
'karma-mocha',
'karma-requirejs',
'karma-spec-reporter',
'karma-chrome-launcher'
]
});
}
Test Main:
var tests = [];
var TEST_REGEXP = /test[A-Za-z0-9]{1,}-[A-Za-z0-9]{1,}\.js/i;
Object.keys(window.__karma__.files).forEach(function(file) {
if (TEST_REGEXP.test(file)) {
tests.push(file);
}
});
requirejs.config({
'baseUrl': '/base/app',
'paths': {
'angular': 'scripts/additional/angular/angular',
'angular-mocks': 'scripts/additional/angular-mocks/angular-mocks',
},
'shim': {
'angular-mocks' : {'exports' : 'angular-mocks', 'deps': ['angular']}
},
'deps': tests,
'callback': window.__karma__.start
});
Any help or direction to fix this is greatly appreciated
the main problem was that the file where my module was getting created was not loaded (i.e. the file executing code var app = angular.module("sampleapp",[]);)
Once that was corrected everything started to work

How to use testr with karma-jasmine adapter?

Everything works (Karama, Jasmine, Underscore, Backbone, testr) as evidenced by the _UnitTestUnitTest passing. But simple testr statements always fail.
The basic _UnitTestUnitTest works!
it('works for jquery', function() {
expect( $("document")).toBeTruthy();
});
it('works for underscore', function() {
expect(_.size([1,2,3])).toEqual(3);
});
it('works for backbone', function() {
var model = Backbone.Model.extend();
expect(model).toBeTruthy();
});
it('works for testr', function() {
expect(testr).toBeTruthy();
});
However, in my other real unit test, it fails on the testr line:
AccountSummaryCollection_CLASS = testr('models/sales-rep/AccountSummaryCollection');
I'm certain i'm including my dependency of 'models/sales-rep/AccountSummaryCollection' correctly in my config (I see it hosted and getting loaded by require.js deps!!!
However, the big problem is it claims our application module is not loaded even though it is. I also tried to wrap the whole AccountSummaryUnitTest.js inside of require([‘AccountSummaryCollection’], function(){…. This produces a new error where inside a dependency (AccountSummary.js) the error “Backbone is not defined” is thrown. That makes no sense in the context because obviously the AccountSummaryCollection has already resolved Backbone.Collection. This bad resolution is what makes me suspect it is testr that is fishy.
I also tried to manually include the file using the karma config, but requirejs does not like that since it’s a conflicting define() function.
Below: serving actually means Requested by Client and the {{{dependency}}} file is my own trace to confirm they are added to the deps list in the karma-spec-runner.js.
It fails at this line:
AccountSummaryUnitCollection line 27: AccountSummaryCollection_CLASS = testr('models/sales-rep/AccountSummaryCollection');
Here's the "spec runner" javascript (basically copied from the docs, with some extra logging).
var dependencies = [];
for (var file in window.__karma__.files) {
if (window.__karma__.files.hasOwnProperty(file)) {
//
if (/Test\.js$/.test(file)) {
//traces my test files fine!
console.log("{{{testing file}}} --> "+ file );
dependencies.push(file);
}
}
}
// jam our application files into the deps
for (var file in window.__karma__.files) {
if (window.__karma__.files.hasOwnProperty(file)) {
if (file.indexOf('src/main/app/') !== -1 ) {
//traces my dep files fine!
console.log("{{{dependency}}} file --> "+ file );
dependencies.push(file);
}
}
}
require.config({
baseUrl: 'base/src/main/app/',
paths: {
'resources' : '../resources/',
'jquery' : '../resources/js/lib/jquery-2.1.0.min',
'text' : '../resources/js/lib/text-2.0.10',
'i18n' : '../resources/js/lib/i18n-2.0.4',
'd3' : '../resources/js/lib/d3.v3.1.10.min',
'AppMeasurement' : '../resources/js/lib/appMeasurement',
'underscore' : '../resources/js/lib/underscore-1.5.2',
'Backbone' : '../resources/js/lib/backbone-1.1.2.min',
'testr' : '../../test/lib/testr'
},
deps: dependencies,
shim: {
d3: {
exports: 'd3'
},
AppMeasurement: {
exports: 'AppMeasurement'
},
underscore: {
deps:["jquery"],
exports: '_'
},
Backbone: {
deps:["jquery"],
exports: 'Backbone'
},
testr:{
exports: 'testr'
}
},
callback: window.__karma__.start,
locale: "en-us"
});
Here's the karma section of my gruntfile
karma: {
unit: {
background: false,
options: {
logLevel : 'debug',
basePath:'./',
// files for karma to host
files: [
{pattern: 'src/main/resources/js/lib/**/*.js', included: false, served: true},
{pattern: 'src/main/resources/js/plugins/**/*.js', included:false, served: true },
{pattern: 'src/test/lib/sinon.js', included: false },
{pattern: 'src/test/lib/testr.js', included: false },
{pattern: 'src/test/js/stubs/**/*.js', included: false, served: true},
// manually load our application unit test & deps to examine the simplest case
{pattern:'src/main/app/models/sales-rep/AccountSummary.js', included: false },
{pattern:'src/main/app/models/sales-rep/AccountSummaryCollection.js', included: false },
{pattern: '_UnitTestUnitTest.js', included: false},
{pattern: 'src/test/js/unit/AccountSummaryCollectionUnitTest.js', included: false},
'src/test/js/karma-spec-runner.js'
],
plugins: [
"karma-jasmine",
"karma-phantomjs-launcher",
"karma-requirejs",
'karma-chrome-launcher',
],
frameworks: [
"jasmine",
"requirejs"
],
browsers: [
//"PhantomJS"
"Chrome"
]
}
}
},
Here's a sample test that fails
Note that the testr config is per unit test. Plus, this test WORKS in plain in the browser jasmine!
// tried with and without the leading require statement as noted in main question.
require( ['models/sales-rep/AccountSummaryCollection'], function() {
describe('AccountSummaryCollectionUnitTest', function () {
var AccountSummaryCollection_CLASS;
function configureTestr() {
testr.config({
whitelist: [
'models/sales-rep/AccountSummaryCollection',
'models/sales-rep/AccountSummary'
]
});
}
beforeEach(function () {
configureTestr();
console.log("initializing AccountSummaryCollection_CLASS");
//fails on following line
AccountSummaryCollection_CLASS = testr('models/sales-rep/AccountSummaryCollection');
});
You need specific versions of libs to get it to work right:
testr 1.0.2 (NOT 1.0.3!!!!!)
Backbone 1.0.0 (not 1.1.2 for some reason)
underscore 1.6
require-2.1.11 [production] (for some reason we had 2.1.2)
Then I had to include:true for underscore and backbone in the Karma config. Then the shim works with require 2.1.11 without the mismatched anonymous define error.
Additioanlly, to make sure to delay the test execution. I did not have luck with the waitSeconds (that just increases the test duration).
The key part of the require config:
// since we are forcing Backbone in the dom instead of requiring it
callback: function(){
setTimeout(function () {
window.__karma__.start();
}, 4000);
},

Categories