From 3c807a1aa075e48b7a5759b5c6d8f3803855b92f Mon Sep 17 00:00:00 2001 From: Wendy Chen Date: Mon, 9 Nov 2020 23:40:14 -0600 Subject: [PATCH 01/12] WC: Added move to top and bottom functionality via long pressing BlockMover buttons and clicking the button on the BottomSheet Picker. --- .../components/block-mover/index.native.js | 70 ++++++++++++++++++- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/packages/block-editor/src/components/block-mover/index.native.js b/packages/block-editor/src/components/block-mover/index.native.js index aa1892c33e8042..192996472c4b04 100644 --- a/packages/block-editor/src/components/block-mover/index.native.js +++ b/packages/block-editor/src/components/block-mover/index.native.js @@ -2,29 +2,75 @@ * External dependencies */ import { first, last, partial, castArray } from 'lodash'; +import React, { useRef, useState } from 'react'; +import { Platform } from 'react-native'; /** * WordPress dependencies */ -import { ToolbarButton } from '@wordpress/components'; -import { withSelect, withDispatch } from '@wordpress/data'; +import { __ } from '@wordpress/i18n'; +import { Picker, ToolbarButton } from '@wordpress/components'; import { withInstanceId, compose } from '@wordpress/compose'; +import { withSelect, withDispatch } from '@wordpress/data'; /** * Internal dependencies */ import { getMoversSetup } from './mover-description'; +const DIRECTION_TOP = 'blockPageMoverOptions-moveToTop'; +const DIRECTION_BOTTOM = 'blockPageMoverOptions-moveToBottom'; + const BlockMover = ( { isFirst, isLast, isLocked, onMoveDown, onMoveUp, + onLongMove, firstIndex, + numberOfBlocks, rootClientId, isStackedHorizontally, } ) => { + const pickerRef = useRef(); + const [ blockPageMoverState, setBlockPageMoverState ] = useState( + undefined + ); + const showBlockPageMover = ( direction ) => () => { + if ( ! pickerRef.current ) { + setBlockPageMoverState( undefined ); + return; + } + + setBlockPageMoverState( direction ); + pickerRef.current.presentPicker(); + }; + + const blockPageMoverOptions = [ + { + label: __( 'Move to top' ), + value: DIRECTION_TOP, + onSelect: () => { + onLongMove()( 0 ); + }, + }, + { + label: __( 'Move to bottom' ), + value: DIRECTION_BOTTOM, + onSelect: () => { + onLongMove()( numberOfBlocks ); + }, + }, + ].filter( ( el ) => el.value === blockPageMoverState ); + + const onPickerSelect = ( value ) => { + const option = blockPageMoverOptions.find( + ( el ) => el.value === value + ); + if ( option && option.onSelect ) option.onSelect(); + }; + const { description: { backwardButtonHint, @@ -46,6 +92,7 @@ const BlockMover = ( { title={ ! isFirst ? backwardButtonTitle : firstBlockTitle } isDisabled={ isFirst } onClick={ onMoveUp } + onLongPress={ showBlockPageMover( DIRECTION_TOP ) } icon={ backwardButtonIcon } extraProps={ { hint: backwardButtonHint } } /> @@ -54,11 +101,20 @@ const BlockMover = ( { title={ ! isLast ? forwardButtonTitle : lastBlockTitle } isDisabled={ isLast } onClick={ onMoveDown } + onLongPress={ showBlockPageMover( DIRECTION_BOTTOM ) } icon={ forwardButtonIcon } extraProps={ { hint: forwardButtonHint, } } /> + + ); }; @@ -83,6 +139,7 @@ export default compose( return { firstIndex, + numberOfBlocks: blockOrder.length - 1, isFirst: firstIndex === 0, isLast: lastIndex === blockOrder.length - 1, isLocked: getTemplateLock( rootClientId ) === 'all', @@ -90,12 +147,19 @@ export default compose( }; } ), withDispatch( ( dispatch, { clientIds, rootClientId } ) => { - const { moveBlocksDown, moveBlocksUp } = dispatch( + const { moveBlocksDown, moveBlocksUp, moveBlocksToPosition } = dispatch( 'core/block-editor' ); return { onMoveDown: partial( moveBlocksDown, clientIds, rootClientId ), onMoveUp: partial( moveBlocksUp, clientIds, rootClientId ), + onLongMove: ( targetIndex ) => + partial( + moveBlocksToPosition, + clientIds, + rootClientId, + targetIndex + ), }; } ), withInstanceId From d9ca0706d6bfcf22799253f5ca42c6c690fed09c Mon Sep 17 00:00:00 2001 From: Wendy Chen Date: Wed, 11 Nov 2020 13:42:07 -0600 Subject: [PATCH 02/12] WIP: Unit tests. --- .../components/block-mover/index.native.js | 17 ++-- .../block-mover/test/index.native.js | 79 +++++++++++++++++++ 2 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 packages/block-editor/src/components/block-mover/test/index.native.js diff --git a/packages/block-editor/src/components/block-mover/index.native.js b/packages/block-editor/src/components/block-mover/index.native.js index 192996472c4b04..5efffa694261c4 100644 --- a/packages/block-editor/src/components/block-mover/index.native.js +++ b/packages/block-editor/src/components/block-mover/index.native.js @@ -18,10 +18,11 @@ import { withSelect, withDispatch } from '@wordpress/data'; */ import { getMoversSetup } from './mover-description'; -const DIRECTION_TOP = 'blockPageMoverOptions-moveToTop'; -const DIRECTION_BOTTOM = 'blockPageMoverOptions-moveToBottom'; +export const BLOCK_MOVER_DIRECTION_TOP = 'blockPageMoverOptions-moveToTop'; +export const BLOCK_MOVER_DIRECTION_BOTTOM = + 'blockPageMoverOptions-moveToBottom'; -const BlockMover = ( { +export const BlockMover = ( { isFirst, isLast, isLocked, @@ -50,14 +51,14 @@ const BlockMover = ( { const blockPageMoverOptions = [ { label: __( 'Move to top' ), - value: DIRECTION_TOP, + value: BLOCK_MOVER_DIRECTION_TOP, onSelect: () => { onLongMove()( 0 ); }, }, { label: __( 'Move to bottom' ), - value: DIRECTION_BOTTOM, + value: BLOCK_MOVER_DIRECTION_BOTTOM, onSelect: () => { onLongMove()( numberOfBlocks ); }, @@ -92,7 +93,7 @@ const BlockMover = ( { title={ ! isFirst ? backwardButtonTitle : firstBlockTitle } isDisabled={ isFirst } onClick={ onMoveUp } - onLongPress={ showBlockPageMover( DIRECTION_TOP ) } + onLongPress={ showBlockPageMover( BLOCK_MOVER_DIRECTION_TOP ) } icon={ backwardButtonIcon } extraProps={ { hint: backwardButtonHint } } /> @@ -101,7 +102,9 @@ const BlockMover = ( { title={ ! isLast ? forwardButtonTitle : lastBlockTitle } isDisabled={ isLast } onClick={ onMoveDown } - onLongPress={ showBlockPageMover( DIRECTION_BOTTOM ) } + onLongPress={ showBlockPageMover( + BLOCK_MOVER_DIRECTION_BOTTOM + ) } icon={ forwardButtonIcon } extraProps={ { hint: forwardButtonHint, diff --git a/packages/block-editor/src/components/block-mover/test/index.native.js b/packages/block-editor/src/components/block-mover/test/index.native.js new file mode 100644 index 00000000000000..6564cf28226331 --- /dev/null +++ b/packages/block-editor/src/components/block-mover/test/index.native.js @@ -0,0 +1,79 @@ +/** + * External dependencies + */ +import { shallow } from 'enzyme'; + +/** + * Internal dependencies + */ +import { + BlockMover, + BLOCK_MOVER_DIRECTION_TOP, + BLOCK_MOVER_DIRECTION_BOTTOM, +} from '../index'; + +describe( 'Block Mover Picker', () => { + it( 'renders without crashing', () => { + const wrapper = shallow( , { + context: { + isFirst: false, + isLast: true, + isLocked: false, + numberOfBlocks: 2, + firstIndex: 1, + + onMoveDown: jest.fn(), + onMoveUp: jest.fn(), + onLongMove: jest.fn(), + + rootClientId: '', + isStackedHorizontally: true, + }, + } ); + expect( wrapper ).toBeTruthy(); + } ); + + it( 'shows "Move to top" on picker when long pressing move up mover', () => { + const wrapper = shallow( , { + context: { + isFirst: false, + isLast: true, + isLocked: false, + numberOfBlocks: 2, + firstIndex: 1, + + onMoveDown: jest.fn(), + onMoveUp: jest.fn(), + onLongMove: jest.fn(), + + rootClientId: '', + isStackedHorizontally: true, + }, + } ); + jest.mock( wrapper.showBlockPageMover, () => {} ); + jest.mock( + wrapper.blockPageMoverState, + () => 'blockPageMoverOptions-moveToTop' + ); + + expect( wrapper.blockPageMoverOptions.length ).toEqual( 1 ); + expect( wrapper.blockPageMoverOptions[ 0 ].value ).toEqual( + BLOCK_MOVER_DIRECTION_TOP + ); + } ); + + // it( 'moves block to first in list when pressing "Move to top"', () => { + // // mock two blocks + // // selected block should be on bottom + // // long press up mover + // // press move up button + // } ); + // + // it( 'shows "Move to bottom" on picker when long pressing move down mover', () => {} ); + // + // it( 'moves block to last in list when pressing "Move to bottom"', () => {} ); + // + // it( "can't long press move up when block is already first", () => {} ); + // + // it( "can't long press move down when block is already last", () => {} ); +} ); From 9c11a7313726dbaaf61ee03641b1caa93a7ef42c Mon Sep 17 00:00:00 2001 From: Wendy Chen Date: Tue, 8 Dec 2020 12:57:38 -0600 Subject: [PATCH 03/12] WC: WIP unit tests for add move to top and bottom --- .../block-mover/test/index.native.js | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/block-editor/src/components/block-mover/test/index.native.js b/packages/block-editor/src/components/block-mover/test/index.native.js index 6564cf28226331..333171ad94b1aa 100644 --- a/packages/block-editor/src/components/block-mover/test/index.native.js +++ b/packages/block-editor/src/components/block-mover/test/index.native.js @@ -9,8 +9,12 @@ import { shallow } from 'enzyme'; import { BlockMover, BLOCK_MOVER_DIRECTION_TOP, - BLOCK_MOVER_DIRECTION_BOTTOM, + // BLOCK_MOVER_DIRECTION_BOTTOM, } from '../index'; +/** + * WordPress dependencies + */ +import { Picker, ToolbarButton } from '@wordpress/components'; describe( 'Block Mover Picker', () => { it( 'renders without crashing', () => { @@ -50,16 +54,18 @@ describe( 'Block Mover Picker', () => { isStackedHorizontally: true, }, } ); - jest.mock( wrapper.showBlockPageMover, () => {} ); - jest.mock( - wrapper.blockPageMoverState, - () => 'blockPageMoverOptions-moveToTop' - ); + console.log( wrapper.debug() ); + console.log( wrapper.find( ToolbarButton ).first().debug() ); + // jest.mock( wrapper.showBlockPageMover, () => {} ); + // jest.mock( + // wrapper.blockPageMoverState, + // () => 'blockPageMoverOptions-moveToTop' + // ); - expect( wrapper.blockPageMoverOptions.length ).toEqual( 1 ); - expect( wrapper.blockPageMoverOptions[ 0 ].value ).toEqual( - BLOCK_MOVER_DIRECTION_TOP - ); + // expect( wrapper.blockPageMoverOptions.length ).toEqual( 1 ); + // expect( wrapper.blockPageMoverOptions[ 0 ].value ).toEqual( + // BLOCK_MOVER_DIRECTION_TOP + // ); } ); // it( 'moves block to first in list when pressing "Move to top"', () => { From 83c1c10b54499f7a1874a17506d4fdf9e0c1b6df Mon Sep 17 00:00:00 2001 From: Wendy Chen Date: Mon, 14 Dec 2020 13:28:37 -0600 Subject: [PATCH 04/12] WC: Moving UI tests to gutenberg with other UI tests instead of keeping at gutenberg-mobile. Adding more convenience functions to EditorPage. --- .../gutenberg-editor-move-block.test.js | 198 ++++++++++++++++++ .../__device-tests__/pages/editor-page.js | 79 ++++++- 2 files changed, 271 insertions(+), 6 deletions(-) create mode 100644 packages/react-native-editor/__device-tests__/gutenberg-editor-move-block.test.js diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-move-block.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-move-block.test.js new file mode 100644 index 00000000000000..29f4efedee9392 --- /dev/null +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-move-block.test.js @@ -0,0 +1,198 @@ +/** + * Internal dependencies + */ +import EditorPage from './pages/editor-page'; +import { + setupDriver, + isLocalEnvironment, + stopDriver, + isAndroid, +} from './helpers/utils'; + +jest.setTimeout( 1000000 ); + +describe( 'Gutenberg Editor Block Mover tests', () => { + let driver; + let editorPage; + let allPassed = true; + const paragraphBlockName = 'Paragraph'; + const headerBlockName = 'Heading'; + const cancelButtonName = 'Cancel'; + const buttonIosType = 'Button'; + const moveTopButtonName = 'Move to top'; + const moveBottomButtonName = 'Move to bottom'; + + // Use reporter for setting status for saucelabs Job + if ( ! isLocalEnvironment() ) { + const reporter = { + specDone: async ( result ) => { + allPassed = allPassed && result.status !== 'failed'; + }, + }; + + // eslint-disable-next-line jest/no-jasmine-globals + jasmine.getEnv().addReporter( reporter ); + } + + async function setupBlocks( text = 'p1' ) { + await editorPage.addNewBlock( paragraphBlockName ); + const paragraphBlock = await editorPage.getBlockAtPosition( + paragraphBlockName + ); + await editorPage.typeTextToParagraphBlock( paragraphBlock, text ); + + await editorPage.addNewBlock( headerBlockName ); + const headerBlock = await editorPage.getBlockAtPosition( + headerBlockName, + 2 + ); + await editorPage.typeTextToParagraphBlock( headerBlock, text ); + } + + async function removeBlocks( blockOrder ) { + for ( let i = blockOrder.length; i > 0; i-- ) { + await editorPage.removeBlockAtPosition( blockOrder[ i - 1 ], i ); + } + } + + async function cancelActionSheet( ePage ) { + if ( isAndroid() ) { + await ePage.tapCoordinates( 100, 100 ); + } else { + await ePage.selectElement( cancelButtonName, buttonIosType ); + } + } + + beforeAll( async () => { + driver = await setupDriver(); + editorPage = new EditorPage( driver ); + } ); + + it( 'should be able to see visual editor', async () => { + await expect( editorPage.getBlockList() ).resolves.toBe( true ); + } ); + + it( 'should be able to see move block to top when long pressing up and change nothing when pressing cancel', async () => { + await setupBlocks( 'p1-up-cancel' ); + + await editorPage.longPressToolBarButton( + 'Move block up from row 2 to row 1' + ); + const moveUpAction = await editorPage.findElement( + moveTopButtonName, + buttonIosType + ); + + expect( moveUpAction ).toBeTruthy(); + + await cancelActionSheet( editorPage ); + const paragraphIsFirst = await editorPage.hasBlockAtPosition( + 1, + paragraphBlockName + ); + + expect( paragraphIsFirst ).toBe( true ); + + await removeBlocks( [ paragraphBlockName, headerBlockName ] ); + } ); + + it( 'should be able to move block to first block when pressing move block to top', async () => { + await setupBlocks( 'p1-up' ); + + await editorPage.longPressToolBarButton( + 'Move block up from row 2 to row 1' + ); + await editorPage.selectElement( moveTopButtonName, buttonIosType ); + const headerIsFirst = await editorPage.hasBlockAtPosition( + 1, + headerBlockName + ); + + expect( headerIsFirst ).toBe( true ); + + await editorPage.selectBlock( paragraphBlockName, 2 ); + await removeBlocks( [ headerBlockName, paragraphBlockName ] ); + } ); + + it( 'should have move up disabled when on top', async () => { + await setupBlocks( 'p1-disabled-top' ); + await editorPage.selectBlock( paragraphBlockName ); + + await editorPage.longPressToolBarButton( 'Move block up' ); + const moveUpAction = await editorPage.findElement( + moveTopButtonName, + buttonIosType + ); + + expect( moveUpAction ).toBe( undefined ); + + await editorPage.selectBlock( headerBlockName, 2 ); + await removeBlocks( [ paragraphBlockName, headerBlockName ] ); + } ); + + it( 'should be able to see move block to bottom when long pressing down and change nothing when pressing cancel', async () => { + await setupBlocks( 'p1-down-cancel' ); + await editorPage.selectBlock( paragraphBlockName ); + + await editorPage.longPressToolBarButton( + 'Move block down from row 1 to row 2' + ); + const moveDownAction = await editorPage.findElement( + moveBottomButtonName, + buttonIosType + ); + + expect( moveDownAction ).toBeTruthy(); + + await cancelActionSheet( editorPage ); + const paragraphIsFirst = await editorPage.hasBlockAtPosition( + 1, + paragraphBlockName + ); + + expect( paragraphIsFirst ).toBe( true ); + + await editorPage.selectBlock( headerBlockName, 2 ); + await removeBlocks( [ paragraphBlockName, headerBlockName ] ); + } ); + + it( 'should be able to move block to last block when pressing move block to bottom', async () => { + await setupBlocks( 'p1-down' ); + await editorPage.selectBlock( paragraphBlockName ); + + await editorPage.longPressToolBarButton( + 'Move block down from row 1 to row 2' + ); + + await editorPage.selectElement( moveBottomButtonName, buttonIosType ); + const headerIsFirst = await editorPage.hasBlockAtPosition( + 1, + headerBlockName + ); + + expect( headerIsFirst ).toBe( true ); + + await removeBlocks( [ headerBlockName, paragraphBlockName ] ); + } ); + + it( 'should have move down disabled when on bottom', async () => { + await setupBlocks( 'p1-disabled-down' ); + + await editorPage.longPressToolBarButton( 'Move block down' ); + const moveDownAction = await editorPage.findElement( + moveBottomButtonName, + buttonIosType + ); + + expect( moveDownAction ).toBe( undefined ); + + await removeBlocks( [ paragraphBlockName, headerBlockName ] ); + } ); + + afterAll( async () => { + if ( ! isLocalEnvironment() ) { + driver.sauceJobStatus( allPassed ); + } + await stopDriver( driver ); + } ); +} ); diff --git a/packages/react-native-editor/__device-tests__/pages/editor-page.js b/packages/react-native-editor/__device-tests__/pages/editor-page.js index 2b08b695935b6a..f83729b3ac8ad0 100644 --- a/packages/react-native-editor/__device-tests__/pages/editor-page.js +++ b/packages/react-native-editor/__device-tests__/pages/editor-page.js @@ -10,7 +10,12 @@ const { typeString, toggleHtmlMode, swipeFromTo, -} = require( '../helpers/utils' ); +} from '../helpers/utils'; +/** + * External dependencies + */ +// eslint-disable-next-line import/no-extraneous-dependencies +import wd from 'wd'; const initializeEditorPage = async () => { const driver = await setupDriver(); @@ -267,6 +272,24 @@ class EditorPage { await toolBarButton.click(); } + async longPressToolBarButton( buttonName ) { + let toolBarButton; + if ( isAndroid() ) { + const blockLocator = `//*[contains(@${ this.accessibilityIdXPathAttrib }, "${ buttonName }")]`; + toolBarButton = await this.driver.elementByXPath( blockLocator ); + } else { + toolBarButton = await this.driver.elementByAccessibilityId( + buttonName + ); + } + + const action = new wd.TouchAction( this.driver ); + action.press( { el: toolBarButton } ); + action.wait( 1000 ); + action.release(); + await action.perform(); + } + // ========================= // Inline toolbar functions // ========================= @@ -363,11 +386,15 @@ class EditorPage { } async typeTextToParagraphBlock( block, text, clear ) { - const textViewElement = await this.getTextViewForParagraphBlock( - block - ); - await typeString( this.driver, textViewElement, text, clear ); - await this.driver.sleep( 1000 ); // Give time for the block to rerender (such as for accessibility) + if ( ! isAndroid() ) { + block.type( text ); + } else { + const textViewElement = await this.getTextViewForParagraphBlock( + block + ); + await typeString( this.driver, textViewElement, text, clear ); + await this.driver.sleep( 1000 ); // Give time for the block to rerender (such as for accessibility) + } } async sendTextToParagraphBlock( position, text, clear ) { @@ -551,6 +578,46 @@ class EditorPage { async sauceJobStatus( allPassed ) { await this.driver.sauceJobStatus( allPassed ); } + + // ============================= + // Misc functions + // ============================= + async findElement( name, iosElementType ) { + const elementName = isAndroid() + ? '//*' + : `//XCUIElementType${ iosElementType }`; + const blockLocator = `${ elementName }[contains(@${ this.accessibilityIdXPathAttrib }, "${ name }")]`; + const elements = await this.driver.elementsByXPath( blockLocator ); + return elements[ 0 ]; + } + + async selectElement( name, iosElementType ) { + const el = await this.findElement( name, iosElementType ); + el.click(); + } + + async selectBlock( + blockName, + position = 1, + options = { autoscroll: false } + ) { + const block = await this.getBlockAtPosition( + blockName, + position, + options + ); + block.click(); + } + + async tapCoordinates( x, y, longPress = false ) { + const action = new wd.TouchAction( this.driver ); + action.press( { x, y } ); + if ( longPress ) { + action.wait( 1000 ); + } + action.release(); + await action.perform(); + } } const blockNames = { From 3f0c29974428afd2d62599f85288026e2fc8bdc4 Mon Sep 17 00:00:00 2001 From: Wendy Chen Date: Wed, 11 Nov 2020 13:42:07 -0600 Subject: [PATCH 05/12] WIP: Unit tests. --- .../block-mover/test/index.native.js | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/packages/block-editor/src/components/block-mover/test/index.native.js b/packages/block-editor/src/components/block-mover/test/index.native.js index 333171ad94b1aa..6564cf28226331 100644 --- a/packages/block-editor/src/components/block-mover/test/index.native.js +++ b/packages/block-editor/src/components/block-mover/test/index.native.js @@ -9,12 +9,8 @@ import { shallow } from 'enzyme'; import { BlockMover, BLOCK_MOVER_DIRECTION_TOP, - // BLOCK_MOVER_DIRECTION_BOTTOM, + BLOCK_MOVER_DIRECTION_BOTTOM, } from '../index'; -/** - * WordPress dependencies - */ -import { Picker, ToolbarButton } from '@wordpress/components'; describe( 'Block Mover Picker', () => { it( 'renders without crashing', () => { @@ -54,18 +50,16 @@ describe( 'Block Mover Picker', () => { isStackedHorizontally: true, }, } ); - console.log( wrapper.debug() ); - console.log( wrapper.find( ToolbarButton ).first().debug() ); - // jest.mock( wrapper.showBlockPageMover, () => {} ); - // jest.mock( - // wrapper.blockPageMoverState, - // () => 'blockPageMoverOptions-moveToTop' - // ); + jest.mock( wrapper.showBlockPageMover, () => {} ); + jest.mock( + wrapper.blockPageMoverState, + () => 'blockPageMoverOptions-moveToTop' + ); - // expect( wrapper.blockPageMoverOptions.length ).toEqual( 1 ); - // expect( wrapper.blockPageMoverOptions[ 0 ].value ).toEqual( - // BLOCK_MOVER_DIRECTION_TOP - // ); + expect( wrapper.blockPageMoverOptions.length ).toEqual( 1 ); + expect( wrapper.blockPageMoverOptions[ 0 ].value ).toEqual( + BLOCK_MOVER_DIRECTION_TOP + ); } ); // it( 'moves block to first in list when pressing "Move to top"', () => { From 49470fa0cc68c6276f3bd3cb44a7aa4413ffcb43 Mon Sep 17 00:00:00 2001 From: Wendy Chen Date: Wed, 16 Dec 2020 15:15:02 -0600 Subject: [PATCH 06/12] WC: Adding icon and title to picker for move to top/bottom. --- .../components/block-mover/index.native.js | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/block-editor/src/components/block-mover/index.native.js b/packages/block-editor/src/components/block-mover/index.native.js index 5efffa694261c4..943e494c91b19b 100644 --- a/packages/block-editor/src/components/block-mover/index.native.js +++ b/packages/block-editor/src/components/block-mover/index.native.js @@ -48,8 +48,20 @@ export const BlockMover = ( { pickerRef.current.presentPicker(); }; + const { + description: { + backwardButtonHint, + forwardButtonHint, + firstBlockTitle, + lastBlockTitle, + }, + icon: { backward: backwardButtonIcon, forward: forwardButtonIcon }, + title: { backward: backwardButtonTitle, forward: forwardButtonTitle }, + } = getMoversSetup( isStackedHorizontally, { firstIndex } ); + const blockPageMoverOptions = [ { + icon: backwardButtonIcon, label: __( 'Move to top' ), value: BLOCK_MOVER_DIRECTION_TOP, onSelect: () => { @@ -57,6 +69,7 @@ export const BlockMover = ( { }, }, { + icon: forwardButtonIcon, label: __( 'Move to bottom' ), value: BLOCK_MOVER_DIRECTION_BOTTOM, onSelect: () => { @@ -72,17 +85,6 @@ export const BlockMover = ( { if ( option && option.onSelect ) option.onSelect(); }; - const { - description: { - backwardButtonHint, - forwardButtonHint, - firstBlockTitle, - lastBlockTitle, - }, - icon: { backward: backwardButtonIcon, forward: forwardButtonIcon }, - title: { backward: backwardButtonTitle, forward: forwardButtonTitle }, - } = getMoversSetup( isStackedHorizontally, { firstIndex } ); - if ( isLocked || ( isFirst && isLast && ! rootClientId ) ) { return null; } @@ -115,6 +117,7 @@ export const BlockMover = ( { ref={ pickerRef } options={ blockPageMoverOptions } onChange={ onPickerSelect } + title={ __( 'Move block position' ) } leftAlign={ true } hideCancelButton={ Platform.OS !== 'ios' } /> From 86fad6609b4a5d0aa135f8f68b52f1a157685190 Mon Sep 17 00:00:00 2001 From: Wendy Chen Date: Fri, 18 Dec 2020 13:33:03 -0600 Subject: [PATCH 07/12] WC: Cleaning up code. --- .../test/__snapshots__/index.native.js.snap | 51 +++++++++++++++++++ .../block-mover/test/index.native.js | 38 ++------------ 2 files changed, 56 insertions(+), 33 deletions(-) create mode 100644 packages/block-editor/src/components/block-mover/test/__snapshots__/index.native.js.snap diff --git a/packages/block-editor/src/components/block-mover/test/__snapshots__/index.native.js.snap b/packages/block-editor/src/components/block-mover/test/__snapshots__/index.native.js.snap new file mode 100644 index 00000000000000..65269234f413f3 --- /dev/null +++ b/packages/block-editor/src/components/block-mover/test/__snapshots__/index.native.js.snap @@ -0,0 +1,51 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Block Mover Picker should match snapshot 1`] = ` + + + + + } + onLongPress={[Function]} + title="Move block up from row NaN to row NaN" + /> + + + + } + onLongPress={[Function]} + title="Move block down from row NaN to row NaN" + /> + + +`; diff --git a/packages/block-editor/src/components/block-mover/test/index.native.js b/packages/block-editor/src/components/block-mover/test/index.native.js index 6564cf28226331..113d61e84cf254 100644 --- a/packages/block-editor/src/components/block-mover/test/index.native.js +++ b/packages/block-editor/src/components/block-mover/test/index.native.js @@ -6,11 +6,7 @@ import { shallow } from 'enzyme'; /** * Internal dependencies */ -import { - BlockMover, - BLOCK_MOVER_DIRECTION_TOP, - BLOCK_MOVER_DIRECTION_BOTTOM, -} from '../index'; +import { BlockMover } from '../index'; describe( 'Block Mover Picker', () => { it( 'renders without crashing', () => { @@ -24,7 +20,7 @@ describe( 'Block Mover Picker', () => { onMoveDown: jest.fn(), onMoveUp: jest.fn(), - onLongMove: jest.fn(), + onLongPress: jest.fn(), rootClientId: '', isStackedHorizontally: true, @@ -33,7 +29,7 @@ describe( 'Block Mover Picker', () => { expect( wrapper ).toBeTruthy(); } ); - it( 'shows "Move to top" on picker when long pressing move up mover', () => { + it( 'should match snapshot', () => { const wrapper = shallow( , { context: { isFirst: false, @@ -44,36 +40,12 @@ describe( 'Block Mover Picker', () => { onMoveDown: jest.fn(), onMoveUp: jest.fn(), - onLongMove: jest.fn(), + onLongPress: jest.fn(), rootClientId: '', isStackedHorizontally: true, }, } ); - jest.mock( wrapper.showBlockPageMover, () => {} ); - jest.mock( - wrapper.blockPageMoverState, - () => 'blockPageMoverOptions-moveToTop' - ); - - expect( wrapper.blockPageMoverOptions.length ).toEqual( 1 ); - expect( wrapper.blockPageMoverOptions[ 0 ].value ).toEqual( - BLOCK_MOVER_DIRECTION_TOP - ); + expect( wrapper ).toMatchSnapshot(); } ); - - // it( 'moves block to first in list when pressing "Move to top"', () => { - // // mock two blocks - // // selected block should be on bottom - // // long press up mover - // // press move up button - // } ); - // - // it( 'shows "Move to bottom" on picker when long pressing move down mover', () => {} ); - // - // it( 'moves block to last in list when pressing "Move to bottom"', () => {} ); - // - // it( "can't long press move up when block is already first", () => {} ); - // - // it( "can't long press move down when block is already last", () => {} ); } ); From 0c4231e4136120453628d0be7e6033e4c92a0a05 Mon Sep 17 00:00:00 2001 From: Wendy Chen Date: Fri, 18 Dec 2020 16:37:10 -0600 Subject: [PATCH 08/12] WC: Fixing merge issue where import was changed to const. --- .../react-native-editor/__device-tests__/pages/editor-page.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-native-editor/__device-tests__/pages/editor-page.js b/packages/react-native-editor/__device-tests__/pages/editor-page.js index f83729b3ac8ad0..3214c53fa4e5aa 100644 --- a/packages/react-native-editor/__device-tests__/pages/editor-page.js +++ b/packages/react-native-editor/__device-tests__/pages/editor-page.js @@ -1,7 +1,7 @@ /** * Internal dependencies */ -const { +import { setupDriver, stopDriver, isAndroid, @@ -578,7 +578,7 @@ class EditorPage { async sauceJobStatus( allPassed ) { await this.driver.sauceJobStatus( allPassed ); } - + // ============================= // Misc functions // ============================= From eccb94f5adc3d7e53bed5f6f7c5b60c2bff1bd97 Mon Sep 17 00:00:00 2001 From: Wendy Chen Date: Fri, 18 Dec 2020 17:02:41 -0600 Subject: [PATCH 09/12] WC: Changing all imports to requires as per jest bug. --- .../__device-tests__/pages/editor-page.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-native-editor/__device-tests__/pages/editor-page.js b/packages/react-native-editor/__device-tests__/pages/editor-page.js index 3214c53fa4e5aa..04e1f39187deb8 100644 --- a/packages/react-native-editor/__device-tests__/pages/editor-page.js +++ b/packages/react-native-editor/__device-tests__/pages/editor-page.js @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import { +const { setupDriver, stopDriver, isAndroid, @@ -10,12 +10,12 @@ import { typeString, toggleHtmlMode, swipeFromTo, -} from '../helpers/utils'; +} = require( '../helpers/utils' ); /** * External dependencies */ // eslint-disable-next-line import/no-extraneous-dependencies -import wd from 'wd'; +const wd = require( 'wd' ); const initializeEditorPage = async () => { const driver = await setupDriver(); From a3425151294f6f9d6f2c0b0e45aea90448e28d5e Mon Sep 17 00:00:00 2001 From: Wendy Chen Date: Tue, 22 Dec 2020 12:31:30 -0600 Subject: [PATCH 10/12] WC: Removing before/afterAll blocks from UI tests. --- .../gutenberg-editor-move-block.test.js | 35 +------------------ 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-move-block.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-move-block.test.js index 29f4efedee9392..b63f839962cc6c 100644 --- a/packages/react-native-editor/__device-tests__/gutenberg-editor-move-block.test.js +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-move-block.test.js @@ -1,20 +1,11 @@ /** * Internal dependencies */ -import EditorPage from './pages/editor-page'; -import { - setupDriver, - isLocalEnvironment, - stopDriver, - isAndroid, -} from './helpers/utils'; +import { isAndroid } from './helpers/utils'; jest.setTimeout( 1000000 ); describe( 'Gutenberg Editor Block Mover tests', () => { - let driver; - let editorPage; - let allPassed = true; const paragraphBlockName = 'Paragraph'; const headerBlockName = 'Heading'; const cancelButtonName = 'Cancel'; @@ -22,18 +13,6 @@ describe( 'Gutenberg Editor Block Mover tests', () => { const moveTopButtonName = 'Move to top'; const moveBottomButtonName = 'Move to bottom'; - // Use reporter for setting status for saucelabs Job - if ( ! isLocalEnvironment() ) { - const reporter = { - specDone: async ( result ) => { - allPassed = allPassed && result.status !== 'failed'; - }, - }; - - // eslint-disable-next-line jest/no-jasmine-globals - jasmine.getEnv().addReporter( reporter ); - } - async function setupBlocks( text = 'p1' ) { await editorPage.addNewBlock( paragraphBlockName ); const paragraphBlock = await editorPage.getBlockAtPosition( @@ -63,11 +42,6 @@ describe( 'Gutenberg Editor Block Mover tests', () => { } } - beforeAll( async () => { - driver = await setupDriver(); - editorPage = new EditorPage( driver ); - } ); - it( 'should be able to see visual editor', async () => { await expect( editorPage.getBlockList() ).resolves.toBe( true ); } ); @@ -188,11 +162,4 @@ describe( 'Gutenberg Editor Block Mover tests', () => { await removeBlocks( [ paragraphBlockName, headerBlockName ] ); } ); - - afterAll( async () => { - if ( ! isLocalEnvironment() ) { - driver.sauceJobStatus( allPassed ); - } - await stopDriver( driver ); - } ); } ); From 22a9f1ee8fd15a7d2d505b6e0505109b86e667c8 Mon Sep 17 00:00:00 2001 From: Wendy Chen Date: Wed, 23 Dec 2020 14:57:32 -0600 Subject: [PATCH 11/12] WC: Removing e2e tests to issue-1191-add-move-to-top-bottom-ui-tests branch. --- .../gutenberg-editor-move-block.test.js | 165 ------------------ .../__device-tests__/pages/editor-page.js | 77 +------- 2 files changed, 5 insertions(+), 237 deletions(-) delete mode 100644 packages/react-native-editor/__device-tests__/gutenberg-editor-move-block.test.js diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-move-block.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-move-block.test.js deleted file mode 100644 index b63f839962cc6c..00000000000000 --- a/packages/react-native-editor/__device-tests__/gutenberg-editor-move-block.test.js +++ /dev/null @@ -1,165 +0,0 @@ -/** - * Internal dependencies - */ -import { isAndroid } from './helpers/utils'; - -jest.setTimeout( 1000000 ); - -describe( 'Gutenberg Editor Block Mover tests', () => { - const paragraphBlockName = 'Paragraph'; - const headerBlockName = 'Heading'; - const cancelButtonName = 'Cancel'; - const buttonIosType = 'Button'; - const moveTopButtonName = 'Move to top'; - const moveBottomButtonName = 'Move to bottom'; - - async function setupBlocks( text = 'p1' ) { - await editorPage.addNewBlock( paragraphBlockName ); - const paragraphBlock = await editorPage.getBlockAtPosition( - paragraphBlockName - ); - await editorPage.typeTextToParagraphBlock( paragraphBlock, text ); - - await editorPage.addNewBlock( headerBlockName ); - const headerBlock = await editorPage.getBlockAtPosition( - headerBlockName, - 2 - ); - await editorPage.typeTextToParagraphBlock( headerBlock, text ); - } - - async function removeBlocks( blockOrder ) { - for ( let i = blockOrder.length; i > 0; i-- ) { - await editorPage.removeBlockAtPosition( blockOrder[ i - 1 ], i ); - } - } - - async function cancelActionSheet( ePage ) { - if ( isAndroid() ) { - await ePage.tapCoordinates( 100, 100 ); - } else { - await ePage.selectElement( cancelButtonName, buttonIosType ); - } - } - - it( 'should be able to see visual editor', async () => { - await expect( editorPage.getBlockList() ).resolves.toBe( true ); - } ); - - it( 'should be able to see move block to top when long pressing up and change nothing when pressing cancel', async () => { - await setupBlocks( 'p1-up-cancel' ); - - await editorPage.longPressToolBarButton( - 'Move block up from row 2 to row 1' - ); - const moveUpAction = await editorPage.findElement( - moveTopButtonName, - buttonIosType - ); - - expect( moveUpAction ).toBeTruthy(); - - await cancelActionSheet( editorPage ); - const paragraphIsFirst = await editorPage.hasBlockAtPosition( - 1, - paragraphBlockName - ); - - expect( paragraphIsFirst ).toBe( true ); - - await removeBlocks( [ paragraphBlockName, headerBlockName ] ); - } ); - - it( 'should be able to move block to first block when pressing move block to top', async () => { - await setupBlocks( 'p1-up' ); - - await editorPage.longPressToolBarButton( - 'Move block up from row 2 to row 1' - ); - await editorPage.selectElement( moveTopButtonName, buttonIosType ); - const headerIsFirst = await editorPage.hasBlockAtPosition( - 1, - headerBlockName - ); - - expect( headerIsFirst ).toBe( true ); - - await editorPage.selectBlock( paragraphBlockName, 2 ); - await removeBlocks( [ headerBlockName, paragraphBlockName ] ); - } ); - - it( 'should have move up disabled when on top', async () => { - await setupBlocks( 'p1-disabled-top' ); - await editorPage.selectBlock( paragraphBlockName ); - - await editorPage.longPressToolBarButton( 'Move block up' ); - const moveUpAction = await editorPage.findElement( - moveTopButtonName, - buttonIosType - ); - - expect( moveUpAction ).toBe( undefined ); - - await editorPage.selectBlock( headerBlockName, 2 ); - await removeBlocks( [ paragraphBlockName, headerBlockName ] ); - } ); - - it( 'should be able to see move block to bottom when long pressing down and change nothing when pressing cancel', async () => { - await setupBlocks( 'p1-down-cancel' ); - await editorPage.selectBlock( paragraphBlockName ); - - await editorPage.longPressToolBarButton( - 'Move block down from row 1 to row 2' - ); - const moveDownAction = await editorPage.findElement( - moveBottomButtonName, - buttonIosType - ); - - expect( moveDownAction ).toBeTruthy(); - - await cancelActionSheet( editorPage ); - const paragraphIsFirst = await editorPage.hasBlockAtPosition( - 1, - paragraphBlockName - ); - - expect( paragraphIsFirst ).toBe( true ); - - await editorPage.selectBlock( headerBlockName, 2 ); - await removeBlocks( [ paragraphBlockName, headerBlockName ] ); - } ); - - it( 'should be able to move block to last block when pressing move block to bottom', async () => { - await setupBlocks( 'p1-down' ); - await editorPage.selectBlock( paragraphBlockName ); - - await editorPage.longPressToolBarButton( - 'Move block down from row 1 to row 2' - ); - - await editorPage.selectElement( moveBottomButtonName, buttonIosType ); - const headerIsFirst = await editorPage.hasBlockAtPosition( - 1, - headerBlockName - ); - - expect( headerIsFirst ).toBe( true ); - - await removeBlocks( [ headerBlockName, paragraphBlockName ] ); - } ); - - it( 'should have move down disabled when on bottom', async () => { - await setupBlocks( 'p1-disabled-down' ); - - await editorPage.longPressToolBarButton( 'Move block down' ); - const moveDownAction = await editorPage.findElement( - moveBottomButtonName, - buttonIosType - ); - - expect( moveDownAction ).toBe( undefined ); - - await removeBlocks( [ paragraphBlockName, headerBlockName ] ); - } ); -} ); diff --git a/packages/react-native-editor/__device-tests__/pages/editor-page.js b/packages/react-native-editor/__device-tests__/pages/editor-page.js index 04e1f39187deb8..2b08b695935b6a 100644 --- a/packages/react-native-editor/__device-tests__/pages/editor-page.js +++ b/packages/react-native-editor/__device-tests__/pages/editor-page.js @@ -11,11 +11,6 @@ const { toggleHtmlMode, swipeFromTo, } = require( '../helpers/utils' ); -/** - * External dependencies - */ -// eslint-disable-next-line import/no-extraneous-dependencies -const wd = require( 'wd' ); const initializeEditorPage = async () => { const driver = await setupDriver(); @@ -272,24 +267,6 @@ class EditorPage { await toolBarButton.click(); } - async longPressToolBarButton( buttonName ) { - let toolBarButton; - if ( isAndroid() ) { - const blockLocator = `//*[contains(@${ this.accessibilityIdXPathAttrib }, "${ buttonName }")]`; - toolBarButton = await this.driver.elementByXPath( blockLocator ); - } else { - toolBarButton = await this.driver.elementByAccessibilityId( - buttonName - ); - } - - const action = new wd.TouchAction( this.driver ); - action.press( { el: toolBarButton } ); - action.wait( 1000 ); - action.release(); - await action.perform(); - } - // ========================= // Inline toolbar functions // ========================= @@ -386,15 +363,11 @@ class EditorPage { } async typeTextToParagraphBlock( block, text, clear ) { - if ( ! isAndroid() ) { - block.type( text ); - } else { - const textViewElement = await this.getTextViewForParagraphBlock( - block - ); - await typeString( this.driver, textViewElement, text, clear ); - await this.driver.sleep( 1000 ); // Give time for the block to rerender (such as for accessibility) - } + const textViewElement = await this.getTextViewForParagraphBlock( + block + ); + await typeString( this.driver, textViewElement, text, clear ); + await this.driver.sleep( 1000 ); // Give time for the block to rerender (such as for accessibility) } async sendTextToParagraphBlock( position, text, clear ) { @@ -578,46 +551,6 @@ class EditorPage { async sauceJobStatus( allPassed ) { await this.driver.sauceJobStatus( allPassed ); } - - // ============================= - // Misc functions - // ============================= - async findElement( name, iosElementType ) { - const elementName = isAndroid() - ? '//*' - : `//XCUIElementType${ iosElementType }`; - const blockLocator = `${ elementName }[contains(@${ this.accessibilityIdXPathAttrib }, "${ name }")]`; - const elements = await this.driver.elementsByXPath( blockLocator ); - return elements[ 0 ]; - } - - async selectElement( name, iosElementType ) { - const el = await this.findElement( name, iosElementType ); - el.click(); - } - - async selectBlock( - blockName, - position = 1, - options = { autoscroll: false } - ) { - const block = await this.getBlockAtPosition( - blockName, - position, - options - ); - block.click(); - } - - async tapCoordinates( x, y, longPress = false ) { - const action = new wd.TouchAction( this.driver ); - action.press( { x, y } ); - if ( longPress ) { - action.wait( 1000 ); - } - action.release(); - await action.perform(); - } } const blockNames = { From 5d1d498c770960eb3eb9a731db42ad33d29eebc4 Mon Sep 17 00:00:00 2001 From: Wendy Chen Date: Wed, 23 Dec 2020 16:15:22 -0600 Subject: [PATCH 12/12] WC: Updating imports to fall in line with other files. --- .../block-editor/src/components/block-mover/index.native.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/block-editor/src/components/block-mover/index.native.js b/packages/block-editor/src/components/block-mover/index.native.js index 943e494c91b19b..d64509ff17726e 100644 --- a/packages/block-editor/src/components/block-mover/index.native.js +++ b/packages/block-editor/src/components/block-mover/index.native.js @@ -2,7 +2,6 @@ * External dependencies */ import { first, last, partial, castArray } from 'lodash'; -import React, { useRef, useState } from 'react'; import { Platform } from 'react-native'; /** @@ -12,6 +11,7 @@ import { __ } from '@wordpress/i18n'; import { Picker, ToolbarButton } from '@wordpress/components'; import { withInstanceId, compose } from '@wordpress/compose'; import { withSelect, withDispatch } from '@wordpress/data'; +import { useRef, useState } from '@wordpress/element'; /** * Internal dependencies