Hi,
I'm writing a Karma test using chai. I need to check that a custom element, once attached to the wrong parent, throws error, but seems that the error has not been captured.
Here is my code:
var element = new OnsTabElement();
expect(function() { document.body.appendChild(element)}).to.throw('Uncaught Error: This ons-tab element is must be child of ons-tabbar element.');
That makes my test to fail cause of the error and the assertion doesn't get executed. The error should have been captured and compared with the string I gave, but it never happens. I tested everything on my browser and the error is correctly displayed, so it's not a problem of my code.
I have already used throw in my assertions, while testing some custom elements, and it worked fine, so I guess the problem is only related to DOM operations.
For example, the following assertions doesn't create any problem, even if it's behavior is similar to the first one I posted (expect the DOM operation).
expect(function(){element._getCurrentPageElement()}).to.throw('Invalid state: page element must be a "ons-page" element.');
Please, confirm if it's a bug.
Hi @andipavllo thanks for the issue.
I think we'd need more information to confirm if it is a bug or not. If you could provide the following information, I may be able to help some more:
However, without that I can offer some limited guidance:
.to.throw just does a try/catch around the function you give it. For starters, this means that all errors have to be synchronous. The callback determining when your element is attached or not could be asynchronous (I don't know what framework you're using for this so I can't answer this).
A simple test would be to try the following code:
it('should pass', function () {
try {
document.body.appendChild(element);
} catch(e) {
console.log('Caught error: ', e);
}
});
That test should pass and log out the expected error. If it fails, or does not log the expected error, then it is something outside of Chai's control.
Closing due to lack of activity in past year but feel free to post if this is still an issue.
I just ran into this and can confirm it is NOT a chai bug. The W3C spec does not guarantee synchronicity on custom element reactions (like connectedCallback).
The way in which custom element reactions are invoked is done with special care, to avoid running author code during the middle of delicate operations. Effectively, they are delayed until "just before returning to user script". This means that for most purposes they appear to execute synchronously, but in the case of complicated composite operations (like cloning, or range manipulation), they will instead be delayed until after all the relevant user agent processing steps have completed, and then run together as a batch.
Additionally, the precise ordering of these reactions is managed via a somewhat-complicated stack-of-queues system, described below. The intention behind this system is to guarantee that custom element reactions always are invoked in the same order as their triggering actions, at least within the local context of a single custom element. (Because custom element reaction code can perform its own mutations, it is not possible to give a global ordering guarantee across multiple elements.)
The way I ended up handling it in my tests was to use the window.onerror global event handler, which looks super ghetto and doesn't actually catch the error, but allows it to be tested.
it('should pass', function (done) {
let onerror = window.onerror,
myElement = new MyCustomElement();
window.onerror(function (msg) {
expect(msg).to.equal("Uncaught Error: ...");
window.onerror = onerror;
done();
});
document.body.appendChild(myElement);
});
Sorry to resurrect this thread. Hopefully this info may be helpful to others.
Most helpful comment
I just ran into this and can confirm it is NOT a chai bug. The W3C spec does not guarantee synchronicity on custom element reactions (like
connectedCallback).The way I ended up handling it in my tests was to use the
window.onerrorglobal event handler, which looks super ghetto and doesn't actually catch the error, but allows it to be tested.Sorry to resurrect this thread. Hopefully this info may be helpful to others.