Created
January 9, 2020 22:38
-
-
Save mrk-han/fcc75e73eb73efc15eb518441a998703 to your computer and use it in GitHub Desktop.
Appium Pre-Run Script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
######################################################################## | |
# Goal: Run this script and start automating! | |
# 1) Pull all changes for Appium/iOS/Android repo | |
# 2) Build iOS App then Copy to Appium Repo | |
# 3) Build Android App then Copy to Appium Repo | |
# 4) Allow user to choose emulator, launch emulator, install app | |
######################################################################## | |
CURRENT_DIRECTORY="$(pwd)" | |
PARENT_DIRECTORY="$(cd ../ && pwd)" | |
IOS_DIR="$PARENT_DIRECTORY/iOS-repo-with-app-to-build" | |
ANDROID_DIR="$PARENT_DIRECTORY/android-repo-with-app-to-build" | |
ANDROID_APP="$CURRENT_DIRECTORY/apps/Android.apk" # For installing to emulator. (Appium automatically does this for iOS, so not needed) | |
APPIUM_GIT_OUTPUT=$(git pull 2>&1) | |
IOS_GIT_OUTPUT=$(cd "$IOS_DIR" && git pull 2>&1) | |
ANDROID_GIT_OUTPUT=$(cd "$ANDROID_DIR" && git pull 2>&1) | |
BOOT_ANIMATION="" | |
FAIL_COUNTER=0 | |
SECONDS_UNTIL_TIMEOUT=60 | |
LINE="$(printf %"$(tput cols)"s | tr " " "-")" # https://stackoverflow.com/a/42763333/9470346 | |
ONLY_EMULATOR=false | |
SHOULD_BUILD_FAST=false | |
SHOULD_LAUNCH_EMULATOR=false | |
ONLY_EMULATOR=false | |
AVD_ARGS=" -wipe-data -no-snapshot" # You need a SPACE before the first argument. Find more args to use here: https://developer.android.com/studio/run/emulator-commandline | |
for arg in "$@"; do | |
if [ "$arg" == "--fast" ] || [ "$arg" == "-f" ]; then | |
SHOULD_BUILD_FAST=true | |
fi | |
if [ "$arg" == "--emulator" ] || [ "$arg" == "-e" ]; then | |
SHOULD_LAUNCH_EMULATOR=true | |
fi | |
if [ "$arg" == "--device" ] || [ "$arg" == "-d" ]; then | |
ONLY_EMULATOR=true | |
fi | |
if [ "$arg" == "-fe" ] || [ "$arg" == "-ef" ]; then | |
SHOULD_BUILD_FAST=true | |
SHOULD_LAUNCH_EMULATOR=true | |
fi | |
if [ "$arg" == "--help" ] || [ "$arg" == "-h" ]; then | |
echo -e "\n${LINE}" | |
echo "Welcome to the help menu for build.sh" | |
echo "${LINE}" | |
echo -e "\n-f or --fast will pull changes and build the Appium, iOS and Android repos" | |
echo -e "Usage: build.sh -f OR build.sh --fast" | |
echo -e "\n${LINE}" | |
echo -e "\n-e or --emulator will also prompt you for an emulator at the end of script if ran with --fast command" | |
echo -e "Usage: build.sh -e OR build.sh --emulator" | |
echo -e "\n${LINE}" | |
echo -e "\nUse -ef, -fe, or --fast --emulator to use the arguments together" | |
echo -e "Usage: build.sh -fe OR build.sh -ef" | |
echo -e "\n${LINE}" | |
echo -e "\nUse -d, or --device to skip everything except for the request to launch an emulator" | |
echo -e "This will make it easy to copy the built APK onto a new emulator to test" | |
echo -e "Usage: build.sh -d OR build.sh --device" | |
exit 1 | |
fi | |
done | |
function pullAppiumRepo() { | |
branch=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p') # https://stackoverflow.com/a/2111099/9470346 | |
echo -e "\n${LINE}" | |
echo -e "\nPulling Latest Appium Changes... Current Branch: ${branch}" | |
echo -e "\n${LINE}" | |
if [[ ${APPIUM_GIT_OUTPUT} =~ "fatal" ]]; then | |
echo -e "\n${APPIUM_GIT_OUTPUT}" | |
echo -e "\n Make sure you are on the VPN or check your internet connection." | |
echo -e "\n Exiting Script..." | |
exit 1 | |
else | |
echo "${APPIUM_GIT_OUTPUT}" | |
fi | |
} | |
function requestToPullAppiumRepo() { | |
read -rp "${LINE} | |
Pull Latest Appium Changes? 1=YES , 2=NO | |
${LINE} | |
-> " answerAppium | |
if [[ ${answerAppium} -eq 1 ]]; then | |
pullAppiumRepo | |
fi | |
} | |
function cdIntoIosRepoAndPrintBranchInformation() { | |
cd "$IOS_DIR" || exit | |
branch=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p') # https://stackoverflow.com/a/2111099/9470346 | |
echo -e "\n${LINE}" | |
echo -e "\nPulling Latest IOS Changes... Current Branch: ${branch}" | |
echo -e "\n${LINE}" | |
} | |
function requestToHardResetIos() { | |
read -rp " | |
Before pulling changes, do you want to erase all uncommitted files in $IOS_DIR? 1=YES , 2=NO | |
${LINE} | |
-> " answerIosHardReset | |
if [[ ${answerIosHardReset} -eq 1 ]]; then | |
echo "${LINE}" | |
echo "git reset --hard HEAD" | |
echo "${LINE}" | |
git reset --hard HEAD | |
fi | |
} | |
function pullIosChanges() { | |
if [[ ${IOS_GIT_OUTPUT} =~ "fatal" ]]; then | |
echo -e "\n${IOS_GIT_OUTPUT}" | |
echo -e "\n Make sure you are on the VPN or check your internet connection." | |
echo -e "\n Exiting Script..." | |
exit 1 | |
else | |
echo "${IOS_GIT_OUTPUT}" | |
fi | |
} | |
function buildThenCopyIosApp() { | |
make clean | |
make build | |
echo -e "\nRemoving old *.app from apps/IOS/ folder." | |
rm -r "${CURRENT_DIRECTORY}"/apps/IOS/*.app | |
./copy_app.sh "$CURRENT_DIRECTORY" | |
} | |
function requestToBuildIos() { | |
read -rp "${LINE} | |
Build iOS? 1=YES , 2=NO | |
${LINE} | |
-> " answerIos | |
if [[ ${answerIos} -eq 1 ]]; then | |
cdIntoIosRepoAndPrintBranchInformation | |
requestToHardResetIos | |
pullIosChanges | |
buildThenCopyIosApp | |
fi | |
} | |
function cdIntoAndroidRepoAndPrintBranchInformation() { | |
cd "$ANDROID_DIR" || exit | |
branch=$(git branch | sed -n -e 's/^\* \(.*\)/\1/p') # https://stackoverflow.com/a/2111099/9470346 | |
echo -e "\n${LINE}" | |
echo -e "\nPulling Latest Android Changes... Current Branch: ${branch}" | |
echo -e "\n${LINE}" | |
} | |
function requestToHardResetAndroid() { | |
read -rp "${LINE} | |
Before pulling changes, do you want to erase all uncommitted files in $ANDROID_DIR? 1=YES , 2=NO | |
${LINE} | |
-> " answerAndroidHardReset | |
if [[ ${answerAndroidHardReset} -eq 1 ]]; then | |
echo "${LINE}" | |
echo "git reset --hard HEAD" | |
echo "${LINE}" | |
git reset --hard HEAD | |
fi | |
} | |
function pullAndroidChanges() { | |
if [[ ${ANDROID_GIT_OUTPUT} =~ "fatal" ]]; then | |
echo -e "\n${ANDROID_GIT_OUTPUT}" | |
echo -e "\n Make sure you are on the VPN or check your internet connection." | |
echo -e "\n Exiting Script..." | |
exit 1 | |
else | |
echo "${ANDROID_GIT_OUTPUT}" | |
fi | |
} | |
function buildThenCopyAndroidApk() { | |
echo -e "\nRunning ./gradlew clean assembleQaAutomation" | |
#./gradlew clean assembleQaAutomation || exit | |
if ./gradlew clean assembleQaAutomation; then | |
echo -e "\nGradle task succeeded" >&2 | |
echo "${LINE}" | |
else | |
echo -e "\nGradle task failed! Exiting script..." >&2 | |
exit 1 | |
fi | |
echo -e "\nRemoving old *.apk from apps/ folder." | |
echo "${LINE}" | |
rm "${CURRENT_DIRECTORY}"/apps/*.apk | |
# Copy Apk to Intellij from Android Studio | |
echo -e "\nCopying APK from Android Studio to IntelliJ..." | |
cp ./app/build/outputs/apk/qa/automation/*.apk "$ANDROID_APP" | |
} | |
function waitForEmulatorToStart() { | |
until [[ "$BOOT_ANIMATION" =~ "stopped" ]]; do | |
BOOT_ANIMATION=$(adb -e shell getprop init.svc.bootanim 2>&1 &) # Checks state of emulator while in the boot animation | |
if [[ "$BOOT_ANIMATION" =~ "device not found" || "$BOOT_ANIMATION" =~ "device offline" || "$BOOT_ANIMATION" =~ "running" ]]; then | |
((FAIL_COUNTER += 1)) | |
echo -e "\nWaiting for emulator to start.. $FAIL_COUNTER" | |
echo "Boot Animation State: $BOOT_ANIMATION" | |
if [[ ${FAIL_COUNTER} -gt ${SECONDS_UNTIL_TIMEOUT} ]]; then | |
echo -e "\nTimeout of $SECONDS_UNTIL_TIMEOUT seconds reached; failed to start emulator" | |
exit 1 | |
fi | |
fi | |
sleep 1 | |
done | |
echo -e "\n${LINE}" | |
echo -e "\nEmulator is ready!" | |
} | |
function waitForBootAnimationThenInstall() { | |
# After the boot animation stops, and while the emulator is starting up there can be an error, so we attempt to install until there isn't this error. | |
ADB_INSTALL_OUTPUT=$(adb install -r "${ANDROID_APP}" 2>&1) | |
regex="Can't find service" | |
until ! [[ "${ADB_INSTALL_OUTPUT}" =~ $regex ]]; do | |
echo "" | |
ADB_INSTALL_OUTPUT=$(adb install -r "${ANDROID_APP}" 2>&1) | |
echo -e "\nRetrying..." | |
echo -e "\n${ADB_INSTALL_OUTPUT}" | |
sleep 2 | |
done | |
} | |
function selectAndLaunchEmulator() { | |
# Check if the emulator command exists on path first | |
if ! type emulator >/dev/null; then # >/dev/null hides stdout message. | |
echo "emulator command not found, make sure \"export PATH=\$PATH:\$ANDROID_HOME/emulator\" is in your Bash Profile and the Android SDK Tools are installed" | |
exit 1 | |
fi | |
if ! type mapfile >/dev/null; then | |
echo "${LINE}" | |
echo "mapfile command not found, this is usually because your bash version is outdated. please run: \"brew install bash\"" | |
echo "${LINE}" | |
exit 1 | |
fi | |
# Gather emulators that exist on this computer | |
# DEVICES=( $(emulator -list-avds 2>&1) ) # 2>&1 reroutes stderr message to same output value as stdout(&1) | |
mapfile -t DEVICES < <(emulator -list-avds 2>&1) | |
# Display list of emulators | |
echo -e "\nAvailable Emulators | |
----------------------------------------" | |
N=1 | |
for DEVICE in "${DEVICES[@]}"; do # Create DEVICES Array and use [@] to allow us to iterate through it | |
echo "$N) $DEVICE" # Iterate through Emulators and display their name next to a number which will be how the user selects the emulator | |
((N = N + 1)) | |
done | |
# Request user input to decide which emulator to start | |
read -rp " | |
Choose an emulator by entering a number: " emulatorNumber | |
# If the input is valid, launch our emulator | |
if [[ ${emulatorNumber} -lt ${N} ]] && [[ ${emulatorNumber} -gt 0 ]]; then | |
DEVICE=${DEVICES[$emulatorNumber - 1]} | |
# shellcheck disable=SC2086 | |
(emulator @${DEVICE}${AVD_ARGS} >/dev/null 2>&1 &) | |
else | |
echo "Invalid Entry. Please enter the number next to the Emulator name. You entered: $emulatorNumber" | |
fi | |
} | |
function launchEmulatorAndInstallApk() { | |
selectAndLaunchEmulator | |
waitForEmulatorToStart | |
waitForBootAnimationThenInstall | |
} | |
function printHelpfulInfoEmulator() { | |
echo "${LINE}" | |
echo -e "\nInstalled $ANDROID_APP to $DEVICE with arguments:$AVD_ARGS" | |
echo "${LINE}" | |
echo -e "\nRemember to:" | |
echo -e "\n Start an appium server: (appium -a 127.0.0.1 -p 4723 from command line, or use appium desktop)" | |
echo -e "\n Start a local wiremock server (./gradlew run from command line, or run the Standalone class from Intellij in Wiremock Repo)" | |
echo -e "\n Adjust your config.yaml and set your schemes" | |
echo -e "\nAnd then you'll be ready to automate! (Appium will start your simulator automatically when you run a test)" | |
echo "${LINE}" | |
} | |
function printHelpfulInfoNoEmulator() { | |
echo "${LINE}" | |
echo -e "\nRemember to:" | |
echo -e "\n Start an emulator (Appium will start your simulator automatically when you run a test)" | |
echo -e "\n Start an appium server: (appium -a 127.0.0.1 -p 4723 or use appium desktop)" | |
echo -e "\n Start a local wiremock server (./gradlew run from command line, or run the Standalone class from Intellij in Wiremock Repo)" | |
echo -e "\n Adjust your config.yaml and set your schemes" | |
echo -e "\nAnd then you'll be ready to automate!" | |
echo "${LINE}" | |
} | |
function requestToLaunchEmulator() { | |
read -rp "${LINE} | |
Would you like to launch an emulator? 1=YES , 2=NO | |
${LINE} | |
-> " answerLaunchEmulator | |
if [[ ${answerLaunchEmulator} -eq 1 ]]; then | |
launchEmulatorAndInstallApk | |
printHelpfulInfoEmulator | |
else | |
printHelpfulInfoNoEmulator | |
fi | |
} | |
function requestToBuildAndroid() { | |
read -rp "${LINE} | |
Build Android? 1=YES , 2=NO | |
${LINE} | |
-> " answerAndroidBuild | |
if [[ ${answerAndroidBuild} -eq 1 ]]; then | |
cdIntoAndroidRepoAndPrintBranchInformation | |
requestToHardResetAndroid | |
pullAndroidChanges | |
buildThenCopyAndroidApk | |
requestToLaunchEmulator | |
fi | |
} | |
function main() { | |
if [[ "$ONLY_EMULATOR" == "true" ]]; then | |
echo "Argument -d or --device found! Only requesting to start device... " | |
requestToLaunchEmulator | |
echo "Argument -d or --device found! Do not pass this in if you want to run the normal build script. EXITING... " | |
exit 1 | |
fi | |
if [[ "$SHOULD_BUILD_FAST" == "true" ]]; then | |
pullAppiumRepo | |
cdIntoIosRepoAndPrintBranchInformation | |
pullIosChanges | |
buildThenCopyIosApp | |
cdIntoAndroidRepoAndPrintBranchInformation | |
pullAndroidChanges | |
buildThenCopyAndroidApk | |
if [[ "$SHOULD_LAUNCH_EMULATOR" == "true" ]]; then | |
requestToLaunchEmulator | |
fi | |
else | |
requestToPullAppiumRepo | |
requestToBuildIos | |
requestToBuildAndroid | |
fi | |
} | |
########################### | |
### ENTRY POINT | |
########################### | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment