I walked through several issues inside the jest-image-shot and puppeteer repos. Yet, I have not able to find a proper solution for this.
Basically, what I want to do is, to allow jest to run its toMatchImageSnapshot
with ignore certain elements or regions within the executed page of puppeteer chrome instance.
Any pointer or existing solution for this within the jest-image-shot itself, or removing the element during execution of puppeteer is the only way to work around it?
No, what you want is not easily possible like that. The library jest-image-snapshot uses the library pixelmatch to compare two images. That means it actually compares the pixels of the image without executing any logic on the document itself.
You have three options:
failureThreshold
to define how much can differfailureThreshold
The library has an option called failureThreshold
built-in, which allows to define a threshold when comparing the images. This threshold is for the whole image and not specific to elements or parts of the image. Depending on your use case, it might be useful if the part of the page you want to ignore is small and other minor changes might be tolerable.
Code sample
it('...', async () => {
// ...
expect(image).toMatchImageSnapshot({
failureThreshold: '0.01',
failureThresholdType: 'percent'
});
});
This would be the easiest way to do it. Remove the element that you want to ignore. If the remaining page does not completely change by this, this might be the easiest and best way.
Code sample
it('...', async () => {
const page = await browser.newPage();
await page.goto('...');
await page.execute(() => {
// remove element from the DOM
const el = document.querySelector('#element-selector');
el.parentElement.removeChild(el);
});
const image = await page.screenshot();
expect(image).toMatchImageSnapshot();
});
If option 2 is not viable for some reason, you could also manipulate the image itself. You first, check the position of the element inside the page and its height and weight and then black the part of the image at that position.
To get the position and size of the element you can use the following code:
const [top, left, weight, height] = await page.execute(() => {
const el = document.querySelector('#element-selector');
const rect = element.getBoundingClientRect();
return [rect.top, rect.left, rect.width, rect.height];
});
After that you could use a library like lwip or jimp to directly manipulate the image and paint that part of the image black (or pixelate) it before comparing them.