Web Component / HtmlElement : unit testing - html

I'm trying to test a web component.
Here is my project structure :
├── package.json
├── src
│   ├── app.js
│   └── index.html
└── test
└── hello-world-test.html
Here is my working code :
class HelloWorld extends HTMLElement {
connectedCallback () {
this.innerHTML = 'Hello, World!'
}
}
customElements.define('hello-world', HelloWorld);
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="app.js"></script>
</head>
<body>
<hello-world></hello-world>
</body>
</html>
I'm trying to test that web component with web-component-tester.
I installed the utility globally :
npm install -g web-component-tester
I declared it in the package.json file :
"devDependencies": {
"web-component-tester": "^6.9.0"
}
then, I wrote my test in the test folder and saved it to hello-world-test.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="../node_modules/web-component-tester/browser.js"></script>
<script src="app.js"></script>
</head>
<body>
<test-fixture id="hello-world-fixture">
<hello-world></hello-world>
</test-fixture>
<script>
suite('<hello-world>', function(){
let component = document.querySelector('hello-world');
test('contains hello world string ?', () => {
let index = component.innerText.indexOf('Hello');
assert.isAtLeast(index, 0);
});
});
</script>
</body>
</html>
Finally, I typed :
wct --npm
Then obtained the following error in Chrome :
What am I missing to run the test correctly ?
The only decent materials I've found are this one and that one but they are outdated.

There are many errors :
First, please read the whole documentation as in the last paragraph it's clear that for those who use npm you need an additional dependency through the wctPackageName :
Components which wish to support npm-based installation should include
wct-browser-legacy in their devDependencies, which is a package that
contains only the client-side javascript necessary for executing WCT
tests in an npm-based environment. WCT will attempt to identify which
package provides the client-side code by checking for compatible
packages in the following order of preference: wct-mocha,
wct-browser-legacy and web-component-tester. If you want to specify
which package provides WCT client-side code, use the
--wct-package-name flag or wctPackageName option in wct.conf.json with the npm package name.
So you will need to add wct-browser-legacy in your devDependencies
Giving your project structure, you are including the app.js as if it was at the same level. It should be ../src/app.js.
You should add the type="module" to that import
You declared a fixture but didn't take profit of it through the function fixture
If I had to correct your code :
The command should be wct --npm -wct-package-name=wct-browser-legacy. Or even better create a wct.conf.js file with the following information :
module.exports = {
npm:true,
verbose: true,
plugins: {
local: {
browsers: ["chrome"]
}
},
wctPackageName: "wct-browser-legacy"
};
Your test should be modified as following :
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script src="../node_modules/web-component-tester/browser.js"></script>
<script src="../src/app.js"></script>
</head>
<body>
<test-fixture id="helloWorldFixture">
<template>
<hello-world>
</hello-world>
</template>
</test-fixture>
<script>
suite('<hello-world>', () => {
let component;
setup(() => {
component = fixture('helloWorldFixture');
});
test('contains hello world string ?', () => {
let index = component.innerText.indexOf('Hello');
assert.isAtLeast(index, 0);
});
});
</script>
</body>
</html>
Please, notice that I used the fixture's id and put the component initialisation in the setup function.

Zakaria's answer is good, but I suggest ditching wct-browser-legacy in favor of wct-mocha as it is lighter-weight and doesn't have out-of-date dependencies like old version of lodash and sinon etc.
See the README for full details: https://www.npmjs.com/package/wct-mocha
tl;dr version:
$ npm rm --save wct-browser-legacy
$ npm install --save-dev \
#webcomponents/webcomponentsjs \
#polymer/test-fixture \
wct-mocha \
mocha \
chai
You shouldn't need to specify it, but if you have wct.conf.js file you should change an existing wctPackageName entry to:
wctPackageName: "wct-mocha"
Your HTML needs to change a little and you need to make sure mocha is a direct dependency, since wct-mocha will not autoload. You'd also need to do that with chai if you're using chai assertions and #polymer/test-fixture if you use those.
<head>
<meta charset="utf-8">
<script src="../node_modules/#webcomponents/webcomponentsjs/webcomponents-loader.js"></script>
<script src="../node_modules/mocha/mocha.js"></script>
<script src="../node_modules/chai/chai.js"></script>
<script src="../node_modules/#polymer/test-fixture/test-fixture.js"></script>
<script src="../node_modules/wct-mocha/wct-mocha.js"></script>
</head>

Related

Gulp to version filename and replace links

For any URL which doesn't start with /static, I serve this index.html:
<!doctype html>
<html lang="en-GB">
<head>
<meta charset="utf-8">
<title>Title</title>
<link rel="import" href="/app.html">
</head>
...
</html>
Note: the / in /app.html to ensure it always serves app.html from the root.
I wish to run gulp/vulcanize over app.html to:
create a bundle which sits in: /static/<version-or-timestampp-or-hash-here>/app.html
change the import in index.html to point to the the above generated bundle
I currently have the following gulp file that will do the vulcanize, but it won't do the versioning or change index.html link:
var gulp = require('gulp');
var vulcanize = require('gulp-vulcanize');
gulp.task('vulcanize', function() {
return gulp.src(['app.html'])
.pipe(vulcanize({
stripComments: true,
inlineScripts: true,
inlineCss: true
}))
.pipe(gulp.dest('static'));
});
gulp.task('default', ['vulcanize']);
How do I achieve the two points above?

Angular fails to bind expression

I am trying to build a simple web app that communicates with an external API , for the first step i wish to check if my controller,service-html integration is all in placed , so I'm tying to bind a simple variable from the controller to the view, but i am getting {{msg}} instead of a successful bind.
please ignore the service for now its just my fundumentals for later on.
main.html :
<!DOCTYPE html>
<html >
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="controller.js"></script>
<head></head>
<body ng-app="queueApi" ng-controller="MainController">
<div>
<h1>{{msg}}</h1>
</div>
</body>
</html>
queueservice.js
angular.module('queueApi')
.factory('queueService', function ($resource){
return $resource('http://127.0.0.1:8080/queue/:id',{id: '#id'});
});
controller.js
var app = angular.module('queueApi' , ['ngResource']);
app.controller('MainController', function($scope,$http, queueService){
$scope.msg = "Hi tom";
// $scope.items = queueService.query({id:2}); //getting all from id 2
});
If you look at your console you can see the error in module creation. It is because the ngResource module is in external source file rather than angular.min.js. Add also the angular-resource.js.
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-resource.min.js"></script>
<script src="controller.js"></script>
In addition to Hamlet Hakobyan's answer, you must ensure that your modules have been included in correct order. With your code structure controller.js should precede queueservice.js.
From the documentation:
Beware that using angular.module('myModule', []) will create the module myModule and overwrite any existing module named myModule. Use angular.module('myModule') to retrieve an existing module.

How to add syntax highlighting to <marked-element>?

I've been trying to add syntax highlighting to <marked-element> using <prism-highlighter>, but I am at a complete loss on how to get this to work.
When reading the documentation for <prism-highlighter>, it states "This flow is supported by <marked-element>", but isn't clear on how to use them together.
When looking into the <prism-highlighter> source on the GitHub, the only demo given is for when using it alone, and using it this way would miss all the benefit of <marked-element>.
I could access the content with <marked-element>.markdown, but I can't figure out how I would process it and send it back, and every attempt to do so failed.
How do I used <marked-element> for the markdown, and also add syntax highlighting?
Or maybe change the iron-demo-helpers' <demo-snippet> so that I get the nice layout with the copy button, but for different languages like bash and python scripts. (Which are both supported according to the supported languages on the PrismJS website.)
Edit: It turns out that it wasn't how I was doing it that was wrong, but that the language I was using wasn't supported by default. Posted solution as answer below.
Insert the <marked-element> with your code after the <prism-highlighter> tag, just as below:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<link rel="import" href="/bower_components/marked-element/marked-element.html">
<link rel="import" href="/bower_components/prism-element/prism-highlighter.html">
</head>
<body>
<prism-highlighter></prism-highlighter>
<marked-element>
<script type="text/markdown">
```html
<div>yes</div>
<i>
console.log( "no log" )
</i>
```
</script>
</marked-element>
</body>
</html>
The highlighter will detect and style the elements inside the <marked-element>.
So the reason it wasn't working is because I didn't realize it was coded in the element to only support a few languages.
My solution was to edit/fork the prism + prism-element components.
(Note: If you edit the files inside bower_components without changing the name or directory you may lose changes upon next update)
I edited the prism-element/prism-highlighter.html file to include additional languages:
if (lang === 'js' || lang.substr(0, 2) === 'es') {
return Prism.languages.javascript;
} else if (lang === 'css') {
return Prism.languages.css;
} else if (lang === 'c') {
return Prism.languages.clike;
} else if (lang === 'bash') { // Check for bash markdown
return Prism.languages.bash;
} else if (lang === 'python') { // Check for python markdown
return Prism.languages.python;
} else {
...
The prism/gulpfile.js to import more language components:
paths = {
componentsFile: 'components.js',
components: ['components/**/*.js', '!components/**/*.min.js'],
main: [
'components/prism-core.js',
'components/prism-markup.js',
'components/prism-css.js',
'components/prism-clike.js',
'components/prism-javascript.js',
'components/prism-bash.js', // Include bash component
'components/prism-python.js', // Include python component
'plugins/file-highlight/prism-file-highlight.js'
],
...
If you changed the name/path of prism, make sure to change the relative paths in prism-element/prism-import.html.
Then in the prism folder run npm install to install dependencies, and gulp to run gulpfile.js and compile to prism/prism.js.
Since I named my fork prism-highlighter-plus, my final code looks like this:
<link rel="import" href="../../bower_components/marked-element/marked-element.html">
<link rel="import" href="../../bower_components/prism-element-plus/prism-highlighter-plus.html">
<dom-module id="backup-script">
<template>
<style>
:host {
display: block;
}
.markdown-html {
overflow-x: auto;
}
</style>
<prism-highlighter-plus></prism-highlighter-plus>
<marked-element>
<div class="markdown-html"></div>
<script type="text/markdown">
```bash
#!/bin/bash
...
excluded_databases="Database|information_schema|performance_schema|mysql"
databases=`mysql -u $mysql_user -p$mysql_password -Bse "SHOW DATABASES;" | egrep -v $excluded_databases`
for db in $databases; do
mysqldump -u $mysql_user -p$mysql_password --databases $db > $mysql_output/$today/$db.sql
done
...
</script>
</marked-element>
</template>
<script>
Polymer({
is: 'backup-script'
});
</script>
</dom-module>

AngularJS - "import" different JS files from HTML

I was trying to import certain script depending on which URL I'm.
Simple <script> tag in my HTML is:
<html ng-app="myApp">
...
<script type="text/javascript" src="{{srcRoute}}" language="JavaScript"></script>
...
</html>
I was trying to get this after main module "myApp", in a run block:
angular.module('myApp', [])
.config(function($routeProvider) {
$routeProvider.
when('/', {controller: MyController, templateUrl: 'partials/home.html'}).
otherwise({redirectTo: '/'});
})
.run(function($rootScope) {
$rootScope.srcRoute = 'some/route/here.js';
});
but when running this I get something like:
GET myRoute/%7B%7BsrcRoute%7D%7D 404 (Not Found)
What I want to do is add a conditional sentence in the run block to decide which route to use. Is there a way to do this?
Thanks!

extjs "helloworld" example, does not run?

According to the example in this website, I followed the steps, but I dont get any output in the browser.
As Stated in the example, the file "index.html" should be in the following path
'D:\xampp\htdocs\helloext\extjs\index.html'
and its"index.html" contents are the following:
<html>
<head>
<title>Hello Ext</title>
<link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">
<script type="text/javascript" src="extjs/ext-debug.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body></body>
</html>
when I run this example in both Chrome or FireFox, however, there is not output to be displayed.
Please guide me to have this samll example run correctly
Did you follow the instructions at the end of section 2.1 (Application Structure)? You need to create the app.js file:
Now you're ready to write your application code. Open app.js and
insert the following JavaScript code:
Ext.application({
name: 'HelloExt',
launch: function() {
Ext.create('Ext.container.Viewport', {
layout: 'fit',
items: [
{
title: 'Hello Ext',
html : 'Hello! Welcome to Ext JS.'
}
]
});
}
});