siesta-lite
Version:
Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers
202 lines (140 loc) • 6.79 kB
JavaScript
StartTest(async function(t) {
const template = document.createElement('template');
template.innerHTML =
`<div style="padding: 30px; box-shadow: 1px 1px 10px #666; height:300px; width:300px">
<h1>Interactions inside a web component</h1>
<button onclick="this.nextElementSibling.value='It works!'">Click me</button>
<input type="text" class="first" placeholder="But does it work?"></input>
<input type="text" class="second" placeholder="2"></input>
<input type="text" class="third" placeholder="3"></input>
</div>`;
class TodoApp extends HTMLElement {
constructor() {
super();
this.attachShadow({ 'mode': 'open' });
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
}
window.customElements.define('todo-app', TodoApp);
let app, button, input, outer
t.beforeEach(() => {
document.body.innerHTML = ''
app = document.createElement('todo-app');
app.style.position = "absolute";
app.style.left = app.style.top = "50px";
document.body.appendChild(app);
outer = document.createElement('div')
outer.innerHTML = 'Normal DOM'
outer.style.position = 'absolute'
outer.style.width = '50px'
document.body.appendChild(outer);
input = app.shadowRoot.querySelector('input');
button = app.shadowRoot.querySelector('button');
})
t.it('click', async t => {
t.isFiredWithSignature(document.documentElement, 'click', event => {
t.is(event.target, app, 'Global root doc event should have the web component as the target');
t.is(event.composedPath()[0], button, 'Root doc event should have correct path');
t.is(event.composed, true, 'event composed');
return true;
});
t.firesOnce(document.documentElement, 'click');
t.firesOnce('todo-app -> button', 'click');
await t.click('todo-app -> button');
t.is(input.value, 'It works!', 'click / moved mouse successfully');
t.is(t.activeElement(), button, 'click / moved mouse successfully');
})
t.it('move', async t => {
t.firesOnce(outer, 'click');
t.firesOnce('todo-app -> button', 'click');
await t.click('todo-app -> button');
await t.click(outer);
})
t.it('typing', async t => {
t.isFiredWithSignature(document.documentElement, 'keydown', event => {
t.is(event.target, app, 'Global root doc event should have the web component as the target');
t.is(event.composedPath()[0], input, 'Root doc event should have correct path');
t.is(event.composed, true, 'event composed');
return true;
});
t.firesAtLeastNTimes(document.documentElement, 'keydown', 1);
await t.click('todo-app -> input');
await t.type(null, 'Sure does', null, null, null, true);
t.hasValue('todo-app -> input', 'Sure does', 'hasValue works');
t.is(input.value, 'Sure does', 'typed successfully');
});
t.it('tabbing', async t => {
const input2 = app.shadowRoot.querySelector('input[placeholder="2"]');
const input3 = app.shadowRoot.querySelector('input[placeholder="3"]');
t.firesAtLeastNTimes(document.documentElement, 'keydown', 1);
await t.type('todo-app -> input', 'Sure does[TAB]Foo[TAB]Bar', null, null, null, true);
t.is(input.value, 'Sure does', 'typed successfully');
t.is(input2.value, 'Foo', 'Tabbed successfully');
t.is(input3.value, 'Bar', 'Tabbed successfully');
});
t.it('click', async t => {
t.isFiredWithSignature(document.documentElement, 'click', event => {
t.is(event.target, app, 'Global root doc event should have the web component as the target');
t.is(event.composedPath()[0], button, 'Root doc event should have correct path');
t.is(event.composed, true, 'event composed');
return true;
});
t.firesOnce(document.documentElement, 'click');
await t.click('todo-app -> button');
t.is(input.value, 'It works!', 'click / moved mouse successfully');
})
t.it('activeElement', async t => {
t.chain(
{ click : 'todo-app', offset : [1,1] },
async () => {
t.is(document.activeElement, document.body, 'Body is activeElement if clicking nonfocusable child of web component');
await t.click('todo-app -> input');
t.is(document.activeElement, document.querySelector('todo-app'), 'Web component element is activeElement if clicking focusable child of web component');
}
);
})
t.it('waitForContentLike', async t => {
await t.waitForContentLike('todo-app -> button', 'Click me');
})
t.it('Should support clicking web component el which targets its inside', async t => {
const buttonTemplate = document.createElement('template');
buttonTemplate.innerHTML = `<button onclick="this.innerHTML='clicked'">Click me</button>`;
class ButtonApp extends HTMLElement {
constructor() {
super();
this.attachShadow({ 'mode': 'open' });
this.shadowRoot.appendChild(buttonTemplate.content.cloneNode(true));
}
}
window.customElements.define('button-app', ButtonApp);
document.body.innerHTML = ''
app = document.createElement('button-app');
document.body.appendChild(app);
await t.click('button-app');
t.selectorExists('button-app -> button:textEquals(clicked)');
})
t.it('Should support clicking pure text web component', async t => {
const textTemplate = document.createElement('template');
textTemplate.innerHTML = `foo`;
class DummyApp extends HTMLElement {
constructor() {
super();
this.attachShadow({ 'mode': 'open' });
this.shadowRoot.appendChild(textTemplate.content.cloneNode(true));
}
}
window.customElements.define('dummy-app', DummyApp);
document.body.innerHTML = ''
app = document.createElement('dummy-app');
app.style.position = "absolute";
app.style.background = "#aaa";
app.style.left = app.style.top = "150px";
app.style.width = app.style.height = "150px";
document.body.appendChild(app);
await t.click('dummy-app');
t.pass('Clicked ok');
})
t.it('monkeyTest', async t => {
t.monkeyTest('todo-app');
})
});