I have written a react component that draws an image to the 'konva react' canvas. The component utilises the useImage hook. The problem is that the canvas will be drawn first and the image will be added to the canvas later. This causes an issue when testing. In my playwright testing I look for a 'canvas' DOM element and take a screenshot to do a visual comparison.
Now, the problem is that 'canvas' will render and the screenshot will be taken before the image is drawn on the canvas. This results in a 'flaky' tests, where sometimes the screenshot is taken before the image is drawn and sometimes after.
Here is a simplified version of the component.
const Figure: React.FC<FigureProps> = ({
url,
x,
y,
}) => {
const [image] = useImage(url);
return (
<Image
x={x}
y={y}
image={image}
/>
);
};
export default Figure;
So far the most similar question I have found is this. However, the suggested solution to use a callback and the 'useImage' status is not really applicable as playwright only sees whether a component is there or not.
I know I could just implement an arbitrary waiting time, but this is not a robust solution. I would like to have a solution where before the screenshot is taken by 'Playwright' I can be certain that the image has been drawn to the canvas.
As mentioned in the link you shared, you can use special logic to track loading of your application. From playwright you can watch for loading variable.
Much simplified version of this can be:
window.loadingCount = 0;
const Figure: React.FC<FigureProps> = ({
url,
x,
y,
}) => {
const [image] = useImage(url);
// use layout effect for faster execution
React.useLayoutEffect(() => {
if(image) {
// image is loaded
window.loadingCount -= 1;
} else {
// image is not loaded yet
window.loadingCount += 1;
}
}, [image]);
return (
<Image
x={x}
y={y}
image={image}
/>
);
};
export default Figure;
Then in playwright you do this:
await page.waitForFunction(() => window.loadingCount === 0);
Just need to make sure that the function will start execution after Figure
component is mounted.