mirror of
https://github.com/status-im/react-native.git
synced 2025-01-10 09:35:48 +00:00
e315ec9891
Summary:
We opt in to version ^5 of the React Native Babel Preset, as required after the bump to Babel 7. This fixes the Objective-C end-to-end test failure in master. (Fixes #19538)
See 34bd776af2 (commitcomment-29024085)
for prior discussion.
There have already been several changes made to the repo during the transition to Babel 7. This PR brings all tests back to green and allows us to move forward with the 0.56 branch cut.
We also bump our tests to use Xcode 9.4.0 and iOS 11.4, the latest stable versions of both.
Once the 0.56 branch makes it to stable, we can change `react-native-babel-preset@latest` on npm to point to `react-native-babel-preset@5.0.1` (or newer), and undo the change made to `init.js` we made as part of this diff.
Wait for Circle CI to run: https://circleci.com/workflow-run/e39a66d7-bf8a-4b31-a22f-eef30a2c53bc
[GENERAL] [BREAKING] [Babel] - Bump React Native Babel Preset version used by RN CLI to Babel v7 compliant release
Closes https://github.com/facebook/react-native/pull/19625
Reviewed By: TheSavior
Differential Revision: D8343861
Pulled By: hramos
fbshipit-source-id: 42644d5b0bfb40a8bc592ae3461c5008deef8232
293 lines
9.0 KiB
JavaScript
293 lines
9.0 KiB
JavaScript
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @format
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* This script tests that React Native end to end installation/bootstrap works for different platforms
|
|
* Available arguments:
|
|
* --ios - 'react-native init' and check iOS app doesn't redbox
|
|
* --tvos - 'react-native init' and check tvOS app doesn't redbox
|
|
* --android - 'react-native init' and check Android app doesn't redbox
|
|
* --js - 'react-native init' and only check the packager returns a bundle
|
|
* --skip-cli-install - to skip react-native-cli global installation (for local debugging)
|
|
* --retries [num] - how many times to retry possible flaky commands: yarn add and running tests, default 1
|
|
*/
|
|
/*eslint-disable no-undef */
|
|
require('shelljs/global');
|
|
|
|
const spawn = require('child_process').spawn;
|
|
const argv = require('yargs').argv;
|
|
const path = require('path');
|
|
|
|
const SCRIPTS = __dirname;
|
|
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_IOS = exec(
|
|
`mktemp ${ROOT}/local-cli/templates/HelloWorld/ios/HelloWorld/XXXXXXXX`,
|
|
).stdout.trim();
|
|
const MARKER_ANDROID = exec(
|
|
`mktemp ${ROOT}/local-cli/templates/HelloWorld/android/XXXXXXXX`,
|
|
).stdout.trim();
|
|
const numberOfRetries = argv.retries || 1;
|
|
let SERVER_PID;
|
|
let APPIUM_PID;
|
|
let exitCode;
|
|
|
|
try {
|
|
// install CLI
|
|
cd('react-native-cli');
|
|
exec('yarn pack');
|
|
const CLI_PACKAGE = path.join(
|
|
ROOT,
|
|
'react-native-cli',
|
|
'react-native-cli-*.tgz',
|
|
);
|
|
cd('..');
|
|
|
|
if (!argv['skip-cli-install']) {
|
|
if (exec(`sudo yarn global add ${CLI_PACKAGE}`).code) {
|
|
echo('Could not install react-native-cli globally.');
|
|
echo('Run with --skip-cli-install to skip this step');
|
|
exitCode = 1;
|
|
throw Error(exitCode);
|
|
}
|
|
}
|
|
|
|
if (argv.android) {
|
|
if (
|
|
exec(
|
|
'./gradlew :ReactAndroid:installArchives -Pjobs=1 -Dorg.gradle.jvmargs="-Xmx512m -XX:+HeapDumpOnOutOfMemoryError"',
|
|
).code
|
|
) {
|
|
echo('Failed to compile Android binaries');
|
|
exitCode = 1;
|
|
throw Error(exitCode);
|
|
}
|
|
}
|
|
|
|
if (exec('yarn pack').code) {
|
|
echo('Failed to pack react-native');
|
|
exitCode = 1;
|
|
throw Error(exitCode);
|
|
}
|
|
|
|
const PACKAGE = path.join(ROOT, 'react-native-*.tgz');
|
|
cd(TEMP);
|
|
if (
|
|
tryExecNTimes(
|
|
() => {
|
|
exec('sleep 10s');
|
|
return exec(`react-native init EndToEndTest --version ${PACKAGE}`).code;
|
|
},
|
|
numberOfRetries,
|
|
() => rm('-rf', 'EndToEndTest'),
|
|
)
|
|
) {
|
|
echo('Failed to execute react-native init');
|
|
echo('Most common reason is npm registry connectivity, try again');
|
|
exitCode = 1;
|
|
throw Error(exitCode);
|
|
}
|
|
|
|
cd('EndToEndTest');
|
|
|
|
if (argv.android) {
|
|
echo('Running an Android end-to-end test');
|
|
echo('Installing end-to-end framework');
|
|
if (
|
|
tryExecNTimes(
|
|
() =>
|
|
exec(
|
|
'yarn add --dev appium@1.5.1 mocha@2.4.5 wd@0.3.11 colors@1.0.3 pretty-data2@0.40.1',
|
|
{silent: true},
|
|
).code,
|
|
numberOfRetries,
|
|
)
|
|
) {
|
|
echo('Failed to install appium');
|
|
echo('Most common reason is npm registry connectivity, try again');
|
|
exitCode = 1;
|
|
throw Error(exitCode);
|
|
}
|
|
cp(`${SCRIPTS}/android-e2e-test.js`, 'android-e2e-test.js');
|
|
cd('android');
|
|
echo('Downloading Maven deps');
|
|
exec('./gradlew :app:copyDownloadableDepsToLibs');
|
|
// Make sure we installed local version of react-native
|
|
if (!test('-e', path.basename(MARKER_ANDROID))) {
|
|
echo('Android marker was not found, react native init command failed?');
|
|
exitCode = 1;
|
|
throw Error(exitCode);
|
|
}
|
|
cd('..');
|
|
exec(
|
|
'keytool -genkey -v -keystore android/keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"',
|
|
);
|
|
|
|
echo(`Starting appium server, ${APPIUM_PID}`);
|
|
const appiumProcess = spawn('node', ['./node_modules/.bin/appium']);
|
|
APPIUM_PID = appiumProcess.pid;
|
|
|
|
echo('Building the app');
|
|
if (exec('buck build android/app').code) {
|
|
echo('could not execute Buck build, is it installed and in PATH?');
|
|
exitCode = 1;
|
|
throw Error(exitCode);
|
|
}
|
|
|
|
echo(`Starting packager server, ${SERVER_PID}`);
|
|
// shelljs exec('', {async: true}) does not emit stdout events, so we rely on good old spawn
|
|
const packagerProcess = spawn('yarn', ['start', '--max-workers 1'], {
|
|
env: process.env,
|
|
});
|
|
SERVER_PID = packagerProcess.pid;
|
|
// wait a bit to allow packager to startup
|
|
exec('sleep 15s');
|
|
echo('Executing android end-to-end test');
|
|
if (
|
|
tryExecNTimes(() => {
|
|
exec('sleep 10s');
|
|
return exec('node node_modules/.bin/_mocha android-e2e-test.js').code;
|
|
}, numberOfRetries)
|
|
) {
|
|
echo('Failed to run Android end-to-end tests');
|
|
echo('Most likely the code is broken');
|
|
exitCode = 1;
|
|
throw Error(exitCode);
|
|
}
|
|
}
|
|
|
|
if (argv.ios || argv.tvos) {
|
|
var iosTestType = argv.tvos ? 'tvOS' : 'iOS';
|
|
echo('Running the ' + iosTestType + ' app');
|
|
cd('ios');
|
|
// Make sure we installed local version of react-native
|
|
if (!test('-e', path.join('EndToEndTest', path.basename(MARKER_IOS)))) {
|
|
echo('iOS marker was not found, `react-native init` command failed?');
|
|
exitCode = 1;
|
|
throw Error(exitCode);
|
|
}
|
|
// shelljs exec('', {async: true}) does not emit stdout events, so we rely on good old spawn
|
|
const packagerEnv = Object.create(process.env);
|
|
packagerEnv.REACT_NATIVE_MAX_WORKERS = 1;
|
|
const packagerProcess = spawn('yarn', ['start', '--nonPersistent'], {
|
|
stdio: 'inherit',
|
|
env: packagerEnv,
|
|
});
|
|
SERVER_PID = packagerProcess.pid;
|
|
exec('sleep 15s');
|
|
// prepare cache to reduce chances of possible red screen "Can't fibd variable __fbBatchedBridge..."
|
|
exec(
|
|
'response=$(curl --write-out %{http_code} --silent --output /dev/null localhost:8081/index.bundle?platform=ios&dev=true)',
|
|
);
|
|
echo(`Starting packager server, ${SERVER_PID}`);
|
|
echo('Executing ' + iosTestType + ' end-to-end test');
|
|
if (
|
|
tryExecNTimes(() => {
|
|
exec('sleep 10s');
|
|
let destination = 'platform=iOS Simulator,name=iPhone 5s,OS=11.4';
|
|
let sdk = 'iphonesimulator';
|
|
let scheme = 'EndToEndTest';
|
|
|
|
if (argv.tvos) {
|
|
destination = 'platform=tvOS Simulator,name=Apple TV,OS=11.4';
|
|
sdk = 'appletvsimulator';
|
|
scheme = 'EndToEndTest-tvOS';
|
|
}
|
|
|
|
return exec(
|
|
[
|
|
'xcodebuild',
|
|
'-destination',
|
|
`"${destination}"`,
|
|
'-scheme',
|
|
`"${scheme}"`,
|
|
'-sdk',
|
|
sdk,
|
|
'test',
|
|
].join(' ') +
|
|
' | ' +
|
|
[
|
|
'xcpretty',
|
|
'--report',
|
|
'junit',
|
|
'--output',
|
|
`"~/react-native/reports/junit/${iosTestType}-e2e/results.xml"`,
|
|
].join(' ') +
|
|
' && exit ${PIPESTATUS[0]}',
|
|
).code;
|
|
}, numberOfRetries)
|
|
) {
|
|
echo('Failed to run ' + iosTestType + ' end-to-end tests');
|
|
echo('Most likely the code is broken');
|
|
exitCode = 1;
|
|
throw Error(exitCode);
|
|
}
|
|
cd('..');
|
|
}
|
|
|
|
if (argv.js) {
|
|
// Check the packager produces a bundle (doesn't throw an error)
|
|
if (
|
|
exec(
|
|
'react-native bundle --max-workers 1 --platform android --dev true --entry-file index.js --bundle-output android-bundle.js',
|
|
).code
|
|
) {
|
|
echo('Could not build Android bundle');
|
|
exitCode = 1;
|
|
throw Error(exitCode);
|
|
}
|
|
if (
|
|
exec(
|
|
'react-native --max-workers 1 bundle --platform ios --dev true --entry-file index.js --bundle-output ios-bundle.js',
|
|
).code
|
|
) {
|
|
echo('Could not build iOS bundle');
|
|
exitCode = 1;
|
|
throw Error(exitCode);
|
|
}
|
|
if (exec(`${ROOT}/node_modules/.bin/flow check`).code) {
|
|
echo('Flow check does not pass');
|
|
exitCode = 1;
|
|
throw Error(exitCode);
|
|
}
|
|
if (exec('yarn test').code) {
|
|
echo('Jest test failure');
|
|
exitCode = 1;
|
|
throw Error(exitCode);
|
|
}
|
|
}
|
|
exitCode = 0;
|
|
} finally {
|
|
cd(ROOT);
|
|
rm(MARKER_IOS);
|
|
rm(MARKER_ANDROID);
|
|
|
|
if (SERVER_PID) {
|
|
echo(`Killing packager ${SERVER_PID}`);
|
|
exec(`kill -9 ${SERVER_PID}`);
|
|
// this is quite drastic but packager starts a daemon that we can't kill by killing the parent process
|
|
// it will be fixed in April (quote David Aurelio), so until then we will kill the zombie by the port number
|
|
exec("lsof -i tcp:8081 | awk 'NR!=1 {print $2}' | xargs kill");
|
|
}
|
|
if (APPIUM_PID) {
|
|
echo(`Killing appium ${APPIUM_PID}`);
|
|
exec(`kill -9 ${APPIUM_PID}`);
|
|
}
|
|
}
|
|
exit(exitCode);
|
|
|
|
/*eslint-enable no-undef */
|