Reputation: 4385
When I run karma testing a javascript file which imports a HTML file I expected the html available for testing. It is not clear for me if I am trying something that it is not karma prepared for or I should somehow add the HTML file before estarting the test.
Put in few words, what I should do in order to unit test bellow webcomponent which is splited in two files (js and html)? Maybe an usefull comment will be if I misunderstood something wrong about karma (for instance, it can't load a file imported by javascript assyncronously)
Console error:
# npm run test
> [email protected] test C:\_d\WSs\rapidapi-vanilla-webcomponents\skyscanner-openwc-graphql
> karma start --coverage
START:
12 08 2019 15:29:40.982:WARN [filelist]: Pattern "C:/_d/WSs/rapidapi-vanilla-webcomponents/skyscanner-openwc-graphql/__snapshots__/**/*.md" does not match any file.
12 08 2019 15:29:41.005:INFO [karma-server]: Karma v4.2.0 server started at http://0.0.0.0:9876/
12 08 2019 15:29:41.007:INFO [launcher]: Launching browsers ChromeHeadlessNoSandbox with concurrency unlimited
12 08 2019 15:29:41.013:INFO [launcher]: Starting browser ChromeHeadless
12 08 2019 15:29:42.172:INFO [HeadlessChrome 76.0.3809 (Windows 10.0.0)]: Connected on socket fPyJTkm8LvWTrPBoAAAA with id 27628633
12 08 2019 15:29:47.926:WARN [web-server]: 404: /src/skyscanner-flight-search/skyscanner-flight-search.html
skyscanner flight search
× show div
HeadlessChrome 76.0.3809 (Windows 10.0.0) skyscanner flight search show div FAILED
TypeError: Cannot read property 'querySelector' of null
at Context.querySelector (test/skyscanner-flight-search.test.js:10:23)
Finished in 0.102 secs / 0.022 secs @ 15:29:48 GMT-0300 (GMT-03:00)
SUMMARY:
√ 0 tests completed
× 1 test failed
FAILED TESTS:
skyscanner flight search
× show div
HeadlessChrome 76.0.3809 (Windows 10.0.0)
TypeError: Cannot read property 'querySelector' of null
at Context.querySelector (test/skyscanner-flight-search.test.js:10:23)
Webcomponent, javascript file (skyscanner-flight-search.js):
(async() => {
const res = await fetch(
"../src/skyscanner-flight-search/skyscanner-flight-search.html"
);
const textTemplate = await res.text();
const HTMLTemplate = new DOMParser()
.parseFromString(textTemplate, "text/html")
.querySelector("template");
class skyscannerFlightSearch extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.attachShadow({ mode: "open" });
this.shadowRoot.appendChild(HTMLTemplate.content.cloneNode(true));
const inputSessionKey = this.shadowRoot.getElementById("inputSessionKey");
//const url = "http://localhost:8080/getsessionkey";
const url = "https://rapid-api-to-learn.herokuapp.com/getsessionkey";
fetch(url)
.then(function(body) {
return body.text();
})
.then(function(data) {
inputSessionKey.value = data;
console.log(data);
});
}
}
window.customElements.define(
"skyscanner-flight-search",
skyscannerFlightSearch
);
})();
Webcomponent, html file (skyscanner-flight-search.html)
<template id="skyscanner-flight-search-template"
><div id="firstdiv"><input id="inputSessionKey" /></div
></template>
Dependencies (just the relevant ones)
"scripts": {
...
"test": "karma start --coverage",
...
},
"dependencies": {
"lit-html": "^1.0.0",
"lit-element": "^2.0.1"
},
"devDependencies": {
"es-dev-server": "^1.5.0",
"@open-wc/eslint-config": "^1.0.0",
"@open-wc/prettier-config": "^0.1.10",
"husky": "^1.0.0",
"lint-staged": "^8.0.0",
"@open-wc/testing-karma": "^3.0.0",
"webpack-merge": "^4.1.5",
"@open-wc/testing-karma-bs": "^1.0.0",
"@open-wc/testing": "^0.11.1",
"@open-wc/demoing-storybook": "^0.3.0"
},
karma.conf.js
const { createDefaultConfig } = require('@open-wc/testing-karma');
const merge = require('webpack-merge');
module.exports = config => {
config.set(
merge(createDefaultConfig(config), {
files: [
{ pattern: config.grep ? config.grep : 'test/**/*-search.test.js', type: 'module' },
],
esm: {
nodeResolve: true,
},
// you can overwrite/extend the config further
}),
);
return config;
};
Upvotes: 0
Views: 386
Reputation: 4385
Thanks to discussion https://github.com/open-wc/open-wc/issues/730 I reached the solution:
I have to do two things in order to unit test my vanilla webcomponent spplited in two files:
my webcomponent javascript
'
const htmlPath = new URL(
'./skyscanner-flight-search.html',
import.meta.url,
);
const res = await fetch(htmlPath);
...
'
my unit test
'
import { html, fixture, expect } from '@open-wc/testing';
import '../src/skyscanner-flight-search/skyscanner-flight-search.js';
describe('skyscanner flight search', () => {
it('show div', async() => {
const el = await fixture(html <skyscanner-flight-search></skyscanner-flight-search>);
window.customElements.whenDefined('skyscanner-flight-search').then(() => {
el.shadowRoot.querySelector('#firstdiv');
expect(el).to.exist;
})
});
});
'
Probably I am missing some basic concept about the time and steps took by Karma in order to unit test a javascript fetching a text file. BTW, the above approach resolve the question title.
*** edited based on discussion https://dev.to/bennypowers/lets-build-web-components-part-3-vanilla-components-4on3
import { html, fixture, expect } from '@open-wc/testing';
import '../src/skyscanner-flight-search/skyscanner-flight-search.js';
describe('skyscanner flight search', () => {
it('show div', async() => {
const el = await fixture(html `
<skyscanner-flight-search></skyscanner-flight-search>
`);
await window.customElements.whenDefined('skyscanner-flight-search')
expect(el.shadowRoot.querySelector('#firstdiv')).to.exist;
});
it('show input for session key', async() => {
const el = await fixture(html `
<skyscanner-flight-search></skyscanner-flight-search>
`);
await window.customElements.whenDefined('skyscanner-flight-search')
expect(el.shadowRoot.querySelector('#inputSessionKey')).to.exist;
});
});
Upvotes: 2