Skip to content

Commit

Permalink
Add waitForVisible() to all blocks (#41126)
Browse files Browse the repository at this point in the history
* add waits to all block - 1st try

* fix failing tests

* correct if else condition

* fix failing cover block test

* update spaces

* update to use new click helper

* wait for blocks to be visible first in getFirstBlock and getLastBlock

* remove length as a parameter

* update timing for long press since it's failing intermittently in ci

* remove deleted param, revert space changes

* remove redundant code

* exit function once condition is met

* increse wait time for long press

* remove unneccesary condition, update message, return click value

Co-authored-by: jos <[email protected]>
  • Loading branch information
jostnes and jostnes authored May 25, 2022
1 parent 6f4bdca commit fcaf478
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 182 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ describe( 'Gutenberg Editor tests for Block insertion', () => {
testData.blockInsertionHtml.toLowerCase()
);

// wait for the block editor to load and for accessibility ids to update
await editorPage.driver.sleep( 3000 );

// Workaround for now since deleting the first element causes a crash on CI for Android
if ( isAndroid() ) {
paragraphBlockElement = await editorPage.getTextBlockAtPosition(
Expand All @@ -55,8 +52,6 @@ describe( 'Gutenberg Editor tests for Block insertion', () => {
await paragraphBlockElement.click();
await editorPage.removeBlockAtPosition( blockNames.paragraph, 3 );
for ( let i = 3; i > 0; i-- ) {
// wait for accessibility ids to update
await editorPage.driver.sleep( 1000 );
paragraphBlockElement = await editorPage.getTextBlockAtPosition(
blockNames.paragraph,
i,
Expand All @@ -72,8 +67,6 @@ describe( 'Gutenberg Editor tests for Block insertion', () => {
}
} else {
for ( let i = 4; i > 0; i-- ) {
// wait for accessibility ids to update
await editorPage.driver.sleep( 1000 );
paragraphBlockElement = await editorPage.getTextBlockAtPosition(
blockNames.paragraph
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,95 +2,49 @@
* Internal dependencies
*/
import { blockNames } from './pages/editor-page';
import { isAndroid, waitForVisible } from './helpers/utils';
import { isAndroid } from './helpers/utils';
import testData from './helpers/test-data';

describe( 'Gutenberg Editor Cover Block test', () => {
it( 'should displayed properly and have properly converted height (ios only)', async () => {
await editorPage.setHtmlContent( testData.coverHeightWithRemUnit );

const coverBlock = await editorPage.getBlockAtPosition(
blockNames.cover,
1,
{ useWaitForVisible: true }
);

// Temporarily this test is skipped on Android,due to the inconsistency of the results,
// which are related to getting values in raw pixels instead of density pixels on Android.
/* eslint-disable jest/no-conditional-expect */
if ( ! isAndroid() ) {
await editorPage.setHtmlContent( testData.coverHeightWithRemUnit );

const coverBlock = await editorPage.getBlockAtPosition(
blockNames.cover
);

const { height } = await coverBlock.getSize();
// Height is set to 20rem, where 1rem is 16.
// There is also block's vertical padding equal 32.
// Finally, the total height should be 20 * 16 + 32 = 352.
expect( height ).toBe( 352 );
}
/* eslint-enable jest/no-conditional-expect */
/* eslint-enable jest/no-conditional-expect */

await coverBlock.click();
expect( coverBlock ).toBeTruthy();
await editorPage.removeBlockAtPosition( blockNames.cover );
await coverBlock.click();
expect( coverBlock ).toBeTruthy();
await editorPage.removeBlockAtPosition( blockNames.cover );
}
} );

// Testing this for iOS on a device is valuable to ensure that it properly
// handles opening multiple modals, as only one can be open at a time.
it( 'allows modifying media from within block settings', async () => {
await editorPage.setHtmlContent( testData.coverHeightWithRemUnit );

const coverBlock = await editorPage.getBlockAtPosition(
blockNames.cover,
1,
{ useWaitForVisible: true }
);
await coverBlock.click();

// Can only add image from media library on iOS
if ( ! isAndroid() ) {
// Open block settings.
const settingsButton = await editorPage.driver.elementByAccessibilityId(
'Open Settings'
);
await settingsButton.click();
await editorPage.setHtmlContent( testData.coverHeightWithRemUnit );

// Add initial media via button within bottom sheet.
const mediaSection = await editorPage.driver.elementByAccessibilityId(
'Media Add image or video'
);
const addMediaButton = await mediaSection.elementByAccessibilityId(
'Add image or video'
const coverBlock = await editorPage.getBlockAtPosition(
blockNames.cover
);
await addMediaButton.click();
await editorPage.chooseMediaLibrary();
await editorPage.driver.sleep( 2000 ); // Await media load.

// Get Edit image button of block
const editImageButtonLocator =
'//XCUIElementTypeButton[@name="Edit image"][@enabled="true"]';
const blockEditImageButton = await waitForVisible(
editorPage.driver,
editImageButtonLocator
);

// Edit media within block settings.
await settingsButton.click();
await editorPage.driver.sleep( 2000 ); // Await media load.

// Get Edit image button of block settings.
// NOTE: Since we have multiple Edit image buttons at this
// point, we have to filter them to obtain the correct one.
const settingsEditImageButtons = await editorPage.driver.elementsByXPath(
editImageButtonLocator
);
const settingsEditImageButton = settingsEditImageButtons.find(
( element ) => element.value !== blockEditImageButton.value
);
await settingsEditImageButton.click();

// Replace image.
const replaceButton = await editorPage.driver.elementByAccessibilityId(
'Replace'
);
await replaceButton.click();
await editorPage.openBlockSettings( coverBlock );
await editorPage.clickAddMediaFromCoverBlock();
await editorPage.chooseMediaLibrary();
await editorPage.replaceMediaImage();

// First modal should no longer be presented.
const replaceButtons = await editorPage.driver.elementsByAccessibilityId(
Expand All @@ -101,9 +55,9 @@ describe( 'Gutenberg Editor Cover Block test', () => {

// Select different media.
await editorPage.chooseMediaLibrary();
}

expect( coverBlock ).toBeTruthy();
await editorPage.removeBlockAtPosition( blockNames.cover );
expect( coverBlock ).toBeTruthy();
await editorPage.removeBlockAtPosition( blockNames.cover );
}
} );
} );
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,7 @@ describe( 'Gutenberg Editor Image Block tests', () => {
await editorPage.closePicker();

const imageBlock = await editorPage.getBlockAtPosition(
blockNames.image,
1,
{
useWaitForVisible: true,
}
blockNames.image
);

// Can only add image from media library on iOS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ describe( 'Gutenberg Editor Search Block tests.', () => {
searchBlock,
'Button inside'
);
await editorPage.isSearchSettingsVisible();
await editorPage.dismissBottomSheet();

// Switch to html and verify.
Expand All @@ -141,6 +142,7 @@ describe( 'Gutenberg Editor Search Block tests.', () => {
searchBlock,
'No button'
);
await editorPage.isSearchSettingsVisible();
await editorPage.dismissBottomSheet();

// Switch to html and verify.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ describe( 'Gutenberg Editor Spacer Block test', () => {
it( 'should be able to add a spacer block', async () => {
await editorPage.addNewBlock( blockNames.spacer );
const spacerBlock = await editorPage.getBlockAtPosition(
blockNames.spacer,
1,
{ useWaitForVisible: true }
blockNames.spacer
);

expect( spacerBlock ).toBeTruthy();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ describe( 'Gutenberg Editor Unsupported Block Editor Tests', () => {
const editButton = await editorPage.getUnsupportedBlockBottomSheetEditButton();
await editButton.click();

await expect(
editorPage.getUnsupportedBlockWebView()
).resolves.toBeTruthy();
const webView = await editorPage.getUnsupportedBlockWebView();
await expect( webView ).toBeTruthy();
} );
} );
75 changes: 57 additions & 18 deletions packages/react-native-editor/__device-tests__/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,8 @@ const longPressMiddleOfElement = async ( driver, element ) => {
const x = location.x + size.width / 2;
const y = location.y + size.height / 2;
action.press( { x, y } );
action.wait( 2000 );
// Setting to wait a bit longer because this is failing more frequently on the CI
action.wait( 5000 );
action.release();
await action.perform();
};
Expand Down Expand Up @@ -419,24 +420,28 @@ const toggleHtmlMode = async ( driver, toggleOn ) => {

const showHtmlButtonXpath =
'/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.ListView/android.widget.TextView[9]';
const showHtmlButton = await driver.elementByXPath(
showHtmlButtonXpath

await clickIfClickable( driver, showHtmlButtonXpath );
} else if ( toggleOn ) {
await clickIfClickable(
driver,
'//XCUIElementTypeButton[@name="..."]'
);
await clickIfClickable(
driver,
'//XCUIElementTypeButton[@name="Switch to HTML"]'
);
await showHtmlButton.click();
} else {
const menuButton = await driver.elementByAccessibilityId( '...' );
await menuButton.click();
let toggleHtmlButton;
if ( toggleOn ) {
toggleHtmlButton = await driver.elementByAccessibilityId(
'Switch to HTML'
);
} else {
toggleHtmlButton = await driver.elementByAccessibilityId(
'Switch To Visual'
);
}
await toggleHtmlButton.click();
// This is to wait for the clipboard paste notification to disappear, currently it overlaps with the menu button
await driver.sleep( 3000 );
await clickIfClickable(
driver,
'//XCUIElementTypeButton[@name="..."]'
);
await clickIfClickable(
driver,
'//XCUIElementTypeButton[@name="Switch To Visual"]'
);
}
};

Expand Down Expand Up @@ -492,7 +497,7 @@ const waitForVisible = async (
}

const element = await driver.elementsByXPath( elementLocator );
if ( element.length !== 1 ) {
if ( element.length === 0 ) {
// if locator is not visible, try again
return waitForVisible(
driver,
Expand Down Expand Up @@ -530,6 +535,39 @@ const isElementVisible = async (
return true;
};

const clickIfClickable = async (
driver,
elementLocator,
maxIteration = 25,
iteration = 0
) => {
const element = await waitForVisible(
driver,
elementLocator,
maxIteration,
iteration
);

try {
return await element.click();
} catch ( error ) {
if ( iteration >= maxIteration ) {
// eslint-disable-next-line no-console
console.error(
`"${ elementLocator }" still not clickable after "${ iteration }" retries`
);
return '';
}

return clickIfClickable(
driver,
elementLocator,
maxIteration,
iteration + 1
);
}
};

// Only for Android
const waitIfAndroid = async () => {
if ( isAndroid() ) {
Expand All @@ -540,6 +578,7 @@ const waitIfAndroid = async () => {
module.exports = {
backspace,
clickBeginningOfElement,
clickIfClickable,
clickMiddleOfElement,
doubleTap,
isAndroid,
Expand Down
Loading

0 comments on commit fcaf478

Please sign in to comment.