diff --git a/scripts/run-ci-e2e-tests.js b/scripts/run-ci-e2e-tests.js index 88b38ba85b96..8baca7f30d3c 100644 --- a/scripts/run-ci-e2e-tests.js +++ b/scripts/run-ci-e2e-tests.js @@ -31,22 +31,13 @@ const ROOT = path.normalize(path.join(__dirname, '..')); const tryExecNTimes = require('./try-n-times'); const TEMP = exec('mktemp -d /tmp/react-native-XXXXXXXX').stdout.trim(); -// To make sure we actually installed the local version -// of react-native, we will create a temp file inside the template -// and check that it exists after `react-native init -const MARKER = exec(`mktemp ${ROOT}/template/XXXXXXXX`).stdout.trim(); const numberOfRetries = argv.retries || 1; let SERVER_PID; let APPIUM_PID; let exitCode; -// Make sure we installed local version of react-native -function checkMarker() { - if (!test('-e', path.basename(MARKER))) { - echo('Marker was not found, react native init command failed?'); - exitCode = 1; - throw Error(exitCode); - } +function describe(message) { + echo(`\n\n>>>>> ${message}\n\n\n`); } try { @@ -81,14 +72,19 @@ try { const PACKAGE = path.join(ROOT, 'react-native-*.tgz'); cd(TEMP); + + echo('Creating EndToEndTest React Native app'); if ( tryExecNTimes( () => { - exec('sleep 10s'); - return exec(`react-native init EndToEndTest --version ${PACKAGE}`).code; + return exec(`react-native init EndToEndTest --version ${PACKAGE} --npm`) + .code; }, numberOfRetries, - () => rm('-rf', 'EndToEndTest'), + () => { + rm('-rf', 'EndToEndTest'); + exec('sleep 10s'); + }, ) ) { echo('Failed to execute react-native init'); @@ -96,12 +92,41 @@ try { exitCode = 1; throw Error(exitCode); } - cd('EndToEndTest'); + echo('Installing React Native package'); + exec(`npm install ${PACKAGE}`); + if ( + tryExecNTimes( + () => { + return exec('npm install --save-dev flow-bin').code; + }, + numberOfRetries, + () => exec('sleep 10s'), + ) + ) { + echo('Failed to install Flow'); + echo('Most common reason is npm registry connectivity, try again'); + exitCode = 1; + throw Error(exitCode); + } + echo('Installing node_modules'); + if ( + tryExecNTimes( + () => { + return exec('npm install').code; + }, + numberOfRetries, + () => exec('sleep 10s'), + ) + ) { + echo('Failed to execute npm install'); + echo('Most common reason is npm registry connectivity, try again'); + exitCode = 1; + throw Error(exitCode); + } if (argv.android) { - echo('Running an Android end-to-end test'); - checkMarker(); + describe('Executing Android end-to-end tests'); echo('Installing end-to-end framework'); if ( tryExecNTimes( @@ -154,12 +179,15 @@ try { SERVER_PID = packagerProcess.pid; // wait a bit to allow packager to startup exec('sleep 15s'); - echo('Executing android end-to-end test'); + describe('Test: Android end-to-end test'); if ( - tryExecNTimes(() => { - exec('sleep 10s'); - return exec('node node_modules/.bin/_mocha android-e2e-test.js').code; - }, numberOfRetries) + tryExecNTimes( + () => { + return exec('node node_modules/.bin/_mocha android-e2e-test.js').code; + }, + numberOfRetries, + () => exec('sleep 10s'), + ) ) { echo('Failed to run Android end-to-end tests'); echo('Most likely the code is broken'); @@ -169,9 +197,8 @@ try { } if (argv.ios || argv.tvos) { - checkMarker(); var iosTestType = argv.tvos ? 'tvOS' : 'iOS'; - echo('Running the ' + iosTestType + ' app'); + describe('Executing ' + iosTestType + ' end-to-end tests'); cd('ios'); // shelljs exec('', {async: true}) does not emit stdout events, so we rely on good old spawn const packagerEnv = Object.create(process.env); @@ -189,45 +216,48 @@ try { echo(`Starting packager server, ${SERVER_PID}`); echo('Running pod install'); exec('pod install'); - echo('Executing ' + iosTestType + ' end-to-end test'); + describe('Test: ' + iosTestType + ' end-to-end test'); if ( - tryExecNTimes(() => { - exec('sleep 10s'); - let destination = 'platform=iOS Simulator,name=iPhone 5s,OS=12.1'; - let sdk = 'iphonesimulator'; - let scheme = 'EndToEndTest'; + tryExecNTimes( + () => { + let destination = 'platform=iOS Simulator,name=iPhone 6s,OS=12.1'; + let sdk = 'iphonesimulator'; + let scheme = 'EndToEndTest'; - if (argv.tvos) { - destination = 'platform=tvOS Simulator,name=Apple TV,OS=11.4'; - sdk = 'appletvsimulator'; - scheme = 'EndToEndTest-tvOS'; - } + if (argv.tvos) { + destination = 'platform=tvOS Simulator,name=Apple TV,OS=11.4'; + sdk = 'appletvsimulator'; + scheme = 'EndToEndTest-tvOS'; + } - return exec( - [ - 'xcodebuild', - '-workspace', - '"EndToEndTest.xcworkspace"', - '-destination', - `"${destination}"`, - '-scheme', - `"${scheme}"`, - '-sdk', - sdk, - '-UseModernBuildSystem=NO', - 'test', - ].join(' ') + - ' | ' + + return exec( [ - 'xcpretty', - '--report', - 'junit', - '--output', - `"~/react-native/reports/junit/${iosTestType}-e2e/results.xml"`, + 'xcodebuild', + '-workspace', + '"EndToEndTest.xcworkspace"', + '-destination', + `"${destination}"`, + '-scheme', + `"${scheme}"`, + '-sdk', + sdk, + '-UseModernBuildSystem=NO', + 'test', ].join(' ') + - ' && exit ${PIPESTATUS[0]}', - ).code; - }, numberOfRetries) + ' | ' + + [ + 'xcpretty', + '--report', + 'junit', + '--output', + `"~/react-native/reports/junit/${iosTestType}-e2e/results.xml"`, + ].join(' ') + + ' && exit ${PIPESTATUS[0]}', + ).code; + }, + numberOfRetries, + () => exec('sleep 10s'), + ) ) { echo('Failed to run ' + iosTestType + ' end-to-end tests'); echo('Most likely the code is broken'); @@ -238,8 +268,9 @@ try { } if (argv.js) { - checkMarker(); + describe('Executing JavaScript end-to-end tests'); // Check the packager produces a bundle (doesn't throw an error) + describe('Test: Verify packager can generate an Android bundle'); if ( exec( 'react-native bundle --max-workers 1 --platform android --dev true --entry-file index.js --bundle-output android-bundle.js', @@ -249,6 +280,7 @@ try { exitCode = 1; throw Error(exitCode); } + describe('Test: Verify packager can generate an iOS bundle'); if ( exec( 'react-native --max-workers 1 bundle --platform ios --dev true --entry-file index.js --bundle-output ios-bundle.js', @@ -258,12 +290,15 @@ try { exitCode = 1; throw Error(exitCode); } + describe('Test: Flow check'); + if (exec('./node_modules/.bin/flow check').code) { + echo('Flow check failed.'); + exitCode = 1; + throw Error(exitCode); + } } exitCode = 0; } finally { - cd(ROOT); - rm(MARKER); - if (SERVER_PID) { echo(`Killing packager ${SERVER_PID}`); exec(`kill -9 ${SERVER_PID}`);