ember-test-helpers
ember-test-helpers copied to clipboard
[BREAKING?] fix(settled, waitUntil): reject with error thrown in run loop
This PR is currently still WIP and failing some tests, but I'd like to receive feedback on the implementation and course-correct, where necessary.
The goal of this PR is to fix the longstanding issue of test helpers not propagating run loop errors thrown during their execution, but instead causing an out of band "global failure" that fails the test. For example:
test('`render` rejects with error thrown inside the run loop', async function (assert) {
// 🔥 BUG: `render` doesn't reject, instead we get an uncatchable "global failure".
await assert.rejects(
render(hbs`<UnknownComponent />`),
/unknown-component/
);
});
test('`click` rejects with run loop errors', async function (assert) {
this.owner.register('component:click-test', Component.extend({
layout: hbs`<div class="click-test"></div>`,
click() {
later(() => {
throw new Error('bazinga');
}, 10);
},
}));
await render(hbs`<ClickTest />`);
// 🔥 BUG: `click` doesn't reject, instead we get an uncatchable "global failure".
await assert.rejects(
click('.click-test'),
/bazinga/,
'rejects with the error thrown inside the run loop'
);
});
Fixes #310. Fixes #453. Relates to #440, #1128, ember-qunit#592
This PR adds an rejectOnError option to waitUntil. It defaults to true, if the test context is set up correctly for use with setupOnerror.
If enabled, waitUntil will reject when an error propagates to Ember.onerror, using setupOnerror under the hood. As such, (a/sync) errors thrown in a run loop will cause waitUntil to fail.
Almost all test helpers end with a call to settled, which just calls waitUntil. Therefore they'll all automatically benefit from this change and reject, if an error is thrown during their execution.
I've written down an in-depth analysis of the flow in this #1128 comment.
This seems good. I think it's the best solution that doesn't require changes to ember itself.
But I view this as a workaround for a feature ember itself should offer. There should be public API that lets you implement render, and it should include more specific error handling than a single global callback.
Is there any movement on this, or perhaps an alternative available pattern?
I'm currently using this asyncThrows helper via ember-custom-assertions (https://gist.github.com/samselikoff/ad5e3695383b91599ee428bf9a2d22ca) but in trying to upgrade some apps, importing Ember is no longer allowed so it's not working.
It'd be great to get some official pattern for handling testing async render errors!
Should we pursue finishing / deciding what to do with this PR?