A set of utility classes and best practices for Polymer 2.x to make testing easier with web-component-tester.
Table of Contents:
Add oo-test-helpers
as dependency to your bower.json
.
{
"dependencies": {
"oo-test-helpers": "oolymer/oo-test-helpers#0.2.0"
}
}
Add browser.js
, mocha-extensions.js
, iron-test-helpers.html
, and oo-test-helpers-html
to your *.test.html
.
<script src="../../webcomponentsjs/webcomponents-loader.js"></script>
<script src="../../web-component-tester/browser.js"></script>
<script src="../../oo-test-helpers/mocha-extensions.js"></script>
<link rel="import" href="../../iron-test-helpers/iron-test-helpers.html">
<link rel="import" href="../../oo-test-helpers/oo-test-helpers.html">
setup.data(path, callbackWithData)
To be done.
setup.wait(callbackWithDone)
To be done.
test.wait(name, callbackWithDone)
To be done.
MockInteractions.click(node)
To be done.
MockInteractions.mouseenter(node)
To be done.
MockInteractions.mouseleave(node)
To be done.
MockInteractions.mouseover(node)
To be done.
Install npm
and bower
dependencies.
$ npm install
$ npm run install:bower
Start the development server and open the default browser.
$ npm start
Run test suites in headless browsers.
$ npm test
Update the change log.
$ github_changelog_generator oolymer/oo-test-helpers --simple-list --no-issues --usernames-as-github-logins --output CHANGES.md --future-release v0.2.0
❓ How to write and run a basic test for a custom element?
Demo: 📄 simple-element.test.html.
It uses several libraries which are included in web-component-tester
:
-
Polymer's
<test-fixture>
(a custom element) to define test fixtures within a<template>
: https://github.com/PolymerElements/test-fixture -
Mocha's (a test framework) TDD-style interface (
suite
,test
,setup
,suiteSetup
,teardown
,suiteTeardown
): https://mochajs.org/#tdd -
Chai's (an assertion library) BDD-style
expect
interface (expect(foo).to.equal("bar")
): http://www.chaijs.com/guide/styles/#expect -
Uses Sinon's (a mocking library) test spies, stubs and mocks (
sinon.spy()
,sinon.stub()
,sinon.mock()
): http://sinonjs.org/releases/v4.5.0/spy-call/
❓ How to test custom elements reasonably?
To be done.
❓ How run tests in a headless browser environment on a CI machine (continuous integration)?
Demo: 📄 package.json, wct-headless.conf.json, .travis.yml.
To be done.
File:
package.json
(excerpt)
"test:headless": "./node_modules/.bin/wct --expanded --local chrome --local firefox --configFile 'wct-headless.conf.json'",
File:
wct-headless.conf.json
{
"suites": [
"test/index.html"
],
"environmentImports": [
"test-fixture/test-fixture.html"
],
"plugins": {
"local": {
"browserOptions": {
"chrome": [
"window-size=1920,1080",
"headless",
"disable-gpu",
"no-sandbox"
],
"firefox": [
"-headless"
]
}
}
}
}
WCT Runner Config:
WCT Plugin Options:
References:
Headless Chrome is shipping in Chrome 59 (June 5, 2017).
Headless Firefox works on Fx55+ (August 8, 2017) on Linux, and 56+ (September 28, 2017) on Windows/Mac.
❓ How run tests in a development environment on a local machine?
Demo: 📄 package.json.
To be done.
File:
package.json
(excerpt)
"serve": "./node_modules/.bin/polymer serve --port $npm_package_config_portServe",
"serve:watch": "./node_modules/.bin/browser-sync start --port $npm_package_config_portServeWatch --proxy \"localhost:$npm_package_config_portServe\" --no-ui --files '*.js, *.html, demo/**/*.html, src/**/*.html, test/**/*.html' --startPath \"/components/$npm_package_name/\"",
File:
package.json
(excerpt)
"test:chrome": "./node_modules/.bin/polymer test --local chrome --persistent --skip-selenium-install",
"test:firefox": "./node_modules/.bin/polymer test --local firefox --persistent --skip-selenium-install",
Browsersync works by injecting an asynchronous script tag (
<script async>...</script>
) right after the<body>
tag during initial request. In order for this to work properly the<body>
tag must be present.
❓ How to setup and cleanup test fixtures (custom components)?
Demo: 📄 simple-element.test.html.
You can define your test fixtures within a <template>
using https://github.com/PolymerElements/test-fixture (which is included in web-component-tester
).
<test-fixture>
is used to prevent shared state, i.e. it will copy a clean, new instance of template content into each test suite (see: https://www.polymer-project.org/2.0/docs/tools/tests#test-fixtures).
❓ How to setup and cleanup test fixtures (serialized objects from json files)?
Demo: 📄 fixture-data.test.html.
To be done.
window.fetch("./fixtures/properties-for-custom-element.json")
.then(response => response.json())
.then(json => console.log(json))
References:
❓ How to pause on setup or on cleanup to see and interact with test fixtures (custom components) manually?
Demo: 📄 mocha-extensions.js.
To be done.
function setupBlocked(block) {
setup(function(done) {
this.enableTimeouts(false)
block(done)
})
}
suite("button", () => {
setupBlocked(() => {
const button = fixture("button-fixture")
})
})
const tddMocha = Mocha.interfaces.tdd
Mocha.interfaces.tdd = function tdd(suite) {
tddMocha(suite)
suite.on("pre-require", (context, file, mocha) => {
context.setup.blocked = function blocked(block) {
context.setup(function(done) {
this.enableTimeouts(false)
block(done)
})
}
})
}
suite("button", () => {
setup.blocked(() => {
const button = fixture("button-fixture")
})
})
❓ How to simulate user interactions on test fixtures (custom components)?
Demo: 📄 user-interaction.test.html.
You can import iron-test-helpers.html
from https://github.com/PolymerElements/iron-test-helpers and use the methods provides in global.MockInteractions
within your test suites.
❓ How to use stub elements (custom components)?
You can replace elements with stub elements to test them in isolation.
setup(() => {
replace("paper-button").with("fake-paper-button")
})
You can overwrite (replace) default implementions with custom methods.
setup(() => {
stub("paper-button", {
click: () => {
console.log("paper-button#click() called")
}
})
})
References: