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

[RFC] Add docs for snapshot testing in Playwright e2e tests #45709

Merged
merged 5 commits into from
Jan 9, 2023

Conversation

kevin940726
Copy link
Member

@kevin940726 kevin940726 commented Nov 10, 2022

What?

This PR does a few things:

  1. Propose an article about overusing snapshots.
  2. Add a new test util called editor.getBlocks().
  3. Rearrange and docs and move them to /docs/contributors/code/e2e/

Why?

I'm seeing that snapshots are being misused in several places. I think an official guide on when and how to use snapshots would be a good idea. Future PRs can link to that document during reviews.

I'd expect things like this would happen more often given that we're in the middle of the discussion about best practices in e2e testing. Hence, I create an e2e folder to put all these RFC-like documents there.

How?

📝

@kevin940726 kevin940726 added the [Type] Automated Testing Testing infrastructure changes impacting the execution of end-to-end (E2E) and/or unit tests. label Nov 10, 2022
@codesandbox
Copy link

codesandbox bot commented Nov 10, 2022

CodeSandbox logoCodeSandbox logo  Open in CodeSandbox Web Editor | VS Code | VS Code Insiders

Comment on lines 54 to 62
expect( blocks[ 0 ] ).toMatchObject( {
name: 'core/quote',
innerBlocks: [
{
name: 'core/paragraph',
attributes: { content: '1' },
},
],
} );
Copy link
Member

Choose a reason for hiding this comment

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

Should we also mention serialized content assertions as well?

Getting the serialized expected results are easier by switching to the code editor.

await expect.poll( editor.getEditedPostContent )
			.toBe( `<!-- wp:paragraph -->
<p>1</p>
<!-- /wp:paragraph -->` );

Copy link
Member Author

Choose a reason for hiding this comment

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

Good idea! I think we should be using editor.getBlocks in these cases too, for the same reason as snapshot testing.

Copy link
Member

Choose a reason for hiding this comment

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

I think I prefer to use serialized inline assertions for simple text blocks. Let's document both use variations, and we can choose depending on the test case. Unless you think this would make standardizing the tests harder.

P.S. I might change my mind when I use editor.geBlocks and toMatchObject more often.

Copy link
Member Author

Choose a reason for hiding this comment

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

I added a section about "snapshot variants". LMK what you think!

Copy link
Member Author

Choose a reason for hiding this comment

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

Oops, didn't see your last comment.

I think I'd prefer getBlocks wherever possible. But it's good because this is what this RFC is for 😆 . Do you have a concrete example of where you think serialized blocks make more sense?

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not denying HTML is readable, just that it might not be the best tool for the job. Imagine when the sole purpose of a test is to check for the content of a single column in the table block. Instead of comparing the full HTML of the table block, checking only the column makes the test easier to follow and review. It depends on the tests and their focus, but I often find comparing the full HTML in a snapshot out of focus. I rarely know what I should be looking for in those HTML when everything is equally important. 😅

Copy link
Member

Choose a reason for hiding this comment

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

That's where we disagree I think. I'd agree when creating unit tests, but with e2e test I think it's good to check the whole content for any unintended side effects.

Copy link
Member Author

Choose a reason for hiding this comment

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

I see! I guess my point is that we already have dedicated tests for that, and there are better ways than outputting the full HTML markup to whoever is reading the code.

May I suggest a middle ground of using the diff snapshot trick for this?

// Insert the block...

const beforeContent = await editor.getEditedPostContent();

// Do something in the test...

const afterContent = await editor.getEditedPostContent();
expect( diff( beforeContent, afterContent ) ).toMatchInlineSnapshot();

I'm perfectly fine with this technique as it also encourages minimal atomic assertions. It's less readable without any comment than explicit assertions though, but easier to write. This way, we get to test the full content without having to sacrifice readability with long dreadful snapshots. The coverage for beforeContent should already be covered in "Full post content test fixtures" so we don't have to check for that again. Would this sound like a better alternative to you?

Copy link
Member

Choose a reason for hiding this comment

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

Interesting. What diff function is that? We can try it for sure.

The coverage for beforeContent should already be covered in "Full post content test fixtures" so we don't have to check for that again.

I'm not talking about the initial content, but rather content after edits or other actions.

Copy link
Member Author

Choose a reason for hiding this comment

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

There are a lot of diff functions out there that we can use. The most common one might be the one from Jest: jest-diff.

I'm not talking about the initial content, but rather content after edits or other actions.

Yep, that's why I said we don't need to check the output of the initial content. We just want to check the "diff" between the initial one and the content after editing. I mentioned this just to note that we aren't sacrificing coverage for readability.

Comment on lines +39 to +43
<details>
<summary><h3>Forbid `$`, use `locator` instead</h3></summary>

In fact, any API that returns `ElementHandle` is [discouraged](https://playwright.dev/docs/api/class-page#page-query-selector). This includes `$`, `$$`, `$eval`, `$$eval`, etc. [`Locator`](https://playwright.dev/docs/api/class-locator) is a much better API and can be used with playwright's [assertions](https://playwright.dev/docs/api/class-locatorassertions). This also works great with Page Object Model since that locator is lazy and doesn't return a promise.
</details>
Copy link
Member

Choose a reason for hiding this comment

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

Observation: The "Best practices" individual sections aren't massive, and details/summary usage might make it less readable. What do you think?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, it seems like GitHub will render large margins between these details tags. I'm fine either way, my main concern is that it might make the "Common pitfalls" section less discoverable.

Copy link
Member

Choose a reason for hiding this comment

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

Maybe we can add ToC for level 2 headings? It should make it easier to scan what's in the document.

Copy link
Member Author

Choose a reason for hiding this comment

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

True! I considered that too. We'd have to make sure future revisions will reflect the TOC though. I wonder if there's already a linter or something similar in place so that we don't have to introduce it in this PR 🤔.

Copy link
Member

Choose a reason for hiding this comment

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

@glendaviesnz
Copy link
Contributor

I have made some minor grammar suggestions. It seems like this is in a reasonable place to merge and iterate on if needed.

Copy link
Member

@Mamaduka Mamaduka left a comment

Choose a reason for hiding this comment

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

I agree with @glendaviesnz. Let's merge and iterate.

@kevin940726
Copy link
Member Author

@ellatrix Pinging you again in case you missed it ❤️ .

@ellatrix
Copy link
Member

Something what we discussed that I find missing here is about doing things in e2e tests programmatically. Would be good if we have a section that says to avoid shortcutting actions programmatically except for at the beginning or end of the test, to set up state or verify state. If you find yourself altering state programmatically somewhere in the middle, it's probably a sign that the test is too big.

@kevin940726
Copy link
Member Author

Something what we discussed that I find missing here is about doing things in e2e tests programmatically.

I have that in mind! I think it deserves another PR and another article though. I believe we still have some disagreement about that and it would be nice to start a new conversation there ❤️ !

kevin940726 and others added 2 commits January 9, 2023 16:50
Co-authored-by: George Mamadashvili <georgemamadashvili@gmail.com>
Copy link
Member

@ellatrix ellatrix left a comment

Choose a reason for hiding this comment

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

Let's try it

@kevin940726 kevin940726 merged commit d3c0c9d into trunk Jan 9, 2023
@kevin940726 kevin940726 deleted the add/doc-for-e2e-snapshots branch January 9, 2023 22:55
@github-actions github-actions bot added this to the Gutenberg 15.0 milestone Jan 9, 2023
@Mamaduka
Copy link
Member

@kevin940726, I think we want to add these new docs to manifest.json, so they appear in the handbook. Currently, the Playwright guide link mentioned in testing overview docs leads to 404 - https://developer.wordpress.org/block-editor/contributors/code/testing-overview/.

@kevin940726
Copy link
Member Author

@Mamaduka Oh yeah, you're right! I opened #48447 for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Type] Automated Testing Testing infrastructure changes impacting the execution of end-to-end (E2E) and/or unit tests. [Type] Developer Documentation Documentation for developers
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants