Reputation: 13
I use Dalek to test my sample to-do application written with help of Mithril framework.
Everything goes fine until .type()
comes in.
If I .type()
something in input
that have bi-directional binding m.prop
with m.withAttr
and then assert
values of that field i get strage behaviour. Instead "test title"
I get "tsttle"
. It seems that test are running too quickly for Mithril to capture changes and render them back to DOM.
If assertions for input equality is removed — all works just fine.
Is there any workaround, can I slow down type process?
P.S. I use Chrome browser as test runner.
Upvotes: 1
Views: 690
Reputation: 686
That definitely is an interesting issue, the problem is though, that Dalek can't control the speed of the letters typed. This is due to the fact that the JSON-Wire Protocol does not give us a way to handle that, see here
One thing you could do, even if it seems like overkill, is to add a long function chain with explicit waits, like this:
.type('#selector', 'H')
.wait(500)
.type('#selector', 'e')
.wait(500)
.type('#selector', 'l')
.wait(500)
.type('#selector', 'l')
.wait(500)
.type('#selector', 'o')
You also could go ahead & write a utility function that handles that for you
function myType (selector, keys, test, wait) {
var keysArr = keys.split('');
keysArr.forEach(function (key) {
test.type(selector, key).wait(wait);
});
return test;
}
And then use it in your test like this:
module.exports = {
'my test': function (test) {
test.open('http://foobar.com');
myType('#selector', 'Hello', test, 500);
test.done();
}
};
Upvotes: 2
Reputation: 1320
Mithril renders asynchronously in response to event handlers (basically so that related groups of events like keypress/input all get a chance to run before redrawing)
You could try a few things:
if you have access to your data model from your test, you could run your assertion against that model value (which is updated synchronously), as opposed to using the DOM value which only gets updated on the next animation frame
otherwise, you could force a synchronous redraw by explicitly calling m.render
(yes, render, not redraw) before running the assertion, to ensure the view is actually in sync w/ the data model
alternatively, you could try waiting for one animation frame (or two) before running the assertion
Upvotes: 0
Reputation: 2049
Mithril, as of when I'm writing this, does a re-render on onkey* events. An option to avoid this is coming.
You could use attr::config at present to handle the onkey* events as this will not cause a rerender. For example:
m('input', {config: addHandler});
function addHandler (el, isInitialized, context) {
if (!isinitialized) {
el.addEventListener('onkeyup', keyHandler, false);
}
}
function keyHandler (event) { /* do something with key press */ }
Its possible {config: addHandler, onchange: m.withAttr('value', mpropData)} will do what you want, but I don't know Dalek. If its doesn't, then you can consider updating mpropData inside keyHandler.
Upvotes: 1