Testacular/Karma: how to reuse browser's tab? - browser

Each time I re-run Karma, it opens new Chrome window although there is already one on the screen and with the same URL in it.
How to make Karma runner to reuse browser window and if appropriate tab was opened - reuse this tab?

In the config, set
browsers = [];

I've landed here while looked for the same question in a bit different context.
When running tests, there are cases where Karma immediately opens 2 tabs, so that all tests are running twice. Usually this should not be an issue, but in our case that causes some unexpected latencies and sporadic failures.
Indeed, in order to prevent this unwanted behaviour one should add the following to the Karma configuration:
restartOnFileChange: true
This, by Karma's spec, is forcing a runner to stop the current execution and start a fresh one, thus effectively reusing the same current tab.
Default behaviour, restartOnFileChange: false, causes to start a new execution while the current one is continuing to run, thus effectively producing 2 concurrently running tabs.

Add the following line inside the config.set({...}) block:
restartOnFileChange: false,
which is a guarantee.
With that line, whenever you save your file/files, the browser will REFRESH itself automatically instead of reopening.
Just in case, the following is my complete karma.conf.js file, which is very efficient:
// Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', '#angular-devkit/build-angular'],
plugins: [
require('karma-jasmine'),
require('karma-chrome-launcher'),
require('karma-jasmine-html-reporter'),
require('karma-coverage-istanbul-reporter'),
require('#angular-devkit/build-angular/plugins/karma')
],
client: {
jasmine: {
random: false
},
clearContext: false // leave Jasmine Spec Runner output visible in browser
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, 'coverage'),
reports: ['html', 'lcovonly', 'text-summary'],
fixWebpackSourcePaths: true
},
reporters: ['progress', 'kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
restartOnFileChange: false,
});
};
In the block, I added the following myself:
jasmine: {
random: false
},
which makes your "it" blocks show in the order the same as they are in your spec file;
and
restartOnFileChange: false,
whose function is what you want and I've already mentioned above.
You can open your code coverage file in src/coverage/index.html of your project.
Note: Sometimes chrome doesn't refresh automatically after you save a file/files. You just refresh it manually, and the whole test will restart. Very simple.

Related

Suppressing nightwatchjs warnings in terminal output

I'm using nightwatchjs to run my test suite, and I would like to remove the warning messages being outputted to my terminal display.
At the moment, I'm getting loads of these (admittedly genuine) warning messages whilst my scripts are running and it's making the reading of the results harder and harder.
As an example;
Yes they are valid messages, but it's not often possible for me to uniquely pick out each individual element and I'm not interested in them for my output.
So, I'd like to know how I can stop them from being reported in my terminal.
Below is what I've tried so far in my nightwatch.conf.js config file;
desiredCapabilities: {
browserName: 'chrome',
javascriptEnabled : true,
acceptSslCerts: true,
acceptInscureCerts: true,
chromeOptions : {
args: [
'--ignore-certificate-errors',
'--allow-running-insecure-content',
'--disable-web-security',
'--disable-infobars',
'--disable-popup-blocking',
'--disable-notifications',
'--log-level=3'],
prefs: {
'profile.managed_default_content_settings.popups' : 1,
'profile.managed_default_content_settings.notifications' : 1
},
},
},
},
but it's still displaying the warnings.
Any help on this would be really appreciated.
Many thanks.
You can try setting detailed_output property to false in the configuration file. This should stop these details from printing in the console.
You can find a sample config file here.
You can find relevant details available under Output Settings section of official docs here.
Update 1: This looks like a combo of properties which controls this and the below combo works for me.
live_output: false,
silent: true,
output: true,
detailed_output: false,
disable_error_log: false,

How do I get the debugger to recognize the sourcemaps in webstorm 10 using the react starter kit

I created a sample react starter kit project in webstorm using webstorm's pre-defined project template and am trying to set breakpoints in debug mode.
I first built the project using npm run build then set the debug configuration to run build/server.js.
However it won't recognize any of the breakpoints in the original source files and seems to be ignoring the sourcemaps. How can I get it to recognize the sourcemaps and allow me to both set breakpoints in the source files as well as step into the source files.
There is this issue in the react starter kit repo: https://github.com/kriasoft/react-starter-kit/issues/121 but I couldn't see what the resolution was, and unlike the commenter, I couldn't even get it to step into the source files... it just stayed on the generated js files instead.
Well...
WebStorm 10 has no support for sourcemaps generated by Webpack. They are partially supported in WebStorm 11 for client-side applications (see http://blog.jetbrains.com/webstorm/2015/09/debugging-webpack-applications-in-webstorm/), but not supported for Node.js.
so, you can't debug server.js in WebStorm 11, but you can debug client side. To do this, try the following:
change appConfig in src/config.js as follows:
const appConfig = merge({}, config, {
entry: [
...(WATCH ? ['webpack-hot-middleware/client'] : []),
'./src/app.js',
],
output: {
path: path.join(__dirname, '../build/public'),
filename: 'app.js',
},
devtool: 'source-map',
module: {
loaders: [
WATCH ? {
...JS_LOADER,
query: {
// Wraps all React components into arbitrary transforms
// https://github.com/gaearon/babel-plugin-react-transform
plugins: ['react-transform'],
extra: {
'react-transform': {
transforms: [
{
transform: 'react-transform-hmr',
imports: ['react'],
locals: ['module'],
}, {
transform: 'react-transform-catch-errors',
imports: ['react', 'redbox-react'],
},
],
},
},
},
} : JS_LOADER,
...config.module.loaders,
{
test: /\.css$/,
loader: 'style-loader/useable!css-loader!postcss-loader',
},
],
},
});
set up the javascript debug run configuration:
URL: http://localhost:5000
Remote URLs: map project root folder to 'webpack:///path/to/react-starter-kit', like 'webpack:///C:/WebstormProjects/react-starter-kit'
map build/public to http://localhost:5000
This doesn't work perfectly, but works in general - breakpoints in src/routes.js, src/app.js are hit

Should requirejs be included in the main built file when using the requirejs bundles option

I'm running into an issue when using the require bundles option. If the main built file has requirejs inside of it everything works fine until I try to load a file from a different bundle. The bundled file is retrieved but then throws an "define is undefined" error. The only way I have been able to get the bundle to load is to make sure requirejs is not in the main-built file or the pm.js and then to load requirejs with a script tag and use the data-main attribute, but this doesn't seem right.
So something like this initially works when requirejs is included in main-built.js (site loads fine), but I get the "define is undefined" error when pm.js bundle loads
<script type="text/javascript" src="~/dist/main-built.js"></script>
requirejs.config({
bundles: {
'pm': ['pm/dashboard', 'text!pm/dashboard.html']
}
});
This is how I ended up getting it to work, but doesn't seem right.
<script type="text/javascript" src="~/scripts/require.js" data-main="dist/main-debug")"></script>
This durandal task creates the main-built file
durandal: {
main: {
src: ["app/**/*.*", "scripts/durandal/**/*.*", "!app/mockup/**/*.*", "!app/performancemanagement/**/*.*"],
options: {
//name: "scripts/require",
name: "",
baseUrl: requireConfig.baseUrl,
paths: mixIn({}, requireConfig.paths, { "require": "scripts/require.js" }),
exclude: ["jquery", "knockout", "toastr", "moment", "underscore", "amplify"],
optimize: "none",
out: "dist/main-debug.js"
}
},
},
This task builds the pm.js bundle
requirejs: {
compile: {
options: {
include: generateFileList("app/pm", "**/*.*", false, false),
//exclude: ["jquery", "knockout", "toastr", "moment", "underscore", "amplify", "preferenceconstants", "constants", "config", "utility/koutilities", "scripts/logger", "base/viewmodel"]
// .concat(generateFileList("scripts/durandal", "**/*.js", false))
// .concat(generateFileList("app/dataservice", "**/*.js", false))
// .concat(generateFileList("app/model", "**/*.js", false))
// .concat(generateFileList("app/reports", "**/*.js", false)),
baseUrl: "app/",
name: "",
paths: mixIn({}, requireConfig.paths, { "almond": "scripts/almond-custom.js" }),
optimize: 'none',
inlineText: true,
pragmas: {
build: true
},
stubModules: ['text'],
out: "dist/pm.js"
}
}
}
The pm.js bundle gets downloaded and executed when anything in main-built requires it, right now its being done by the router in Durandal, but I'm pretty sure Durandal has nothing to do with the issue.
This appears suspicious in your main file build:
paths: mixIn({}, requireConfig.paths, { "require": "scripts/require.js" }),
I'm not sure what the mixIn bit does as this is not stock RequireJS code, but you seem to want to include RequireJS in the build under the name require, which is definitely wrong. The documentation says:
If you want to include require.js with the main.js source, you can use this kind of command:
node ../../r.js -o baseUrl=. paths.requireLib=../../require name=main include=requireLib out=main-built.js
Since "require" is a reserved dependency name, you create a "requireLib" dependency and map it to the require.js file.

E2E Testing Angular with Karma - ng-scenario 'Module is not defined'

I've been trying to run some e2e tests with Karma.
It's not working for me at all.
Right now I'm getting the following error:
Firefox 28.0.0 (Windows 7) ERROR
ReferenceError: module is not defined
at C:/MYPATH/Test/node_modules/karma-ng-scenario/lib/ind
ex.js:12
Firefox 28.0.0 (Windows 7) ERROR
ReferenceError: browser is not defined
at C:/MYPATH/Test/e2e/scenarios.js:12
My config file looks like this:
module.exports = function(config){
config.set({
basePath : './',
frameworks: ['ng-scenario'],
files : [
'./node_modules/karma-ng-scenario/lib/*.js',
'./e2e/*.js'
],
autoWatch : true,
singleRun : true,
browsers : ['Firefox'],
plugins : [
'karma-ng-scenario',
'karma-chrome-launcher',
'karma-firefox-launcher'
],
junitReporter : {
outputFile: 'test_out/unit.xml',
suite: 'unit'
},
urlRoot : '/__karma/',
proxies : {
'/public/' : 'http://localhost:8080'
}
});
};
My scenarios file just tests to see if the base path redirects.
I've already done a lot of messing with npm to get to this point, most recently "npm install karma-ng-scenario --save-dev" but no luck unfortunately.
In files[] specify path to angular.js as a very first, then any other angular modules you use (angular-mocks.js, angular-resource.js, angular-cookies.js), then any library you use, then your own code.
In files:[...] array you have to specify all the files that contain the actual code to which you are writing tests, if your module is using other modules, then you should add files of all the modules on which your module depends.
suppose you are testing 'someModule' module you have to include the 'someModule' controllers, views, services, directives and other modules if your module depends on them
Note: Assuming your files are in their specific directories
files: [
... //angularjs, angular-mocks, karma, protractor and other files you need
...
'scripts/someModule/controllers/*.js',
'scripts/someModule/services/*.js',
'scripts/someModule/directives/*.js',
'views/someModule/*.html'
]
or simply
files: [
... //angularjs, angular-mocks, karma, protractor and other files you need
...
'scripts/someModule/**/*.js',
'views/someModule/*.html'
]
And make sure to install and include all the testing libraries you depend on (i.e, angularjs, angular-mocks, protrator, karma etc) in the files array
So the configuration I finally got my E2E tests to work with was this:
// Karma configuration
// Generated on Fri Apr 11 2014 02:35:20 GMT+0800 (China Standard Time)
module.exports = function(config) {
config.set({
// base path, that will be used to resolve files and exclude
basePath: '..',
// frameworks to use
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
ANGULAR_SCENARIO,
ANGULAR_SCENARIO_ADAPTER,
'test/e2e/*.js',
],
// list of files to exclude
exclude: [
],
// 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 (has to be installed with `npm install karma-opera-launcher`)
// - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`)
// - PhantomJS
// - IE (only Windows; has to be installed with `npm install karma-ie-launcher`)
//browsers: ['PhantomJS', 'Firefox', 'Chrome'],
browsers: ['Firefox', 'Chrome'],
// 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,
proxies : {
"/": "http://localhost:8080"
},
urlRoot : "/__karma/"
});
};
It seems that a better solution for running end to end tests is to use protractor. NG-SCENARIO is depreciated and will cause warnings but this should still run. https://github.com/angular/protractor

Generating istanbul code coverage reports for jasmine tests run (via grunt) on a browserify bundle in phantomjs

The title says it all really. Despite trawling the internet I haven't found a single example of a solution to this problem.
Here are some near misses
https://github.com/amitayd/grunt-browserify-jasmine-node-example - grunt, browserify and jasmine
https://github.com/gotwarlost/istanbul/issues/59#issuecomment-18799734 - browserify and istanbul
Here is my in-progress code https://github.com/wheresrhys/on-guard/tree/browserify (note it's the 'browserify' branch - Gruntfile.js is a bit of a mess but will tidy it up shortly). My initial investigations using console.log indicate that somehow bundle.src.js is being loaded in the page but when the tests are run (and passed!) the code in bundle.src.js isn't being run, so I have a feeling it might be an aliasing problem... though one that's limited to phantomjs as when I open the specrunner in chrome the code is getting run.
I'm using grunt-browserify + browserify-istanbul + grunt-contrib-jasmine + grunt-template-jasmine-istanbul as solution. This solution has also excluded third party libraries when building source files using browserify.
Show the code first, I'll explain later,
grunt.initConfig({
browserify: {
// build specs using browserify
specs: {
src: ["spec/**/*Spec.js"],
dest: "spec/build/specs.js",
options: {
debug: true
}
},
// build source files using browserify and browserify-istanbul
dev: {
options: {
debug: true,
browserifyOptions: {
standalone: 'abc'
},
transform: [['browserify-istanbul', {
ignore: ['**/node_modules/**'], // ignore third party libs
defaultIgnore: true
}]]
},
src: ['abc.js'],
dest: 'dist/abc.js'
}
},
connect: {
server: {
options: {
port: 7000
}
}
},
// test using jasmine, generate coverage report using istanbul
jasmine: {
coverage: {
src: ['dist/abc.js'],
options: {
junit: {
path: 'bin/junit'
},
host: 'http://localhost:7000/',
specs: 'spec/build/specs.js',
keepRunner: true,
summary: true,
template: require('grunt-template-jasmine-istanbul'),
templateOptions: {
replace: false, // *** this option is very important
coverage: 'bin/coverage/coverage.json',
report: [
{
type: 'html',
options: {
dir: 'spec/coverage/html'
}
}]
}
}
}
}
grunt.registerTask('specs', ['browserify:specs', 'browserify:dev', 'connect', 'jasmine']);
The steps of generating istanbul coverage report can be concluded into three:
Instrument code
Run test
Generate coverage report
In our solution, we use browerify-istanbul in step 1, grunt-contrib-jasmine and runt-template-jasmine-istanbul in step 2 and 3.
browserify-istanbul will let you instrument code in browserify building step, in this way, we can easily ignore third party libs. But the grunt-template-jasmine-istanbul will instrument code again. To avoid this, you can set replace to false in the options.
Refs:
Istanbul steps
broswerify-istanbul
grunt-contrib-jasmine
grunt-template-jasmine-istanbul -- replace option

Resources