auto-refresh (gulp+livereload+jasmine) - unit-testing

I'm trying to creat a gulp task to run a test and automatically refresh when changes occur in any .js test file.
This is the code:
gulp.task('watch-test', function() {
// start live-reload server
plugins.livereload.listen({ start: true});
var filesForTest = [ 'bower_components/angular/angular.js',
'bower_components/angular-mocks/angular-mocks.js',
'src/app/blocks/testController.module.js',
'src/app/blocks/testController.js',
'src/test/spec/sillyControllerSpec.js']
return gulp.src(filesForTest)
.pipe(watch(filesForTest))
.pipe(plugins.jasmineBrowser.specRunner())
.pipe(plugins.jasmineBrowser.server({port: 8888}))
.pipe(plugins.livereload());
});
It watches the files, but I have to refresh manually the page at the browser.
Any idea what can I do?

I found this package that incluide jasmine + livereload
https://www.npmjs.com/package/gulp-jasmine-livereload-task

Related

Webpack hot module replacement through Django template

I'm trying to set up hot module replacement for my bundled frontend static assets that are served through Django's template system, if that's even possible. I'm currently refreshing the page via livereload whenever the compiled assets are changed, but the compile times are getting longer and any CSS changes end up triggering a full page reload.
Here is an example of the template file in Django.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- Header Links -->
</head>
<body>
<div id="app"></div>
<script type="text/javascript">
window.CONFIG = {
/** Injected application configuration from Django. */
};
</script>
<!-- Webpack bundle url -->
<script src="{{ bundle_url }}"></script>
</body>
</html>
I've been able to serve the assets through webpack dev server and inject the bundle url http://localhost:3000/bundle.js through template variables, so I can see the application in the view.
Webpack Configuration
'use strict';
const webpack = require('webpack');
const CONFIG = require('./config');
/**
* Webpack configuration for a development environment.
* #type {Object}
*/
module.exports = {
devtool: 'cheap-module-eval-source-map',
entry: [
require.resolve('core-js/shim'),
CONFIG.PATHS.ENTRY,
],
output: {
path: CONFIG.PATHS.BUILD,
filename: CONFIG.OUTPUT_FILENAME,
},
module: {
rules: CONFIG.SHARED_RULES.concat([{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
}, {
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}]),
},
resolve: CONFIG.WEBPACK_RESOLVE,
plugins: [
new webpack.HotModuleReplacementPlugin(),
],
};
Start Script:
'use strict';
// Crashes the script on unhandled rejections instead of silently ignoring.
process.on('unhandledRejection', (error) => { throw error; });
process.env.NODE_ENV = 'development';
// Vendor
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const chalk = require('chalk');
// Local
const WEBPACK_CONFIG = require('../config/webpack.config.dev');
const CONFIG = require('../config/config');
const PORT = parseInt(process.env.PORT, 10) || CONFIG.DEFAULT_PORT;
const HOST = process.env.HOST || CONFIG.DEFAULT_HOST;
const URL = `http://${HOST}:${PORT}/`;
const compiler = webpack(WEBPACK_CONFIG);
const server = new WebpackDevServer(compiler, {
compress: true,
hot: true,
host: HOST,
stats: 'minimal',
});
server.listen(PORT, HOST, (error) => {
if (error) { return console.log(chalk.red(error)); }
console.log(chalk.cyan(`Starting the development server at ${URL}...`));
['SIGINT', 'SIGTERM'].forEach((signal) => {
process.on(signal, () => {
server.close();
process.exit();
});
});
});
I'm uncertain how the dev server triggers a hot reload. I was under the impression that the bundle includes a script that connects to a Websocket connection on the dev server and that the connection would trigger the script to download and display the new assets. This may not be the case though, and I haven't been able to find any info pertaining to how hot reloads are communicated. I've only found a general overview of how hot reloads work once the client receives the update.
After a lot of searching, I finally found a solution to my problem. I found information about how to integrate webpack-dev-server with an existing server in the old webpack docs, so I got rid of the entire build script and replaced it with a script in package.json that only used webpack-dev-server without any flags at all:
"scripts": {
"start": "cross-env NODE_ENV=development webpack-dev-server",
// Scripts...
}
This automatically injected the hot module replacement code into my bundle and refreshes my page on a change. This is much faster than my previous livereload server. The bundle is referenced via the url http:localhost:8080/bundle.js in my application template and not by a local path. Local paths wouldn't work anyways since the bundles are saved in memory.
The url also explains how to get the --inline --hot functionality working too, but I was never able to get it to work on my setup.
If you need to use local path's instead of referencing the bundles via url, than you would have to rely on using webpack's watch mode and manually refreshing the page or rely on a Django plugin. The solution I found worked well for me because it mirrors our production environment. Our Django deployment references the frontend assets through a CDN that we manage. It may not work well for you if you have to deploy the frontend assets with your Django code, but it's possible if you create a Django setting that toggles between two different application templates: one for development that uses the URL to pull in the script and one for production that references the files from the STATICFILES_DIRS.
The problem I don't think is Webpack's fault. I've noticed these speed problems occur when I had Django serve my React files. When you use Django, your files are served by the Django server, and that inherently is pretty slow compared to the webpack-dev server. The whole communication process between webpack dev server to Django can be time taking, which has to have the Django server to trigger a change and then re-serve the static files again.
One solution to this would be to isolate React front end code from the backend code and have your React consume your Django's REST API. It runs extremely smooth and reduces a lot of load on the server.

phantomjs not showing form fields

I am using following js script to phantomjs on ember site running locally:
//test_phantomjs.js
require('phantomjs-polyfill');
var page = require('webpage').create();
page.open('http://localhost:4200/', function(status) {
console.log("Status: " + status);
if(status === "success") {
page.render('example.png');
}
phantom.exit();
});
The command I run the test this script is as follow:
phantomjs --remote-debugger-port=9001 --remote-debugger-autorun=yes test_phantomjs.js
I am suppose to get login form, but instead I am not getting the form just an empty page.
however if change the url to development ember app, then I get the full page with form fields.
How can I fix it for locally running ember app so I can test this with poltergeist?

ember cli multiple index files

I have an ember-cli based app which needs to be integrated into an existing java/JSP app. For this to happen I need to generate a JSP file with js/css fingerprinted URLs which are generated by ember-cli/broccoli-asset-rev.
This is working fine for a html file and I can set it use a JSP file by changing my Brocfile.js to include:
var app = new EmberApp({
outputPaths: {
app : {
html: 'index.jsp'
}
}
});
but this prevents ember serve working as it uses the index.jsp as the html file. Is it possible to have both generated?
After trying many things I have come up with two solutions, both have drawbacks. The first is to use make a new broccoli tree and merge it with he app tree then explicity run broccoli-asset-rev on the resulting tree. The downside of this is that the mustache does not get hydrated, this is useful for outputting config. This would look something like:
//Brocfile.js
var mergeTrees = require('broccoli-merge-trees');
var funnel = require('broccoli-funnel');
var assetRev = require('broccoli-asset-rev');
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
var jspTree;
var app = new EmberApp({
fingerprint: {
enabled: false
},
storeConfigInMeta: false
});
jspTree = funnel('app', {
files: ['index.jsp']
});
module.exports = assetRev(mergeTrees([appTree = app.toTree(), jspTree]), {
extensions: ['js', 'css'],
replaceExtensions: ['jsp', 'html']
});
The other solution is the override a private api method in ember-cli which builds the tree for the index. This solution does let the mustache get hydrated but relies on a private method. You can find details here and here
How about adding symbolic link?
ln -s index.jsp index.html
Depending on what build tool you're using in your project, I'd probably recommend something like the following:
Put some placeholder sections in your index.html.
Copy index.jsp to index.jsp.tmp.
Copy in code from index.jsp into your placeholder sections.
Move index.jsp.tmp back to index.jsp and clean up.
You might consider something like gulp-replace to do the work.

Selectively Run Mocha Tests In Browser

I want to selectively run mocha tests in the browser even after multiple files with tests have been loaded with requirejs. At the moment if I load user_model_tests and user_view_tests with require js, every time after that when I call mocha.run() all of them are run.
The end goal is to run tests selectively based on the user checking off boxes on a form, and having only those tests appear in the browser. Right now, this works the first time to selectively load and run tests, but once tests are loaded, even if the user unchecks the boxes, the tests are still run because they were required in previously.
Is there a solution within the mocha framework to this? Or do I have to somehow dump requirejs's cache?
var TestRunner = {
start: function(tests) {
require(tests, function(require) { mocha.run() });
},
formListener: function() {
$('form.test-selector').submit(function(event) {
event.preventDefault();
var choices = $('form.test-selector input.test-choice');
var selections = []
_.forEach(choices, function(choice) {
if ($(choice).is(':checked')) {
selections.push($(choice).val());
}
})
TestRunner.start(selections);
})
}
};
$(document).ready(function() {
TestRunner.formListener();
})
When using both requirejs and mocha:
Mocha will run whatever tests have been loaded by requirejs in the context.
The trick is to use require.undef() to get remove the tests from the context each time after the tests are run. Once this has been done, you'll have a clean slate to run whichever tests you want the next time.
start: function(tests) {
$('#mocha').html('');
require(tests.concat('vendor/mocha'), function() {
var mocha = _(arguments).last();
mocha.setup('bdd');
var expect = chai.expect
chai.use(chaijquery);
mocha.run();
});
require.undef('vendor/mocha')
tests.forEach(function(test) {
require.undef(test);
})
},
(Notice the last 4 lines which remove the test files from the context.)

phantomjs missing cookies, compared with firebug?

i am trying to get cookies using phantomjs, but it appears to be incomplete?
at command line:
phantomjs --cookies-file=cookies.txt --debug=true test.js
test.js:
var page = require('webpage').create();
page.open('http://example.com', function (status) {
page.evaluate(function() {
document.cookie;
});
page.cookies;
phantom.cookies;
});
i compare cookies.txt with firebug cookies and LiveHttpHeaders, and see there are some cookies missing in the phantomjs saved file?