Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Playwright Snapshots blog #295

Open
wants to merge 32 commits into
base: gh-pages
Choose a base branch
from

Conversation

mnyamunda-scottlogic
Copy link

@mnyamunda-scottlogic mnyamunda-scottlogic commented Jan 24, 2025

Please add a direct link to your post here: https://mnyamunda-scottlogic.github.io/blog/2025/01/22/playwright-visual-testing.html

Have you (please tick each box to show completion):

  • Added your blog post to a single category?
  • Added a brief summary for your post? Summaries should be roughly two sentences in length and give potential readers a good idea of the contents of your post.
  • Checked that the build passes?
  • Checked your spelling (you can use npm install followed by npx mdspell "**/{FILE_NAME}.md" --en-gb -a -n -x -t if that's your thing)
  • Ensured that your author profile contains a profile image, and a brief description of yourself? (make it more interesting than just your job title!)
  • Optimised any images in your post? They should be less than 100KBytes as a general guide.

Posts are reviewed / approved by your Regional Tech Lead.


## The Problem

The main challenge was to create a dashboard that shows discrepancies between forecasted air quality and the real time measurements. The main page was simple enough as it was using ag grid, hence we could mock and assert values within each cell. However, it would not be as simple with chart-like elements. We needed to test that the data in these charts was visualised correctly. With default mocked data and then secondly, we needed to test that the various UI interactions transform the charts correctly.
Copy link
Member

@chriswilty chriswilty Feb 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

visualised correctly. With default mocked data

Don't think this full-stop should be there, and there's also a Secondly without a Firstly.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!


![Forecasted and in-situ air quality graphs for the city Seoul]({{ site.baseurl }}/mnyamunda/assets/aqi-charts.png)

Shown above is the UI consisting of six different charts that show forecasted and in-situ pollutant measurements. The first big problem is that the data is non-static. We solve this by mocking data via Playwright. This way, our regression focuses on the functionality and various transformations that the data undergoes. The second problem is how do we know that the actual data is being visualised correctly? This is where Playwright snapshots come in.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"solve this by mocking the data API" maybe? Also a link to the docs would be helpful...
https://playwright.dev/docs/mock

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Copy link
Member

@chriswilty chriswilty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments. Many of the code blocks are messed up, don't know why...

## Playwright Snapshotting Explained

Playwright will startup each browser and complete various actions and take a screenshot of the DOM element(s) state. It will then sequentially look at each pixel and check if it’s RGBA values match up to the comparison image created in the codebase.
With Playwright snapshots we can easily assert how a page element should look. Provided that we don’t have a comparison image in the codebase our first run of `npx playwright test` will create a comparison image for us. Now we must tweak our test steps until we are satisfied with the snapshot created by playwright. Once satisfied we now run the same command with the flag `--update-snapshots` which then saves the snapshot as our golden standard referral image. Now each time we run the test we will compare against that image.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Playwright docs make a clear distinction between screenshots, and (aria) snapshots. In fact, the docs state this:

image

Are you using snapshots because you want to take a partial screenshot, of just the chart element?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct, we specifically used it to capture the chart elements.

test('Verify so2 graph updates correctly when sites are removed', async ({
cityPage,
}) => {
await cityPage.siteRemover('Centro')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's that for then? If it's not relevant to the post, remove it, else explain what you're doing?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I see what this is for now, having read the rest of the post, but up here I did not catch on from the name of the test. Might be better to simplify this test example just to capture the snapshot and verify it.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a fair point, i will adda comment to indicate what the step is actually doing 💯


Shown above is the UI consisting of six different charts that show forecasted and in-situ pollutant measurements. The first big problem is that the data is non-static. We solve this by mocking data via Playwright. This way, our regression focuses on the functionality and various transformations that the data undergoes. The second problem is how do we know that the actual data is being visualised correctly? This is where Playwright snapshots come in.

## Playwright Snapshotting Explained
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find any reference to the term Snapshotting, maybe best leave it as Snapshot Testing.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good to me


## Playwright Snapshotting Explained

Playwright will startup each browser and complete various actions and take a screenshot of the DOM element(s) state. It will then sequentially look at each pixel and check if it’s RGBA values match up to the comparison image created in the codebase.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

complete various actions

A bit woolly. What actions? Authentication, navigate to page and wait for it to load?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, will give some examples!


Without any additional parameters, the comparison will fail if a single pixel is different. This option allows for maximum accuracy.

```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea why this is not rendering correctly 🤔

image


“maxDiffPixels”

`in-situ-AQI-is-4-at-00:00-due-to-PM2.5.png,{ maxDiffPixels:27 }`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest including function name, toMatchSnapshot(

Otherwise it's not clear where these options are supposed to go.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with that, will update!


This is instead a percentage check. If up to 27% of the pixels do not match, then the test will still pass. Upon running the test through playwright CLI commands, a report is generated at the end of the test. This will show us what is different in the image.

## What does failure look like?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your previous headings are ## All Words Propercased as opposed to ## First word capitalized like a sentence. Might be better to stick to one or other, for consistency.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True! Will rectify this.


Expected:

![sulphur dioxide polution level chart expectation]({{ site.baseurl }}/mnyamunda/assets/sulphur-dioxide-chart-expected.png)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: pollution

I assume these are the broken/missing images you mentioned in teams?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good spot, broken images are now fixed. Will correct this!

- Saves on some lengthy manual work. As shown above we could have to manually check and click around on 6 different charts which would be very time consuming if regression is carried out on a per-ticket basis.
- Sometimes you can expect the element to be visible but the actual contents of it may be misrepresented or broken.

![Broken image icon]({{ site.baseurl }}/mnyamunda/assets/broken-image-icon.png)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure what this image is portraying, as there is nothing for comparison.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey Chris, this might not actually add much value. It was just supposed to be a broken image png

const siteDeselect = this.page.getByLabel(`Remove ${location}`)
await siteDeselect.click()
}
```
Copy link
Member

@chriswilty chriswilty Feb 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, these code blocks are broken in the current view:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants