From 96b9006e5672acdb8dce603445dc15c5f988303e Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Thu, 30 Mar 2023 11:53:36 -0400 Subject: [PATCH] test: Add Writing Flow tests (#49352) * test: Multi-line Quote should render expected markup * test: Multi-line Pullquote should render expected markup * test: Multi-line Verse should render expected markup * test: Multi-line Preformatted should render expected markup * test: Rename Preformatted block tests The "Preformatted" description feels more appropriate and mirrors other block tests. I am uncertain as to why this was named differently originally. * test: Add note to expand multi-line test coverage Our helpers do not support typing multiple lines of text into Rich Text inputs. Ideally, we could add this feature to improve our test coverage. * test: Paragraph should left/center/right align text * test: Paragraph should bold/italicize/strikethrough text * test: Paragraph should preserve alignment when split * test: Paragraph should link text with selection * test: Paragraph should link text without selection * test: Paragraph should link text with clipboard contents * test: Await bottom sheet navigation events to avoid act warnings * test: Paragraph should not remove whitespace when formatting * test: Expand native test matcher to include top-level test directory This allows placing integration tests that target high-level features that span across multiple areas of the product, e.g. editor undo/redo history. * test: Editor History should remove and add blocks * test: Editor History should remove and add text * test: Editor History should remove and add text formatting * test: Separate top-level and nested test directory matcher The previous matcher caused fixture files to be run as tests. Also, splitting the regex likely improves the comprehensibility of the expression. * refactor: Use existing getBlock test helper * test: Avoid stale comment reference --- .../src/paragraph/test/edit.native.js | 357 +++++++++++++++++- .../test/__snapshots__/edit.native.js.snap | 4 +- .../src/preformatted/test/edit.native.js | 47 ++- .../src/pullquote/test/edit.native.js | 70 ++++ .../src/quote/test/edit.native.js | 92 +++++ .../src/verse/test/edit.native.js | 33 ++ .../integration/editor-history.native.js | 177 +++++++++ test/native/jest.config.js | 1 + 8 files changed, 776 insertions(+), 5 deletions(-) create mode 100644 packages/block-library/src/pullquote/test/edit.native.js create mode 100644 packages/block-library/src/quote/test/edit.native.js create mode 100644 test/native/integration/editor-history.native.js diff --git a/packages/block-library/src/paragraph/test/edit.native.js b/packages/block-library/src/paragraph/test/edit.native.js index 5a3f4120d4723..02501a3cd49eb 100644 --- a/packages/block-library/src/paragraph/test/edit.native.js +++ b/packages/block-library/src/paragraph/test/edit.native.js @@ -1,13 +1,33 @@ /** * External dependencies */ -import { render } from 'test/helpers'; +import { + act, + addBlock, + getBlock, + changeTextOfRichText, + changeAndSelectTextOfRichText, + fireEvent, + getEditorHtml, + initializeEditor, + render, + setupCoreBlocks, + within, +} from 'test/helpers'; +import Clipboard from '@react-native-clipboard/clipboard'; + +/** + * WordPress dependencies + */ +import { ENTER } from '@wordpress/keycodes'; /** * Internal dependencies */ import Paragraph from '../edit'; +setupCoreBlocks(); + const getTestComponentWithContent = ( content ) => { return render( { const screen = getTestComponentWithContent( '' ); expect( screen.container ).toBeTruthy(); } ); + + it( 'should bold text', async () => { + // Arrange + const screen = await initializeEditor(); + await addBlock( screen, 'Paragraph' ); + + // Act + const paragraphBlock = getBlock( screen, 'Paragraph' ); + fireEvent.press( paragraphBlock ); + const paragraphTextInput = + within( paragraphBlock ).getByPlaceholderText( 'Start writing…' ); + changeAndSelectTextOfRichText( + paragraphTextInput, + 'A quick brown fox jumps over the lazy dog.', + { selectionStart: 2, selectionEnd: 7 } + ); + fireEvent.press( screen.getByLabelText( 'Bold' ) ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

A quick brown fox jumps over the lazy dog.

+ " + ` ); + } ); + + it( 'should italicize text', async () => { + // Arrange + const screen = await initializeEditor(); + await addBlock( screen, 'Paragraph' ); + + // Act + const paragraphBlock = getBlock( screen, 'Paragraph' ); + fireEvent.press( paragraphBlock ); + const paragraphTextInput = + within( paragraphBlock ).getByPlaceholderText( 'Start writing…' ); + changeAndSelectTextOfRichText( + paragraphTextInput, + 'A quick brown fox jumps over the lazy dog.', + { selectionStart: 2, selectionEnd: 7 } + ); + fireEvent.press( screen.getByLabelText( 'Italic' ) ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

A quick brown fox jumps over the lazy dog.

+ " + ` ); + } ); + + it( 'should strikethrough text', async () => { + // Arrange + const screen = await initializeEditor(); + await addBlock( screen, 'Paragraph' ); + + // Act + const paragraphBlock = getBlock( screen, 'Paragraph' ); + fireEvent.press( paragraphBlock ); + const paragraphTextInput = + within( paragraphBlock ).getByPlaceholderText( 'Start writing…' ); + changeAndSelectTextOfRichText( + paragraphTextInput, + 'A quick brown fox jumps over the lazy dog.', + { selectionStart: 2, selectionEnd: 7 } + ); + fireEvent.press( screen.getByLabelText( 'Strikethrough' ) ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

A quick brown fox jumps over the lazy dog.

+ " + ` ); + } ); + + it( 'should left align text', async () => { + // Arrange + const screen = await initializeEditor(); + await addBlock( screen, 'Paragraph' ); + + // Act + const paragraphBlock = getBlock( screen, 'Paragraph' ); + fireEvent.press( paragraphBlock ); + const paragraphTextInput = + within( paragraphBlock ).getByPlaceholderText( 'Start writing…' ); + changeTextOfRichText( + paragraphTextInput, + 'A quick brown fox jumps over the lazy dog.' + ); + fireEvent.press( screen.getByLabelText( 'Align text' ) ); + fireEvent.press( screen.getByLabelText( 'Align text left' ) ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

A quick brown fox jumps over the lazy dog.

+ " + ` ); + } ); + + it( 'should center align text', async () => { + // Arrange + const screen = await initializeEditor(); + await addBlock( screen, 'Paragraph' ); + + // Act + const paragraphBlock = getBlock( screen, 'Paragraph' ); + fireEvent.press( paragraphBlock ); + const paragraphTextInput = + within( paragraphBlock ).getByPlaceholderText( 'Start writing…' ); + changeTextOfRichText( + paragraphTextInput, + 'A quick brown fox jumps over the lazy dog.' + ); + fireEvent.press( screen.getByLabelText( 'Align text' ) ); + fireEvent.press( screen.getByLabelText( 'Align text center' ) ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

A quick brown fox jumps over the lazy dog.

+ " + ` ); + } ); + + it( 'should right align text', async () => { + // Arrange + const screen = await initializeEditor(); + await addBlock( screen, 'Paragraph' ); + + // Act + const paragraphBlock = getBlock( screen, 'Paragraph' ); + fireEvent.press( paragraphBlock ); + const paragraphTextInput = + within( paragraphBlock ).getByPlaceholderText( 'Start writing…' ); + changeTextOfRichText( + paragraphTextInput, + 'A quick brown fox jumps over the lazy dog.' + ); + fireEvent.press( screen.getByLabelText( 'Align text' ) ); + fireEvent.press( screen.getByLabelText( 'Align text right' ) ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

A quick brown fox jumps over the lazy dog.

+ " + ` ); + } ); + + it( 'should preserve alignment when split', async () => { + // Arrange + const screen = await initializeEditor(); + await addBlock( screen, 'Paragraph' ); + + // Act + const paragraphBlock = getBlock( screen, 'Paragraph' ); + fireEvent.press( paragraphBlock ); + fireEvent.press( screen.getByLabelText( 'Align text' ) ); + fireEvent.press( screen.getByLabelText( 'Align text center' ) ); + const paragraphTextInput = + within( paragraphBlock ).getByPlaceholderText( 'Start writing…' ); + const string = 'A quick brown fox jumps over the lazy dog.'; + changeAndSelectTextOfRichText( paragraphTextInput, string, { + selectionStart: string.length / 2, + selectionEnd: string.length / 2, + } ); + fireEvent( paragraphTextInput, 'onKeyDown', { + nativeEvent: {}, + preventDefault() {}, + keyCode: ENTER, + } ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

A quick brown fox jum

+ + + +

ps over the lazy dog.

+ " + ` ); + } ); + + it( 'should link text without selection', async () => { + // Arrange + const screen = await initializeEditor(); + await addBlock( screen, 'Paragraph' ); + + // Act + const paragraphBlock = getBlock( screen, 'Paragraph' ); + fireEvent.press( paragraphBlock ); + // Await React Navigation: https://github.com/WordPress/gutenberg/issues/35685#issuecomment-961919931 + await act( () => fireEvent.press( screen.getByLabelText( 'Link' ) ) ); + // Await React Navigation: https://github.com/WordPress/gutenberg/issues/35685#issuecomment-961919931 + await act( () => + fireEvent.press( + screen.getByLabelText( 'Link to, Search or type URL' ) + ) + ); + fireEvent.changeText( + screen.getByPlaceholderText( 'Search or type URL' ), + 'wordpress.org' + ); + fireEvent.changeText( + screen.getByPlaceholderText( 'Add link text' ), + 'WordPress' + ); + jest.useFakeTimers(); + fireEvent.press( screen.getByLabelText( 'Apply' ) ); + // Await link picker navigation delay + act( () => jest.runOnlyPendingTimers() ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

WordPress

+ " + ` ); + + jest.useRealTimers(); + } ); + + it( 'should link text with selection', async () => { + // Arrange + const screen = await initializeEditor(); + await addBlock( screen, 'Paragraph' ); + + // Act + const paragraphBlock = getBlock( screen, 'Paragraph' ); + fireEvent.press( paragraphBlock ); + const paragraphTextInput = + within( paragraphBlock ).getByPlaceholderText( 'Start writing…' ); + changeAndSelectTextOfRichText( + paragraphTextInput, + 'A quick brown fox jumps over the lazy dog.', + { + selectionStart: 2, + selectionEnd: 7, + } + ); + // Await React Navigation: https://github.com/WordPress/gutenberg/issues/35685#issuecomment-961919931 + await act( () => fireEvent.press( screen.getByLabelText( 'Link' ) ) ); + // Await React Navigation: https://github.com/WordPress/gutenberg/issues/35685#issuecomment-961919931 + await act( () => + fireEvent.press( + screen.getByLabelText( 'Link to, Search or type URL' ) + ) + ); + fireEvent.changeText( + screen.getByPlaceholderText( 'Search or type URL' ), + 'wordpress.org' + ); + jest.useFakeTimers(); + fireEvent.press( screen.getByLabelText( 'Apply' ) ); + // Await link picker navigation delay + act( () => jest.runOnlyPendingTimers() ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

A quick brown fox jumps over the lazy dog.

+ " + ` ); + + jest.useRealTimers(); + } ); + + it( 'should link text with clipboard contents', async () => { + // Arrange + Clipboard.getString.mockResolvedValue( 'https://wordpress.org' ); + const screen = await initializeEditor(); + await addBlock( screen, 'Paragraph' ); + + // Act + const paragraphBlock = getBlock( screen, 'Paragraph' ); + fireEvent.press( paragraphBlock ); + const paragraphTextInput = + within( paragraphBlock ).getByPlaceholderText( 'Start writing…' ); + changeAndSelectTextOfRichText( + paragraphTextInput, + 'A quick brown fox jumps over the lazy dog.', + { + selectionStart: 2, + selectionEnd: 7, + } + ); + // Await React Navigation: https://github.com/WordPress/gutenberg/issues/35685#issuecomment-961919931 + await act( () => fireEvent.press( screen.getByLabelText( 'Link' ) ) ); + // Await React Navigation: https://github.com/WordPress/gutenberg/issues/35685#issuecomment-961919931 + await act( () => + fireEvent.press( + screen.getByLabelText( 'Link to, Search or type URL' ) + ) + ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

A quick brown fox jumps over the lazy dog.

+ " + ` ); + + Clipboard.getString.mockReset(); + } ); + + it( 'should not remove leading or trailing whitespace when formatting', async () => { + // Arrange + const screen = await initializeEditor(); + await addBlock( screen, 'Paragraph' ); + + // Act + const paragraphBlock = getBlock( screen, 'Paragraph' ); + fireEvent.press( paragraphBlock ); + const paragraphTextInput = + within( paragraphBlock ).getByPlaceholderText( 'Start writing…' ); + changeAndSelectTextOfRichText( + paragraphTextInput, + ' some text ', + { + selectionStart: 5, + selectionEnd: 14, + } + ); + fireEvent.press( screen.getByLabelText( 'Italic' ) ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

some text

+ " + ` ); + } ); } ); diff --git a/packages/block-library/src/preformatted/test/__snapshots__/edit.native.js.snap b/packages/block-library/src/preformatted/test/__snapshots__/edit.native.js.snap index e37d8beb3d540..7c0a7aa1dcf48 100644 --- a/packages/block-library/src/preformatted/test/__snapshots__/edit.native.js.snap +++ b/packages/block-library/src/preformatted/test/__snapshots__/edit.native.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`core/more/edit/native should match snapshot when content is empty 1`] = ` +exports[`Preformatted should match snapshot when content is empty 1`] = ` `; -exports[`core/more/edit/native should match snapshot when content is not empty 1`] = ` +exports[`Preformatted should match snapshot when content is not empty 1`] = ` { +setupCoreBlocks(); + +describe( 'Preformatted', () => { it( 'renders without crashing', () => { const screen = render( { ); expect( screen.toJSON() ).toMatchSnapshot(); } ); + + it( 'should produce expected markup for multiline text', async () => { + // Arrange + const screen = await initializeEditor(); + + // Act + await addBlock( screen, 'Preformatted' ); + const verseTextInput = await screen.findByPlaceholderText( + 'Write preformatted text…' + ); + const string = 'A great statement.'; + changeAndSelectTextOfRichText( verseTextInput, string, { + selectionStart: string.length, + selectionEnd: string.length, + } ); + fireEvent( verseTextInput, 'onKeyDown', { + nativeEvent: {}, + preventDefault() {}, + keyCode: ENTER, + } ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +
A great statement.
+ " + ` ); + } ); } ); diff --git a/packages/block-library/src/pullquote/test/edit.native.js b/packages/block-library/src/pullquote/test/edit.native.js new file mode 100644 index 0000000000000..a3c11d445ad76 --- /dev/null +++ b/packages/block-library/src/pullquote/test/edit.native.js @@ -0,0 +1,70 @@ +/** + * External dependencies + */ +import { + addBlock, + getBlock, + initializeEditor, + setupCoreBlocks, + getEditorHtml, + fireEvent, + within, + waitFor, + changeAndSelectTextOfRichText, +} from 'test/helpers'; + +/** + * WordPress dependencies + */ +import { ENTER } from '@wordpress/keycodes'; + +setupCoreBlocks(); + +describe( 'Pullquote', () => { + it( 'should produce expected markup for multiline text', async () => { + // Arrange + const screen = await initializeEditor(); + await addBlock( screen, 'Pullquote' ); + // Await inner blocks to be rendered + const citationBlock = await waitFor( () => + screen.getByPlaceholderText( 'Add citation' ) + ); + + // Act + const pullquoteBlock = getBlock( screen, 'Pullquote' ); + fireEvent.press( pullquoteBlock ); + const pullquoteTextInput = + within( pullquoteBlock ).getByPlaceholderText( 'Add quote' ); + const string = 'A great statement.'; + changeAndSelectTextOfRichText( pullquoteTextInput, string, { + selectionStart: string.length, + selectionEnd: string.length, + } ); + fireEvent( pullquoteTextInput, 'onKeyDown', { + nativeEvent: {}, + preventDefault() {}, + keyCode: ENTER, + } ); + + // TODO: Determine a way to type after pressing ENTER within the block. + + const citationTextInput = + within( citationBlock ).getByPlaceholderText( 'Add citation' ); + changeAndSelectTextOfRichText( citationTextInput, 'A person', { + selectionStart: 2, + selectionEnd: 2, + } ); + fireEvent( citationTextInput, 'onKeyDown', { + nativeEvent: {}, + preventDefault() {}, + keyCode: ENTER, + } ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

A great statement.

A
person
+ " + ` ); + } ); +} ); diff --git a/packages/block-library/src/quote/test/edit.native.js b/packages/block-library/src/quote/test/edit.native.js new file mode 100644 index 0000000000000..f0279ee03334a --- /dev/null +++ b/packages/block-library/src/quote/test/edit.native.js @@ -0,0 +1,92 @@ +/** + * External dependencies + */ +import { + addBlock, + getBlock, + initializeEditor, + setupCoreBlocks, + getEditorHtml, + fireEvent, + within, + waitFor, + changeAndSelectTextOfRichText, +} from 'test/helpers'; + +/** + * WordPress dependencies + */ +import { ENTER } from '@wordpress/keycodes'; + +setupCoreBlocks(); + +describe( 'Quote', () => { + it( 'should produce expected markup for multiline text', async () => { + // Arrange + const screen = await initializeEditor(); + await addBlock( screen, 'Quote' ); + const quoteBlock = getBlock( screen, 'Quote' ); + // A layout event must be explicitly dispatched in BlockList component, + // otherwise the inner blocks are not rendered. + fireEvent( + within( quoteBlock ).getByTestId( 'block-list-wrapper' ), + 'layout', + { + nativeEvent: { + layout: { + width: 320, + }, + }, + } + ); + // Await inner blocks to be rendered + const citationBlock = await waitFor( () => + screen.getByPlaceholderText( 'Add citation' ) + ); + + // Act + fireEvent.press( quoteBlock ); + // screen.debug(); + let quoteTextInput = + within( quoteBlock ).getByPlaceholderText( 'Start writing…' ); + const string = 'A great statement.'; + changeAndSelectTextOfRichText( quoteTextInput, string, { + selectionStart: string.length, + selectionEnd: string.length, + } ); + fireEvent( quoteTextInput, 'onKeyDown', { + nativeEvent: {}, + preventDefault() {}, + keyCode: ENTER, + } ); + quoteTextInput = + within( quoteBlock ).getAllByPlaceholderText( + 'Start writing…' + )[ 1 ]; + changeAndSelectTextOfRichText( quoteTextInput, 'Again.' ); + const citationTextInput = + within( citationBlock ).getByPlaceholderText( 'Add citation' ); + changeAndSelectTextOfRichText( citationTextInput, 'A person', { + selectionStart: 2, + selectionEnd: 2, + } ); + fireEvent( citationTextInput, 'onKeyDown', { + nativeEvent: {}, + preventDefault() {}, + keyCode: ENTER, + } ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +
+

A great statement.

+ + + +

Again.

+ A
person
+ " + ` ); + } ); +} ); diff --git a/packages/block-library/src/verse/test/edit.native.js b/packages/block-library/src/verse/test/edit.native.js index 96bc431be4bbd..6663926a7db64 100644 --- a/packages/block-library/src/verse/test/edit.native.js +++ b/packages/block-library/src/verse/test/edit.native.js @@ -6,6 +6,8 @@ import { getEditorHtml, initializeEditor, getBlock, + changeAndSelectTextOfRichText, + fireEvent, } from 'test/helpers'; /** @@ -13,6 +15,7 @@ import { */ import { getBlockTypes, unregisterBlockType } from '@wordpress/blocks'; import { registerCoreBlocks } from '@wordpress/block-library'; +import { ENTER } from '@wordpress/keycodes'; beforeAll( () => { // Register all core blocks @@ -51,4 +54,34 @@ describe( 'Verse block', () => { expect( verseBlock ).toBeVisible(); expect( getEditorHtml() ).toMatchSnapshot(); } ); + + it( 'should produce expected markup for multiline text', async () => { + // Arrange + const screen = await initializeEditor(); + await addBlock( screen, 'Verse' ); + + // Act + const verseTextInput = await screen.findByPlaceholderText( + 'Write verse…' + ); + const string = 'A great statement.'; + changeAndSelectTextOfRichText( verseTextInput, string, { + selectionStart: string.length, + selectionEnd: string.length, + } ); + fireEvent( verseTextInput, 'onKeyDown', { + nativeEvent: {}, + preventDefault() {}, + keyCode: ENTER, + } ); + + // TODO: Determine a way to type after pressing ENTER within the block. + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +
A great statement.
+ " + ` ); + } ); } ); diff --git a/test/native/integration/editor-history.native.js b/test/native/integration/editor-history.native.js new file mode 100644 index 0000000000000..4afdcc5bbefe2 --- /dev/null +++ b/test/native/integration/editor-history.native.js @@ -0,0 +1,177 @@ +/** + * External dependencies + */ +import { + addBlock, + getBlock, + changeTextOfRichText, + changeAndSelectTextOfRichText, + fireEvent, + getEditorHtml, + initializeEditor, + setupCoreBlocks, + within, +} from 'test/helpers'; + +setupCoreBlocks(); + +describe( 'Editor History', () => { + it( 'should remove and add blocks', async () => { + // Arrange + const screen = await initializeEditor(); + + // Act + await addBlock( screen, 'Verse' ); + await addBlock( screen, 'Image' ); + await addBlock( screen, 'Paragraph' ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

+		
+
+		
+		
+ + + +

+ " + ` ); + + // Act + fireEvent.press( screen.getByLabelText( 'Undo' ) ); + fireEvent.press( screen.getByLabelText( 'Undo' ) ); + fireEvent.press( screen.getByLabelText( 'Undo' ) ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( `""` ); + + // Act + fireEvent.press( screen.getByLabelText( 'Redo' ) ); + fireEvent.press( screen.getByLabelText( 'Redo' ) ); + fireEvent.press( screen.getByLabelText( 'Redo' ) ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

+		
+
+		
+		
+ + + +

+ " + ` ); + } ); + + it( 'should remove and add text', async () => { + // Arrange + const screen = await initializeEditor(); + await addBlock( screen, 'Paragraph' ); + + // Act + const paragraphBlock = getBlock( screen, 'Paragraph' ); + fireEvent.press( paragraphBlock ); + const paragraphTextInput = + within( paragraphBlock ).getByPlaceholderText( 'Start writing…' ); + changeTextOfRichText( + paragraphTextInput, + 'A quick brown fox jumps over the lazy dog.' + ); + + // TODO: Determine a way to type multiple times within a given block. + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

A quick brown fox jumps over the lazy dog.

+ " + ` ); + + // Act + fireEvent.press( screen.getByLabelText( 'Undo' ) ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

+ " + ` ); + + // Act + fireEvent.press( screen.getByLabelText( 'Redo' ) ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

A quick brown fox jumps over the lazy dog.

+ " + ` ); + } ); + + it( 'should remove and add text formatting', async () => { + // Arrange + const screen = await initializeEditor(); + await addBlock( screen, 'Paragraph' ); + + // Act + const paragraphBlock = getBlock( screen, 'Paragraph' ); + fireEvent.press( paragraphBlock ); + const paragraphTextInput = + within( paragraphBlock ).getByPlaceholderText( 'Start writing…' ); + changeAndSelectTextOfRichText( + paragraphTextInput, + 'A quick brown fox jumps over the lazy dog.', + { selectionStart: 2, selectionEnd: 7 } + ); + // Artifical delay to create two history entries for typing and bolding. + await new Promise( ( resolve ) => setTimeout( resolve, 1000 ) ); + fireEvent.press( screen.getByLabelText( 'Bold' ) ); + fireEvent.press( screen.getByLabelText( 'Italic' ) ); + + // TODO: Determine a way to type multiple times within a given block. + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

A quick brown fox jumps over the lazy dog.

+ " + ` ); + + // Act + fireEvent.press( screen.getByLabelText( 'Undo' ) ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

A quick brown fox jumps over the lazy dog.

+ " + ` ); + + // Act + fireEvent.press( screen.getByLabelText( 'Undo' ) ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

A quick brown fox jumps over the lazy dog.

+ " + ` ); + + // Act + fireEvent.press( screen.getByLabelText( 'Redo' ) ); + fireEvent.press( screen.getByLabelText( 'Redo' ) ); + + // Assert + expect( getEditorHtml() ).toMatchInlineSnapshot( ` + " +

A quick brown fox jumps over the lazy dog.

+ " + ` ); + } ); +} ); diff --git a/test/native/jest.config.js b/test/native/jest.config.js index 39e5e6fc6a593..22bd62065ca7d 100644 --- a/test/native/jest.config.js +++ b/test/native/jest.config.js @@ -27,6 +27,7 @@ module.exports = { setupFiles: [ '/setup.js' ], setupFilesAfterEnv: [ '/setup-after-env.js' ], testMatch: [ + '/../../test/**/*.native.[jt]s?(x)', '/../../**/test/!(helper)*.native.[jt]s?(x)', '/../../packages/react-native-*/**/?(*.)+(spec|test).[jt]s?(x)', ],