From c908c06a950b0a402e72704bba82f58986c333e5 Mon Sep 17 00:00:00 2001 From: Derek Blank Date: Tue, 9 May 2023 17:20:23 +1000 Subject: [PATCH 1/9] Add rel to link formatting attributes --- packages/format-library/src/link/index.native.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/format-library/src/link/index.native.js b/packages/format-library/src/link/index.native.js index 2588937f2d828c..3a39485bce120a 100644 --- a/packages/format-library/src/link/index.native.js +++ b/packages/format-library/src/link/index.native.js @@ -37,6 +37,7 @@ export const link = { attributes: { url: 'href', target: 'target', + rel: 'rel', }, edit: withSpokenMessages( class LinkEdit extends Component { From ccef5a6616a63e7518ef1ad6ee19297ec37d952d Mon Sep 17 00:00:00 2001 From: Derek Blank Date: Wed, 10 May 2023 13:10:28 +1000 Subject: [PATCH 2/9] Update CHANGELOG to add undo/redo fix to Unreleased section --- packages/react-native-editor/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index 10d1831413d0ca..6e60ffdf5b12dc 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -10,6 +10,7 @@ For each user feature we should also add a importance categorization label to i --> ## Unreleased +- [**] Fix bug affecting undo and redo history when instering a link configured to open in a new tab ## 1.93.0 - [***] [iOS] Fixed iOS scroll jumping issue by refactoring KeyboardAwareFlatList improving writing flow and caret focus handling. [#48791] From 74236fb410f0a3e22acd2028beb9b4723799e7d2 Mon Sep 17 00:00:00 2001 From: Derek Blank Date: Fri, 12 May 2023 08:35:13 +1000 Subject: [PATCH 3/9] Update packages/react-native-editor/CHANGELOG.md Co-authored-by: Tanner Stokes --- packages/react-native-editor/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index d8c298f1531b56..0b75d1f5733ba9 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -13,7 +13,7 @@ For each user feature we should also add a importance categorization label to i - [*] Fix crash when trying to convert to regular blocks an undefined/deleted reusable block [#50475] - [**] Tapping on a nested block now gets focus directly instead of having to tap multiple times depeding on the nesting levels. [#50108] - [*] Use host app namespace in reusable block message [#50478] -- [**] Fix bug affecting undo and redo history when instering a link configured to open in a new tab [#50460] +- [**] Fix bug affecting undo and redo history when inserting a link configured to open in a new tab [#50460] ## 1.94.0 - [*] Split pasted content between title and body. [#37169] From b4816cea49bbaab1070e8498827943ab8ba8fbd7 Mon Sep 17 00:00:00 2001 From: Derek Blank Date: Mon, 15 May 2023 17:32:25 +1000 Subject: [PATCH 4/9] Update packages/react-native-editor/CHANGELOG.md Co-authored-by: David Calhoun --- packages/react-native-editor/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-native-editor/CHANGELOG.md b/packages/react-native-editor/CHANGELOG.md index 0b75d1f5733ba9..cf41643a5377de 100644 --- a/packages/react-native-editor/CHANGELOG.md +++ b/packages/react-native-editor/CHANGELOG.md @@ -13,7 +13,7 @@ For each user feature we should also add a importance categorization label to i - [*] Fix crash when trying to convert to regular blocks an undefined/deleted reusable block [#50475] - [**] Tapping on a nested block now gets focus directly instead of having to tap multiple times depeding on the nesting levels. [#50108] - [*] Use host app namespace in reusable block message [#50478] -- [**] Fix bug affecting undo and redo history when inserting a link configured to open in a new tab [#50460] +- [**] Configuring a link to open in a new tab no longer results in a partial loss of edit history (undo and redo) [#50460] ## 1.94.0 - [*] Split pasted content between title and body. [#37169] From 602f8a92fadcf93b07bef11534c00043d6d8b140 Mon Sep 17 00:00:00 2001 From: Derek Blank Date: Mon, 22 May 2023 16:43:32 +1000 Subject: [PATCH 5/9] Add test for checking undo/redo history when a link is configured to open in a new tab --- .../integration/editor-history.native.js | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/test/native/integration/editor-history.native.js b/test/native/integration/editor-history.native.js index acb3eb23192afd..c8f64ff982f5df 100644 --- a/test/native/integration/editor-history.native.js +++ b/test/native/integration/editor-history.native.js @@ -2,6 +2,7 @@ * External dependencies */ import { + act, addBlock, getBlock, typeInRichText, @@ -173,4 +174,72 @@ describe( 'Editor History', () => { " ` ); } ); + + it( 'should preserve editor history when a link has been added and configured to open in a new tab', 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…' ); + typeInRichText( + paragraphTextInput, + 'A quick brown fox jumps over the lazy dog.', + { + finalSelectionStart: 2, + finalSelectionEnd: 7, + } + ); + + // Await React Navigation: https://github.com/WordPress/gutenberg/issues/35685#issuecomment-961919931 + await act( () => fireEvent.press( screen.getByLabelText( 'Link' ) ) ); + 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() ); + + const linkTargetButton = screen.getByText( 'Open in new tab' ); + fireEvent.press( linkTargetButton ); + + // 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.

+ " + ` ); + + jest.useRealTimers(); + } ); } ); From 17266631f6ad3f67d72330fb59ab3df9f675c674 Mon Sep 17 00:00:00 2001 From: Derek Blank Date: Mon, 22 May 2023 19:43:51 +1000 Subject: [PATCH 6/9] Update link settings modal test case to check for correct editor history --- .../format-library/src/link/modal.native.js | 1 + .../integration/editor-history.native.js | 55 +++++++++---------- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/packages/format-library/src/link/modal.native.js b/packages/format-library/src/link/modal.native.js index 67de4197159549..8d29437385f1c6 100644 --- a/packages/format-library/src/link/modal.native.js +++ b/packages/format-library/src/link/modal.native.js @@ -19,6 +19,7 @@ const ModalLinkUI = ( { isVisible, ...restProps } ) => { hideHeader onClose={ restProps.onClose } hasNavigation + testId={ 'link-settings-modal' } > diff --git a/test/native/integration/editor-history.native.js b/test/native/integration/editor-history.native.js index c8f64ff982f5df..e5248c39ab4048 100644 --- a/test/native/integration/editor-history.native.js +++ b/test/native/integration/editor-history.native.js @@ -4,12 +4,15 @@ import { act, addBlock, + dismissModal, getBlock, typeInRichText, fireEvent, getEditorHtml, initializeEditor, setupCoreBlocks, + selectRangeInRichText, + waitFor, within, } from 'test/helpers'; @@ -177,46 +180,42 @@ describe( 'Editor History', () => { it( 'should preserve editor history when a link has been added and configured to open in a new tab', async () => { // Arrange - const screen = await initializeEditor(); - await addBlock( screen, 'Paragraph' ); + const initialHtml = ` +

A quick brown fox jumps over the lazy dog.

+ `; + const screen = await initializeEditor( { + initialHtml, + } ); // Act - const paragraphBlock = getBlock( screen, 'Paragraph' ); + const paragraphBlock = await waitFor( () => + getBlock( screen, 'Paragraph' ) + ); + fireEvent.press( paragraphBlock ); + const paragraphTextInput = within( paragraphBlock ).getByPlaceholderText( 'Start writing…' ); - typeInRichText( - paragraphTextInput, - 'A quick brown fox jumps over the lazy dog.', - { - finalSelectionStart: 2, - finalSelectionEnd: 7, - } - ); - + selectRangeInRichText( paragraphTextInput, 2, 7 ); // Await React Navigation: https://github.com/WordPress/gutenberg/issues/35685#issuecomment-961919931 await act( () => fireEvent.press( screen.getByLabelText( 'Link' ) ) ); - await act( () => - fireEvent.press( - screen.getByLabelText( 'Link to, Search or type URL' ) - ) - ); - fireEvent.changeText( - screen.getByPlaceholderText( 'Search or type URL' ), - 'wordpress.org' + + const newTabButton = await waitFor( () => + screen.getByText( 'Open in new tab' ) ); - jest.useFakeTimers(); - fireEvent.press( screen.getByLabelText( 'Apply' ) ); - // Await link picker navigation delay - act( () => jest.runOnlyPendingTimers() ); + fireEvent.press( newTabButton ); - const linkTargetButton = screen.getByText( 'Open in new tab' ); - fireEvent.press( linkTargetButton ); + await dismissModal( screen.getByTestId( 'link-settings-modal' ) ); + + typeInRichText( + paragraphTextInput, + 'A quick brown fox jumps over the lazy dog.' + ); // Assert expect( getEditorHtml() ).toMatchInlineSnapshot( ` " -

A quick brown fox jumps over the lazy dog.

+

A quick brown fox jumps over the lazy dog. A quick brown fox jumps over the lazy dog.

" ` ); @@ -239,7 +238,5 @@ describe( 'Editor History', () => {

A quick brown fox jumps over the lazy dog.

" ` ); - - jest.useRealTimers(); } ); } ); From 997f8d6f993bb0256ec77a4a996886a7874e5a60 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Mon, 22 May 2023 11:20:30 -0400 Subject: [PATCH 7/9] test: Fix React prop typo --- packages/format-library/src/link/modal.native.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/format-library/src/link/modal.native.js b/packages/format-library/src/link/modal.native.js index 8d29437385f1c6..a41c435df214b9 100644 --- a/packages/format-library/src/link/modal.native.js +++ b/packages/format-library/src/link/modal.native.js @@ -19,7 +19,7 @@ const ModalLinkUI = ( { isVisible, ...restProps } ) => { hideHeader onClose={ restProps.onClose } hasNavigation - testId={ 'link-settings-modal' } + testID="link-settings-modal" > From 87dcd92d61ba5911f5049f53eab6ed8392656745 Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Mon, 22 May 2023 11:22:44 -0400 Subject: [PATCH 8/9] test: Simplify test queries The targeted elements do not require asynchronous queries. Using synchronous queries is more concise and easier to comprehend. --- test/native/integration/editor-history.native.js | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/test/native/integration/editor-history.native.js b/test/native/integration/editor-history.native.js index e5248c39ab4048..0c336f92be47bd 100644 --- a/test/native/integration/editor-history.native.js +++ b/test/native/integration/editor-history.native.js @@ -2,7 +2,6 @@ * External dependencies */ import { - act, addBlock, dismissModal, getBlock, @@ -12,7 +11,6 @@ import { initializeEditor, setupCoreBlocks, selectRangeInRichText, - waitFor, within, } from 'test/helpers'; @@ -188,24 +186,18 @@ describe( 'Editor History', () => { } ); // Act - const paragraphBlock = await waitFor( () => - getBlock( screen, 'Paragraph' ) - ); - + const paragraphBlock = getBlock( screen, 'Paragraph' ); fireEvent.press( paragraphBlock ); const paragraphTextInput = within( paragraphBlock ).getByPlaceholderText( 'Start writing…' ); selectRangeInRichText( paragraphTextInput, 2, 7 ); - // Await React Navigation: https://github.com/WordPress/gutenberg/issues/35685#issuecomment-961919931 - await act( () => fireEvent.press( screen.getByLabelText( 'Link' ) ) ); + fireEvent.press( screen.getByLabelText( 'Link' ) ); - const newTabButton = await waitFor( () => - screen.getByText( 'Open in new tab' ) - ); + const newTabButton = screen.getByText( 'Open in new tab' ); fireEvent.press( newTabButton ); - await dismissModal( screen.getByTestId( 'link-settings-modal' ) ); + dismissModal( screen.getByTestId( 'link-settings-modal' ) ); typeInRichText( paragraphTextInput, From d0098e6edb5085ff4c2c489232c01ea258324a7c Mon Sep 17 00:00:00 2001 From: David Calhoun Date: Mon, 22 May 2023 11:24:45 -0400 Subject: [PATCH 9/9] test: Increase editor history link test accuracy The targeted bug occurs when: 1. Changing a link to "Open in a new tab." 2. Performing additional changes, e.g. typing. 3. Undoing both actions. 4. Redoing both actions. Thus, this changes the initial HTML, adds additional undo/redo invocations, and updates inline snapshots to match the expected outcomes. --- test/native/integration/editor-history.native.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test/native/integration/editor-history.native.js b/test/native/integration/editor-history.native.js index 0c336f92be47bd..35ab4d54a0a08e 100644 --- a/test/native/integration/editor-history.native.js +++ b/test/native/integration/editor-history.native.js @@ -179,7 +179,7 @@ describe( 'Editor History', () => { it( 'should preserve editor history when a link has been added and configured to open in a new tab', async () => { // Arrange const initialHtml = ` -

A quick brown fox jumps over the lazy dog.

+

A quick brown fox jumps over the lazy dog.

`; const screen = await initializeEditor( { initialHtml, @@ -201,7 +201,7 @@ describe( 'Editor History', () => { typeInRichText( paragraphTextInput, - 'A quick brown fox jumps over the lazy dog.' + ' A quick brown fox jumps over the lazy dog.' ); // Assert @@ -213,21 +213,23 @@ describe( 'Editor History', () => { // Act fireEvent.press( screen.getByLabelText( 'Undo' ) ); + 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.

+

A quick brown fox jumps over the lazy dog. A quick brown fox jumps over the lazy dog.

" ` ); } );