1#!/bin/bash 2# Copyright (c) Meta Platforms, Inc. and affiliates. 3# 4# This source code is licensed under the MIT license found in the 5# LICENSE file in the root directory of this source tree. 6 7# Script used to run iOS tests. 8# If no arguments are passed to the script, it will only compile 9# the RNTester. 10# If the script is called with a single argument "test", we'll 11# run the RNTester unit and integration tests 12# ./objc-test.sh test 13 14SCRIPTS=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) 15ROOT=$(dirname "$SCRIPTS") 16 17SKIPPED_TESTS=() 18SKIPPED_TESTS+=("-skip-testing:RNTesterIntegrationTests/RNTesterSnapshotTests") 19# TODO: T60408036 This test crashes iOS 13 for bad access, please investigate 20# and re-enable. See https://gist.github.com/0xced/56035d2f57254cf518b5. 21SKIPPED_TESTS+=("-skip-testing:RNTesterUnitTests/RCTJSONTests/testNotUTF8Convertible") 22 23# Create cleanup handler 24cleanup() { 25 EXIT=$? 26 set +e 27 28 if [ $EXIT -ne 0 ]; 29 then 30 WATCHMAN_LOGS=/usr/local/Cellar/watchman/3.1/var/run/watchman/$USER.log 31 [ -f "$WATCHMAN_LOGS" ] && cat "$WATCHMAN_LOGS" 32 fi 33 # kill whatever is occupying port 8081 (packager) 34 lsof -i tcp:8081 | awk 'NR!=1 {print $2}' | xargs kill 35 # kill whatever is occupying port 5555 (web socket server) 36 lsof -i tcp:5555 | awk 'NR!=1 {print $2}' | xargs kill 37} 38 39# Wait for the package to start 40waitForPackager() { 41 local -i max_attempts=60 42 local -i attempt_num=1 43 44 until curl -s http://localhost:8081/status | grep "packager-status:running" -q; do 45 if (( attempt_num == max_attempts )); then 46 echo "Packager did not respond in time. No more attempts left." 47 exit 1 48 else 49 (( attempt_num++ )) 50 echo "Packager did not respond. Retrying for attempt number $attempt_num..." 51 sleep 1 52 fi 53 done 54 55 echo "Packager is ready!" 56} 57 58waitForWebSocketServer() { 59 local -i max_attempts=60 60 local -i attempt_num=1 61 62 until curl -s http://localhost:5555 | grep "Upgrade Required" -q; do 63 if (( attempt_num == max_attempts )); then 64 echo "WebSocket Server did not respond in time. No more attempts left." 65 exit 1 66 else 67 (( attempt_num++ )) 68 echo "WebSocket Server did not respond. Retrying for attempt number $attempt_num..." 69 sleep 1 70 fi 71 done 72 73 echo "WebSocket Server is ready!" 74} 75 76runTests() { 77 # shellcheck disable=SC1091 78 source "./scripts/.tests.env" 79 xcodebuild build test \ 80 -workspace packages/rn-tester/RNTesterPods.xcworkspace \ 81 -scheme RNTester \ 82 -sdk iphonesimulator \ 83 -destination "platform=iOS Simulator,name=$IOS_DEVICE,OS=$IOS_TARGET_OS" \ 84 "${SKIPPED_TESTS[@]}" 85} 86 87buildProject() { 88 xcodebuild build \ 89 -workspace packages/rn-tester/RNTesterPods.xcworkspace \ 90 -scheme RNTester \ 91 -sdk iphonesimulator 92} 93 94xcprettyFormat() { 95 if [ "$CI" ]; then 96 # Circle CI expects JUnit reports to be available here 97 REPORTS_DIR="$HOME/react-native/reports/junit" 98 else 99 THIS_DIR=$(cd -P "$(dirname "$(realpath "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd) 100 101 # Write reports to the react-native root dir 102 REPORTS_DIR="$THIS_DIR/../build/reports" 103 fi 104 105 xcpretty --report junit --output "$REPORTS_DIR/ios/results.xml" 106} 107 108preloadBundles() { 109 # Preload the RNTesterApp bundle for better performance in integration tests 110 curl -s 'http://localhost:8081/packages/rn-tester/js/RNTesterApp.ios.bundle?platform=ios&dev=true' -o /dev/null 111 curl -s 'http://localhost:8081/packages/rn-tester/js/RNTesterApp.ios.bundle?platform=ios&dev=true&minify=false' -o /dev/null 112 curl -s 'http://localhost:8081/IntegrationTests/IntegrationTestsApp.bundle?platform=ios&dev=true' -o /dev/null 113 curl -s 'http://localhost:8081/IntegrationTests/RCTRootViewIntegrationTestApp.bundle?platform=ios&dev=true' -o /dev/null 114} 115 116main() { 117 cd "$ROOT" || exit 118 119 # If first argument is "test", actually start the packager and run tests. 120 # Otherwise, just build RNTester and exit 121 if [ "$1" = "test" ]; then 122 123 # Start the WebSocket test server 124 echo "Launch WebSocket Server" 125 sh "./IntegrationTests/launchWebSocketServer.sh" & 126 waitForWebSocketServer 127 128 # Start the packager 129 yarn start --max-workers=1 || echo "Can't start packager automatically" & 130 waitForPackager 131 preloadBundles 132 133 # Build and run tests. 134 if [ -x "$(command -v xcpretty)" ]; then 135 runTests | xcprettyFormat && exit "${PIPESTATUS[0]}" 136 else 137 echo 'Warning: xcpretty is not installed. Install xcpretty to generate JUnit reports.' 138 runTests 139 fi 140 else 141 # Build without running tests. 142 if [ -x "$(command -v xcpretty)" ]; then 143 buildProject | xcprettyFormat && exit "${PIPESTATUS[0]}" 144 else 145 buildProject 146 fi 147 fi 148} 149 150trap cleanup EXIT 151main "$@" 152