karma-runner: load scripts (and CSS) via DOM - karma-runner

I want to inject some CSS and JavaScript files via a preprocessor.
In my preprocessor I inject the html template to the body element.
I printed the result out via console.log(document.body) - you can see the result at the bottom. It looks good, but the script is not evaluated.
If I run console.log(window.foobar) in my test, it's undefined.
Actually I don't want to to inject simple scripts, I want to load some files via
<script src="build/app.js"></script>
I need it in every test, so I don't want to refactor every single test for the same code injection, that's the reason why I tried to put it into the html generated by karma.
<body><script> window.foobar = 'miau!';</script>
<!-- The scripts need to be at the end of body, so that some test running frameworks
(Angular Scenario, for example) need the body to be loaded so that it can insert its magic
into it. If it is before body, then it fails to find the body and crashes and burns in an epic
manner. -->
<script type="text/javascript">
// sets window.__karma__ and overrides console and error handling
// Use window.opener if this was opened by someone else - in a new window
if (window.opener) {
window.opener.karma.setupContext(window);
} else {
window.parent.karma.setupContext(window);
}
// All served files with the latest timestamps
window.__karma__.files = {
'/base/node_modules/mocha/mocha.js': '253e2fdce43a4b2eed46eb25139b784adbb5c47f',
'/base/node_modules/karma-mocha/lib/adapter.js': '3664759c75e6f4e496fef20ad115ce8233a0f7b5',
'/base/test/custom-test.js': 'abf5b0b3f4dbb62653c816b264a251c7fc264fb9',
'/base/test/build/build.css': 'df7e943e50164a1fc4b66e0a0c46fc86efdef656',
'/base/test/build/build.js': '9f0a39709e073846c73481453cdee8d37e528856',
'/base/test/build/test.js': '0ccd4711b9c887458f81cf1dedc04c6ed59abe43'
};
</script>
<!-- Dynamically replaced with <script> tags -->
<script type="text/javascript" src="/base/node_modules/mocha/mocha.js?253e2fdce43a4b2eed46eb25139b784adbb5c47f"></script>
<script type="text/javascript" src="/base/node_modules/karma-mocha/lib/adapter.js?3664759c75e6f4e496fef20ad115ce8233a0f7b5"></script>
<script type="text/javascript" src="/base/test/custom-test.js?abf5b0b3f4dbb62653c816b264a251c7fc264fb9"></script></body>

Karma introduces the page scripts/html just like ajax, so it wont execute once the append has finished.
You will need to append the files for each spec. I have a helper for this job:
function appendCSS(path){
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href='base/' + path;
document.body.appendChild(link)
}
function appendScript(path){
var link = document.createElement('script');
link.type = 'javascript';
link.src='base/' + path;
document.body.appendChild(link)
}
function loadAssets(page){
document.body.innerHTML = __html__['_site/' + (page || 'index') + '.html'];
appendCSS('_site/styles/demo.css');
appendCSS('_site/styles/' + page + '.css');
appendScript('_site/scripts/vendor.js');
appendScript('_site/scripts/' + page + '.js');
}
module.exports = {
loadAssets: loadAssets
};
In my spec i then simply call the helper, passing the name of the html page to be tested.
require('../helper').loadAssets('tested-page-name');
As you can see, i use the borwserify plugin, but i hope this helps.

Related

Is it possible to access webpack config properties through the preview-head.html file for storybook.js?

I am trying to add storybook.js into my react project and there is a pre-requisite script I need to add to every storybook page so as to render some custom components.
The script's URL needs to be auto generated on the fly in webpack configuration.
This Story rendering section of storybook's documentation mentioned a preview-head.html through which script tags can be injected into the final index HTML file.
I am wondering whether it supports EJS syntax like below for me to access a config option value of the HtmlWebpackPlugin.
<script src="<%= htmlWebpackPlugin.options.foobar %>"></script>
As a workaround, I wrote a decorator in the preview.js file to purposely insert the <script /> tag into the storybook iframe with dynamically generated src field.
const loadAssets = () => {
const scriptElement = document.createElement('script');
// scriptElement.src = /* dynamically generated from dependencies */;
document.querySelector('head').appendChild(scriptElement);
};
const AssetLoader = props => {
React.useEffect(() => loadAssets(), []);
return <>{props.children}</>;
};
const assetLoaderDecorator = storyFn => (
<AssetLoader>{storyFn()}</AssetLoader>
);
addDecorator(assetLoaderDecorator);
It's a bit clumsy but it serves the purpose at the moment.
Inspired by https://github.com/jhta/storybook-external-links.

why my Riot JS update isn't working?

So I'm learning Riot JS, following a guide. Gives an example explaining step by step.
And adds a "this.update()" to update the riot js variables. Now, it is working for him, but not for me. Can you guys tell me why?
Here's the code.
This is the index.html
<body>
<script src="bower_components/riot/riot.min.js" type="text/javascript"></script>
<script src="tags/all.js" type="text/javascript"></script>
<contact-list></contact-list>
<script>
riot.mount('contact-list', {callback: tagCallback});
function tagCallback(theTag) {
console.log('callback executed');
var request = new XMLHttpRequest();
request.open('GET', 'people.json', true);
request.onload = function() {
if(request.status == 200) {
var data = JSON.parse(request.responseText);
console.log(data);
theTag.trigger('data_loaded', data);
}
}
setTimeout(function() {
request.send();
},2000);
}
</script>
</body>
And this is my contact-list.tag
<contact-list>
<h1>Contacts</h1>
<ul>
<li each={p in opts.people}>{p.first} {p.last}</li>
</ul>
<script>
this.on('mount', function() {
console.log('Riot mount event fired');
opts.callback(this);
})
this.on('data_loaded', function(peeps) {
console.log(peeps);
opts.people = peeps;
this.update();
})
</script>
</contact-list>
After debugging with the console.logs I can see i'm retrieving data correctly from my JSON file, my contact list data is there. But the bullet list isn't updated. It's displayed empty.
Is there any reason for using a callback function?
If not, move your callback function into the tag and update it directly after assigning your fetched data to your tags variable.
Look at the sources in riotgear:
https://github.com/RiotGear/rg/blob/master/tags/rg-include/rg-include.tag
For me it was a perfect example.
Oh nevermind guys, sorry. Don't know how actually the example of the guy in the video worked. Because I had to pass data.people on the html trigger event. Otherwise i was passing a plane Object with an Array in it.

Access coffeescript function in another file

I have this main coffeescript code:
<script src="libs/coffeeScript.js"> </script>
<script src="maths.coffee"> </script>
<script type="text/coffeescript">
document.write math.cube 2
</script>
and this code in the "maths.coffee" file:
math ={}
math.cube=(x)->x*x*x
Why can I not access the cube function?
I already tried a lot of solutions found on this site, without success.
The Problem:
When a CoffeeScript file is compiled into JavaScript it is wrapped in an IIFE. So the JS code you end up with looks something like this:
(function () {
var math = {};
math.cube = function(x) {
return x * x * x;
};
})();
What this means is that the function is only scoped within that IIFE, which prevents polution of the global namespace.
The solution:
Because you are including your CoffeeScript inline, you need to explicitly expose any functions you want to use in other files onto a global object, e.g. window
math = {}
math.cube = (x) -> x * x * x
window.math = math
Alternatively, you could compile your CoffeeScript before hand, and pass in the --bare option. Then just include the JavaScript file with your page.

Embed google-plus in GWT

I am trying to embed Google-Plus into my GWT Application. I would like it to be embedded into a HorizontalPanel. I did read +1button developers google. I didn't find any post about this particular problem in stackoverflow. My problem might be that I don't understand how to include the js into a GUI component. I would appreciate an Example of how to add the Google+ code into a Panel.
Here is how to do it:
Documentation:
<!-- Place this tag in your head or just before your close body tag -->
<script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>
<!-- Place this tag where you want the +1 button to render -->
<g:plusone></g:plusone>
in GWT:
private void drawPlusOne() {
String s = "<g:plusone href=\"http://urltoplusone.com\"></g:plusone>";
HTML h = new HTML(s);
somePanel.add(h);
// You can insert a script tag this way or via your .gwt.xml
Document doc = Document.get();
ScriptElement script = doc.createScriptElement();
script.setSrc("https://apis.google.com/js/plusone.js");
script.setType("text/javascript");
script.setLang("javascript");
doc.getBody().appendChild(script);
}
I've personally never embedded the +1 button in GWT, but the linked article seems pretty self explanatory.
In the section "A Simple Button", it indicates that the simplest way of implementing GooglePlus integration is to add this:
<script src="https://apis.google.com/js/plusone.js" />
<g:plusone></g:plusone>
First, the <script> tag should be included in your .gwt.xml file.
Then I'd implement the <g:plusone></g:plusone> like this:
public class GPlusOne extends SimplePanel {
public GPlusOne () {
super((Element)Document.get().createElement("g:plusone").cast());
}
}
(Note that this code is untested, but it's based on the simple concept that a SimplePanel can be extended to compile as any HTML element.)
Then you'd use the new GPlusOne element wherever you'd want the button to show.
I found a better way to do it:
Follow this example to have the button work on invocation on a normal html page (you can try one here http://jsfiddle.net/JQAdc/)
<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script src="https://apis.google.com/js/plusone.js">
{"parsetags": "explicit"}
</script>
<script type="text/javascript">
function gPlusBtn(id, params) {
/* window.alert("searching for "+ id +" with params: "+ params) */
paramsObj = eval( '('+params+')' );
gapi.plusone.render(id, paramsObj );
}
// params is here just for a reference to simulate what will come from gwt
params = '{href:"http://1vu.fr", size:"tall"}';
</script>
</head>
<body>
taken from http://jsfiddle.net/JQAdc/
<div id="gplus" />
<button onclick="gPlusBtn('gplus', params)">show!</button>
</body>
</html>
Then you can call a native method to trigger the button display on Activity start (if you're using MVP).
protected native void plusOneButton(String id, String params) /*-{
$wnd.gPlusBtn(id, params);
}-*/;
You can have multiple buttons with different urls, that's why id is left as a parameter.
NOTE: for me the raw HTML works on localhost, but the GWT version. I have to deploy to the server to be able to see the results

Writing script src dynamically via wicket

I want my page to load javascript dynamically to my body:
<script type= "text/javascript" src="this path should be decided from wicket dynamically"/>
I am using wicket version 1.4 therefore JavaScriptResourceReference does not exist in my version (for my inspection it wasn't ' )
how can I solve this ?
thanks in advance :).
I specify my comment into an answer.
You can use this code snippet:
WebMarkupContainer scriptContainer = new WebMarkupContainer("scriptContainer ");
scriptContainer .add(new AttributeAppender("type", Model.of("text/javascript")));
scriptContainer .add(
new AttributeAppender("src", urlFor(
new JavaScriptResourceReference(
YourClass.class, "JavaScriptFile.js"), null).toString()));
add(scriptContainer );
and the corresponding html:
<script wicket:id="scriptContainer "></script>
Just change the string JavaScriptFile.js to load any other Javascript file.
JavascriptPackageResource.getHeaderContributor() does exactly what you need.
You need nothing in your markup, just add the HeaderContributor it returns to your page.
Update: For Wicket 1.5 see the migration guide, but it goes like this:
public class MyPage extends WebPage {
public MyPage() {
}
public void renderHead(IHeaderResponse response) {
response.renderJavaScriptReference(new PackageResourceReference(YuiLib.class,
"yahoo-dom-event/yahoo-dom-event.js"));
response.renderCSSReference(new PackageResourceReference(AbstractCalendar.class,
"assets/skins/sam/calendar.css"));
}
}
If you want to put your <script> element in the body, you can simply declare it as a WebMarkupContainer and add an AttributeModifier to set the src attribute. Although in that case wicket won't generate the relative URLs for you, you have to do it yourself.
I'm not sure I understood completely.
If you are trying to create and append a script to the body after the page is loaded you should do it this way:
<script type="text/javascript">
function load_js() {
var element = document.createElement("script");
element.src = "scripts/YOUR_SCRIPT_SRC.js"; // <---- HERE <-----
document.body.appendChild(element);
}
// Wait for the page to be loaded
if(window.addEventListener)
window.addEventListener("load",load_js,false);
else if(window.attachEvent)
window.attachEvent("onload",load_js);
else
window.onload = load_js;
</script>
What I did here is create a new script element, and then apply to it its source.
That way you can control dynamicaly the src. After that I append it to the body.
The last part is there so the new element is applied only after the page is loaded.