My project is built with vue-cordova-webpack template. I created a vue-component. There is v-ons-input
inside the template of my component. I need to change the value of v-ons-input
during the unit test of my component. I can do it only after ons-input
is compiled, because only after compilation ons-input
has input
inside (see about OnsenUI component compilation). The problem is a compilation is executed asynchronously and I didn't find any "legit" way to catch the event when OnsenUI component is ready for use.
What do I do? I created a sinon spy for an internal method _compile
of the ons-input
and wait until it's been called:
it('test', (done) => {
const wrapper = mount(myVueComponent)
// here I can't set a value for ons-input
var spy = sinon.spy(wrapper.find('ons-input').element, '_compile')
function waitForCall(spy) {
return new Promise(function (resolve, reject) {
(function wait() {
if (spy.called) {
return resolve()
}
setTimeout(wait, 10)
})()
})
}
waitForCall(spy).then(function () {
// now ons-input is compiled and I can set a value for ons-input
wrapper.find('ons-input').element.value = 'foo'
...
}).then(done, done)
})
Is there more "clean" way to determine that OnsenUI component is ready for use in a unit test (without manipulation with internal methods of the component)?
P.S. I know the way not for test environment - listening for init
event for document
(see here), but it doesn't work in unit tests.
setTimeout
should be as good as anything here.
setTimeout(() => document.querySelector('ons-input input'));
The file defining VOnsInput
imports ons-input
, which registers ons-input
as a Custom Element. This happens synchronously so as long as the Vue component's script has been executed, it is guaranteed that ons-input
will be registered as a Custom Element.
During registration of ons-input
, Onsen UI uses a function contentReady
to wait for compilation to be finished, but that function is not part of the public API. However, contentReady
uses setTimeout
(technically setImmediate
but it amounts to the same thing) as a fallback so by using setTimeout
once you are effectively doing the same thing.
In short, this means that using setTimeout
should guarantee that the inner input
is attached when setTimeout
's callback is run.