Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
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
362 changes: 203 additions & 159 deletions .github/workflows/test-scripts.yml

Large diffs are not rendered by default.

87 changes: 71 additions & 16 deletions mac/common-utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,25 @@ handle_app_upload() {
log_msg_to "Exported APP_PLATFORM=$APP_PLATFORM"
else
local choice
choice=$(osascript -e '
display dialog "How would you like to select your app?" ¬
with title "BrowserStack App Upload" ¬
with icon note ¬
buttons {"Use Sample App", "Upload my App (.apk/.ipa)", "Cancel"} ¬
default button "Upload my App (.apk/.ipa)"
' 2>/dev/null)
if [[ "$NOW_OS" == "macos" ]]; then
choice=$(osascript -e '
display dialog "How would you like to select your app?" ¬
with title "BrowserStack App Upload" ¬
with icon note ¬
buttons {"Use Sample App", "Upload my App (.apk/.ipa)", "Cancel"} ¬
default button "Upload my App (.apk/.ipa)"
' 2>/dev/null)
else
echo "How would you like to select your app?"
select opt in "Use Sample App" "Upload my App (.apk/.ipa)" "Cancel"; do
case $opt in
"Use Sample App") choice="Use Sample App"; break ;;
"Upload my App (.apk/.ipa)") choice="Upload my App"; break ;;
"Cancel") choice="Cancel"; break ;;
*) echo "Invalid option";;
esac
done
fi

if [[ "$choice" == *"Use Sample App"* ]]; then
upload_sample_app
Expand Down Expand Up @@ -135,9 +147,18 @@ upload_custom_app() {
local file_path

# Convert to POSIX path
file_path=$(osascript -e \
'POSIX path of (choose file with prompt "Select your .apk or .ipa file:" of type {"apk", "ipa"})' \
2>/dev/null)
# Convert to POSIX path
if [[ "$NOW_OS" == "macos" ]]; then
file_path=$(osascript -e \
'POSIX path of (choose file with prompt "Select your .apk or .ipa file:" of type {"apk", "ipa"})' \
2>/dev/null)
else
echo "Please enter the full path to your .apk or .ipa file:"
read -r file_path
# Remove quotes if user added them
file_path="${file_path%\"}"
file_path="${file_path#\"}"
fi

# Trim whitespace
file_path="${file_path%"${file_path##*[![:space:]]}"}"
Expand Down Expand Up @@ -210,7 +231,7 @@ fetch_plan_details() {
local web_unauthorized=false
local mobile_unauthorized=false

if [[ "$test_type" == "web" || "$test_type" == "both" ]]; then
if [[ "$test_type" == "web" ]]; then
RESPONSE_WEB=$(curl -s -w "\n%{http_code}" -u "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" https://api.browserstack.com/automate/plan.json)
HTTP_CODE_WEB=$(echo "$RESPONSE_WEB" | tail -n1)
RESPONSE_WEB_BODY=$(echo "$RESPONSE_WEB" | sed '$d')
Expand All @@ -225,7 +246,7 @@ fetch_plan_details() {
fi
fi

if [[ "$test_type" == "app" || "$test_type" == "both" ]]; then
if [[ "$test_type" == "app" ]]; then
RESPONSE_MOBILE=$(curl -s -w "\n%{http_code}" -u "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" https://api-cloud.browserstack.com/app-automate/plan.json)
HTTP_CODE_MOBILE=$(echo "$RESPONSE_MOBILE" | tail -n1)
RESPONSE_MOBILE_BODY=$(echo "$RESPONSE_MOBILE" | sed '$d')
Expand All @@ -243,11 +264,21 @@ fetch_plan_details() {
log_info "Plan summary: Web $WEB_PLAN_FETCHED ($TEAM_PARALLELS_MAX_ALLOWED_WEB max), Mobile $MOBILE_PLAN_FETCHED ($TEAM_PARALLELS_MAX_ALLOWED_MOBILE max)"

if [[ "$test_type" == "web" && "$web_unauthorized" == true ]] || \
[[ "$test_type" == "app" && "$mobile_unauthorized" == true ]] || \
[[ "$test_type" == "both" && "$web_unauthorized" == true && "$mobile_unauthorized" == true ]]; then
[[ "$test_type" == "app" && "$mobile_unauthorized" == true ]]; then
log_msg_to "❌ Unauthorized to fetch required plan(s). Exiting."
exit 1
fi

if [[ "$RUN_MODE" == *"--silent"* ]]; then
if [[ "$test_type" == "web" ]]; then
TEAM_PARALLELS_MAX_ALLOWED_WEB=5
export TEAM_PARALLELS_MAX_ALLOWED_WEB=5
else
TEAM_PARALLELS_MAX_ALLOWED_MOBILE=5
export TEAM_PARALLELS_MAX_ALLOWED_MOBILE=5
fi
log_info "Resetting Plan summary: Web $WEB_PLAN_FETCHED ($TEAM_PARALLELS_MAX_ALLOWED_WEB max), Mobile $MOBILE_PLAN_FETCHED ($TEAM_PARALLELS_MAX_ALLOWED_MOBILE max)"
fi
}

# Function to check if IP is private
Expand All @@ -270,7 +301,7 @@ is_domain_private() {
export CX_TEST_URL="$CX_TEST_URL"

# Resolve domain using Cloudflare DNS
IP_ADDRESS=$(dig +short "$domain" @1.1.1.1 | head -n1)
IP_ADDRESS=$(resolve_ip "$domain")

# Determine if domain is private
if is_private_ip "$IP_ADDRESS"; then
Expand All @@ -284,6 +315,31 @@ is_domain_private() {
return $is_cx_domain_private
}

resolve_ip() {
local domain=$1
local ip=""

# Try dig first (standard on macOS/Linux, optional on Windows)
if command -v dig >/dev/null 2>&1; then
ip=$(dig +short "$domain" @1.1.1.1 | head -n1)
fi

# Try Python if dig failed or missing
if [ -z "$ip" ] && command -v python3 >/dev/null 2>&1; then
ip=$(python3 -c "import socket; print(socket.gethostbyname('$domain'))" 2>/dev/null)
fi

# Try nslookup as last resort (parsing is fragile)
if [ -z "$ip" ] && command -v nslookup >/dev/null 2>&1; then
# Windows/Generic nslookup parsing
# Look for "Address:" or "Addresses:" after "Name:"
# This is a best-effort attempt
ip=$(nslookup "$domain" 2>/dev/null | grep -A 10 "Name:" | grep "Address" | tail -n1 | awk '{print $NF}')
fi

echo "$ip"
}


identify_run_status_java() {
local log_file=$1
Expand Down Expand Up @@ -401,4 +457,3 @@ detect_os() {

export NOW_OS=$response
}

14 changes: 10 additions & 4 deletions mac/env-setup-run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ setup_environment() {

# Calculate parallels
local total_parallels
total_parallels=$(echo "$max_parallels" | bc | cut -d'.' -f1)
total_parallels=$(awk -v n="$max_parallels" 'BEGIN { printf "%d", n }')
[ -z "$total_parallels" ] && total_parallels=1
local parallels_per_platform=$total_parallels

Expand Down Expand Up @@ -536,7 +536,13 @@ detect_setup_python_env() {
exit 1
}

# shellcheck source=/dev/null
source .venv/bin/activate
# Activate virtual environment (handle Windows/Unix paths)
if [ -f ".venv/Scripts/activate" ]; then
# shellcheck source=/dev/null
source .venv/Scripts/activate
else
# shellcheck source=/dev/null
source .venv/bin/activate
fi
log_success "Virtual environment created and activated."
}
}
47 changes: 41 additions & 6 deletions mac/user-interaction.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,29 @@ get_browserstack_credentials() {
access_key="$BROWSERSTACK_ACCESS_KEY"
log_info "BrowserStack credentials loaded from environment variables for user: $username"
else
if [[ "$NOW_OS" == "macos" ]]; then
username=$(osascript -e 'Tell application "System Events" to display dialog "Please enter your BrowserStack Username.\n\nNote: Locate it in your BrowserStack account profile page.\nhttps://www.browserstack.com/accounts/profile/details" default answer "" with title "BrowserStack Setup" buttons {"OK"} default button "OK"' \
-e 'text returned of result')
else
echo "Please enter your BrowserStack Username."
echo "Note: Locate it in your BrowserStack account profile page: https://www.browserstack.com/accounts/profile/details"
read -r username
fi

if [ -z "$username" ]; then
log_msg_to "❌ Username empty"
return 1
fi

if [[ "$NOW_OS" == "macos" ]]; then
access_key=$(osascript -e 'Tell application "System Events" to display dialog "Please enter your BrowserStack Access Key.\n\nNote: Locate it in your BrowserStack account page.\nhttps://www.browserstack.com/accounts/profile/details" default answer "" with hidden answer with title "BrowserStack Setup" buttons {"OK"} default button "OK"' \
-e 'text returned of result')
else
echo "Please enter your BrowserStack Access Key."
echo "Note: Locate it in your BrowserStack account page: https://www.browserstack.com/accounts/profile/details"
read -rs access_key
echo "" # Newline after secret input
fi
if [ -z "$access_key" ]; then
log_msg_to "❌ Access Key empty"
return 1
Expand All @@ -41,8 +54,18 @@ get_tech_stack() {
tech_stack="$TSTACK"
log_msg_to "✅ Selected Tech Stack from environment: $tech_stack"
else
if [[ "$NOW_OS" == "macos" ]]; then
tech_stack=$(osascript -e 'Tell application "System Events" to display dialog "Select installed tech stack:" buttons {"java", "python", "nodejs"} default button "java" with title "Testing Framework Technology Stack"' \
-e 'button returned of result')
else
echo "Select installed tech stack:"
select opt in "java" "python" "nodejs"; do
case $opt in
"java"|"python"|"nodejs") tech_stack=$opt; break ;;
*) echo "Invalid option";;
esac
done
fi
fi
log_msg_to "✅ Selected Tech Stack: $tech_stack"
log_info "Tech Stack: $tech_stack"
Expand All @@ -56,8 +79,14 @@ get_tech_stack() {
get_test_url() {
local test_url=$DEFAULT_TEST_URL

test_url=$(osascript -e 'Tell application "System Events" to display dialog "Enter the URL you want to test with BrowserStack:\n(Leave blank for default: '"$DEFAULT_TEST_URL"')" default answer "" with title "Test URL Setup" buttons {"OK"} default button "OK"' \
-e 'text returned of result')
if [[ "$NOW_OS" == "macos" ]]; then
test_url=$(osascript -e 'Tell application "System Events" to display dialog "Enter the URL you want to test with BrowserStack:\n(Leave blank for default: '"$DEFAULT_TEST_URL"')" default answer "" with title "Test URL Setup" buttons {"OK"} default button "OK"' \
-e 'text returned of result')
else
echo "Enter the URL you want to test with BrowserStack:"
echo "(Leave blank for default: $DEFAULT_TEST_URL)"
read -r test_url
fi

if [ -n "$test_url" ]; then
log_msg_to "🌐 Using custom test URL: $test_url"
Expand All @@ -79,8 +108,18 @@ get_test_type() {
test_type=$TT
log_msg_to "✅ Selected Testing Type from environment: $TEST_TYPE"
else
if [[ "$NOW_OS" == "macos" ]]; then
test_type=$(osascript -e 'Tell application "System Events" to display dialog "Select testing type:" buttons {"web", "app"} default button "web" with title "Testing Type"' \
-e 'button returned of result')
else
echo "Select testing type:"
select opt in "web" "app"; do
case $opt in
"web"|"app") test_type=$opt; break ;;
*) echo "Invalid option";;
esac
done
fi
log_msg_to "✅ Selected Testing Type: $TEST_TYPE"
RUN_MODE=$test_type
log_info "Run Mode: ${RUN_MODE:-default}"
Expand All @@ -98,10 +137,6 @@ perform_next_steps_based_on_test_type() {
"app")
get_upload_app
;;
"both")
get_test_url
get_upload_app
;;
esac
}

Expand Down
Loading
Loading