diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-block-insertion.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-block-insertion.test.js index 0ee6a985c4f921..3c9a8b233ea1a0 100644 --- a/packages/react-native-editor/__device-tests__/gutenberg-editor-block-insertion.test.js +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-block-insertion.test.js @@ -8,7 +8,7 @@ import testData from './helpers/test-data'; describe( 'Gutenberg Editor tests for Block insertion', () => { it( 'should be able to insert multi-paragraph text, and text to another paragraph block in between', async () => { await editorPage.addNewBlock( blockNames.paragraph ); - let paragraphBlockElement = await editorPage.getBlockAtPosition( + let paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph ); if ( isAndroid() ) { @@ -18,7 +18,7 @@ describe( 'Gutenberg Editor tests for Block insertion', () => { await editorPage.sendTextToParagraphBlock( 1, testData.longText ); // Should have 3 paragraph blocks at this point. - paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph, 2 ); @@ -26,7 +26,7 @@ describe( 'Gutenberg Editor tests for Block insertion', () => { await editorPage.addNewBlock( blockNames.paragraph ); - paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph, 3 ); @@ -44,7 +44,7 @@ describe( 'Gutenberg Editor tests for Block insertion', () => { // Workaround for now since deleting the first element causes a crash on CI for Android if ( isAndroid() ) { - paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph, 3, { @@ -57,7 +57,7 @@ describe( 'Gutenberg Editor tests for Block insertion', () => { for ( let i = 3; i > 0; i-- ) { // wait for accessibility ids to update await editorPage.driver.sleep( 1000 ); - paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph, i, { @@ -74,7 +74,7 @@ describe( 'Gutenberg Editor tests for Block insertion', () => { for ( let i = 4; i > 0; i-- ) { // wait for accessibility ids to update await editorPage.driver.sleep( 1000 ); - paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph ); await clickMiddleOfElement( @@ -88,7 +88,7 @@ describe( 'Gutenberg Editor tests for Block insertion', () => { it( 'should be able to insert block at the beginning of post from the title', async () => { await editorPage.addNewBlock( blockNames.paragraph ); - let paragraphBlockElement = await editorPage.getBlockAtPosition( + let paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph ); if ( isAndroid() ) { @@ -110,7 +110,7 @@ describe( 'Gutenberg Editor tests for Block insertion', () => { await titleElement.click(); await editorPage.addNewBlock( blockNames.paragraph ); - paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph ); await clickMiddleOfElement( editorPage.driver, paragraphBlockElement ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-heading-@canary.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-heading-@canary.test.js index 64b4ab460e48c8..fc88db8e55246e 100644 --- a/packages/react-native-editor/__device-tests__/gutenberg-editor-heading-@canary.test.js +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-heading-@canary.test.js @@ -9,7 +9,11 @@ describe( 'Gutenberg Editor tests', () => { it( 'should be able to create a post with heading and paragraph blocks', async () => { await editorPage.addNewBlock( blockNames.heading ); let headingBlockElement = await editorPage.getBlockAtPosition( - blockNames.heading + blockNames.heading, + 1, + { + useWaitForVisible: true, + } ); if ( isAndroid() ) { await headingBlockElement.click(); @@ -21,7 +25,7 @@ describe( 'Gutenberg Editor tests', () => { ); await editorPage.addNewBlock( blockNames.paragraph ); - let paragraphBlockElement = await editorPage.getBlockAtPosition( + let paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph, 2 ); @@ -31,7 +35,7 @@ describe( 'Gutenberg Editor tests', () => { ); await editorPage.addNewBlock( blockNames.paragraph ); - paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph, 3 ); @@ -41,7 +45,7 @@ describe( 'Gutenberg Editor tests', () => { ); await editorPage.addNewBlock( blockNames.heading ); - headingBlockElement = await editorPage.getBlockAtPosition( + headingBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.heading, 4 ); @@ -51,7 +55,7 @@ describe( 'Gutenberg Editor tests', () => { ); await editorPage.addNewBlock( blockNames.paragraph ); - paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph, 5 ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-image-@canary.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-image-@canary.test.js index d5b9f0ba6eed85..e475cc69afa7a4 100644 --- a/packages/react-native-editor/__device-tests__/gutenberg-editor-image-@canary.test.js +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-image-@canary.test.js @@ -8,11 +8,14 @@ import testData from './helpers/test-data'; describe( 'Gutenberg Editor Image Block tests', () => { it( 'should be able to add an image block', async () => { await editorPage.addNewBlock( blockNames.image ); - await editorPage.driver.sleep( 1000 ); await editorPage.closePicker(); - let imageBlock = await editorPage.getBlockAtPosition( - blockNames.image + const imageBlock = await editorPage.getBlockAtPosition( + blockNames.image, + 1, + { + useWaitForVisible: true, + } ); // Can only add image from media library on iOS @@ -26,7 +29,6 @@ describe( 'Gutenberg Editor Image Block tests', () => { await editorPage.dismissKeyboard(); // End workaround. - imageBlock = await editorPage.getBlockAtPosition( imageBlock ); await swipeUp( editorPage.driver, imageBlock ); await editorPage.enterCaptionToSelectedImageBlock( testData.imageCaption, @@ -35,7 +37,7 @@ describe( 'Gutenberg Editor Image Block tests', () => { await editorPage.dismissKeyboard(); } await editorPage.addNewBlock( blockNames.paragraph ); - const paragraphBlockElement = await editorPage.getBlockAtPosition( + const paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph, 2 ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-paragraph.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-paragraph.test.js index ff648eeeda3cbc..dc21fb856ec2ce 100644 --- a/packages/react-native-editor/__device-tests__/gutenberg-editor-paragraph.test.js +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-paragraph.test.js @@ -13,118 +13,92 @@ import testData from './helpers/test-data'; describe( 'Gutenberg Editor tests for Paragraph Block', () => { it( 'should be able to split one paragraph block into two', async () => { await editorPage.addNewBlock( blockNames.paragraph ); - const paragraphBlockElement = await editorPage.getBlockAtPosition( + const paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph ); - if ( isAndroid() ) { - await paragraphBlockElement.click(); - } - await editorPage.typeTextToParagraphBlock( paragraphBlockElement, testData.shortText ); - const textViewElement = await editorPage.getTextViewForParagraphBlock( - paragraphBlockElement + await clickMiddleOfElement( + editorPage.driver, + paragraphBlockElement, + true ); - await clickMiddleOfElement( editorPage.driver, textViewElement ); await editorPage.typeTextToParagraphBlock( paragraphBlockElement, '\n', false ); - expect( - ( await editorPage.hasBlockAtPosition( - 1, - blockNames.paragraph - ) ) && - ( await editorPage.hasBlockAtPosition( - 2, - blockNames.paragraph - ) ) - ).toBe( true ); - const text0 = await editorPage.getTextForParagraphBlockAtPosition( 1 ); const text1 = await editorPage.getTextForParagraphBlockAtPosition( 2 ); + expect( await editorPage.getNumberOfParagraphBlocks() ).toEqual( 2 ); expect( text0 ).not.toBe( '' ); expect( text1 ).not.toBe( '' ); expect( testData.shortText ).toMatch( new RegExp( `${ text0 + text1 }|${ text0 } ${ text1 }` ) ); - await editorPage.removeBlockAtPosition( blockNames.paragraph, 2 ); await editorPage.removeBlockAtPosition( blockNames.paragraph ); } ); it( 'should be able to merge 2 paragraph blocks into 1', async () => { await editorPage.addNewBlock( blockNames.paragraph ); - let paragraphBlockElement = await editorPage.getBlockAtPosition( + let paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph ); if ( isAndroid() ) { await paragraphBlockElement.click(); } - await editorPage.typeTextToParagraphBlock( paragraphBlockElement, testData.shortText ); - let textViewElement = await editorPage.getTextViewForParagraphBlock( - paragraphBlockElement + await clickMiddleOfElement( + editorPage.driver, + paragraphBlockElement, + true ); - await clickMiddleOfElement( editorPage.driver, textViewElement ); await editorPage.typeTextToParagraphBlock( paragraphBlockElement, '\n' ); - expect( - ( await editorPage.hasBlockAtPosition( - 1, - blockNames.paragraph - ) ) && - ( await editorPage.hasBlockAtPosition( - 2, - blockNames.paragraph - ) ) - ).toBe( true ); const text0 = await editorPage.getTextForParagraphBlockAtPosition( 1 ); const text1 = await editorPage.getTextForParagraphBlockAtPosition( 2 ); + expect( await editorPage.getNumberOfParagraphBlocks() ).toEqual( 2 ); paragraphBlockElement = await editorPage.getBlockAtPosition( blockNames.paragraph, - 2 + 2, + { + useWaitForVisible: true, + } ); if ( isAndroid() ) { await paragraphBlockElement.click(); } - textViewElement = await editorPage.getTextViewForParagraphBlock( + const textViewElement = await editorPage.getTextViewForParagraphBlock( paragraphBlockElement ); await clickBeginningOfElement( editorPage.driver, textViewElement ); + + const backspaceKey = isAndroid() ? backspace : '\b\b'; await editorPage.typeTextToParagraphBlock( paragraphBlockElement, - backspace + backspaceKey ); const text = await editorPage.getTextForParagraphBlockAtPosition( 1 ); - expect( text0 + text1 ).toMatch( text ); - expect( - await editorPage.hasBlockAtPosition( 2, blockNames.paragraph ) - ).toBe( false ); + text0.replace( /\s/g, '' ) + text1.replace( /\s/g, '' ) + ).toMatch( text.replace( /\s/g, '' ) ); + expect( await editorPage.getNumberOfParagraphBlocks() ).toEqual( 1 ); await editorPage.removeBlockAtPosition( blockNames.paragraph ); } ); it( 'should be able to create a post with multiple paragraph blocks', async () => { await editorPage.addNewBlock( blockNames.paragraph ); - const paragraphBlockElement = await editorPage.getBlockAtPosition( - blockNames.paragraph - ); - if ( isAndroid() ) { - await paragraphBlockElement.click(); - } - await editorPage.sendTextToParagraphBlock( 1, testData.longText ); for ( let i = 3; i > 0; i-- ) { @@ -139,18 +113,27 @@ describe( 'Gutenberg Editor tests for Paragraph Block', () => { testData.lettersInParagraphBlock, ].join( '\n\n' ) ); - // // Merge paragraphs. - const secondParagraphBlockElement = await editorPage.getBlockAtPosition( + + // Merge paragraphs. + await editorPage.getTextForParagraphBlockAtPosition( 2 ); + const paragraphBlockElement = await editorPage.getBlockAtPosition( blockNames.paragraph, - 2 + 2, + { + useWaitForVisible: true, + } ); - await clickBeginningOfElement( - editorPage.driver, - secondParagraphBlockElement + + const textViewElement = await editorPage.getTextViewForParagraphBlock( + paragraphBlockElement ); + + await clickBeginningOfElement( editorPage.driver, textViewElement ); + + const backspaceKey = isAndroid() ? backspace : '\b\b'; await editorPage.typeTextToParagraphBlock( - secondParagraphBlockElement, - backspace + paragraphBlockElement, + backspaceKey ); // Verify the editor has not crashed. @@ -168,21 +151,25 @@ describe( 'Gutenberg Editor tests for Paragraph Block', () => { testData.paragraphBlockEmpty, ].join( '\n\n' ) ); - // // Merge paragraphs. - const secondParagraphBlockElement = await editorPage.getBlockAtPosition( + + // Merge paragraphs. + const paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph, 2 ); - await secondParagraphBlockElement.click(); + const backspaceKey = isAndroid() ? backspace : '\b\b'; await editorPage.typeTextToParagraphBlock( - secondParagraphBlockElement, - backspace + paragraphBlockElement, + backspaceKey ); // Verify the editor has not crashed. const text = await editorPage.getTextForParagraphBlockAtPosition( 1 ); expect( text.length ).not.toEqual( 0 ); + if ( isAndroid() ) { + await paragraphBlockElement.click(); + } await editorPage.removeBlockAtPosition( blockNames.paragraph ); } ); } ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-paste.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-paste.test.js index 5e4084fc531edb..53746b0324772c 100644 --- a/packages/react-native-editor/__device-tests__/gutenberg-editor-paste.test.js +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-paste.test.js @@ -26,7 +26,7 @@ describe( 'Gutenberg Editor paste tests', () => { it( 'copies plain text from one paragraph block and pastes in another', async () => { await editorPage.addNewBlock( blockNames.paragraph ); - const paragraphBlockElement = await editorPage.getBlockAtPosition( + const paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph ); if ( isAndroid() ) { @@ -37,14 +37,17 @@ describe( 'Gutenberg Editor paste tests', () => { paragraphBlockElement, testData.pastePlainText ); - const textViewElement = await editorPage.getTextViewForParagraphBlock( - paragraphBlockElement - ); // Copy content to clipboard. - await longPressMiddleOfElement( editorPage.driver, textViewElement ); - await tapSelectAllAboveElement( editorPage.driver, textViewElement ); - await tapCopyAboveElement( editorPage.driver, textViewElement ); + await longPressMiddleOfElement( + editorPage.driver, + paragraphBlockElement + ); + await tapSelectAllAboveElement( + editorPage.driver, + paragraphBlockElement + ); + await tapCopyAboveElement( editorPage.driver, paragraphBlockElement ); // Create another paragraph block. await editorPage.addNewBlock( blockNames.paragraph ); @@ -52,7 +55,7 @@ describe( 'Gutenberg Editor paste tests', () => { // On Andrdoid 10 a new auto-suggestion popup is appearing to let the user paste text recently put in the clipboard. Let's dismiss it. await editorPage.dismissAndroidClipboardSmartSuggestion(); } - const paragraphBlockElement2 = await editorPage.getBlockAtPosition( + const paragraphBlockElement2 = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph, 2 ); @@ -60,13 +63,12 @@ describe( 'Gutenberg Editor paste tests', () => { await paragraphBlockElement2.click(); } - const textViewElement2 = await editorPage.getTextViewForParagraphBlock( + // Paste into second paragraph block. + await longPressMiddleOfElement( + editorPage.driver, paragraphBlockElement2 ); - - // Paste into second paragraph block. - await longPressMiddleOfElement( editorPage.driver, textViewElement2 ); - await tapPasteAboveElement( editorPage.driver, textViewElement2 ); + await tapPasteAboveElement( editorPage.driver, paragraphBlockElement2 ); const text = await editorPage.getTextForParagraphBlockAtPosition( 2 ); expect( text ).toBe( testData.pastePlainText ); @@ -78,21 +80,23 @@ describe( 'Gutenberg Editor paste tests', () => { it( 'copies styled text from one paragraph block and pastes in another', async () => { // Create paragraph block with styled text by editing html. await editorPage.setHtmlContent( testData.pasteHtmlText ); - const paragraphBlockElement = await editorPage.getBlockAtPosition( + const paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph ); if ( isAndroid() ) { await paragraphBlockElement.click(); } - const textViewElement = await editorPage.getTextViewForParagraphBlock( + // Copy content to clipboard. + await longPressMiddleOfElement( + editorPage.driver, paragraphBlockElement ); - - // Copy content to clipboard. - await longPressMiddleOfElement( editorPage.driver, textViewElement ); - await tapSelectAllAboveElement( editorPage.driver, textViewElement ); - await tapCopyAboveElement( editorPage.driver, textViewElement ); + await tapSelectAllAboveElement( + editorPage.driver, + paragraphBlockElement + ); + await tapCopyAboveElement( editorPage.driver, paragraphBlockElement ); // Create another paragraph block. await editorPage.addNewBlock( blockNames.paragraph ); @@ -100,7 +104,7 @@ describe( 'Gutenberg Editor paste tests', () => { // On Andrdoid 10 a new auto-suggestion popup is appearing to let the user paste text recently put in the clipboard. Let's dismiss it. await editorPage.dismissAndroidClipboardSmartSuggestion(); } - const paragraphBlockElement2 = await editorPage.getBlockAtPosition( + const paragraphBlockElement2 = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph, 2 ); @@ -108,13 +112,12 @@ describe( 'Gutenberg Editor paste tests', () => { await paragraphBlockElement2.click(); } - const textViewElement2 = await editorPage.getTextViewForParagraphBlock( + // Paste into second paragraph block. + await longPressMiddleOfElement( + editorPage.driver, paragraphBlockElement2 ); - - // Paste into second paragraph block. - await longPressMiddleOfElement( editorPage.driver, textViewElement2 ); - await tapPasteAboveElement( editorPage.driver, textViewElement2 ); + await tapPasteAboveElement( editorPage.driver, paragraphBlockElement2 ); // Check styled text by verifying html contents. const html = await editorPage.getHtmlContent(); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-rotation.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-rotation.test.js index cbaebfd3c57f85..97c9bcd78f0cc7 100644 --- a/packages/react-native-editor/__device-tests__/gutenberg-editor-rotation.test.js +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-rotation.test.js @@ -8,7 +8,7 @@ import testData from './helpers/test-data'; describe( 'Gutenberg Editor tests', () => { it( 'should be able to add blocks , rotate device and continue adding blocks', async () => { await editorPage.addNewBlock( blockNames.paragraph ); - let paragraphBlockElement = await editorPage.getBlockAtPosition( + let paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph ); if ( isAndroid() ) { @@ -32,7 +32,7 @@ describe( 'Gutenberg Editor tests', () => { await editorPage.driver.hideDeviceKeyboard(); } - paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockElement = await editorPage.getTextBlockLocatorAtPosition( blockNames.paragraph, 2 ); diff --git a/packages/react-native-editor/__device-tests__/helpers/utils.js b/packages/react-native-editor/__device-tests__/helpers/utils.js index 03f3002c59b142..992ef2f02fd5cc 100644 --- a/packages/react-native-editor/__device-tests__/helpers/utils.js +++ b/packages/react-native-editor/__device-tests__/helpers/utils.js @@ -282,12 +282,17 @@ const typeStringAndroid = async ( }; // Calculates middle x,y and clicks that position -const clickMiddleOfElement = async ( driver, element ) => { +const clickMiddleOfElement = async ( driver, element, isParagraph = false ) => { const location = await element.getLocation(); const size = await element.getSize(); const action = await new wd.TouchAction( driver ); - action.press( { x: location.x + size.width / 2, y: location.y } ); + // Condition to make it work on iOS Paragraph blocks, the default calculation somehow doesn't work just for this combination but worked for others. + if ( isParagraph === true && ! isAndroid() ) { + action.press( { x: 183, y: 195 } ); + } else { + action.press( { x: location.x + size.width / 2, y: location.y } ); + } action.release(); await action.perform(); }; 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 0a89deba8d5027..1503e43808944f 100644 --- a/packages/react-native-editor/__device-tests__/pages/editor-page.js +++ b/packages/react-native-editor/__device-tests__/pages/editor-page.js @@ -45,6 +45,25 @@ class EditorPage { return await this.driver.hasElementByAccessibilityId( 'block-list' ); } + // For text blocks, e.g Paragraph, Heading + async getTextBlockLocatorAtPosition( blockName, position = 1 ) { + // iOS needs a click before + if ( ! isAndroid() ) { + const textBlockLocator = `(//XCUIElementTypeButton[contains(@name, "${ blockName } Block. Row ${ position }")])`; + const textBlock = await waitForVisible( + this.driver, + textBlockLocator + ); + await textBlock.click(); + } + + const blockLocator = isAndroid() + ? `//android.view.ViewGroup[contains(@content-desc, "${ blockName } Block. Row ${ position }.")]/android.widget.EditText` + : `//XCUIElementTypeButton[contains(@name, "${ blockName } Block. Row ${ position }.")]//XCUIElementTypeTextView`; + + return await waitForVisible( this.driver, blockLocator ); + } + // Finds the wd element for new block that was added and sets the element attribute // and accessibilityId attributes on this object and selects the block // position uses one based numbering. @@ -136,7 +155,9 @@ class EditorPage { async hasBlockAtPosition( position = 1, blockName = '' ) { return ( undefined !== - ( await this.getBlockAtPosition( blockName, position ) ) + ( await this.getBlockAtPosition( blockName, position, { + useWaitForVisible: true, + } ) ) ); } @@ -455,9 +476,10 @@ class EditorPage { this.driver, blockActionsMenuButtonLocator ); - if ( isAndroid() ) { - const block = await this.getBlockAtPosition( blockName, position ); + const block = await this.getBlockAtPosition( blockName, position, { + useWaitForVisible: true, + } ); let checkList = await this.driver.elementsByXPath( blockActionsMenuButtonLocator ); @@ -470,7 +492,6 @@ class EditorPage { } await blockActionsMenuButton.click(); - const removeActionButtonIdentifier = 'Remove block'; const removeActionButtonLocator = `${ buttonElementName }[contains(@${ this.accessibilityIdXPathAttrib }, "${ removeActionButtonIdentifier }")]`; const removeActionButton = await waitForVisible( @@ -501,22 +522,20 @@ 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) + await typeString( this.driver, block, text, clear ); } async sendTextToParagraphBlock( position, text, clear ) { const paragraphs = text.split( '\n' ); for ( let i = 0; i < paragraphs.length; i++ ) { - // Select block first. - const block = await this.getBlockAtPosition( - this.paragraphBlockName, + const block = await this.getTextBlockLocatorAtPosition( + blockNames.paragraph, position + i ); - await block.click(); + + if ( isAndroid() ) { + await block.click(); + } await this.typeTextToParagraphBlock( block, @@ -529,28 +548,13 @@ class EditorPage { } } - async getTextForParagraphBlock( block ) { - const textViewElement = await this.getTextViewForParagraphBlock( - block - ); - const text = await textViewElement.text(); - return text.toString(); - } - async getTextForParagraphBlockAtPosition( position ) { - // Select block first. - let block = await this.getBlockAtPosition( - this.paragraphBlockName, + const blockLocator = await this.getTextBlockLocatorAtPosition( + blockNames.paragraph, position ); - await block.click(); - block = await this.getBlockAtPosition( - this.paragraphBlockName, - position - ); - const text = await this.getTextForParagraphBlock( block ); - return text.toString(); + return await blockLocator.text(); } // ========================= @@ -601,8 +605,13 @@ class EditorPage { } async chooseMediaLibrary() { - const mediaLibraryButton = await this.driver.elementByAccessibilityId( - 'WordPress Media Library' + const mediaLibraryLocator = isAndroid() + ? `//android.widget.Button[@content-desc="WordPress Media Library"]` + : `//XCUIElementTypeButton[@name="WordPress Media Library"]`; + + const mediaLibraryButton = await waitForVisible( + this.driver, + mediaLibraryLocator ); await mediaLibraryButton.click(); } @@ -766,6 +775,16 @@ class EditorPage { async sauceJobStatus( allPassed ) { await this.driver.sauceJobStatus( allPassed ); } + + async getNumberOfParagraphBlocks() { + const paragraphBlockLocator = isAndroid() + ? `//android.view.ViewGroup[contains(@content-desc, "Paragraph Block. Row")]/android.widget.EditText` + : `(//XCUIElementTypeButton[contains(@name, "Paragraph Block. Row")])`; + const locator = await this.driver.elementsByXPath( + paragraphBlockLocator + ); + return locator.length; + } } const blockNames = {