3

I am very new to playwright and i have a problem. I am trying to implement comparing two screenshots (before and after) in one test. this is what i want to achieve:

  1. navigate to webpage
  2. take screenshot (before.png)
  3. do some stuff,state changes, etc
  4. take screenshot (after.png)
  5. compare before.png to after.png (if they are the same test should pass, otherwise test fails)

something like this:

test('compare screenshots', async ({ page }) => {
  await page.goto('my website here');
  const beforeImage = await page.screenshot({
    path: `./screenshots/before.png`
  })
  //
  // some state changes implemented here
  //
  const afterImage = await page.screenshot({
    path: `./screenshots/after.png`
  })
  expect(beforeImage).toMatchSnapshot(afterImage)
});

but it does not work like this. Any ideas/suggestions how can i achieve this? Help would be greatly appreciated

Luka Mis
  • 543
  • 1
  • 7
  • 18

2 Answers2

0

You can do something like this:

test('compare screenshots', async ({ page }, testInfo)=>{
  await page.goto(pageUrl);
  const screenshotTarget =  page.locator(scTarget);
  await expect(screenshotTarget).toHaveScreenshot( `${testInfo.title}.png`);
  //
  // some state changes implemented here
  //
  await expect(screenshotTarget).toHaveScreenshot( `${testInfo.title}.png`);
});

I prefer to use the test titel for naming my screenshots but it should also work if you just enter the same name twice. Then if you run your tests without --update-snapshots they should fail if some visual changes happened.

Basti
  • 449
  • 2
  • 13
0

The problem with Playwright's toHaveScreenshot and toMatchSnapshot is that they're a bit over-engineered and will only compare a current screenshot to a screenshot from a previous test run. If you want to compare two screenshots that you have as Buffers in memory, you can use the getComparator method that Playwright uses behind the scenes:

import { getComparator } from 'playwright-core/lib/utils';

await page.goto('my website here');
const beforeImage = await page.screenshot({
    path: `./screenshots/before.png`
});
//
// some state changes implemented here
//
const afterImage = await page.screenshot({
  path: `./screenshots/after.png`
});

const comparator = getComparator('image/png');
expect(comparator(beforeImage, afterImage)).toBeNull();

The advantage of using getComparator is that it fuzzy matches, and you can set the threshold of how many pixels are allowed to be different. If you just want to check that the PNGs are exactly identical, a dead simple method to check for equality between the two screenshots is:

expect(Buffer.compare(beforeImage, afterImage)).toEqual(0)

Beware though - this simpler method is flakey and sensitive to a single pixel difference in rendering (such as if any animations/transitions are not completed or if there are differences in anti-aliasing).

d2vid
  • 2,014
  • 1
  • 22
  • 25
  • the import line doesn't work: I use 1.35 the most recent version as of now. How to do that? – Brian Hong Jul 12 '23 at 17:20
  • If I use comparator, Is it possible in somehow to create png file which show a differences between compared images ? :) – Marcin Aug 11 '23 at 10:23
  • @Marcin This article shows how, using Conholdate.Total nuget: https://blog.conholdate.com/total/compare-two-images-and-highlight-differences-csharp/ – Ekus Aug 23 '23 at 18:51
  • @Marcin (my previous comment uses c# solution so you'd have to run it after playwright generated the images.. but similar solutions exist in js, e.g. https://stackoverflow.com/questions/11358461) – Ekus Aug 23 '23 at 18:57