Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 97 additions & 62 deletions scripts/run-ci-e2e-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -81,27 +72,61 @@ 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');
echo('Most common reason is npm registry connectivity, try again');
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(
Expand Down Expand Up @@ -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');
Expand All @@ -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);
Expand All @@ -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');
Expand All @@ -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',
Expand All @@ -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',
Expand All @@ -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}`);
Expand Down