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

[RNMobile] Refactor react-native-editor initialization test #37955

Merged
merged 9 commits into from Jan 24, 2022

Conversation

fluiddot
Copy link
Contributor

@fluiddot fluiddot commented Jan 13, 2022

Description

Add test case for covering that the editor initializes correctly and renders the example initial HTML content.

How has this been tested?

  1. Observe that PR check Unit Tests / Mobile passes.
  2. Run command npm run native test and observe that all tests pass.

Screenshots

N/A

Types of changes

Improvement

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • I've tested my changes with keyboard and screen readers.
  • 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 (please manually search all *.native.js files for terms that need renaming or removal).
  • I've updated related schemas if appropriate.

@fluiddot fluiddot added the Mobile App - i.e. Android or iOS Native mobile impl of the block editor. (Note: used in scripts, ping mobile folks to change) label Jan 13, 2022
@fluiddot fluiddot self-assigned this Jan 13, 2022
@github-actions
Copy link

github-actions bot commented Jan 13, 2022

Size Change: +2 B (0%)

Total Size: 1.13 MB

Filename Size Change
build/block-library/index.min.js 166 kB +2 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 960 B
build/admin-manifest/index.min.js 1.1 kB
build/annotations/index.min.js 2.75 kB
build/api-fetch/index.min.js 2.21 kB
build/autop/index.min.js 2.12 kB
build/blob/index.min.js 459 B
build/block-directory/index.min.js 6.28 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 B
build/block-editor/index.min.js 141 kB
build/block-editor/style-rtl.css 14.6 kB
build/block-editor/style.css 14.6 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 111 B
build/block-library/blocks/audio/style.css 111 B
build/block-library/blocks/audio/theme-rtl.css 125 B
build/block-library/blocks/audio/theme.css 125 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 470 B
build/block-library/blocks/button/editor.css 470 B
build/block-library/blocks/button/style-rtl.css 560 B
build/block-library/blocks/button/style.css 560 B
build/block-library/blocks/buttons/editor-rtl.css 292 B
build/block-library/blocks/buttons/editor.css 292 B
build/block-library/blocks/buttons/style-rtl.css 275 B
build/block-library/blocks/buttons/style.css 275 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 90 B
build/block-library/blocks/code/style.css 90 B
build/block-library/blocks/code/theme-rtl.css 131 B
build/block-library/blocks/code/theme.css 131 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 406 B
build/block-library/blocks/columns/style.css 406 B
build/block-library/blocks/comment-template/style-rtl.css 127 B
build/block-library/blocks/comment-template/style.css 127 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/cover/editor-rtl.css 546 B
build/block-library/blocks/cover/editor.css 547 B
build/block-library/blocks/cover/style-rtl.css 1.22 kB
build/block-library/blocks/cover/style.css 1.22 kB
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 417 B
build/block-library/blocks/embed/style.css 417 B
build/block-library/blocks/embed/theme-rtl.css 124 B
build/block-library/blocks/embed/theme.css 124 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 255 B
build/block-library/blocks/file/style.css 255 B
build/block-library/blocks/file/view.min.js 322 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 965 B
build/block-library/blocks/gallery/editor.css 967 B
build/block-library/blocks/gallery/style-rtl.css 1.6 kB
build/block-library/blocks/gallery/style.css 1.6 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 159 B
build/block-library/blocks/group/editor.css 159 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 114 B
build/block-library/blocks/heading/style.css 114 B
build/block-library/blocks/html/editor-rtl.css 332 B
build/block-library/blocks/html/editor.css 333 B
build/block-library/blocks/image/editor-rtl.css 810 B
build/block-library/blocks/image/editor.css 809 B
build/block-library/blocks/image/style-rtl.css 507 B
build/block-library/blocks/image/style.css 511 B
build/block-library/blocks/image/theme-rtl.css 124 B
build/block-library/blocks/image/theme.css 124 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 199 B
build/block-library/blocks/latest-posts/editor.css 198 B
build/block-library/blocks/latest-posts/style-rtl.css 447 B
build/block-library/blocks/latest-posts/style.css 446 B
build/block-library/blocks/list/style-rtl.css 94 B
build/block-library/blocks/list/style.css 94 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 493 B
build/block-library/blocks/media-text/style.css 490 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 649 B
build/block-library/blocks/navigation-link/editor.css 650 B
build/block-library/blocks/navigation-link/style-rtl.css 94 B
build/block-library/blocks/navigation-link/style.css 94 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation-submenu/view.min.js 343 B
build/block-library/blocks/navigation/editor-rtl.css 1.99 kB
build/block-library/blocks/navigation/editor.css 2 kB
build/block-library/blocks/navigation/style-rtl.css 1.85 kB
build/block-library/blocks/navigation/style.css 1.84 kB
build/block-library/blocks/navigation/view.min.js 2.81 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 401 B
build/block-library/blocks/page-list/editor.css 402 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 273 B
build/block-library/blocks/paragraph/style.css 273 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/style-rtl.css 446 B
build/block-library/blocks/post-comments-form/style.css 446 B
build/block-library/blocks/post-comments/style-rtl.css 521 B
build/block-library/blocks/post-comments/style.css 521 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 721 B
build/block-library/blocks/post-featured-image/editor.css 721 B
build/block-library/blocks/post-featured-image/style-rtl.css 153 B
build/block-library/blocks/post-featured-image/style.css 153 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 323 B
build/block-library/blocks/post-template/style.css 323 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 80 B
build/block-library/blocks/post-title/style.css 80 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 389 B
build/block-library/blocks/pullquote/style.css 388 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 234 B
build/block-library/blocks/query-pagination/style.css 231 B
build/block-library/blocks/query/editor-rtl.css 131 B
build/block-library/blocks/query/editor.css 132 B
build/block-library/blocks/quote/style-rtl.css 187 B
build/block-library/blocks/quote/style.css 187 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 397 B
build/block-library/blocks/search/style.css 398 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 B
build/block-library/blocks/separator/editor-rtl.css 99 B
build/block-library/blocks/separator/editor.css 99 B
build/block-library/blocks/separator/style-rtl.css 245 B
build/block-library/blocks/separator/style.css 245 B
build/block-library/blocks/separator/theme-rtl.css 172 B
build/block-library/blocks/separator/theme.css 172 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 744 B
build/block-library/blocks/site-logo/editor.css 744 B
build/block-library/blocks/site-logo/style-rtl.css 181 B
build/block-library/blocks/site-logo/style.css 181 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 177 B
build/block-library/blocks/social-link/editor.css 177 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.32 kB
build/block-library/blocks/social-links/style.css 1.32 kB
build/block-library/blocks/spacer/editor-rtl.css 332 B
build/block-library/blocks/spacer/editor.css 332 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 471 B
build/block-library/blocks/table/editor.css 472 B
build/block-library/blocks/table/style-rtl.css 481 B
build/block-library/blocks/table/style.css 481 B
build/block-library/blocks/table/theme-rtl.css 188 B
build/block-library/blocks/table/theme.css 188 B
build/block-library/blocks/tag-cloud/style-rtl.css 214 B
build/block-library/blocks/tag-cloud/style.css 215 B
build/block-library/blocks/template-part/editor-rtl.css 560 B
build/block-library/blocks/template-part/editor.css 559 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 571 B
build/block-library/blocks/video/editor.css 572 B
build/block-library/blocks/video/style-rtl.css 173 B
build/block-library/blocks/video/style.css 173 B
build/block-library/blocks/video/theme-rtl.css 124 B
build/block-library/blocks/video/theme.css 124 B
build/block-library/common-rtl.css 908 B
build/block-library/common.css 905 B
build/block-library/editor-rtl.css 10.1 kB
build/block-library/editor.css 10.1 kB
build/block-library/reset-rtl.css 474 B
build/block-library/reset.css 474 B
build/block-library/style-rtl.css 10.8 kB
build/block-library/style.css 10.8 kB
build/block-library/theme-rtl.css 672 B
build/block-library/theme.css 676 B
build/block-serialization-default-parser/index.min.js 1.09 kB
build/block-serialization-spec-parser/index.min.js 2.79 kB
build/blocks/index.min.js 46.4 kB
build/components/index.min.js 215 kB
build/components/style-rtl.css 15.5 kB
build/components/style.css 15.5 kB
build/compose/index.min.js 11.2 kB
build/core-data/index.min.js 13.3 kB
build/customize-widgets/index.min.js 11.4 kB
build/customize-widgets/style-rtl.css 1.5 kB
build/customize-widgets/style.css 1.49 kB
build/data-controls/index.min.js 631 B
build/data/index.min.js 7.49 kB
build/date/index.min.js 31.9 kB
build/deprecated/index.min.js 485 B
build/dom-ready/index.min.js 304 B
build/dom/index.min.js 4.5 kB
build/edit-navigation/index.min.js 16 kB
build/edit-navigation/style-rtl.css 3.76 kB
build/edit-navigation/style.css 3.76 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/index.min.js 29.6 kB
build/edit-post/style-rtl.css 7.15 kB
build/edit-post/style.css 7.14 kB
build/edit-site/index.min.js 37.7 kB
build/edit-site/style-rtl.css 6.85 kB
build/edit-site/style.css 6.84 kB
build/edit-widgets/index.min.js 16.5 kB
build/edit-widgets/style-rtl.css 4.17 kB
build/edit-widgets/style.css 4.17 kB
build/editor/index.min.js 38.4 kB
build/editor/style-rtl.css 3.71 kB
build/editor/style.css 3.71 kB
build/element/index.min.js 3.29 kB
build/escape-html/index.min.js 517 B
build/format-library/index.min.js 6.58 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.63 kB
build/html-entities/index.min.js 424 B
build/i18n/index.min.js 3.75 kB
build/is-shallow-equal/index.min.js 501 B
build/keyboard-shortcuts/index.min.js 1.8 kB
build/keycodes/index.min.js 1.39 kB
build/list-reusable-blocks/index.min.js 1.72 kB
build/list-reusable-blocks/style-rtl.css 838 B
build/list-reusable-blocks/style.css 838 B
build/media-utils/index.min.js 2.92 kB
build/notices/index.min.js 925 B
build/nux/index.min.js 2.08 kB
build/nux/style-rtl.css 747 B
build/nux/style.css 743 B
build/plugins/index.min.js 1.84 kB
build/primitives/index.min.js 924 B
build/priority-queue/index.min.js 582 B
build/react-i18n/index.min.js 671 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/redux-routine/index.min.js 2.65 kB
build/reusable-blocks/index.min.js 2.22 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 11 kB
build/server-side-render/index.min.js 1.58 kB
build/shortcode/index.min.js 1.49 kB
build/token-list/index.min.js 639 B
build/url/index.min.js 1.9 kB
build/viewport/index.min.js 1.05 kB
build/warning/index.min.js 248 B
build/widgets/index.min.js 7.15 kB
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.04 kB

compressed-size-action

@fluiddot fluiddot marked this pull request as ready for review January 14, 2022 17:31
packages/react-native-editor/src/test/index.test.js Outdated Show resolved Hide resolved
Comment on lines 226 to 227
// It's expected that some blocks are upgraded and inform about it (example: "Updated Block: core/cover")
expect( console ).toHaveInformed();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This might be giving us a clue about using outdated versions of blocks in initialHtml file.

Copy link
Member

Choose a reason for hiding this comment

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

By not passing arguments to toHaveInformed, I would imagine we expose ourselves to additional console.info calls accumulating without our knowledge. From reviewing the source of @wordpress/jest-console, I suppose there is no way to further constrain this assertion without passing the entirety of the explicit block update output, which is not manageable unfortunately.

This might be giving us a clue about using outdated versions of blocks in initialHtml file.

With this are you implying that we should fix the initialHtml rather than suppressing the console.info message here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

By not passing arguments to toHaveInformed, I would imagine we expose ourselves to additional console.info calls accumulating without our knowledge. From reviewing the source of @wordpress/jest-console, I suppose there is no way to further constrain this assertion without passing the entirety of the explicit block update output, which is not manageable unfortunately.

Exactly, there might be some cases where you could overlook extra or unexpected info logs using this function without passing arguments. In the case of this test, although we know the expected log output, I decided not to include it due to its size.

With this are you implying that we should fix the initialHtml rather than suppressing the console.info message here?

Yep, I haven't investigated this further, but the fact that some blocks are being upgraded makes me wonder whether they should be reviewed, in case the HTML we're using for them is old.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In any case, I think we could address this in a different PR, I'll open a ticket for this as a follow-up.

import * as wpHooks from '@wordpress/hooks';
import '@wordpress/jest-console';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I found this library quite useful for assuring we don't produce unexpected logs. In the future, it would be great to enable it globally 🤩 .

An important note about using it is that it silences potential logs that happen after the test. For example, these test cases are generating "act" warnings (i.e. An update to EditorProvider inside a test was not wrapped in act(...).) due to the fact that some store state updates are happening after the test is finished. In the beginning, I thought of this as an issue, but I think it's safe to omit them as they are happening after the test ends.

Copy link
Member

@dcalhoun dcalhoun Jan 17, 2022

Choose a reason for hiding this comment

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

I found this library quite useful for assuring we don't produce unexpected logs. In the future, it would be great to enable it globally 🤩 .

Agreed. I would love to enable this globally, we'll just need to address all the current warnings and errors in our test logs first.

An important note about using it is that it silences potential logs that happen after the test.

Yeah, this has confused me before while debugging failing web tests, which do enable @wordpress/jest-console globally. In order to intentionally log information, one has to explicitly assert the log should occur.

For example, these test cases are generating "act" warnings (i.e. An update to EditorProvider inside a test was not wrapped in act(...).) due to the fact that some store state updates are happening after the test is finished. In the beginning, I thought of this as an issue, but I think it's safe to omit them as they are happening after the test ends.

While these particular updates may not dangerous for this specific context, I think it may be dangerous to set the precedent that it is safe to ignore the warnings. It is very possible for a post-assertion update to nullify the validity of a successful assertion. E.g. if one asserts an element is present, a later state update may unexpectedly and erroneously removes the element, which would mean the test is a false positive. The logs occurring "after the test ends" I believe is merely a result of them occurring after the final assertion, which doesn't inherently make them safe.

Is there a way for us to address the act warnings in these tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed. I would love to enable this globally, we'll just need to address all the current warnings and errors in our test logs first.

In fact, I'm planning to open a ticket specific to addressing this topic.

While these particular updates may not dangerous for this specific context, I think it may be dangerous to set the precedent that it is safe to ignore the warnings. It is very possible for a post-assertion update to nullify the validity of a successful assertion. E.g. if one asserts an element is present, a later state update may unexpectedly and erroneously remove the element, which would mean the test is a false positive. The logs occurring "after the test ends" I believe is merely a result of them occurring after the final assertion, which doesn't inherently make them safe.

Good point, I understand and share your concern about the potential side effects of ignoring the warnings. However, using the @wordpress/jest-console package would make it very easy to ignore them, so it would be great to discuss whether including (although its benefits) it would be safe in relation to this issue. I guess the main problem here is how to know when the editor and its components finish triggering all the state updates, although I'd like to note that it's also important that we identify potential errors upon unmounting the editor or components, in order to prevent memory leaks caused by unclosed listeners.

Being this said, I'm thinking of creating a native version of the supported matchers and excluding the error logs. This way we would assure the "act" errors (note that they're warnings but logged via console.error) are logged hence, we could easily identify them in the output.

Is there a way for us to address the act warnings in these tests?

Actually, I managed to find a workaround by delaying the query passed to the waitFor function an execution block cycle (check the rnmobile/add/use-immediate-wait-for branch). I haven't investigated the original issue, but I have the gut feeling that it might be related to how the store actions and updates are executed.

Copy link
Member

Choose a reason for hiding this comment

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

However, using the @wordpress/jest-console package would make it very easy to ignore them, so it would be great to discuss whether including (although its benefits) it would be safe in relation to this issue.

The absence of @wordpress/jest-console makes it far easier for warnings and errors to go unnoticed, as they will not necessarily cause test failures. I agree @wordpress/jest-console makes it easier to explicitly hide warnings and errors. I would posit the former is worst. The latter is at least an intentional act.

I guess the main problem here is how to know when the editor and its components finish triggering all the state updates, although I'd like to note that it's also important that we identify potential errors upon unmounting the editor or components, in order to prevent memory leaks caused by unclosed listeners.

Agreed. We appear to be aligned that it is not safe or good practice to ignore the warnings or assume they are safe.

Being this said, I'm thinking of creating a native version of the supported matchers and excluding the error logs. This way we would assure the "act" errors (note that they're warnings but logged via console.error) are logged hence, we could easily identify them in the output.

Maybe I am mistaken, but I interpret the intent of @wordpress/jest-console is to fail tests when console logs, warnings, or errors occur. act errors would trigger test failures when @wordpress/jest-console is enabled. So, @wordpress/jest-console itself should already accomplish your proposed end goal: ensure act errors are not overlooked. I.e. someone is far more likely to notice — and hopefully fix — a failing test (due to an act error) than a passing test that happens to also log an act error.

Example Failure from act + @wordpress/jest-console
 FAIL  ../block-library/src/cover/test/edit.native.js (7.967 s)
  when no media is attached
    ○ skipped adds an image or video
  when an image is attached
    ✕ discards canceled focal point changes (343 ms)
    ○ skipped edits the image
    ○ skipped replaces the image
    ○ skipped clears the image within image edit button
    ○ skipped toggles a fixed background
    ○ skipped edits the focal point with a slider
    ○ skipped edits the focal point with a text input
    ○ skipped clears the media within cell button
  color settings
    ○ skipped sets a color for the overlay background when the placeholder is visible
    ○ skipped sets a gradient overlay background when a solid background was already selected
    ○ skipped toggles between solid colors and gradients
    ○ skipped clears the selected overlay color and mantains the inner blocks

  ● when an image is attached › discards canceled focal point changes

    expect(jest.fn()).not.toHaveErrored(expected)

    Expected mock function not to be called but it was called with:
    ["Warning: An update to %s inside a test was not wrapped in act(...).·
    When testing, code that causes React state updates should be wrapped into act(...):·
    act(() => {
      /* fire events that update state */
    });
    /* assert on the output */·
    This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act%s", "ForwardRef(NavigationContainer)", "
        at NavigationContainer (/Users/[REDACTED]/Sites/a8c/gutenberg/node_modules/@react-navigation/native/lib/commonjs/NavigationContainer.tsx:40:5)
        at View
        at View (/Users/[REDACTED]/Sites/a8c/gutenberg/node_modules/react-native/jest/mockComponent.js:28:18)
        at BottomSheetNavigationContainer (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/components/src/mobile/bottom-sheet/bottom-sheet-navigation/navigation-container.native.js:63:2)
        at View
        at View (/Users/[REDACTED]/Sites/a8c/gutenberg/node_modules/react-native/jest/mockComponent.js:28:18)
        at View
        at View (/Users/[REDACTED]/Sites/a8c/gutenberg/node_modules/react-native/jest/mockComponent.js:28:18)
        at KeyboardAvoidingView (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/components/src/mobile/bottom-sheet/keyboard-avoiding-view.native.js:26:16)
        at Modal
        at /Users/[REDACTED]/Sites/a8c/gutenberg/test/native/setup.js:88:8
        at BottomSheet (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/components/src/mobile/bottom-sheet/index.native.js:51:16)
        at BottomSheetSettings (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/block-editor/src/components/block-settings/container.native.js:29:2)
        at WithDispatch(BottomSheetSettings) (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/data/src/components/with-dispatch/index.js:95:26)
        at /Users/[REDACTED]/Sites/a8c/gutenberg/packages/data/src/components/with-select/index.js:56:24
        at WithSelect(WithDispatch(BottomSheetSettings)) (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/compose/src/higher-order/pure/index.tsx:35:3)
        at SlotFillProvider (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/components/src/slot-fill/provider.js:18:16)
        at CoverEdit"],["Warning: An update to %s inside a test was not wrapped in act(...).·
    When testing, code that causes React state updates should be wrapped into act(...):·
    act(() => {
      /* fire events that update state */
    });
    /* assert on the output */·
    This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act%s", "Cover", "
        at Cover (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/block-library/src/cover/edit.native.js:83:2)
        at WithDispatch(Component) (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/data/src/components/with-dispatch/index.js:95:26)
        at /Users/[REDACTED]/Sites/a8c/gutenberg/packages/data/src/components/with-select/index.js:56:24
        at WithSelect(WithDispatch(Component)) (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/compose/src/higher-order/pure/index.tsx:35:3)
        at Edit (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/block-editor/src/components/block-edit/edit.native.js:29:10)
        at WithToolbarControls(Edit) (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/block-editor/src/hooks/align.js:119:11)
        at WithInspectorControl(WithToolbarControls(Edit)) (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/block-editor/src/hooks/anchor.js:68:45)
        at WithToolbarControls(WithInspectorControl(WithToolbarControls(Edit))) (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/block-editor/src/hooks/style.js:262:33)
        at WithFilters(Edit) (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/components/src/higher-order/with-filters/index.js:49:18)
        at BlockEdit (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/block-editor/src/components/block-edit/index.js:23:10)
        at SlotFillProvider (/Users/[REDACTED]/Sites/a8c/gutenberg/packages/components/src/slot-fill/provider.js:18:16)
        at CoverEdit"]

      34 |      function assertExpectedCalls() {
      35 |              if ( spy.assertionsNumber === 0 && spy.mock.calls.length > 0 ) {
    > 36 |                      expect( console ).not[ matcherName ]();
         |                      ^
      37 |              }
      38 |      }
      39 |

      at Object.assertExpectedCalls (packages/jest-console/src/index.js:36:4)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 12 skipped, 13 total
Snapshots:   0 total
Time:        9.12 s
Ran all test suites matching /packages\/block-library\/src\/cover\/test\/edit.native.js/i.

Actually, I managed to find a workaround by delaying the query passed to the waitFor function an execution block cycle (check the rnmobile/add/use-immediate-wait-for branch). I haven't investigated the original issue, but I have the gut feeling that it might be related to how the store actions and updates are executed.

Interesting. I have limited knowledge of the error, so I am uncertain to the appropriateness of the possible fix. 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Maybe I am mistaken, but I interpret the intent of @wordpress/jest-console is to fail tests when console logs, warnings, or errors occur. act errors would trigger test failures when @wordpress/jest-console is enabled. So, @wordpress/jest-console itself should already accomplish your proposed end goal: ensure act errors are not overlooked. I.e. someone is far more likely to notice — and hopefully fix — a failing test (due to an act error) than a passing test that happens to also log an act error.

That's correct, however, it doesn't identify the act warnings that happen after the test finishes, which are the ones that we wouldn't notice if we enable @wordpress/jest-console.

Let me share the following table, in order to make clearer the benefits and drawbacks of whether enable @wordpress/jest-console:

Using @wordpress/jest-console Not using @wordpress/jest-console
Benefits:
- act warnings will make the test fail hence, it will require contributors to fix them.
- Other log types will also be required to be addressed, which would help in having more robust tests.

Drawbacks:
- Any type of log that happens before or after a test won't be displayed and either considered a test failure. This implies that for component rendering, some act warnings will be unnoticed.
Benefits:
- We won't experience the drawbacks of using @wordpress/jest-console related to omitting warnings or error logs out of the scope of tests.

Drawbacks:
- Nevertheless, the logs won't produce test failures, which would require manual observation of test output.
- For some tests, the output might be too verbose, unless we mock console functions for those cases.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@dcalhoun I removed the use of @wordpress/jest-console package in 4e08331, note that it required a small refactor to cover the same logic. I'd appreciate it if you could take a look and let me know your thoughts about that approach, thanks 🙇 .

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looks like using Jest v27 would help on this issue, per this comment, I noticed that a recently added test is failing due to an act warning being logged after the test is finished 🤩 , and includes the @wordpress/jest-console (this is the first test we have introduced it).

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 correct, however, it doesn't identify the act warnings that happen after the test finishes, which are the ones that we wouldn't notice if we enable @wordpress/jest-console.

Interesting. I was not aware of that. That is really surprising. I wonder why that is. My understanding of act warnings was that they specifically warn about changes that occur after the test finishes. @wordpress/jest-console "swallows" all act warnings — both during and after tests — but only fails the test for act warnings that occur "during" the test?

@dcalhoun I removed the use of @wordpress/jest-console package in 4e08331, note that it required a small refactor to cover the same logic. I'd appreciate it if you could take a look and let me know your thoughts about that approach, thanks 🙇 .

I think the new approach is an appropriate solution while we further investigate more global, long-term solutions.

Looks like using Jest v27 would help on this issue, per this comment, I noticed that a recently added test is failing due to an act warning being logged after the test is finished 🤩 , and includes the @wordpress/jest-console (this is the first test we have introduced it).

👀 Following along that conversation and exploration as well. 👍🏻

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interesting. I was not aware of that. That is really surprising. I wonder why that is. My understanding of act warnings was that they specifically warn about changes that occur after the test finishes. @wordpress/jest-console "swallows" all act warnings — both during and after tests — but only fails the test for act warnings that occur "during" the test?

Exactly, only fails for act warnings that occur during the test. However, when using Jest v27, I noticed that this behavior changed and also makes the test fail when those warnings happen after the test 🤷‍♂️ .

I think the new approach is an appropriate solution while we further investigate more global, long-term solutions.

Great, I'll proceed with it, and we'll see how we could improve it in the next iteration 👍.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Heads up that I re-enabled this import as with Jest v27 the act warnings that occur after the test are also identified as errors.

Comment on lines 34 to 36
jest.isolateModules( () => {
screen = render( <EditorComponent { ...editorProps } /> );
} );
Copy link
Contributor Author

Choose a reason for hiding this comment

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

With this approach, we no longer need to reset modules for testing the call order of hooks and callbacks. Besides, I found out that resetting modules was breaking the test cases that render the editor.

Copy link
Member

@dcalhoun dcalhoun left a comment

Choose a reason for hiding this comment

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

Thank you for putting this work together. I left a few comments for consideration.

import * as wpHooks from '@wordpress/hooks';
import '@wordpress/jest-console';
Copy link
Member

@dcalhoun dcalhoun Jan 17, 2022

Choose a reason for hiding this comment

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

I found this library quite useful for assuring we don't produce unexpected logs. In the future, it would be great to enable it globally 🤩 .

Agreed. I would love to enable this globally, we'll just need to address all the current warnings and errors in our test logs first.

An important note about using it is that it silences potential logs that happen after the test.

Yeah, this has confused me before while debugging failing web tests, which do enable @wordpress/jest-console globally. In order to intentionally log information, one has to explicitly assert the log should occur.

For example, these test cases are generating "act" warnings (i.e. An update to EditorProvider inside a test was not wrapped in act(...).) due to the fact that some store state updates are happening after the test is finished. In the beginning, I thought of this as an issue, but I think it's safe to omit them as they are happening after the test ends.

While these particular updates may not dangerous for this specific context, I think it may be dangerous to set the precedent that it is safe to ignore the warnings. It is very possible for a post-assertion update to nullify the validity of a successful assertion. E.g. if one asserts an element is present, a later state update may unexpectedly and erroneously removes the element, which would mean the test is a false positive. The logs occurring "after the test ends" I believe is merely a result of them occurring after the final assertion, which doesn't inherently make them safe.

Is there a way for us to address the act warnings in these tests?

packages/react-native-editor/src/test/index.test.js Outdated Show resolved Hide resolved
packages/react-native-editor/src/test/index.test.js Outdated Show resolved Hide resolved
packages/react-native-editor/src/test/index.test.js Outdated Show resolved Hide resolved
packages/react-native-editor/src/test/index.test.js Outdated Show resolved Hide resolved
Comment on lines 226 to 227
// It's expected that some blocks are upgraded and inform about it (example: "Updated Block: core/cover")
expect( console ).toHaveInformed();
Copy link
Member

Choose a reason for hiding this comment

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

By not passing arguments to toHaveInformed, I would imagine we expose ourselves to additional console.info calls accumulating without our knowledge. From reviewing the source of @wordpress/jest-console, I suppose there is no way to further constrain this assertion without passing the entirety of the explicit block update output, which is not manageable unfortunately.

This might be giving us a clue about using outdated versions of blocks in initialHtml file.

With this are you implying that we should fix the initialHtml rather than suppressing the console.info message here?

Due to this package removal the tests related to initialization have been refactored to cover the same logic.
Comment on lines 207 to 212
// Some of the store updates that happen upon editor initialization are executed at the end of the current
// Javascript block execution and after the test is finished. In order to prevent "act" warnings due to
// this behavior, we wait for the execution block to be finished before acting on the test.
await act(
() => new Promise( ( resolve ) => setImmediate( resolve ) )
);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we don't wait for the JS block to be finished, we get a bunch of act warnings:

Warning: An update to EditorProvider inside a test was not wrapped in act(...).

Copy link
Member

Choose a reason for hiding this comment

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

Leaving a note that we are actively investigating this issue and approach further in #38052. We should likely retroactively apply whatever global solution we find there to this test.

Copy link
Member

@dcalhoun dcalhoun left a comment

Choose a reason for hiding this comment

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

LGTM. I support merging this in its current state if you'd like. We can always revisit these particular tests whenever we finish the Jest 27 work in #38052. Thank you for improving these tests! 🙇🏻

Comment on lines 207 to 212
// Some of the store updates that happen upon editor initialization are executed at the end of the current
// Javascript block execution and after the test is finished. In order to prevent "act" warnings due to
// this behavior, we wait for the execution block to be finished before acting on the test.
await act(
() => new Promise( ( resolve ) => setImmediate( resolve ) )
);
Copy link
Member

Choose a reason for hiding this comment

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

Leaving a note that we are actively investigating this issue and approach further in #38052. We should likely retroactively apply whatever global solution we find there to this test.

@fluiddot
Copy link
Contributor Author

LGTM. I support merging this in its current state if you'd like. We can always revisit these particular tests whenever we finish the Jest 27 work in #38052. Thank you for improving these tests! 🙇🏻

Thanks for the review 🙇 , now that we have a better workaround (the one you introduced for fixing the act warnings of the Jest v27 update), I'll update the PR and apply it here too.

# Conflicts:
#	packages/react-native-editor/src/test/index.test.js
`initGutenberg` function now returns the Editor component instead of rendering the editor.
Now the initialize editor case renders the actual Editor component including the example initial html.
Copy link
Contributor Author

@fluiddot fluiddot left a comment

Choose a reason for hiding this comment

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

@dcalhoun I've updated the PR with the latest changes from trunk, including the Jest v27 updated, which implied applying some updates to the test cases. Additionally, I updated the initializes the editor test case to cover the actual rendering of the editor with the example initial HTML. Let me know if you could do another review, thanks 🙇 !

import * as wpHooks from '@wordpress/hooks';
import '@wordpress/jest-console';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Heads up that I re-enabled this import as with Jest v27 the act warnings that occur after the test are also identified as errors.

Comment on lines -34 to -37
beforeEach( () => {
// We need to reset modules to guarantee that setup module is imported on every test.
jest.resetModules();
} );
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is no longer necessary as the setup module import is guaranteed by using the jest.isolateModules function when rendering the editor.

@@ -122,7 +123,7 @@ export function waitFor(
).then( () => {
if ( ! result ) {
reject(
`waitFor timed out after ${ timeout }ms for callback:\n${ cb }`
`waitFor timed out after ${ timeout }ms for callback:\n${ cb }\n${ lastError.toString() }`
Copy link
Contributor Author

Choose a reason for hiding this comment

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

While testing I realized that errors not directly related to timeout, like syntax errors, were omitted. For this reason, I updated this function by displaying now the last error that caused the timeout:

Example 1 - Querying for an unexisting text:
Screenshot 2022-01-24 at 11 17 30

Example 2 - Reference error:
Screenshot 2022-01-24 at 12 00 45

Copy link
Member

@dcalhoun dcalhoun left a comment

Choose a reason for hiding this comment

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

Great work! 🚀

@fluiddot fluiddot merged commit c04a386 into trunk Jan 24, 2022
@fluiddot fluiddot deleted the rnmobile/update/editor-initialization-tests branch January 24, 2022 15:01
@github-actions github-actions bot added this to the Gutenberg 12.5 milestone Jan 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Mobile App - i.e. Android or iOS Native mobile impl of the block editor. (Note: used in scripts, ping mobile folks to change)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants