Does not work in jest test environment
ktrungha opened this issue · 5 comments
I have to make changes to the code to make it works
Basically, you need to attach the fullfill
function to the Image
object before setting the src attribute
That’s the case if you only use the load
event, but image-promise
also checks the .complete
property.
This might be the same as #10. If not, please give more details than “it does not work”
My case is I use jest to test my app in React-redux.
By not working, it means the promise neither resolve nor reject leaving my test app in a hanging state
Does Jest execute in a real browser? If not, it doesn’t sound like the implementation follow the specification. The complete
property immediately follows setting naturalWidth
and is followed by the load
event. image-promise
expects either property to be truthy or a load
event to fire. They can’t be both falsy without being followed by a load
event.
Once one body part has been completely decoded, the user agent must set the img element to the completely available state and queue a task to fire a simple event named load at the img element.
Your situation seems to happen because load
fires before naturalWidth
is ready and before compleye
is false
Either that, or the problem is elsewhere.
Jest does not execute in a real browser, it has its own mock DOM environment. However, that is beside the point.
So you agree that it can
happen because load fires before naturalWidth is ready and before compleye is false
My understanding is that loading image in Jest will lead to error (because we are in a test, no real network activity allowed), so the event for onerror
will be fired first, and then your code checks for naturalWidth
which is 0, and then the image is in broken state so complete
is false
In addition, it is also possible that your code allows a race condition in real browser (it is rare but it can happen) . It happens when the load event is fired right after you check the complete
attr, and before the event listener function is registered.
Either way, I think it makes more sense to attach the event listener before setting src
. I am forking your code, thanks for the base
that is beside the point.
That is the whole point. If the mock DOM environment does it wrong, it's not image-promise
's bug.
so the event for
onerror
will be fired first, and then your code checks fornaturalWidth
which is 0, and then the image is in broken state socomplete
is false
Incorrect. complete
is true whether it's loaded or not (errored or no-src at all).
demo code
img = new Image();
img.addEventListener("error", err => {
// attached first to log all errors
console.error(err);
console.log("complete (pre-attached event):", img.complete);
});
img.src = "///broken"; // fails on github.com
img.addEventListener("error", err => {
// attached later to see if it's still fired
console.log("complete (post-attached event):", img.complete);
});
console.log("complete (sync):", img.complete);
attach the event listener before setting
src
I can't do that because image-promise
also accepts DOM nodes that are already loading. I can't have it behave differently based on input.