How to test Durandal.js viewmodel containing i18next implementation? - jasmine

I'm new to both Durandal.js and Javascript testing with Jasmine, and need some help. I have managed to get a testing environment up and running with Karma and Jasmine, but I struggle to figure out how to test my viewmodels that contains i18next dependencies.
Here's a stripped down example of my setup:
main.js
requirejs.config({
paths: {
'models': 'models',
'text': '../lib/require/text',
'durandal': '../lib/durandal/js',
'plugins': '../lib/durandal/js/plugins',
'transitions': '../lib/durandal/js/transitions',
'knockout': '../lib/knockout/knockout-2.3.0',
'bootstrap': '../lib/bootstrap/js/bootstrap.min',
'jquery': '../lib/jquery/jquery-1.9.1',
'i18next': '../lib/i18next/i18next.amd.withJQuery-1.7.1.min'
}
});
define(['plugins/router', 'durandal/system', 'durandal/app', 'durandal/binder', 'durandal/viewLocator', 'knockout', 'jquery', 'i18next'], function (router, system, app, binder, viewLocator, ko, $, i18n) {
app.configurePlugins({
router: true
});
app.start().then(function () {
// Setup of i18n
i18n.init({
detectFromHeaders: false,
fallbackLng: 'en',
preload: ['nb', 'en'],
supportedLngs: ['nb', 'en'],
resGetPath: 'locales/__lng__.json',
useCookie: true,
}, function () {
binder.binding = function (obj, view) {
$(view).i18n();
};
viewLocator.useConvention();
app.setRoot('viewmodels/shell');
});
});
});
shell.js
define(['plugins/router', 'durandal/app', 'i18next'], function (router, app, i18n) {
return {
router: router,
activate: function () {
return router.map([
{ route: '', title: i18n.t('pageTitle'), moduleId: 'viewmodels/ViewModel', nav: true }
]).buildNavigationModel().mapUnknownRoutes('viewmodels/ViewModel', 'unknown').activate({
pushState: false,
hashChange: true
});
}
};
});
test.js (own require.js config)
var tests = [];
for (var file in window.__karma__.files) {
if (window.__karma__.files.hasOwnProperty(file)) {
if (/.*\.spec\.js$/.test(file)) {
tests.push(file);
}
}
}
//Workaround for the timestamp issue
for (var file in window.__karma__.files) {
window.__karma__.files[file.replace(/^\//, '')] = window.__karma__.files[file];
}
require.config({
baseUrl: 'base',
paths: {
'models': 'app/models',
'viewModels': 'app/viewmodels',
'specs': 'tests/specs/',
'text': 'lib/require/text',
'durandal': 'lib/durandal/js',
'plugins': 'lib/durandal/js/plugins',
'transitions': 'lib/durandal/js/transitions',
'knockout': 'lib/knockout/knockout-2.3.0',
'jquery': 'lib/jquery/jquery-1.9.1',
'i18next': 'lib/i18next/i18next.amd.withJQuery-1.7.1.min',
},
// ask Require.js to load these files (all our tests)
deps: tests,
// start test run, once Require.js is done
callback: window.__karma__.start
});
karma.conf.js
// Karma configuration
module.exports = function (config) {
config.set({
// base path, that will be used to resolve files and exclude
basePath: '',
// frameworks to use
frameworks: ['jasmine', 'requirejs'],
// list of files / patterns to load in the browser
files: [
{ pattern: 'lib/jquery/jquery-1.9.1.js', watched: false, included: true, served: true },
{ pattern: 'tests/jasmine/jasmine-jquery.js', watched: false, served: true, included: true },
{ pattern: 'tests/specs/**/*.js', included: false },
{ pattern: 'tests/sinon.js', included: false },
{ pattern: 'lib/**/*.js', included: false, served: true },
{ pattern: 'app/**/*.js', included: false, served: true },
'tests/test.js',
//Serve the fixtures
{ pattern: 'app/**/*.html', watched: true, served: true, included: false },
{ pattern: 'app/**/*.json', watched: true, served: true, included: false },
{ pattern: 'tests/**/*.json', watched: true, served: true, included: false }
],
preprocessors: [
{ '**/*.html': '' }
],
// list of files to exclude
exclude: [
'foundation/*.js',
'require.js',
'init.js',
'jasmine/jasmine.js',
'jasmine/jasmine-html.js',
'node_modules/**/*.html'
],
// test results reporter to use
// possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// Start these browsers, currently available:
// - Chrome
// - ChromeCanary
// - Firefox
// - Opera
// - Safari (only Mac)
// - PhantomJS
// - IE (only Windows)
browsers: ['PhantomJS'],
//browsers: ['Chrome', 'Firefox', 'IE'],
// If browser does not capture in given timeout [ms], kill it
captureTimeout: 60000,
// Continuous Integration mode
// if true, it capture browsers, run tests and exit
singleRun: false
});
};
ViewModel (i18next):
define(["i18next"], function (i18n) {
var pageTitle = i18n.t("pageTitle");
return {
pageTitle: pageTitle
};
});
Spec (i18next)
define(['viewModels/ViewModel'], function (ViewModel) {
describe("Viewmodel test", function () {
it("should be testable", function () {
expect(true).toEqual(true);
});
it("should have title", function () {
expect(ViewModel.pageTitle).not.toBeEmpty();
});
});
});
Test runner output
PhantomJS 1.9.2 (Mac OS X) ERROR
ReferenceError: Can't find variable: initialized
at /Users/xxx/dev/projectXYZ/lib/i18next/i18next.amd.withJQuery-1.7.1.min.js:5
PhantomJS 1.9.2 (Mac OS X): Executed 0 of 0 ERROR (0.312 secs / 0 secs)
ViewModel (wo/i18next):
define([], function () {
var pageTitle = "This is the page title";
return {
pageTitle: pageTitle
};
});
Spec (wo/i18next)
define(['viewModels/ViewModel'], function (ViewModel) {
describe("Viewmodel test", function () {
it("should be testable", function () {
expect(true).toEqual(true);
});
it("should have title", function () {
expect(ViewModel.pageTitle).toEqual("This is the page title");
});
});
});
Test runner output (wo/i18next)
PhantomJS 1.9.2 (Mac OS X): Executed 2 of 2 SUCCESS (0.312 secs / 0.164 secs)
I guess I have to somehow initialize i18next, but I dont know how.
Any help would be much appreciated.
Regards,
Remi
UPDATE
This is what I ended up doing:
test.js:
'i18next-original': 'lib/i18next/i18next.amd.withJQuery-1.7.1.min',
'i18next': 'tests/i18n-test'
i18n-test.js:
define(['i18next-original'], function (i18noriginal) {
'use strict';
i18noriginal.init({
lng: 'nb',
detectFromHeaders: false,
fallbackLng: 'en',
preload: ['nb', 'en'],
supportedLngs: ['nb', 'en'],
resGetPath: 'base/locales/__lng__.json',
useCookie: false,
debug: false,
getAsync: false
});
return i18noriginal;
});
karma.conf.js:
{ pattern: 'tests/i18n-test.js', included: false, served: true },

Hallais Remi!
You can initialize i18next in beforeEach like this:
define(['viewModels/ViewModel', 'i18next'], function (ViewModel, i18n) {
describe("Viewmodel test", function () {
beforeEach(function() {
var initialized = false;
runs(function() {
i18n.init({
detectFromHeaders: false,
fallbackLng: 'en',
preload: ['nb', 'en'],
supportedLngs: ['nb', 'en'],
resGetPath: 'locales/__lng__.json',
useCookie: true
}, function () { initialized = true; });
});
waitsFor(function() {
return initialized;
}, 'i18n to initialize', 100);
});
it("should be testable", function () {
expect(true).toEqual(true);
});
it("should have title", function () {
expect(ViewModel.pageTitle).not.toBeEmpty();
});
});
});
For focusing the test on code inside the viewModel itself you can consider instead to mock the i18n object used in your viewModel.
testr.js might help you mock require.js dependencies: https://github.com/medallia/testr.js

Related

Gulp 4 error: The following tasks did not complete: Did you forget to signal async completion?

I get this error when isDev = false. Here is my part of gulpfile.js
function CSSLoaders(isDev) {
let loaders = []
isDev ? loaders.push('vue-style-loader') : loaders.push(MiniCssExtractPlugin.loader)
loaders.push({
loader: 'css-loader',
options: {
url: false,
sourceMap: isDev,
importLoaders: isDev ? 1 : 2,
modules: {
localIdentName: "[local]"
}
}
})
if (!isDev) {
loaders.push('postcss-loader')
loaders.push({
loader: 'string-replace-loader',
options: {
multiple: [...Array(100).fill({search: '../..', replace: ''})]
}
})
}
return loaders
}
function webpackConfig(isDev) {
return {
output: {
filename: '[name].js'
},
resolve: {
extensions: ['.js', '.vue', '.json'],
alias: {
// 'vue': 'vue/dist/vue.esm-bundler.js',
'vue': 'vue/dist/vue.esm.js',
// 'mixins-c': path.resolve(__dirname, '../../sass/_mixins-c.scss;')
}
},
module: {
rules: [
{
test: /\.s[ac]ss$/i,
use: CSSLoaders(isDev)
},
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: '/node_modules/'
}
]
},
plugins: [
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: isDev ? 'css/[name].css' : 'skin/lightui/css/[name].css'
}),
// new cssoLoader(),
new webpack.LoaderOptionsPlugin({
minimize: true
})
],
optimization: {
minimizer: [
new UglifyJsPlugin({
sourceMap: false,
uglifyOptions: {
warnings: false,
compress: true
}
})
],
},
mode: isDev ? 'development' : 'production',
devtool: isDev ? 'eval-source-map' : 'none'
}
};
function js_build() {
return src(['src/pages/**/js/*.js'])
.pipe(named())
.pipe(webpackStream(webpackConfig(false)))
.pipe(dest('dist/js/'))
}
let build = gulp.series(js_build)
exports.build = build
I tried
async function js_build() {
return await src(['src/pages/**/js/*.js'])
.pipe(named())
.pipe(webpackStream(webpackConfig(false)))
.pipe(dest('dist/js/'))
}
and
var print = require('gulp-print');
function js_build() {
return src(['src/pages/**/js/*.js'])
.pipe(named())
.pipe(webpackStream(webpackConfig(false)))
.pipe(dest('dist/js/'))
.pipe(print.default(function() { return 'HTTP Server Started'; }));
}
But got the same error. I've found out that the problem disappear with block in function CSSLoaders():
if (!isDev) {
loaders.push('postcss-loader')
loaders.push({
loader: 'string-replace-loader',
options: {
multiple: [...Array(100).fill({search: '../..', replace: ''})]
}
})
}
I dont understand why i can use "css-loader" without mistakes and cannot "postcss-loader", what the difference? Where should i put the sign, that async is completed?
Can anyone help me understand what i should do?
Using callback and onEnd method should do the trick.
function js_build(callback) {
return src(['src/pages/**/js/*.js'])
.pipe(named())
.pipe(webpackStream(webpackConfig(false)))
.pipe(dest('dist/js/'))
.pipe(print.default(function() { return 'HTTP Server Started'; }))
.on('end', function () {
callback();
});
}
This question was answer here :
Gulp error: The following tasks did not complete: Did you forget to signal async completion?

Nativescript-Angular code sharing: How do I create platform specific modules?

Imagine I have OrderComponent and CustomerComponent that represent two screens.
In the web version you can create a new customer while in the order screen by launching the customer component inside a popup. So OrderComponent references CustomerComponent directly in the template. So I have to keep both in the same FeaturesModule for this to work.
On the other hand in the Nativescript mobile version, there is no such capability and so the two components/screens are completely independent, so I would like to put them in 2 separate modules: OrderModule, and CustomerModule. And lazy load them so the app launches faster.
In my real application of course it's not just 2 components but several dozens so the mobile app performance is a more pressing issue.
When I try to add a module file with the tns extension like this: order.module.tns.ts, without the corresponding web file, it seems as if the NativeScript bundler is not picking it up, I get the following error:
ERROR: C:\...\src\app\features\orders\orders.module.ts is missing from the TypeScript compilation. Please make sure it is in your tsconfig via the 'files' or 'include' property.
at AngularCompilerPlugin.getCompiledFile (C:\Users\...\node_modules\#ngtools\webpack\src\angular_compiler_plugin.js:753:23)
at plugin.done.then (C:\Users\...\node_modules\#ngtools\webpack\src\loader.js:41:31)
at process._tickCallback (internal/process/next_tick.js:68:7)
# ../$$_lazy_route_resource lazy namespace object ./features/measurement-units/measurement-units.module
# ../node_modules/#angular/core/fesm5/core.js
# ../node_modules/nativescript-angular/platform.js
# ./main.ns.ts
But according to the docs, all I have to do to make a nativescript specific component is add it with the tns extension. Is there another step to make this work for module files?? Help is appreciated
Update
Here is my tsconfig.tns.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "es2015",
"moduleResolution": "node",
"baseUrl": "./",
"paths": {
"~/*": [
"src/*"
],
"*": [
"./node_modules/tns-core-modules/*",
"./node_modules/*"
]
}
}
}
Update 2
My webpack.config.js:
const { join, relative, resolve, sep } = require("path");
const webpack = require("webpack");
const nsWebpack = require("nativescript-dev-webpack");
const nativescriptTarget = require("nativescript-dev-webpack/nativescript-target");
const { nsReplaceBootstrap } = require("nativescript-dev-webpack/transformers/ns-replace-bootstrap");
const CleanWebpackPlugin = require("clean-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const { BundleAnalyzerPlugin } = require("webpack-bundle-analyzer");
const { NativeScriptWorkerPlugin } = require("nativescript-worker-loader/NativeScriptWorkerPlugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const { AngularCompilerPlugin } = require("#ngtools/webpack");
module.exports = env => {
// Add your custom Activities, Services and other Android app components here.
const appComponents = [
"tns-core-modules/ui/frame",
"tns-core-modules/ui/frame/activity",
];
const platform = env && (env.android && "android" || env.ios && "ios");
if (!platform) {
throw new Error("You need to provide a target platform!");
}
const projectRoot = __dirname;
// Default destination inside platforms/<platform>/...
const dist = resolve(projectRoot, nsWebpack.getAppPath(platform, projectRoot));
const appResourcesPlatformDir = platform === "android" ? "Android" : "iOS";
const {
// The 'appPath' and 'appResourcesPath' values are fetched from
// the nsconfig.json configuration file
// when bundling with `tns run android|ios --bundle`.
appPath = "app",
appResourcesPath = "app/App_Resources",
// You can provide the following flags when running 'tns run android|ios'
aot, // --env.aot
snapshot, // --env.snapshot
uglify, // --env.uglify
report, // --env.report
sourceMap, // --env.sourceMap
hmr, // --env.hmr,
} = env;
const externals = (env.externals || []).map((e) => { // --env.externals
return new RegExp(e + ".*");
});
const appFullPath = resolve(projectRoot, appPath);
const appResourcesFullPath = resolve(projectRoot, appResourcesPath);
const entryModule = `${nsWebpack.getEntryModule(appFullPath)}.ts`;
const entryPath = `.${sep}${entryModule}`;
const ngCompilerPlugin = new AngularCompilerPlugin({
hostReplacementPaths: nsWebpack.getResolver([platform, "tns"]),
platformTransformers: aot ? [nsReplaceBootstrap(() => ngCompilerPlugin)] : null,
mainPath: resolve(appPath, entryModule),
tsConfigPath: join(__dirname, "tsconfig.tns.json"),
skipCodeGeneration: !aot,
sourceMap: !!sourceMap,
});
const config = {
mode: uglify ? "production" : "development",
context: appFullPath,
externals,
watchOptions: {
ignored: [
appResourcesFullPath,
// Don't watch hidden files
"**/.*",
]
},
target: nativescriptTarget,
entry: {
bundle: entryPath,
},
output: {
pathinfo: false,
path: dist,
libraryTarget: "commonjs2",
filename: "[name].js",
globalObject: "global",
},
resolve: {
extensions: [".ts", ".js", ".scss", ".css"],
// Resolve {N} system modules from tns-core-modules
modules: [
resolve(__dirname, "node_modules/tns-core-modules"),
resolve(__dirname, "node_modules"),
"node_modules/tns-core-modules",
"node_modules",
],
alias: {
'~': appFullPath
},
symlinks: true
},
resolveLoader: {
symlinks: false
},
node: {
// Disable node shims that conflict with NativeScript
"http": false,
"timers": false,
"setImmediate": false,
"fs": "empty",
"__dirname": false,
},
devtool: sourceMap ? "inline-source-map" : "none",
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
name: "vendor",
chunks: "all",
test: (module, chunks) => {
const moduleName = module.nameForCondition ? module.nameForCondition() : '';
return /[\\/]node_modules[\\/]/.test(moduleName) ||
appComponents.some(comp => comp === moduleName);
},
enforce: true,
},
}
},
minimize: !!uglify,
minimizer: [
new UglifyJsPlugin({
parallel: true,
cache: true,
uglifyOptions: {
output: {
comments: false,
},
compress: {
// The Android SBG has problems parsing the output
// when these options are enabled
'collapse_vars': platform !== "android",
sequences: platform !== "android",
}
}
})
],
},
module: {
rules: [
{
test: new RegExp(entryPath),
use: [
// Require all Android app components
platform === "android" && {
loader: "nativescript-dev-webpack/android-app-components-loader",
options: { modules: appComponents }
},
{
loader: "nativescript-dev-webpack/bundle-config-loader",
options: {
angular: true,
loadCss: !snapshot, // load the application css if in debug mode
}
},
].filter(loader => !!loader)
},
{ test: /\.html$|\.xml$/, use: "raw-loader" },
// tns-core-modules reads the app.css and its imports using css-loader
{
test: /[\/|\\]app\.css$/,
use: {
loader: "css-loader",
options: { minimize: false, url: false },
}
},
{
test: /[\/|\\]app\.scss$/,
use: [
{ loader: "css-loader", options: { minimize: false, url: false } },
"sass-loader"
]
},
// Angular components reference css files and their imports using raw-loader
{ test: /\.css$/, exclude: /[\/|\\]app\.css$/, use: "raw-loader" },
{ test: /\.scss$/, exclude: /[\/|\\]app\.scss$/, use: ["raw-loader", "resolve-url-loader", "sass-loader"] },
{
test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
use: [
"nativescript-dev-webpack/moduleid-compat-loader",
"#ngtools/webpack",
]
},
// Mark files inside `#angular/core` as using SystemJS style dynamic imports.
// Removing this will cause deprecation warnings to appear.
{
test: /[\/\\]#angular[\/\\]core[\/\\].+\.js$/,
parser: { system: true },
},
],
},
plugins: [
// Define useful constants like TNS_WEBPACK
new webpack.DefinePlugin({
"global.TNS_WEBPACK": "true",
"process": undefined,
}),
// Remove all files from the out dir.
new CleanWebpackPlugin([`${dist}/**/*`]),
// Copy native app resources to out dir.
new CopyWebpackPlugin([
{
from: `${appResourcesFullPath}/${appResourcesPlatformDir}`,
to: `${dist}/App_Resources/${appResourcesPlatformDir}`,
context: projectRoot
},
]),
// Copy assets to out dir. Add your own globs as needed.
new CopyWebpackPlugin([
{ from: "fonts/**" },
{ from: "**/*.jpg" },
{ from: "**/*.png" },
], { ignore: [`${relative(appPath, appResourcesFullPath)}/**`] }),
// Generate a bundle starter script and activate it in package.json
new nsWebpack.GenerateBundleStarterPlugin([
"./vendor",
"./bundle",
]),
// For instructions on how to set up workers with webpack
// check out https://github.com/nativescript/worker-loader
new NativeScriptWorkerPlugin(),
ngCompilerPlugin,
// Does IPC communication with the {N} CLI to notify events when running in watch mode.
new nsWebpack.WatchStateLoggerPlugin(),
],
};
if (report) {
// Generate report files for bundles content
config.plugins.push(new BundleAnalyzerPlugin({
analyzerMode: "static",
openAnalyzer: false,
generateStatsFile: true,
reportFilename: resolve(projectRoot, "report", `report.html`),
statsFilename: resolve(projectRoot, "report", `stats.json`),
}));
}
if (snapshot) {
config.plugins.push(new nsWebpack.NativeScriptSnapshotPlugin({
chunk: "vendor",
angular: true,
requireModules: [
"reflect-metadata",
"#angular/platform-browser",
"#angular/core",
"#angular/common",
"#angular/router",
"nativescript-angular/platform-static",
"nativescript-angular/router",
],
projectRoot,
webpackConfig: config,
}));
}
if (hmr) {
config.plugins.push(new webpack.HotModuleReplacementPlugin());
}
return config;
};

Webpack img(image) path error

I'm using webpack in my project, there are two images in my project.
the first image path is: /build/img/1.png (The following is called A)
the second image path is /build/img/2.png, (The following is called B)
The two pictures have the same path. but, the A can be displayed on the page, B can not.
my webpack.config.js:
var webpack = require('webpack');
var path = require('path');
var fs = require('fs');
var AssetsPlugin = require('assets-webpack-plugin');
// var assetsPluginInstance = new AssetsPlugin();
// var proxy = require('http-proxy-middleware');
var remotePath = "./__build__/";
fs.readdir(remotePath, function (err, files) {
if (!err) {
for (var i = 0; i < files.length; i++) {
var filesName = files[i];
if (filesName.indexOf("chunk.js") > 1) {
fs.unlink('./__build__/' + filesName);
}
}
}
});
module.exports = {
entry: {
bundle: "./web_app/index.js"
},
devtool: 'cheap-module-eval-source-map',
output: {
path: __dirname + '/__build__',
filename: '[name].js',
chunkFilename: (new Date()).getTime() + '[id].chunk.js',
publicPath: '/__build__/'
},
devServer: {
hot: true,
inline: true,
proxy: {
'*': {
changeOrigin: true,
//target: 'xxx',
target: 'xxx',
secure: false
}
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
},
}),
// new webpack.HotModuleReplacementPlugin(),
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./__build__/dll/lib-manifest.json')
}),
new AssetsPlugin({
filename: '__build__/webpack.assets.js',
processOutput: function (assets) {
return 'window.WEBPACK_ASSETS = ' + JSON.stringify(assets);
}
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
}),
// new webpack.optimize.UglifyJsPlugin({
// mangle: {
// except: ['$super', '$', 'exports', 'require']
// },
// compress: {
// warnings: false,
// },
// output: {
// comments: false,
// },
// }),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
],
resolve: {
extensions: ['', '.js', '.jsx'],
resolve: {
alias: {
moment: "moment/min/moment-with-locales.min.js"
}
}
},
module: {
loaders: [
{
test: /\.jsx?$/,
// loaders: ['babel-loader?presets[]=es2015&presets[]=react&presets[]=stage-0'],
loader: 'babel-loader',
query: {
plugins: ["transform-object-assign", "add-module-exports"],
presets: ['es2015', 'stage-0', 'react']
},
include: path.join(__dirname, '.')
}, {
test: /\.css$/,
loader: 'style!css'
}, {
test: /\.less$/,
loader: 'style!css!less'
}, {
test: /\.(eot|woff|svg|ttf|woff2|gif|appcache)(\?|$)/,
exclude: /^node_modules$/,
loader: 'file-loader?name=[name].[ext]'
}, {
test: /\.(png|jpg)$/,
exclude: /^node_modules$/,
loader: 'url?name=[name].[ext]'
}
]
}
};
my project structure
Image sequence: React code, project directory, dev Tool
I've merged several images, because stackoverflow rules that I can only publish two links

Gulp watch task not running karma jasmine tests

I'm trying to setup a gulp watch task to run all test under a set of folder, I can get the gulp tasks to run successful:
[10:20:15] Finished 'karma' after 5.86 s
[10:20:15] Starting 'default'...
[10:20:15] Finished 'default' after 9.45 ms
But no notification of any test passing?
Here is my karma.config:
var webpack = require("webpack"),
path = require("path");
module.exports = function (config) {
config.set({
basePath: "",
frameworks: ["jasmine"],
files: [
"./App/src/tests/**/*.js"
],
preprocessors: {
"./App/src/tests/**/*.js": ["webpack"]
},
webpack: {
module: {
loaders: [
{ test: /\.js$/, loader: "jsx-loader" }
]
},
plugins: [
new webpack.ResolverPlugin([
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"])
])
],
resolve: {
root: [path.join(__dirname, "./bower_components"), path.join(__dirname, "./src")]
}
},
webpackMiddleware: {
noInfo: true
},
plugins: [
require("karma-webpack"),
require("karma-jasmine"),
require("karma-chrome-launcher")
],
reporters: ["dots"],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ["Chrome"],
singleRun: false
});
};
Here is my karma.js:
var gulp = require('gulp');
var karma = require('gulp-karma');
function handleError(err) {
this.emit('end');
}
gulp.task('karma', function() {
return gulp
.src('./App/src/tests/**/*.js')
.pipe(karma({
configFile: 'karma.conf.js',
action: 'run'
}))
.on("error", handleError);
});
Gulpfile:
var gulp = require('gulp'),
requireDir = require('require-dir');
requireDir('./gulp-tasks');
gulp.task('default', ['browserify','css','karma'], function () {
gulp.watch('../App/src/**/*.js', ['browserify']);
gulp.watch('../App/src/**/*.css', ['css']);
gulp.watch('../App/src/tests/**/*.js', ['karma']);
});

Jasmine HTML2 Reporter

I have been using Jasmine2-HTML-Reporter and it's been fine. Produces a multi-spec report with screenshots - just as I need.
However, something seems to have gone awry! Now I will only get a report for the first Spec and nothing for any other spec. Also, the system used to delete the previous report/screenshot but now this has to be done manually.
I really cannot think what's changed in the rest of the package to cause this!!
Here's the entry in the conf.js files...identical for each conf file. I've tried adding the various switches - no effect at all!
Thanks
var Jasmine2HtmlReporter = require('protractor-jasmine2-html-reporter');
exports.config = {
//seleniumAddress: 'http://localhost:444/wd/hub',
params: require ('Models/Baths.js'),
directConnect: true,
capabilities: {
cssSelectorsEnabled: true,
'browserName': 'chrome',
specs:['Specs/001-First.js',
'Specs/003-Exp.js'
],
allScriptsTimeout: 120000,
getPageTimetout: 30000,
framework: 'jasmine2',
showColors: true,
isVerbose: true,
onPrepare: function() {
Jasmine.getEnv().addReporter(
new Jasmine2HtmlReporter({
takeScreenshots: true,
savePath: './Reports',
fileName: 'B&Q'
})
);
var SpecReporter = require ( 'jasmine-spec-reporter').SpecReporter;
jasmine.getEnv().addReporter( new SpecReporter( {
displayStacktrace: true,
displayFailureSummary: true,
displayPendingSummary: true,
displaySuccessfulSpec: true,
displayFailedSpec: true,
displaySpecDuration: true,
displaySuiteNumber: false,
colors: {
success: 'green',
failure: 'red',
pending: 'yellow'
},
customProcessors: []
} ));
}
}
};
Try with below conf file, it should work for you.
var Jasmine2HtmlReporter = require('protractor-jasmine2-html-reporter');
var log4js = require('log4js');
var params = process.argv;
var args = process.argv.slice(3);
exports.config = {
//seleniumServerJar: './node_modules/gulp-protractor/node_modules/protractor/selenium/selenium-server-standalone-2.48.2.jar',
seleniumAddress: 'http://localhost:4444/wd/hub',
allScriptsTimeout: 100000,
framework: 'jasmine2',
onPrepare: function () {
browser.manage().timeouts().implicitlyWait(11000);
var width = 768;
var height = 1366;
browser.driver.manage().window().setSize(768, 1366);
browser.ignoreSynchronization = false;
jasmine.getEnv().addReporter(
new Jasmine2HtmlReporter({
savePath: __dirname+'/qualityreports/testresults/e2e',
takeScreenshots: false,
filePrefix: 'automationReport',
consolidate: true,
cleanDestination: false,
consolidateAll: true
})
);
},
suites:{
example:['./test/e2e/specs/**/*Spec.js',]
},
capabilities: {
'browserName': 'chrome'
},
resultJsonOutputFile:'./results.json',
// Options to be passed to Jasmine-node.
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 100000
}
};

Resources