From 3157a243f65635bcdb1fa8aca6855d054b9f51a3 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Fri, 26 Jan 2024 11:28:00 +0100 Subject: [PATCH 01/10] Remove unused pre/post bundle commands --- packages/react-native-editor/package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/react-native-editor/package.json b/packages/react-native-editor/package.json index f2a57980c86ec..1a5392c56a01f 100644 --- a/packages/react-native-editor/package.json +++ b/packages/react-native-editor/package.json @@ -81,9 +81,7 @@ "start:debug": "node --inspect-brk node_modules/.bin/react-native start", "start:reset": "npm run clean:runtime && npm run start:quick -- --reset-cache", "start:quick": "react-native start", - "prern-bundle": "cd ../.. && patch-package --patch-dir packages/react-native-editor/metro-patch", "rn-bundle": "react-native bundle", - "postrn-bundle": "cd ../.. && patch-package --reverse --patch-dir packages/react-native-editor/metro-patch", "prebundle": "npm run i18n-cache:force", "bundle": "npm run bundle:android && npm run bundle:ios", "bundle:android": "mkdir -p bundle/android && npm run rn-bundle -- --platform android --dev false --entry-file index.js --assets-dest bundle/android --bundle-output bundle/android/App.text.js --sourcemap-output bundle/android/App.text.js.map && ./../../node_modules/react-native/sdks/hermesc/`node -e \"const platform=require('os').platform();console.log(platform === 'darwin' ? 'osx-bin' : (platform === 'linux' ? 'linux64-bin' : (platform === 'win32' ? 'win64-bin' : 'unsupported-os')));\"`/hermesc -emit-binary -O -out bundle/android/App.js bundle/android/App.text.js -output-source-map", From 1b1b1a50fd97dd82e4d1d5ea8f1572f9b975b649 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Fri, 26 Jan 2024 13:12:13 +0100 Subject: [PATCH 02/10] Set the same Gradle properties --- packages/react-native-aztec/android/gradle.properties | 5 ++++- packages/react-native-bridge/android/gradle.properties | 5 ++++- packages/react-native-editor/android/gradle.properties | 3 +++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/react-native-aztec/android/gradle.properties b/packages/react-native-aztec/android/gradle.properties index 81529680627fb..d10ae706af10f 100644 --- a/packages/react-native-aztec/android/gradle.properties +++ b/packages/react-native-aztec/android/gradle.properties @@ -1,6 +1,9 @@ # Project-wide Gradle settings. -org.gradle.jvmargs=-Xmx2g -XX:+HeapDumpOnOutOfMemoryError +org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError +org.gradle.parallel=true +org.gradle.configureondemand=true +org.gradle.caching=true # React Native Aztec properties. diff --git a/packages/react-native-bridge/android/gradle.properties b/packages/react-native-bridge/android/gradle.properties index eb15f4b384486..9323c4396aeb6 100644 --- a/packages/react-native-bridge/android/gradle.properties +++ b/packages/react-native-bridge/android/gradle.properties @@ -1,6 +1,9 @@ # Project-wide Gradle settings. -org.gradle.jvmargs=-Xmx2g -XX:+HeapDumpOnOutOfMemoryError +org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError +org.gradle.parallel=true +org.gradle.configureondemand=true +org.gradle.caching=true # React Native Bridge properties. diff --git a/packages/react-native-editor/android/gradle.properties b/packages/react-native-editor/android/gradle.properties index 0705a21e44f05..33ddc2c948001 100644 --- a/packages/react-native-editor/android/gradle.properties +++ b/packages/react-native-editor/android/gradle.properties @@ -12,6 +12,9 @@ # Default value: -Xmx10248m -XX:MaxPermSize=256m # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError +org.gradle.parallel=true +org.gradle.configureondemand=true +org.gradle.caching=true # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit From d60062a3de8415239fc017089467dab79ee046eb Mon Sep 17 00:00:00 2001 From: Gerardo Date: Fri, 26 Jan 2024 16:09:06 +0100 Subject: [PATCH 03/10] Remove Xcode patch --- package.json | 2 +- patches/patch-xcode.js | 54 ------------------------------------------ 2 files changed, 1 insertion(+), 55 deletions(-) delete mode 100644 patches/patch-xcode.js diff --git a/package.json b/package.json index daa11fa2df048..2cc85f3f0219a 100644 --- a/package.json +++ b/package.json @@ -306,7 +306,7 @@ "other:check-local-changes": "node ./bin/check-local-changes.js", "other:cherry-pick": "node ./bin/cherry-pick.mjs", "other:update-packages:php": "wp-env run --env-cwd='wp-content/plugins/gutenberg' cli composer update --no-interaction", - "postinstall": "patch-package && node ./patches/patch-xcode.js", + "postinstall": "patch-package", "prepare": "husky install", "prepublishOnly": "npm run clean:package-types && npm run build:packages", "start": "npm run dev", diff --git a/patches/patch-xcode.js b/patches/patch-xcode.js deleted file mode 100644 index 4e8543f8affa7..0000000000000 --- a/patches/patch-xcode.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * External dependencies - */ -const fs = require( 'fs' ); -const path = require( 'path' ); - -/** - * Temporary patch to fix all xCode 12 libs - */ - -const nodeModulesDir = path.join( __dirname, '../', 'node_modules' ); - -const fetchRNPackageDirs = ( dir ) => { - const dirList = fs.readdirSync( dir, { withFileTypes: true } ); - const packageDirs = []; - dirList - .filter( ( file ) => file.isDirectory() ) - .map( ( file ) => file.name ) - .forEach( ( packageName ) => { - const packageDir = path.join( dir, packageName ); - if ( packageName.startsWith( '@' ) ) { - packageDirs.push( ...fetchRNPackageDirs( packageDir ) ); - } else { - const files = fs.readdirSync( packageDir ); - const podSpecs = files.filter( ( file ) => - file.toLowerCase().endsWith( '.podspec' ) - ); - if ( podSpecs.length > 0 ) { - packageDirs.push( { - dir: packageDir, - files: podSpecs, - package: packageName, - } ); - } - } - } ); - return packageDirs; -}; - -const packagesWithPodspec = fetchRNPackageDirs( nodeModulesDir ); -const dependencyRegex = /(s\.dependency +(?:'|"))React('|")/; -packagesWithPodspec.forEach( ( packageWithPodspec ) => { - packageWithPodspec.files.forEach( ( file ) => { - const filePath = path.join( packageWithPodspec.dir, file ); - const fileContents = fs.readFileSync( filePath ); - - if ( `${ fileContents }`.match( dependencyRegex ) ) { - fs.writeFileSync( - filePath, - `${ fileContents }`.replace( dependencyRegex, '$1React-Core$2' ) - ); - } - } ); -} ); From b0b8fcdea984c12a36df814b8ea05b4a0e3a8864 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Fri, 26 Jan 2024 17:41:34 +0100 Subject: [PATCH 04/10] Update iOS config to pass the environment it is currenlty running local/github --- .github/workflows/rnmobile-ios-runner.yml | 4 +- .../__device-tests__/helpers/caps.js | 35 +++++-------- .../helpers/device-config.json | 12 ++--- .../__device-tests__/helpers/utils.js | 51 +++++++++---------- 4 files changed, 45 insertions(+), 57 deletions(-) diff --git a/.github/workflows/rnmobile-ios-runner.yml b/.github/workflows/rnmobile-ios-runner.yml index 9ead788343b8d..9ef6ebaa71f2f 100644 --- a/.github/workflows/rnmobile-ios-runner.yml +++ b/.github/workflows/rnmobile-ios-runner.yml @@ -44,7 +44,7 @@ jobs: key: ${{ runner.os }}-tests-setup-${{ hashFiles('package-lock.json') }} - name: Prepare tests setup - run: npm run native test:e2e:setup + run: TEST_ENV=github npm run native test:e2e:setup - name: Prepare build cache key run: find package-lock.json packages/react-native-editor/ios packages/react-native-aztec/ios packages/react-native-bridge/ios -type f -print0 | sort -z | xargs -0 shasum | tee ios-checksums.txt @@ -77,7 +77,7 @@ jobs: run: test -d packages/react-native-editor/ios/build/WDA || npm run native test:e2e:build-wda - name: Run iOS Device Tests - run: TEST_RN_PLATFORM=ios npm run native device-tests:local ${{ matrix.native-test-name }} + run: TEST_ENV=github TEST_RN_PLATFORM=ios npm run native device-tests:local ${{ matrix.native-test-name }} - name: Prepare build cache run: | diff --git a/packages/react-native-editor/__device-tests__/helpers/caps.js b/packages/react-native-editor/__device-tests__/helpers/caps.js index fc73b1c1c878a..2d5fcf1c0f58c 100644 --- a/packages/react-native-editor/__device-tests__/helpers/caps.js +++ b/packages/react-native-editor/__device-tests__/helpers/caps.js @@ -15,28 +15,19 @@ const ios = { autoLaunch: false, }; -exports.iosLocal = ( { iPadDevice = false } ) => ( { - ...ios, - deviceName: ! iPadDevice - ? iOSConfig.local.deviceName - : iOSConfig.local.deviceTabletName, - platformVersion: iOSConfig.local.platformVersion, - pixelRatio: ! iPadDevice - ? iOSConfig.pixelRatio.iPhone - : iOSConfig.pixelRatio.iPad, - usePrebuiltWDA: true, -} ); - -exports.iosServer = ( { iPadDevice = false } ) => ( { - ...ios, - deviceName: ! iPadDevice - ? iOSConfig.saucelabs.deviceName - : iOSConfig.saucelabs.deviceTabletName, - platformVersion: iOSConfig.local.platformVersion, - pixelRatio: ! iPadDevice - ? iOSConfig.pixelRatio.iPhone - : iOSConfig.pixelRatio.iPad, -} ); +exports.iosLocal = ( { iPadDevice = false, environment } ) => { + return { + ...ios, + deviceName: ! iPadDevice + ? iOSConfig[ environment ].deviceName + : iOSConfig[ environment ].deviceTabletName, + platformVersion: iOSConfig[ environment ].platformVersion, + pixelRatio: ! iPadDevice + ? iOSConfig.pixelRatio.iPhone + : iOSConfig.pixelRatio.iPad, + usePrebuiltWDA: true, + }; +}; exports.android = { platformVersion: androidConfig.local.platformVersion, diff --git a/packages/react-native-editor/__device-tests__/helpers/device-config.json b/packages/react-native-editor/__device-tests__/helpers/device-config.json index 5f952099133dd..e691585888949 100644 --- a/packages/react-native-editor/__device-tests__/helpers/device-config.json +++ b/packages/react-native-editor/__device-tests__/helpers/device-config.json @@ -1,17 +1,15 @@ { "ios": { "local": { + "deviceName": "iPhone 15", + "deviceTabletName": "iPad (10th generation)", + "platformVersion": "17.0" + }, + "github": { "deviceName": "iPhone 14", "deviceTabletName": "iPad (10th generation)", "platformVersion": "16.2" }, - "saucelabs": { - "deviceName": "iPhone 14 Simulator", - "deviceTabletName": "iPad (10th generation) Simulator" - }, - "buildkite": { - "platformVersion": "16.4" - }, "pixelRatio": { "iPhone": 3, "iPad": 2 diff --git a/packages/react-native-editor/__device-tests__/helpers/utils.js b/packages/react-native-editor/__device-tests__/helpers/utils.js index c44bc277155e2..5e600be3d0302 100644 --- a/packages/react-native-editor/__device-tests__/helpers/utils.js +++ b/packages/react-native-editor/__device-tests__/helpers/utils.js @@ -12,7 +12,6 @@ const path = require( 'path' ); */ const serverConfigs = require( './serverConfigs' ); const { - iosServer, iosLocal, android, sauceOptions, @@ -126,38 +125,38 @@ const setupDriver = async () => { desiredCaps.newCommandTimeout = SAUCE_LABS_TIMEOUT; } } else { - desiredCaps = iosServer( { iPadDevice } ); + desiredCaps = desiredCaps = iosLocal( { + iPadDevice, + environment: testEnvironment, + } ); desiredCaps.newCommandTimeout = SAUCE_LABS_TIMEOUT; desiredCaps.app = `storage:filename=Gutenberg-${ safeBranchName }.app.zip`; // App should be preloaded to sauce storage, this can also be a URL. - if ( isLocalEnvironment() ) { - desiredCaps = iosLocal( { iPadDevice } ); - const iosPlatformVersions = getIOSPlatformVersions( { - requiredVersion: desiredCaps.platformVersion, - } ); - if ( iosPlatformVersions.length === 0 ) { - throw new Error( - `No compatible iOS simulators available! Please verify that you have iOS ${ desiredCaps.platformVersion } simulators installed.` - ); - } - // eslint-disable-next-line no-console - console.log( - 'Available iOS platform versions:', - iosPlatformVersions.map( ( { name } ) => name ) + const iosPlatformVersions = getIOSPlatformVersions( { + requiredVersion: desiredCaps.platformVersion, + } ); + if ( iosPlatformVersions.length === 0 ) { + throw new Error( + `No compatible iOS simulators available! Please verify that you have iOS ${ desiredCaps.platformVersion } simulators installed.` ); + } + // eslint-disable-next-line no-console + console.log( + 'Available iOS platform versions:', + iosPlatformVersions.map( ( { name } ) => name ) + ); - if ( ! desiredCaps.platformVersion ) { - desiredCaps.platformVersion = iosPlatformVersions[ 0 ].version; - - // eslint-disable-next-line no-console - console.log( - `Using iOS ${ desiredCaps.platformVersion } platform version` - ); - } + if ( ! desiredCaps.platformVersion ) { + desiredCaps.platformVersion = iosPlatformVersions[ 0 ].version; - desiredCaps.app = path.resolve( localIOSAppPath ); - desiredCaps.derivedDataPath = path.resolve( webDriverAgentPath ); + // eslint-disable-next-line no-console + console.log( + `Using iOS ${ desiredCaps.platformVersion } platform version` + ); } + + desiredCaps.app = path.resolve( localIOSAppPath ); + desiredCaps.derivedDataPath = path.resolve( webDriverAgentPath ); } const sauceOptionsConfig = ! isLocalEnvironment() From 56eb68e35d5bcb95c7f755313782efd300786772 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Fri, 26 Jan 2024 17:42:07 +0100 Subject: [PATCH 05/10] Update test-e2e-setup script to pass the TEST_ENV variable --- packages/react-native-editor/bin/test-e2e-setup.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/react-native-editor/bin/test-e2e-setup.sh b/packages/react-native-editor/bin/test-e2e-setup.sh index ed896a03eacb8..f78e7388e1cce 100755 --- a/packages/react-native-editor/bin/test-e2e-setup.sh +++ b/packages/react-native-editor/bin/test-e2e-setup.sh @@ -21,6 +21,7 @@ function log_error() { printf "❌ $1\n" } +TEST_ENV=${TEST_ENV:-"local"} output=$($APPIUM_CMD driver list --installed --json) if echo "$output" | grep -q 'uiautomator2'; then @@ -38,7 +39,7 @@ else fi CONFIG_FILE="$(pwd)/__device-tests__/helpers/device-config.json" -IOS_PLATFORM_VERSION=$(jq -r '.ios.local.platformVersion' "$CONFIG_FILE") +IOS_PLATFORM_VERSION=$(jq -r ".ios.$TEST_ENV.platformVersion" "$CONFIG_FILE") # Throw an error if the required iOS runtime is not installed IOS_RUNTIME_INSTALLED=$(xcrun simctl list runtimes -j | jq -r --arg version "$IOS_PLATFORM_VERSION" '.runtimes | to_entries[] | select(.value.version | contains($version))') @@ -62,8 +63,8 @@ function detect_or_create_simulator() { fi } -IOS_DEVICE_NAME=$(jq -r '.ios.local.deviceName' "$CONFIG_FILE") -IOS_DEVICE_TABLET_NAME=$(jq -r '.ios.local.deviceTabletName' "$CONFIG_FILE") +IOS_DEVICE_NAME=$(jq -r ".ios.$TEST_ENV.deviceName" "$CONFIG_FILE") +IOS_DEVICE_TABLET_NAME=$(jq -r ".ios.$TEST_ENV.deviceTabletName" "$CONFIG_FILE") # Create the required iOS simulators, if they don't exist detect_or_create_simulator "$IOS_DEVICE_NAME" From 58718e205bf44148521a6a96c02b2902b77f0376 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Fri, 26 Jan 2024 17:42:31 +0100 Subject: [PATCH 06/10] Remove setting the OS argument for e2e builds --- packages/react-native-editor/bin/build-e2e-wda.sh | 2 +- packages/react-native-editor/bin/build_e2e_ios_app | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/react-native-editor/bin/build-e2e-wda.sh b/packages/react-native-editor/bin/build-e2e-wda.sh index 2b835fbd6e608..39431f61db771 100755 --- a/packages/react-native-editor/bin/build-e2e-wda.sh +++ b/packages/react-native-editor/bin/build-e2e-wda.sh @@ -7,4 +7,4 @@ CONFIG_FILE="$(pwd)/__device-tests__/helpers/device-config.json" IOS_DEVICE_NAME=$(jq -r '.ios.local.deviceName' "$CONFIG_FILE") IOS_PLATFORM_VERSION=$(jq -r '.ios.local.platformVersion' "$CONFIG_FILE") -xcodebuild -project ~/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination "platform=iOS Simulator,name=$IOS_DEVICE_NAME,OS=$IOS_PLATFORM_VERSION" -derivedDataPath ios/build/WDA +xcodebuild -project ~/.appium/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent/WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination "platform=iOS Simulator,name=$IOS_DEVICE_NAME" -derivedDataPath ios/build/WDA diff --git a/packages/react-native-editor/bin/build_e2e_ios_app b/packages/react-native-editor/bin/build_e2e_ios_app index 2a0a293adedcb..a167a30c9b4a7 100755 --- a/packages/react-native-editor/bin/build_e2e_ios_app +++ b/packages/react-native-editor/bin/build_e2e_ios_app @@ -7,7 +7,7 @@ CONFIG_FILE="$(pwd)/__device-tests__/helpers/device-config.json" IOS_DEVICE_NAME=$(jq -r '.ios.local.deviceName' "$CONFIG_FILE") IOS_PLATFORM_VERSION=$(jq -r '.ios.local.platformVersion' "$CONFIG_FILE") -DEFAULT_DESTINATION="platform=iOS Simulator,name=$IOS_DEVICE_NAME,OS=$IOS_PLATFORM_VERSION" +DEFAULT_DESTINATION="platform=iOS Simulator,name=$IOS_DEVICE_NAME" if [[ -z "${RN_EDITOR_E2E_IOS_DESTINATION-}" ]]; then DESTINATION="$DEFAULT_DESTINATION" else From 2f527807a9ee6d8fb4df948cbc660652fcc3cd8b Mon Sep 17 00:00:00 2001 From: Gerardo Date: Sun, 28 Jan 2024 21:57:57 +0100 Subject: [PATCH 07/10] Update tests and utils --- .../gutenberg-editor-media-blocks-@canary.test.js | 4 +++- .../__device-tests__/helpers/caps.js | 3 +++ .../__device-tests__/helpers/utils.js | 11 +++++------ 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-media-blocks-@canary.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-media-blocks-@canary.test.js index 480d19cb966a0..699950a453ae9 100644 --- a/packages/react-native-editor/__device-tests__/gutenberg-editor-media-blocks-@canary.test.js +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-media-blocks-@canary.test.js @@ -124,7 +124,9 @@ onlyOniOS( 'Gutenberg Editor Cover Block test', () => { // Height is set to 20rem, where 1rem is 16. // There is also block's vertical padding equal 16. // Finally, the total height should be 20 * 16 + 16 = 336. - expect( height ).toBe( 336 ); + // Since different simulators may have slight variations, we allow a range of values. + expect( height ).toBeGreaterThanOrEqual( 336 ); + expect( height ).toBeLessThanOrEqual( 337 ); await coverBlock.click(); expect( coverBlock ).toBeTruthy(); diff --git a/packages/react-native-editor/__device-tests__/helpers/caps.js b/packages/react-native-editor/__device-tests__/helpers/caps.js index 2d5fcf1c0f58c..4e9a038071d9a 100644 --- a/packages/react-native-editor/__device-tests__/helpers/caps.js +++ b/packages/react-native-editor/__device-tests__/helpers/caps.js @@ -13,6 +13,9 @@ const ios = { args: [ 'uitesting' ], }, autoLaunch: false, + simulatorStartupTimeout: 240, + reduceMotion: true, + maxTypingFrequency: 30, }; exports.iosLocal = ( { iPadDevice = false, environment } ) => { diff --git a/packages/react-native-editor/__device-tests__/helpers/utils.js b/packages/react-native-editor/__device-tests__/helpers/utils.js index 5e600be3d0302..c9bb3cc8385c3 100644 --- a/packages/react-native-editor/__device-tests__/helpers/utils.js +++ b/packages/react-native-editor/__device-tests__/helpers/utils.js @@ -223,11 +223,6 @@ const typeString = async ( driver, element, str, clear ) => { } await element.addValue( str ); - - if ( ! isAndroid() ) { - // Await the completion of the scroll-to-text-input animation - await driver.pause( 3000 ); - } }; /** @@ -295,11 +290,15 @@ const clickMiddleOfElement = async ( driver, element ) => { // Clicks in the top left of an element. const clickBeginningOfElement = async ( driver, element ) => { const location = await element.getLocation(); + const borderPadding = 8; await driver .action( 'pointer', { parameters: { pointerType: 'touch' }, } ) - .move( { x: location.x, y: location.y } ) + .move( { + x: location.x + borderPadding, + y: location.y + borderPadding, + } ) .down() .up() .perform(); From 17af08f4cb86b014f80689fefaaeabbb34428dc5 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Mon, 29 Jan 2024 16:57:46 +0100 Subject: [PATCH 08/10] Update utils --- .../__device-tests__/helpers/utils.js | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/packages/react-native-editor/__device-tests__/helpers/utils.js b/packages/react-native-editor/__device-tests__/helpers/utils.js index c9bb3cc8385c3..58040deee6b70 100644 --- a/packages/react-native-editor/__device-tests__/helpers/utils.js +++ b/packages/react-native-editor/__device-tests__/helpers/utils.js @@ -406,7 +406,7 @@ const selectTextFromElement = async ( driver, element ) => { .perform(); } else { // On iOS we can use the context menu to "Select all" text. - await longPressMiddleOfElement( driver, element ); + await clickBeginningOfElement( driver, element ); const selectAllElement = await driver.$( '//XCUIElementTypeMenuItem[@name="Select All"]' @@ -534,23 +534,16 @@ const toggleHtmlMode = async ( driver, toggleOn ) => { '/hierarchy/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.ListView/android.widget.TextView[9]'; await clickIfClickable( driver, showHtmlButtonXpath ); - } else if ( toggleOn ) { - const moreOptionsButton = await driver.$( '~editor-menu-button' ); - await moreOptionsButton.click(); - - await clickIfClickable( - driver, - '//XCUIElementTypeButton[@name="Switch to HTML"]' - ); } else { - // This is to wait for the clipboard paste notification to disappear, currently it overlaps with the menu button - await driver.pause( 3000 ); + const action = toggleOn ? 'Switch to HTML' : 'Switch To Visual'; + await driver.waitUntil( driver.$( '~editor-menu-button' ).isDisplayed ); const moreOptionsButton = await driver.$( '~editor-menu-button' ); await moreOptionsButton.click(); - await clickIfClickable( - driver, - '//XCUIElementTypeButton[@name="Switch To Visual"]' - ); + + await driver.waitUntil( driver.$( `~${ action }` ).isDisplayed ); + + const actionButton = await driver.$( `~${ action }` ); + await actionButton.click(); } }; From c93c3f625163902ba45252c04ec235f5c1880fdb Mon Sep 17 00:00:00 2001 From: Gerardo Date: Mon, 29 Jan 2024 17:24:24 +0100 Subject: [PATCH 09/10] Update selectTextFromElement --- .../__device-tests__/helpers/utils.js | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/packages/react-native-editor/__device-tests__/helpers/utils.js b/packages/react-native-editor/__device-tests__/helpers/utils.js index 58040deee6b70..d75ad96e1c1f6 100644 --- a/packages/react-native-editor/__device-tests__/helpers/utils.js +++ b/packages/react-native-editor/__device-tests__/helpers/utils.js @@ -408,11 +408,23 @@ const selectTextFromElement = async ( driver, element ) => { // On iOS we can use the context menu to "Select all" text. await clickBeginningOfElement( driver, element ); - const selectAllElement = await driver.$( - '//XCUIElementTypeMenuItem[@name="Select All"]' - ); - await selectAllElement.waitForDisplayed( { timeout } ); - await selectAllElement.click(); + const selectAllSelector = + '//XCUIElementTypeMenuItem[@name="Select All"]'; + const selectCopySelector = '//XCUIElementTypeMenuItem[@name="Copy"]'; + + // Wait for the context menu to be opened, there are cases where it selects the + // text automatticaly so the context option will be different. + await driver.waitUntil( async function () { + return ( + ( await driver.$( selectAllSelector ).isDisplayed() ) || + ( await driver.$( selectCopySelector ).isDisplayed() ) + ); + } ); + + const selectAllElement = await driver.$$( selectAllSelector ); + if ( selectAllElement.length > 0 ) { + await selectAllElement[ 0 ].click(); + } } }; From 7af4b7d927f0319a31a763e86b49d3862dedd718 Mon Sep 17 00:00:00 2001 From: Gerardo Date: Mon, 29 Jan 2024 18:39:09 +0100 Subject: [PATCH 10/10] Increase timeout --- .../__device-tests__/helpers/utils.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/react-native-editor/__device-tests__/helpers/utils.js b/packages/react-native-editor/__device-tests__/helpers/utils.js index d75ad96e1c1f6..348b11cc71d62 100644 --- a/packages/react-native-editor/__device-tests__/helpers/utils.js +++ b/packages/react-native-editor/__device-tests__/helpers/utils.js @@ -414,12 +414,15 @@ const selectTextFromElement = async ( driver, element ) => { // Wait for the context menu to be opened, there are cases where it selects the // text automatticaly so the context option will be different. - await driver.waitUntil( async function () { - return ( - ( await driver.$( selectAllSelector ).isDisplayed() ) || - ( await driver.$( selectCopySelector ).isDisplayed() ) - ); - } ); + await driver.waitUntil( + async function () { + return ( + ( await driver.$( selectAllSelector ).isDisplayed() ) || + ( await driver.$( selectCopySelector ).isDisplayed() ) + ); + }, + { timeout: 8000 } + ); const selectAllElement = await driver.$$( selectAllSelector ); if ( selectAllElement.length > 0 ) {