From 953889da511013361dedd754e72ccbb843c908a2 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Fri, 20 Dec 2024 06:19:17 -0800 Subject: [PATCH] Stabilize Android tests adding retries for failed tests (#48324) Summary: Sometimes, specific E2E tests can fail. This change tries to run specific E2E tests with retries, to compensate for their flakyness. ## Changelog: [Internal] - Add single test retry for Android E2E tests Pull Request resolved: https://github.com/facebook/react-native/pull/48324 Test Plan: GHA Reviewed By: huntie Differential Revision: D67396758 Pulled By: cipolleschi fbshipit-source-id: 7d806fe7354bd9e826c591ea9628c73c3b258fce --- .github/workflow-scripts/maestro-android.js | 45 +++++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/.github/workflow-scripts/maestro-android.js b/.github/workflow-scripts/maestro-android.js index 8e30b75d9e3..8feee95c6c4 100644 --- a/.github/workflow-scripts/maestro-android.js +++ b/.github/workflow-scripts/maestro-android.js @@ -8,6 +8,7 @@ */ const childProcess = require('child_process'); +const fs = require('fs'); const usage = ` === Usage === @@ -33,6 +34,37 @@ const MAESTRO_FLOW = args[2]; const IS_DEBUG = args[3] === 'debug'; const WORKING_DIRECTORY = args[4]; +const MAX_ATTEMPTS = 3; + +async function executeFlowWithRetries(flow, currentAttempt) { + try { + console.info(`Executing flow: ${flow}`); + childProcess.execSync( + `MAESTRO_DRIVER_STARTUP_TIMEOUT=120000 $HOME/.maestro/bin/maestro test ${flow} --format junit -e APP_ID=${APP_ID} --debug-output /tmp/MaestroLogs`, + {stdio: 'inherit'}, + ); + } catch (err) { + if (currentAttempt < MAX_ATTEMPTS) { + console.info(`Retrying...`); + await executeFlowWithRetries(flow, currentAttempt + 1); + } else { + throw err; + } + } +} + +async function executeFlowInFolder(flowFolder) { + const files = fs.readdirSync(flowFolder); + for (const file of files) { + const filePath = `${flowFolder}/${file}`; + if (fs.lstatSync(filePath).isDirectory()) { + await executeFlowInFolder(filePath); + } else { + await executeFlowWithRetries(filePath, 0); + } + } +} + async function main() { console.info('\n=============================='); console.info('Running tests for Android with the following parameters:'); @@ -81,10 +113,15 @@ async function main() { console.info(`Start testing ${MAESTRO_FLOW}`); let error = null; try { - childProcess.execSync( - `MAESTRO_DRIVER_STARTUP_TIMEOUT=120000 $HOME/.maestro/bin/maestro test ${MAESTRO_FLOW} --format junit -e APP_ID=${APP_ID} --debug-output /tmp/MaestroLogs`, - {stdio: 'inherit'}, - ); + //check if MAESTRO_FLOW is a folder + if ( + fs.existsSync(MAESTRO_FLOW) && + fs.lstatSync(MAESTRO_FLOW).isDirectory() + ) { + await executeFlowInFolder(MAESTRO_FLOW); + } else { + await executeFlowWithRetries(MAESTRO_FLOW, 0); + } } catch (err) { error = err; } finally {