The "problem" with elements that depend on Chrome Apps APIs is that you can't test/use them outside of Chrome Apps, so I went ahead and created some gulp tasks to make things easier for me.
The main idea of these tasks is to put the contents of
demo
or test
, which you would normally run directly, and all dependencies into one Chrome app that would then use demo/index.html
or test/index.html
as main page.First I take all the files relevant for the element itself + the test/demo files, run the html files through crisper and put the result into the output
components/my-element/
folder (following the layout of gh-pages for Polymer elements).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Get folder name (that should match the name of the element) | |
var element = __dirname.split(path.sep).pop(); | |
// All files necessary for the element + test files | |
// This will have to be extended, e.g. if your element uses images | |
gulp.src([ | |
'./*.html', | |
'./*.js', | |
'./*.css', | |
'./test/**', | |
'!./gulpfile.js', | |
'!./index.html', | |
],{base: './'}) | |
// run all html files through crisper for CSP | |
.pipe($.if('*.html', $.crisper())) | |
// put everything into ./{{dest}}/components/{your-element}/ | |
.pipe(gulp.dest(path.join(destDir, 'components', element))); |
components
folder.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// take all bower dependencies | |
gulp.src(['bower_components/**/*']) | |
// run all html files through crisper for CSP | |
.pipe($.if('*.html', $.crisper())) | |
// put everything into ./{{dest}}/components/ | |
.pipe(gulp.dest(path.join(destDir, 'components'))); |
manifest.json
defines the necessary permissions (e.g. to use chrome-storage
the "storage"
permission is required).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"manifest_version": 2, | |
"name": "_element_ _type_", | |
"version": "0.0.1", | |
"minimum_chrome_version": "34", | |
"app": { | |
"background": { | |
"scripts": ["main.js"] | |
} | |
}, | |
"permissions": [ | |
"storage" | |
] | |
} |
main.js
launches the test or demo page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Listens for the app launching then creates the window | |
*/ | |
chrome.app.runtime.onLaunched.addListener(function() { | |
chrome.app.window.create('components/_element_/_type_/index.html'); | |
}); |
window.create
call to point to the right file, e.g at components/my-element/test/index.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
gulp.src(['./chrome-app/**']) | |
.pipe($.replace('_element_', element)) | |
.pipe($.replace('_type_', 'test')) | |
.pipe(gulp.dest(destDir)); |
This works nicely for the demo app, but unfortunately the test app reveals this in the console when starting it:
Uncaught Error: document.write() is not available in packaged apps.
Investigating the problem reveals this line in the web-component-tester to cause the issue, which makes sure that all dependencies are loaded before WCT is actually started.
To work around this issue you have to include the necessary scripts in the test files explicitly...
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="../../stacky/lib/parsing.js"></script> | |
<script src="../../stacky/lib/formatting.js"></script> | |
<script src="../../stacky/lib/normalization.js"></script> | |
<script src="../../async/lib/async.js"></script> | |
<script src="../../lodash/lodash.js"></script> | |
<script src="../../mocha/mocha.js"></script> | |
<script src="../../chai/chai.js"></script> | |
<script src="../../sinonjs/sinon.js"></script> | |
<script src="../../sinon-chai/lib/sinon-chai.js"></script> | |
<script src="../../accessibility-developer-tools/dist/js/axs_testing.js"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
WCT = { | |
environmentScripts: [] | |
}; |
web-component-tester/browser.js
on all the test pages.So that I don't have to copy the same couple of lines into each of the test files separately, I extended the gulp-copy task to automatically insert the necessary lines in all files that include a reference to
web-component-tester/browser.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var wctScripts = [ | |
'<script src="../../stacky/lib/parsing.js"></script>', | |
'<script src="../../stacky/lib/formatting.js"></script>', | |
'<script src="../../stacky/lib/normalization.js"></script>', | |
'<script src="../../async/lib/async.js"></script>', | |
'<script src="../../lodash/lodash.js"></script>', | |
'<script src="../../mocha/mocha.js"></script>', | |
'<script src="../../chai/chai.js"></script>', | |
'<script src="../../sinonjs/sinon.js"></script>', | |
'<script src="../../sinon-chai/lib/sinon-chai.js"></script>', | |
'<script src="../../accessibility-developer-tools/dist/js/axs_testing.js"></script>', | |
'<script src="prepare_wct.js"></script>' | |
].join('\n'); | |
gulp.src(...) | |
... | |
// Insert WCT Scripts in test files before WCT is loaded | |
.pipe( | |
$.if('*.html', $.insertLines({ | |
before: /<script\ src="..\/..\/web-component-tester\/browser.js/, | |
lineBefore: wctScripts | |
})) | |
) |
Following the idea of my previous article I also wanted to enable live-reload for this workflow
As opposed to my article where the
livereload.js
is removed for the production build, I did it the other way round here by adding it to the test/index.html
or demo/index.html
when running the gulp-live-task.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Insert live-reload script into main demo/test files | |
.pipe( | |
$.if( | |
'**/index.html', | |
$.insertLines({ | |
before: /<\/head>/, | |
lineBefore: '<script src="../../chrome-app-livereload/livereload.js' + | |
'?host=localhost&port=35729"></script>' | |
}) | |
) | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var lr = tinylr(); | |
lr.listen(35729); | |
// watch for changes and rebuild the chrome app if necessary | |
gulp.watch(['./*', './test/**'], ['copy-live:test']); | |
gulp.watch(['./chrome-app/**'], ['app:test']); | |
gulp.watch(['bower_components/**'], ['bower:test']); | |
// trigger live-reload when the app was changed in some way | |
gulp.watch([destDir + '/**'], $.batch({timeout: 500}, function (events, cb) { | |
var paths = []; | |
events.on('data', function (evt) { | |
paths.push(evt.path); | |
}).on('end', function () { | |
lr.changed({ | |
body: {files: paths} | |
}); | |
cb(); | |
}); | |
})); |
And now back to actually working on my app. All those distractions you run into while traversing (mostly) uncharted waters ☺