Install local react-native package in e2e (#24381)

Summary:
Following 6df2edeb2a, the template for a new app no longer refers to a specific version of React Native, as the React Native CLI will set the correct version when `react-native init` is run. As it happens, the CLI cannot find a local react-native@1000 version when run as part of the JavaScript e2e tests. Therefore, I am working around using the CLI directly, and instead we're copying the contents of `template/` into a temporary directory for e2e tests. This is not dissimilar to what we already test internally at Facebook.

[General] [Fixed] - Fixed JavaScript e2e tests
Pull Request resolved: https://github.com/facebook/react-native/pull/24381

Differential Revision: D14865627

Pulled By: hramos

fbshipit-source-id: b036da7479200f3efe41b81b6b336333d5558182
This commit is contained in:
Héctor Ramos
2019-04-09 18:43:02 -07:00
committed by Facebook Github Bot
parent 6a3e7991a8
commit 3cc256ebaf

View File

@@ -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}`);