eavichay / showroom Goto Github PK
View Code? Open in Web Editor NEWUniversal development and automated test environment for web components
Home Page: https://showroomjs.com
License: Apache License 2.0
Universal development and automated test environment for web components
Home Page: https://showroomjs.com
License: Apache License 2.0
At the moment it’s only possible to query a single element, after the find
method based on querySelector
.
For testing components with tables, or lists it would be very usefull if there would be an findAll
all query, based on querySelectorAll
which returns an array.
Example:
const result = await (await showroom.utils.findAll('//td')).getProperty('innerText‘);
expect(result).toBe(['hello', 'world']);
Just starting to develop tests for my native web components and really love this project. The only thing I can't figure out from the samples is how do you call a method on a web component and return the value to my test?
nodemon
isn't declared as a dependancy
Showroom seems to be very usefull for web components, but the documentation needs to be improved.
Your puppeteer integration example didn’t work for me, but I found this blog
https://medium.com/@eavichay/easy-unit-tests-for-your-web-components-e26bf88483a9
which is using require('showroom/puppeteer')()
. But showroom/puppeteer
isn’t mentioned in your docu.
trigger()
is also not documented, which allows us to call the showroom functions from our config.
Some documentation for find()
would would be also useful.
My current test looks with puppeteer and jest looks like this:
const showroom = require('showroom/puppeteer')();
describe('My awesome Test Suite', async () => {
beforeAll(async () => {
await showroom.start();
});
beforeEach(async () => {
await showroom.utils.setTestSubject('calendar-graph');
});
afterAll(async ()=>{
await showroom.stop();
});
test('Awesome component test', async () => {
await showroom.utils.trigger('initStatusMapping');
await showroom.utils.trigger('initData');
const foo = await (await showroom.utils.find('//*')).getProperty('innerHTML');
expect(foo._remoteObject.value).toBe('test');
});
});
For some reason getProperty()
returns an Object instead of the string directly.
Please consider transpiling to AMD or other such solution for the demo. Preferably, using differential serving to reserve transformed builds for incapable browsers only.
Best,
B
Using showroom.utils.trigger('myFunction')
is fluffy and leads sometimes (especially if I repeat the test in short intervals) to the error:
Evaluation failed: TypeError: this.customControlForm.triggers[fnName] is not a function
at HTMLElement.trigger (http:/127.0.0.1:3001/component-dashboard.js:26:46)
at __puppeteer_evaluation_script__:3:17
at ExecutionContext.evaluateHandle (node_modules/puppeteer/lib/ExecutionContext.js:121:13)
-- ASYNC --
at ExecutionContext.<anonymous> (node_modules/puppeteer/lib/helper.js:108:27)
at ExecutionContext.evaluate (node_modules/puppeteer/lib/ExecutionContext.js:48:31)
at ExecutionContext.<anonymous> (node_modules/puppeteer/lib/helper.js:109:23)
at DOMWorld.evaluate (node_modules/puppeteer/lib/DOMWorld.js:105:20)
-- ASYNC --
at Frame.<anonymous> (node_modules/puppeteer/lib/helper.js:108:27)
at Page.evaluate (node_modules/puppeteer/lib/Page.js:815:43)
at Page.<anonymous> (node_modules/puppeteer/lib/helper.js:109:23)
at TestUtils.trigger (node_modules/showroom/test-utils.js:306:21)
at Object.trigger (test/e2e/calendar-graph.test.js:33:26)
-- ASYNC --
at Page.<anonymous> (node_modules/puppeteer/lib/helper.js:108:27)
at TestUtils.trigger (node_modules/showroom/test-utils.js:306:21)
This seems to be a timing issue. Workaround:
beforeEach(async () => {
await new Promise(resolve=>setTimeout(()=>resolve(), 10));
});
The main dashboard area is made up of the render container and a wrapper div that contains the properties/attributes, event log, etc. The wrapper is specified as position absolute and overlays the render container. This is awkward for testing elements that through various techniques are meant to fill or overlay their container.
I would like to suggest that you make the wrapper static so it does not overlay the render container. An alternative if you want to support both is to add a pin button to the wrapper that can toggle it between static or absolute/overlay.
If you would like a pull request, please let me know.
Hi there,
I have a web component HeaderImage.js which looks something like this
export default class HeaderImage extends HTMLElement {
constructor() {
// We are not even going to touch this.
super();
// lets create our shadow root
this.shadowObj = this.attachShadow({mode: 'open'});
this.altText = this.getAttribute('alt');
this.src = this.getAttribute('src');
// Then lets render the template
this.render();
}
render() {
this.shadowObj.innerHTML = this.getTemplate();
}
getTemplate() {
return `
<img src="${this.src}"
alt="${this.altText}"/>
${this.handleErrors()}
<style>
img {
width: 400px;;
}
</style>
`;
}
handleErrors() {
if(!this.getAttribute('alt')) {
return `
<div class="error">Missing Alt Text</div>
<style>
.error {
color: red;
}
</style>
`;
}
return ``;
}
}
And I would like to write a unit test to check the following:
altText
is getting set in the beginningsrc
is getting set in the beginningaltText
is empty string or null, the function handleErrors()
is getting called.I have been trying for the past few days now, and I havent been able to understand how I can check these. I was wondering if someone would be able to help me out.
I really dont know what I am doing here, but here is the code:
HeaderImage.showroom.js
file inside .showroom
folderexport default {
component: 'header-image',
alias: 'Extending Native Elements',
section: 'Vanilla',
path: '../HeaderImage.js',
attributes: {
alt: 'Sky and Clouds',
src: '../sky.jpg'
},
innerHTML: `
<img src="../sky.jpg"
alt="Sky and Clouds"/>
<style>
img {
width: 400px;;
}
</style>
`,
outerHTML: `
<div>
<header-image alt="Sky and Clouds"
src="../sky.jpg"></header-image>
</div>
`
}
HeaderImage.spec.js
in test
folderconst showroom = require('showroom/puppeteer')();
const assert = require('assert');
describe('header-image', () => {
before( async () => {
await showroom.start();
})
after( async () => {
await showroom.stop();
})
beforeEach( async () => {
await showroom.setTestSubject('header-image');
})
it('Should update alt text', async () => {
await showroom.setAttribute('alt', 'Hello Sky');
const alt = await showroom.getAttribute('alt');
assert.equal(alt, 'Hello Sky');
})
it('Should update altText property', async () => {
await showroom.setAttribute('alt', 'Hello Sky');
const imgAlt = await showroom.getProperty('altText');
// FAILS
assert.equal(imgAlt, 'test alt text');
})
it('should show error class when alt text is not present', async () => {
await showroom.setAttribute('alt', '');
await showroom.setAttribute('src', '../sky.jpg');
const src = await showroom.getAttribute('src');
assert.equal(src, '../sky.jpg');
})
it('Should update src property', async () => {
await showroom.setAttribute('src', '../sky.jpg');
const src = await showroom.getProperty('src');
// FAILS
assert.equal(src, 'test alt text');
})
});
The error that I see in Mocha is
1) header-image
Should update altText property:
AssertionError [ERR_ASSERTION]: undefined == 'test alt text'
at Context.it (test/HeaderImage.spec.js:28:12)
at process._tickCallback (internal/process/next_tick.js:68:7)
2) header-image
Should update src property:
AssertionError [ERR_ASSERTION]: undefined == 'test alt text'
at Context.it (test/HeaderImage.spec.js:43:12)
at process._tickCallback (internal/process/next_tick.js:68:7)
I really have no clue what is going on here. And I dont know what I am missing here. Sorry :(
Any help is appreciated.
Thanks
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.