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

Add regresion E2E test for the empty reusable block causing WSODs issue #26913

Merged
merged 5 commits into from
Nov 14, 2020
Merged

Add regresion E2E test for the empty reusable block causing WSODs issue #26913

merged 5 commits into from
Nov 14, 2020

Conversation

fullofcaffeine
Copy link
Member

@fullofcaffeine fullofcaffeine commented Nov 12, 2020

Description

Issue: #26548

Adds a regression test in the client block E2E spec to avoid the regression of this issue: #26485.

How to test

diff --git c/packages/block-editor/src/store/selectors.js w/packages/block-editor/src/store/selectors.js
index c2153ee33c..9432c252bb 100644
--- c/packages/block-editor/src/store/selectors.js
+++ w/packages/block-editor/src/store/selectors.js
@@ -1704,11 +1704,7 @@ export const __experimentalGetParsedReusableBlock = createSelector(
 
 		// Only reusableBlock.content.raw should be used here, `reusableBlock.content` is a
 		// workaround until #22127 is fixed.
-		return parse(
-			typeof reusableBlock.content.raw === 'string'
-				? reusableBlock.content.raw
-				: reusableBlock.content
-		);
+		return parse( reusableBlock.content.raw || reusableBlock.content );
 	},
 	( state ) => [ getReusableBlocks( state ) ]
 );

Prepare the env

  • Run npm run build and npm run wp-env-start;
  • Access your wp-env instance and make sure Gutenberg is active.

Run the E2E test

  • Run npm run test-e2e packages/e2e-tests/specs/editor/various/reusable-blocks.test.js;
  • The test will create a reusable block, then edit it and make it empty, then try to insert a block in a new post. Verify that the error happens and that the test fails;
  • Now remove the patch (git checkout -- packages/block-editor/src/store/selectors.js), and rebuild (npm run build);
  • Re-run the e2e test. It should pass this time.

Run the unit test

  • Run npm run test-unit-js packages/block-editor/src/store/test/selectors.js.
  • The test will create a reusable block, then edit it and make it empty, then try to insert a block in a new post. Verify that the error happens and that the test fails.
  • Now remove the patch (git checkout -- packages/block-editor/src/store/selectors.js), and rebuild (npm run build).
  • Re-run the unit test. It should pass this time.

Types of changes

New E2E test.

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR.

Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

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

I left some minor comments. Thank you for sending PR with new tests added 👍

it( "should not throw an exception if reusable block's content.raw is an empty string", () => {
expect( () =>
__experimentalGetParsedReusableBlock( state, 1 )
).not.toThrowError();
Copy link
Member

Choose a reason for hiding this comment

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

You can also update this check and test for the actual result. If code would throw it will fail the test as well.

Copy link
Member Author

@fullofcaffeine fullofcaffeine Nov 13, 2020

Choose a reason for hiding this comment

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

Do you mean to re-purpose the test to test one of the actual scenarios/happy-path for the __experimentalGetParsedReusableBlock helper func? That means it wouldn't be a specific regression test anymore (as stated in the describe). That's not a big deal, but then we'd be testing the func, and not the bug regression (which would still be tested indirectly, as you mention, though). I'm fine with that but just want to make sure we're on the same page.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, this is what I meant. not.toThrowError(); part would be replaced with the assertion checking the actual result and the description for the test updated.

@@ -35,6 +35,7 @@ export {
insertBlockDirectoryBlock,
openGlobalBlockInserter,
closeGlobalBlockInserter,
toggleGlobalBlockInserter,
Copy link
Member

Choose a reason for hiding this comment

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

There are 2 existing helpers to control the block inserter. Would it be possible to use them instead of introducing another helper function?

Copy link
Member Author

@fullofcaffeine fullofcaffeine Nov 13, 2020

Choose a reason for hiding this comment

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

👋🏻 Hi Greg! I tried openGlobalBlockInserter but it waits for the actual inserter el to be present on the page. In the case the error ever regresses, it would cause a timeout because the inserter is never shown. What we really need is to just click to show the inserter, and this helper does just that. What's the other helper?

Copy link
Member Author

Choose a reason for hiding this comment

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

Also, this is actually an existing helper, I just exported it.

Copy link
Member

Choose a reason for hiding this comment

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

I tried openGlobalBlockInserter but it waits for the actual inserter el to be present on the page. In the case the error ever regresses, it would cause a timeout because the inserter is never shown.

It looks like openGlobalBlockInserter is exactly what fits best here. toggleGlobalBlockInserter only verifies if the button can be clicked. The waiting part is crucial here to prevent regression. If it would timeout in the future, that's a proper way to signal that something went wrong.

Copy link
Member Author

Choose a reason for hiding this comment

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

toggleGlobalBlockInserter only verifies if the button can be clicked.

Hmm, it actually wraps a click call: https://github.com/WordPress/gutenberg/blob/master/packages/e2e-test-utils/src/inserter.js#L49. For the purposes of this regression test, that's all we need.

If we decide to use openGlobalBlockInserter, there's another potential problem as well (which I just tested): if it the bug regresses, it will fail with the timeout and not with the expect below it. It also means it will slow down the actual test that would finish faster if we weren't waiting for an inserter we know won't appear.


await toggleGlobalBlockInserter();

expect( console ).not.toHaveErrored();
Copy link
Member

Choose a reason for hiding this comment

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

This check is scoped only to the e2e spec. It isn't possible to catch errors on the page this way. We have a global verification for the page:

page.on( 'console', ( message ) => {

Copy link
Member Author

@fullofcaffeine fullofcaffeine Nov 13, 2020

Choose a reason for hiding this comment

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

Hmmm, interesting. It seemed like it did catch the error when I tested. Or maybe it was just the error bubbling up. Maybe I missed something.

Copy link
Member Author

@fullofcaffeine fullofcaffeine Nov 13, 2020

Choose a reason for hiding this comment

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

Do you mean then this assertion is not needed at all? Any hints on how I should rewrite that?

Copy link
Member

Choose a reason for hiding this comment

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

It would mean there is console.error call in the test code, not on the page. What error do you get when it isn't called?

Copy link
Member Author

@fullofcaffeine fullofcaffeine Nov 13, 2020

Choose a reason for hiding this comment

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

I double-checked (by re-introducing the bug that caused the regression) and that expect does seem to work for the purposes of the test, see the output in the gist:

https://gist.github.com/fullofcaffeine/453e58fba78d902bc690e0b6994e7b31

It is true that it might be considered redundant because if I remove it, the test still fails because the error bubbles up (as described here) and it caught from within the console object:

https://gist.github.com/fullofcaffeine/ade1be595e7f1c5bd46ed5b652814934

That being said, I'd rather keep the expect there as it communicates what the test is not expecting.

So, it seems it's fine the way it is? Let me know if I missed something 🙇🏻

@gziolo gziolo added [Type] Automated Testing Testing infrastructure changes impacting the execution of end-to-end (E2E) and/or unit tests. [Feature] Synced Patterns Related to synced patterns (formerly reusable blocks) labels Nov 13, 2020
@sirreal sirreal added the [Type] Code Quality Issues or PRs that relate to code quality label Nov 14, 2020
@gziolo gziolo merged commit 1b2d663 into WordPress:master Nov 14, 2020
@github-actions github-actions bot added this to the Gutenberg 9.4 milestone Nov 14, 2020
gziolo added a commit that referenced this pull request Nov 14, 2020
@gziolo
Copy link
Member

gziolo commented Nov 14, 2020

It looks like the new e2e test fails on master. I’m opening a revert PR for now but we should definitely update this test and try merge again.

@fullofcaffeine
Copy link
Member Author

It looks like the new e2e test fails on master. I’m opening a revert PR for now but we should definitely update this test and try merge again.

Strange, this spec is green for me locally.

It seems to fail when trying to get hold of the block toolbar, maybe the approach to focus the block is flaky? It does seem to consistently work locally for me, though.

I'll create a new PR for the revert of the revert and look into this next week.

Thanks! 🙇🏻

@fullofcaffeine
Copy link
Member Author

fullofcaffeine commented Nov 14, 2020

Revert of revert PR is here, I'll investigate the flakiness and check what's up. The linked PR fixes the issue ✅

gziolo pushed a commit that referenced this pull request Nov 16, 2020
* Revert "Revert "Add regresion E2E test for the empty reusable block causing WSODs issue (#26913)" (#26979)"

This reverts commit cca33e5.

* Wait for the block to be present on the page and click it to five it focus instead of tabbing to it

* Make the test more resilient by waiting for the Update button to become enabled
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Synced Patterns Related to synced patterns (formerly reusable blocks) [Type] Automated Testing Testing infrastructure changes impacting the execution of end-to-end (E2E) and/or unit tests. [Type] Code Quality Issues or PRs that relate to code quality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants