diff --git a/README.md b/README.md index 64fdc8a..962cccb 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,10 @@ This utility automates the entire first-mile experience β€” from credential inpu | πŸ” Pre-requisite Check | Validates if Java, Node, and Python are installed. Provides installation guidance if they are missing. | | πŸ“Š Plan Variant Detection | Calls the `/plan` API to tailor the sample repo based on the customer’s subscription tier (e.g., Live, Pro). | | βœ… Console UX with Checkmarks | Mimics the BrowserStack Network Assessment Tool for a familiar experience. | -| πŸͺ΅ Logging for Debugging | Saves all raw logs under `~/.browserstack/bstack_onboarding.log` for support and debugging purposes. | +| πŸͺ΅ Logging for Debugging | Saves all raw logs under `~/.browserstack/NOW` for support and debugging purposes. | | πŸ–₯️ (Planned) UI Framework Picker | Allows customers to select their preferred test framework via an interactive UI. | -## How to Use +## How to Use? You can either run the script directly from the web or clone the repository and run it locally. @@ -24,7 +24,7 @@ You can either run the script directly from the web or clone the repository and 1. Clone the repository: ```bash - git clone https://github.com/http-heading/browserstack-now.git + git clone https://github.com/BrowserStackCE/browserstack-now.git ``` 2. Navigate to the directory: ```bash @@ -34,12 +34,17 @@ You can either run the script directly from the web or clone the repository and **macOS / Linux** ```bash - bash mac_os.sh + bash mac/run.sh or ./mac/run.sh ``` + If you encounter any permission issues, ensure the script is executable: + ``` + chmod +x ./mac/run.sh + ``` + **Windows** ```powershell - ./windows.ps1 + ./win/run.ps1 ``` ### Remote Execution @@ -49,7 +54,7 @@ You can either run the script directly from the web or clone the repository and To run the onboarding utility on macOS or Linux without cloning, execute the following command in your terminal: ```bash -/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/http-heading/browserstack-now/main/mac_os.sh)" +/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/http-heading/browserstack-now/main/mac/run.sh)" ``` #### Windows @@ -58,6 +63,23 @@ To run the onboarding utility on Windows without cloning, execute the following **Note:** You may need to set the execution policy to `RemoteSigned` or `Bypass` to run the script. ```powershell -iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/http-heading/browserstack-now/main/windows.ps1')) +iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/http-heading/browserstack-now/main/win/run.ps1')) +``` + +## Identifying and sharing the log files + +The NOW framework creates the log files in this folder. To seek assistance from the BrowserStack team after running this Github repository, please share a zip of the logs with the BrowserStack team in toucn with you. + +### NOW Framework Logs + +#### macOS / Linux +``` +$HOME/.browserstack/NOW/logs ``` + +#### Windows ``` +$HOME/.browserstack/NOW/logs +``` + + diff --git a/mac/proxy-check.sh b/mac/proxy-check.sh new file mode 100755 index 0000000..4e6ba4b --- /dev/null +++ b/mac/proxy-check.sh @@ -0,0 +1,56 @@ +#!/usr/bin/env sh + +# URL to test +TEST_URL="https://www.browserstack.com/automate/browsers.json" + +# Detect proxy from env (case insensitive) +PROXY="${http_proxy:-${HTTP_PROXY:-${https_proxy:-${HTTPS_PROXY}}}}" + +# Reset output variables +export PROXY_HOST="" +export PROXY_PORT="" + +# Function: parse proxy url to host + port +parse_proxy() { + p="$1" + # strip protocol e.g. http://, https:// + p="${p#http://}" + p="${p#https://}" + # strip credentials if any user:pass@ + p="${p#*[@]}" + + # extract host and port + export PROXY_HOST="${p%%:*}" + export PROXY_PORT="${p##*:}" +} + +base64_encoded_creds=$(printf "%s" $BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY | base64 | tr -d '\n') + + +# If no proxy configured, exit early +if [ -z "$PROXY" ]; then + echo "No proxy found in environment. Clearing proxy host and port variables." + export PROXY_HOST="" + export PROXY_PORT="" + return 0 2>/dev/null || exit 0 +fi + +echo "Proxy detected: $PROXY" +parse_proxy "$PROXY" + +echo "Testing reachability via proxy..." + + +STATUS_CODE=$(curl -sS -o /dev/null -H "Authorization: Basic ${base64_encoded_creds}" -w "%{http_code}" --proxy "$PROXY" "$TEST_URL" 2>/dev/null) + +if [ "${STATUS_CODE#2}" != "$STATUS_CODE" ]; then + echo "βœ… Reachable. HTTP $STATUS_CODE" + echo "Exporting PROXY_HOST=$PROXY_HOST" + echo "Exporting PROXY_PORT=$PROXY_PORT" + export PROXY_HOST + export PROXY_PORT +else + echo "❌ Not reachable (HTTP $STATUS_CODE). Clearing variables." + export PROXY_HOST="" + export PROXY_PORT="" +fi diff --git a/mac.sh b/mac/run.sh similarity index 60% rename from mac.sh rename to mac/run.sh index ebd7d29..2adbe88 100755 --- a/mac.sh +++ b/mac/run.sh @@ -26,13 +26,6 @@ APP_URL="" APP_PLATFORM="" # ios | android | all -# ===== Error Patterns ===== -WEB_SETUP_ERRORS=("") -WEB_LOCAL_ERRORS=("") - -MOBILE_SETUP_ERRORS=("") -MOBILE_LOCAL_ERRORS=("") - # ===== Example Platform Templates (replace with your full lists if available) ===== WEB_PLATFORM_TEMPLATES=( "Windows|10|Chrome" @@ -40,157 +33,12 @@ WEB_PLATFORM_TEMPLATES=( "Windows|11|Edge" "Windows|11|Chrome" "Windows|8|Chrome" - "OS X|Monterey|Safari" "OS X|Monterey|Chrome" "OS X|Ventura|Chrome" - "OS X|Big Sur|Safari" "OS X|Catalina|Firefox" ) -MOBILE_TIER1=( - "ios|iPhone 15|17" - "ios|iPhone 15 Pro|17" - "ios|iPhone 16|18" - "android|Samsung Galaxy S25|15" - "android|Samsung Galaxy S24|14" -) - -# Tier 2 – Up to 40 parallels -MOBILE_TIER2=( - "ios|iPhone 14 Pro|16" - "ios|iPhone 14|16" - "ios|iPad Air 13 2025|18" - "android|Samsung Galaxy S23|13" - "android|Samsung Galaxy S22|12" - "android|Samsung Galaxy S21|11" - "android|Samsung Galaxy Tab S10 Plus|15" -) - -# Tier 3 – Up to 16 parallels -MOBILE_TIER3=( - "ios|iPhone 13 Pro Max|15" - "ios|iPhone 13|15" - "ios|iPhone 12 Pro|14" - "ios|iPhone 12 Pro|17" - "ios|iPhone 12|17" - "ios|iPhone 12|14" - "ios|iPhone 12 Pro Max|16" - "ios|iPhone 13 Pro|15" - "ios|iPhone 13 Mini|15" - "ios|iPhone 16 Pro|18" - "ios|iPad 9th|15" - "ios|iPad Pro 12.9 2020|14" - "ios|iPad Pro 12.9 2020|16" - "ios|iPad 8th|16" - "android|Samsung Galaxy S22 Ultra|12" - "android|Samsung Galaxy S21|12" - "android|Samsung Galaxy S21 Ultra|11" - "android|Samsung Galaxy S20|10" - "android|Samsung Galaxy M32|11" - "android|Samsung Galaxy Note 20|10" - "android|Samsung Galaxy S10|9" - "android|Samsung Galaxy Note 9|8" - "android|Samsung Galaxy Tab S8|12" - "android|Google Pixel 9|15" - "android|Google Pixel 6 Pro|13" - "android|Google Pixel 8|14" - "android|Google Pixel 7|13" - "android|Google Pixel 6|12" - "android|Vivo Y21|11" - "android|Vivo Y50|10" - "android|Oppo Reno 6|11" -) - -# Tier 4 – Up to 5 parallels -MOBILE_TIER4=( - "ios|iPhone 15 Pro Max|17" - "ios|iPhone 15 Pro Max|26" - "ios|iPhone 15|26" - "ios|iPhone 15 Plus|17" - "ios|iPhone 14 Pro|26" - "ios|iPhone 14|18" - "ios|iPhone 14|26" - "ios|iPhone 13 Pro Max|18" - "ios|iPhone 13|16" - "ios|iPhone 13|17" - "ios|iPhone 13|18" - "ios|iPhone 12 Pro|18" - "ios|iPhone 14 Pro Max|16" - "ios|iPhone 14 Plus|16" - "ios|iPhone 11|13" - "ios|iPhone 8|11" - "ios|iPhone 7|10" - "ios|iPhone 17 Pro Max|26" - "ios|iPhone 17 Pro|26" - "ios|iPhone 17 Air|26" - "ios|iPhone 17|26" - "ios|iPhone 16e|18" - "ios|iPhone 16 Pro Max|18" - "ios|iPhone 16 Plus|18" - "ios|iPhone SE 2020|16" - "ios|iPhone SE 2022|15" - "ios|iPad Air 4|14" - "ios|iPad 9th|18" - "ios|iPad Air 5|26" - "ios|iPad Pro 11 2021|18" - "ios|iPad Pro 13 2024|17" - "ios|iPad Pro 12.9 2021|14" - "ios|iPad Pro 12.9 2021|17" - "ios|iPad Pro 11 2024|17" - "ios|iPad Air 6|17" - "ios|iPad Pro 12.9 2022|16" - "ios|iPad Pro 11 2022|16" - "ios|iPad 10th|16" - "ios|iPad Air 13 2025|26" - "ios|iPad Pro 11 2020|13" - "ios|iPad Pro 11 2020|16" - "ios|iPad 8th|14" - "ios|iPad Mini 2021|15" - "ios|iPad Pro 12.9 2018|12" - "ios|iPad 6th|11" - "android|Samsung Galaxy S23 Ultra|13" - "android|Samsung Galaxy S22 Plus|12" - "android|Samsung Galaxy S21 Plus|11" - "android|Samsung Galaxy S20 Ultra|10" - "android|Samsung Galaxy S25 Ultra|15" - "android|Samsung Galaxy S24 Ultra|14" - "android|Samsung Galaxy M52|11" - "android|Samsung Galaxy A52|11" - "android|Samsung Galaxy A51|10" - "android|Samsung Galaxy A11|10" - "android|Samsung Galaxy A10|9" - "android|Samsung Galaxy Tab A9 Plus|14" - "android|Samsung Galaxy Tab S9|13" - "android|Samsung Galaxy Tab S7|10" - "android|Samsung Galaxy Tab S7|11" - "android|Samsung Galaxy Tab S6|9" - "android|Google Pixel 9|16" - "android|Google Pixel 10 Pro XL|16" - "android|Google Pixel 10 Pro|16" - "android|Google Pixel 10|16" - "android|Google Pixel 9 Pro XL|15" - "android|Google Pixel 9 Pro|15" - "android|Google Pixel 6 Pro|12" - "android|Google Pixel 6 Pro|15" - "android|Google Pixel 8 Pro|14" - "android|Google Pixel 7 Pro|13" - "android|Google Pixel 5|11" - "android|OnePlus 13R|15" - "android|OnePlus 12R|14" - "android|OnePlus 11R|13" - "android|OnePlus 9|11" - "android|OnePlus 8|10" - "android|Motorola Moto G71 5G|11" - "android|Motorola Moto G9 Play|10" - "android|Vivo V21|11" - "android|Oppo A96|11" - "android|Oppo Reno 3 Pro|10" - "android|Xiaomi Redmi Note 11|11" - "android|Xiaomi Redmi Note 9|10" - "android|Huawei P30|9" -) - MOBILE_ALL=( # Tier 1 "ios|iPhone 15|17" @@ -336,7 +184,6 @@ APP_URL="" APP_PLATFORM="" # ios | android | all - # ===== Log files (runtime only; created on first write) ===== # ===== Log files (per-run) ===== LOG_DIR="$WORKSPACE_DIR/$PROJECT_FOLDER/logs" @@ -352,6 +199,7 @@ mkdir -p "$LOG_DIR" : > "$WEB_LOG_FILE" : > "$MOBILE_LOG_FILE" + # ===== Logging helper (runtime timestamped logging) ===== # Usage: log_msg_to "message" "$DEST_FILE" (DEST_FILE optional; prints to console always) log_msg_to() { @@ -371,6 +219,21 @@ log_msg_to() { fi } +# Spinner function +show_spinner() { + local pid=$1 + local spin='|/-\' + local i=0 + local ts + ts="$(date +"%Y-%m-%d %H:%M:%S")" + while kill -0 "$pid" 2>/dev/null; do + i=$(( (i+1) %4 )) + printf "\r[$ts] ⏳ Processing... ${spin:$i:1}" + sleep 0.1 + done + log_msg_to "βœ… Done!" +} + # ===== validate_prereqs shim (keeps compatibility with older code) ===== validate_prereqs() { # For backwards compatibility call validate_tech_stack_installed @@ -390,7 +253,7 @@ setup_workspace() { ask_browserstack_credentials() { # Prompt username - BROWSERSTACK_USERNAME=$(osascript -e 'Tell application "System Events" to display dialog "Enter your BrowserStack Username:" default answer "" with title "BrowserStack Setup" buttons {"OK"} default button "OK"' \ + BROWSERSTACK_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') if [ -z "$BROWSERSTACK_USERNAME" ]; then log_msg_to "❌ Username empty" "$GLOBAL" @@ -398,7 +261,7 @@ ask_browserstack_credentials() { fi # Prompt access key (hidden) - BROWSERSTACK_ACCESS_KEY=$(osascript -e 'Tell application "System Events" to display dialog "Enter your BrowserStack Access Key:" default answer "" with hidden answer with title "BrowserStack Setup" buttons {"OK"} default button "OK"' \ + BROWSERSTACK_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') if [ -z "$BROWSERSTACK_ACCESS_KEY" ]; then log_msg_to "❌ Access Key empty" "$GLOBAL" @@ -408,26 +271,13 @@ ask_browserstack_credentials() { log_msg_to "βœ… BrowserStack credentials captured (access key hidden)" "$GLOBAL" } -# ask_test_type() { -# TEST_TYPE=$(osascript -e 'Tell application "System Events" to display dialog "Select testing type:" buttons {"Web", "App", "Both"} default button "Web" with title "Testing Type"' \ -# -e 'button returned of result') -# log_msg_to "βœ… Selected Testing Type: $TEST_TYPE" "$GLOBAL" -# } ask_tech_stack() { - TECH_STACK=$(osascript -e 'Tell application "System Events" to display dialog "Select installed tech stack:" buttons {"Java", "Python"} default button "Java" with title "Tech Stack"' \ + 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') log_msg_to "βœ… Selected Tech Stack: $TECH_STACK" "$GLOBAL" } -# ask_tech_stack() { -# TECH_STACK=$(osascript -e 'Tell application "System Events" to display dialog "Select installed tech stack:" buttons {"Java", "Python"} default button "Java" with title "Tech Stack"' \ -# -e 'button returned of result') -# log_msg_to "βœ… Selected Tech Stack: $TECH_STACK" "$GLOBAL" -# } - - - validate_tech_stack_installed() { log_msg_to "ℹ️ Checking prerequisites for $TECH_STACK" "$GLOBAL" @@ -463,7 +313,7 @@ validate_tech_stack_installed() { log_msg_to "βœ… Python3 is installed: $PYTHON_VERSION_OUTPUT" "$GLOBAL" ;; - JS|JavaScript) + NodeJS) log_msg_to "πŸ” Checking if 'node' command exists..." "$GLOBAL" if ! command -v node >/dev/null 2>&1; then log_msg_to "❌ Node.js command not found in PATH." "$GLOBAL" @@ -596,109 +446,6 @@ generate_web_platforms_yaml() { echo "$yaml" } -# generate_mobile_platforms_yaml() { -# local max_total_parallels=$1 -# local max -# max=$(echo "$max_total_parallels * $PARALLEL_PERCENTAGE" | bc | cut -d'.' -f1) -# [ -z "$max" ] && max=0 -# local yaml="" -# local count=0 - -# for template in "${MOBILE_DEVICE_TEMPLATES[@]}"; do -# IFS="|" read -r platformName deviceName platformVersion <<< "$template" -# yaml+=" - platformName: $platformName -# deviceName: $deviceName -# platformVersion: '${platformVersion}.0' -# " -# count=$((count + 1)) -# if [ "$count" -ge "$max" ]; then -# echo "$yaml" -# return -# fi -# done - -# echo "$yaml" -# } - - - -# ask_and_upload_app() { -# APP_FILE_PATH=$(osascript -e 'POSIX path of (choose file with prompt "πŸ“± Please select your .apk or .ipa app file to upload to BrowserStack")') - -# if [ -z "$APP_FILE_PATH" ]; then -# log_msg_to "⚠️ No app selected. Using default sample app: bs://sample.app" "$GLOBAL" -# APP_URL="bs://sample.app" -# APP_PLATFORM="all" -# return -# fi - -# # Detect platform -# if [[ "$APP_FILE_PATH" == *.apk ]]; then -# APP_PLATFORM="android" -# elif [[ "$APP_FILE_PATH" == *.ipa ]]; then -# APP_PLATFORM="ios" -# else -# log_msg_to "❌ Unsupported file type. Only .apk or .ipa allowed." "$GLOBAL" -# exit 1 -# fi - -# # Upload app -# log_msg_to "⬆️ Uploading $APP_FILE_PATH to BrowserStack..." "$GLOBAL" -# UPLOAD_RESPONSE=$(curl -s -u "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" \ -# -X POST "https://api-cloud.browserstack.com/app-automate/upload" \ -# -F "file=@$APP_FILE_PATH") - -# APP_URL=$(echo "$UPLOAD_RESPONSE" | grep -o '"app_url":"[^"]*' | cut -d'"' -f4) - -# if [ -z "$APP_URL" ]; then -# log_msg_to "❌ Upload failed. Response: $UPLOAD_RESPONSE" "$GLOBAL" -# exit 1 -# fi - -# log_msg_to "βœ… App uploaded successfully: $APP_URL" "$GLOBAL" -# } - -# generate_mobile_platforms_yaml() { -# local max_total_parallels=$1 -# local yaml="" -# local count=0 - -# # Select tier based on parallel count -# if (( max_total_parallels >= 80 )); then -# devices=("${MOBILE_TIER1[@]}") -# elif (( max_total_parallels >= 40 )); then -# devices=("${MOBILE_TIER2[@]}") -# elif (( max_total_parallels >= 16 )); then -# devices=("${MOBILE_TIER3[@]}") -# else -# devices=("${MOBILE_TIER4[@]}") -# fi - -# # Filter devices by platform and limit by max_total_parallels -# for template in "${devices[@]}"; do -# IFS="|" read -r platformName deviceName platformVersion <<< "$template" - -# # Skip if platform mismatch -# if [[ "$APP_PLATFORM" == "ios" && "$platformName" != "ios" ]]; then -# continue -# fi -# if [[ "$APP_PLATFORM" == "android" && "$platformName" != "android" ]]; then -# continue -# fi - -# yaml+=" - platformName: $platformName -# deviceName: $deviceName -# platformVersion: ${platformVersion}.0 -# " - -# count=$((count + 1)) -# if (( count >= max_total_parallels )); then -# break -# fi -# done - -# echo "$yaml" -# } generate_mobile_platforms_yaml() { local max_total_parallels=$1 @@ -740,9 +487,6 @@ generate_mobile_platforms_yaml() { } - - - generate_web_caps_json() { local max_total_parallels=$1 local max @@ -779,20 +523,21 @@ generate_web_caps_json() { generate_mobile_caps_json() { local max_total=$1 + local output_file="$WORKSPACE_DIR/$PROJECT_FOLDER/usage_file.json" + : > "$output_file" # Clear the output file + local count=0 - local usage_file="/tmp/device_usage.txt" - : > "$usage_file" - local json="[" - for template in "${MOBILE_DEVICE_TEMPLATES[@]}"; do - IFS="|" read -r platformName deviceName baseVersion <<< "$template" - local usage - usage=$(grep -Fxc "$deviceName" "$usage_file") + local json="[" - if [ "$usage" -ge 5 ]; then + for template in "${MOBILE_ALL[@]}"; do + IFS="|" read -r platformName deviceName baseVersion <<< "$template" + if [ "$APP_PLATFORM" == "ios" ] && [ "$platformName" != "ios" ]; then + continue + elif [ "$APP_PLATFORM" == "android" ] || [ "$APP_PLATFORM" == "all" ] && [ "$platformName" != "android" ]; then continue fi - + json="${json}{ \"bstack:options\": { \"deviceName\": \"${deviceName}\", @@ -800,18 +545,14 @@ generate_mobile_caps_json() { } }," - echo "$deviceName" >> "$usage_file" count=$((count + 1)) if [ "$count" -ge "$max_total" ]; then break fi - done - + done # End of the loop json="${json%,}]" - echo "$json" - rm -f "$usage_file" + echo "$json" > "$output_file" } - # ===== Fetch plan details (writes to GLOBAL) ===== fetch_plan_details() { log_msg_to "ℹ️ Fetching BrowserStack Plan Details..." "$GLOBAL" @@ -854,132 +595,73 @@ fetch_plan_details() { fi } +# Function to check if IP is private +is_private_ip() { + case $1 in + 10.* | 192.168.* | 172.16.* | 172.17.* | 172.18.* | 172.19.* | \ + 172.20.* | 172.21.* | 172.22.* | 172.23.* | 172.24.* | 172.25.* | \ + 172.26.* | 172.27.* | 172.28.* | 172.29.* | 172.30.* | 172.31.* | "") + return 0 ;; # Private + *) + return 1 ;; # Public + esac +} +is_domain_private() { + domain=${CX_TEST_URL#*://} # remove protocol + domain=${domain%%/*} # remove everything after first "/" + log_msg_to "Website domain: $domain" + export NOW_WEB_DOMAIN="$CX_TEST_URL" -# setup_web_java_tested() { -# local local_flag=$1 -# local parallels=$2 -# local log_file=$3 - -# REPO="testng-browserstack" -# TARGET_DIR="$WORKSPACE_DIR/$PROJECT_FOLDER/$REPO" - -# mkdir -p "$WORKSPACE_DIR/$PROJECT_FOLDER" - -# # Clone repo if not present -# if [ ! -d "$TARGET_DIR" ]; then -# log_msg_to "πŸ“¦ Cloning repo $REPO into $TARGET_DIR" "$GLOBAL" -# git clone https://github.com/browserstack/testng-browserstack.git "$TARGET_DIR" -# else -# log_msg_to "πŸ“‚ Repo $REPO already exists at $TARGET_DIR, skipping clone." "$GLOBAL" -# fi - -# cd "$TARGET_DIR" || return 1 - -# validate_prereqs || return 1 - -# # Export credentials for Maven to use -# export BROWSERSTACK_USERNAME="$BROWSERSTACK_USERNAME" -# export BROWSERSTACK_ACCESS_KEY="$BROWSERSTACK_ACCESS_KEY" - -# # Run BrowserStack SDK archetype setup -# log_msg_to "βš™οΈ Setting up BrowserStack SDK project" "$GLOBAL" -# mvn archetype:generate -B \ -# -DarchetypeGroupId=com.browserstack \ -# -DarchetypeArtifactId=browserstack-sdk-archetype-setup \ -# -DarchetypeVersion=1.1 \ -# -DgroupId=com.browserstack \ -# -DartifactId=testng-browserstack \ -# -Dversion=1.0 \ -# -DBROWSERSTACK_USERNAME="$BROWSERSTACK_USERNAME" \ -# -DBROWSERSTACK_ACCESS_KEY="$BROWSERSTACK_ACCESS_KEY" \ -# -DBROWSERSTACK_PROJECT_REPO="$REPO" >> "$log_file" 2>&1 || true - -# # cd testng-browserstack || return 1 - -# # Update base URL in the Java code (replacing https://www.bstackdemo.com) -# sed -i.bak "s|https://www.bstackdemo.com|$CX_TEST_URL|g" $(grep -rl "https://www.bstackdemo.com" .) - -# # Log local flag status -# if [ "$local_flag" = "true" ]; then -# log_msg_to "⚠️ BrowserStack Local is ENABLED for this run." "$GLOBAL" -# else -# log_msg_to "⚠️ BrowserStack Local is DISABLED for this run." "$GLOBAL" -# fi - -# # Generate platforms YAML -# platform_yaml=$(generate_web_platforms_yaml "$TEAM_PARALLELS_MAX_ALLOWED_WEB") - -# # Overwrite YAML config at the root level -# cat > browserstack.yml <> "$log_file" 2>&1 || true - -# cd "$WORKSPACE_DIR/$PROJECT_FOLDER" -# return 0 -# } +# Resolve domain using Cloudflare DNS +IP_ADDRESS=$(dig +short "$domain" @1.1.1.1 | head -n1) + +# Determine if domain is private +if is_private_ip "$IP_ADDRESS"; then + is_cx_domain_private=0 +else + is_cx_domain_private=-1 +fi + +log_msg_to "Resolved IPs: $IP_ADDRESS" + +return $is_cx_domain_private +} setup_web_java() { local local_flag=$1 local parallels=$2 - REPO="testng-browserstack" + REPO="now-testng-browserstack" TARGET_DIR="$WORKSPACE_DIR/$PROJECT_FOLDER/$REPO" mkdir -p "$WORKSPACE_DIR/$PROJECT_FOLDER" - + rm -rf $TARGET_DIR # === 1️⃣ Clone Repo === - if [ ! -d "$TARGET_DIR" ]; then log_msg_to "πŸ“¦ Cloning repo $REPO into $TARGET_DIR" "$GLOBAL" "$WEB_LOG_FILE" - git clone https://github.com/browserstack/testng-browserstack.git "$TARGET_DIR" >> "$WEB_LOG_FILE" 2>&1 || true - else - log_msg_to "πŸ“‚ Repo $REPO already exists at $TARGET_DIR, skipping clone." "$GLOBAL" "$WEB_LOG_FILE" - fi + git clone https://github.com/browserstackCE/now-testng-browserstack.git "$TARGET_DIR" >> "$WEB_LOG_FILE" 2>&1 || true + cd "$TARGET_DIR" || return 1 - validate_prereqs || return 1 + # validate_prereqs || return 1 - # === 2️⃣ SDK Setup === - log_msg_to "βš™οΈ Setting up BrowserStack SDK project" "$GLOBAL" "$WEB_LOG_FILE" - mvn archetype:generate -B \ - -DarchetypeGroupId=com.browserstack \ - -DarchetypeArtifactId=browserstack-sdk-archetype-setup \ - -DarchetypeVersion=1.1 \ - -DgroupId=com.browserstack \ - -DartifactId=testng-browserstack \ - -Dversion=1.0 \ - -DBROWSERSTACK_USERNAME="$BROWSERSTACK_USERNAME" \ - -DBROWSERSTACK_ACCESS_KEY="$BROWSERSTACK_ACCESS_KEY" \ - -DBROWSERSTACK_PROJECT_REPO="$REPO" >> "$WEB_LOG_FILE" 2>&1 || true - - # cd testng-browserstack || return 1 # === 3️⃣ Update Base URL === if grep -qr "https://www.bstackdemo.com" .; then log_msg_to "🌐 Updating base URL to $CX_TEST_URL" "$GLOBAL" "$WEB_LOG_FILE" - sed -i.bak "s|https://www.bstackdemo.com|$CX_TEST_URL|g" $(grep -rl "https://www.bstackdemo.com" .) + sed -i "s|https://www.bstackdemo.com|$CX_TEST_URL|g" $(grep -rl "https://www.bstackdemo.com" .) + fi + + if is_domain_private; then + local_flag=true fi # === 4️⃣ Local Flag === if [ "$local_flag" = "true" ]; then - log_msg_to "⚠️ BrowserStack Local is ENABLED for this run." "$GLOBAL" "$WEB_LOG_FILE" + log_msg_to "βœ… BrowserStack Local is ENABLED for this run." "$GLOBAL" "$WEB_LOG_FILE" else - log_msg_to "⚠️ BrowserStack Local is DISABLED for this run." "$GLOBAL" "$WEB_LOG_FILE" + log_msg_to "βœ… BrowserStack Local is DISABLED for this run." "$GLOBAL" "$WEB_LOG_FILE" fi # === 5️⃣ YAML Setup === @@ -990,7 +672,7 @@ userName: $BROWSERSTACK_USERNAME accessKey: $BROWSERSTACK_ACCESS_KEY framework: testng browserstackLocal: $local_flag -buildName: browserstack-sample-java-web +buildName: now-testng-java-web projectName: NOW-Web-Test percy: true accessibility: true @@ -999,46 +681,50 @@ $platform_yaml parallelsPerPlatform: $parallels EOF + + # === 6️⃣ Build and Run === log_msg_to "βš™οΈ Running 'mvn install -DskipTests'" "$GLOBAL" "$WEB_LOG_FILE" mvn install -DskipTests >> "$WEB_LOG_FILE" 2>&1 || true - log_msg_to "πŸš€ Running 'mvn test -P sample-test'" "$GLOBAL" "$WEB_LOG_FILE" - mvn test -P sample-test >> "$WEB_LOG_FILE" 2>&1 || true + log_msg_to "πŸš€ Running 'mvn test -P sample-test'. This could take a few minutes. Follow the Automaton build here: https://automation.browserstack.com/" "$GLOBAL" "$WEB_LOG_FILE" + mvn test -P sample-test >> "$WEB_LOG_FILE" 2>&1 & + cmd_pid=$!|| true + + show_spinner "$cmd_pid" + wait "$cmd_pid" cd "$WORKSPACE_DIR/$PROJECT_FOLDER" return 0 } - - setup_web_python() { local local_flag=$1 local parallels=$2 local log_file=$3 - REPO="pytest-browserstack" + REPO="now-pytest-browserstack" TARGET_DIR="$WORKSPACE_DIR/$PROJECT_FOLDER/$REPO" - if [ ! -d "$TARGET_DIR" ]; then - git clone https://github.com/browserstack/$REPO.git "$TARGET_DIR" + rm -rf $TARGET_DIR + + git clone https://github.com/browserstackCE/$REPO.git "$TARGET_DIR" >> "$WEB_LOG_FILE" 2>&1 || true log_msg_to "βœ… Cloned repository: $REPO into $TARGET_DIR" "$PRE_RUN_LOG_FILE" - else - log_msg_to "ℹ️ Repository already exists at: $TARGET_DIR (skipping clone)" "$PRE_RUN_LOG_FILE" - fi + cd "$TARGET_DIR" || return 1 - validate_prereqs || return 1 + #validate_prereqs || return 1 # Setup Python venv if [ ! -d "venv" ]; then python3 -m venv venv - log_msg_to "βœ… Created Python virtual environment" "$PRE_RUN_LOG_FILE" + log_msg_to "βœ… Created Python virtual environment" fi + # shellcheck disable=SC1091 source venv/bin/activate - pip install -r requirements.txt >> "$log_file" 2>&1 + pip3 install -r requirements.txt >> "$WEB_LOG_FILE" 2>&1 # Export credentials for pytest to use export BROWSERSTACK_USERNAME="$BROWSERSTACK_USERNAME" @@ -1048,6 +734,17 @@ setup_web_python() { export BROWSERSTACK_CONFIG_FILE="browserstack.yml" platform_yaml=$(generate_web_platforms_yaml "$TEAM_PARALLELS_MAX_ALLOWED_WEB") + if is_domain_private; then + local_flag=true + fi + + # === 4️⃣ Local Flag === + if [ "$local_flag" = "true" ]; then + log_msg_to "βœ… BrowserStack Local is ENABLED for this run." "$GLOBAL" "$WEB_LOG_FILE" + else + log_msg_to "βœ… BrowserStack Local is DISABLED for this run." "$GLOBAL" "$WEB_LOG_FILE" + fi + cat > browserstack.yml < tests/bstack-sample-test.py <<'PYEOF' -import pytest - -def test_universal_browserstack_check(selenium): + log_msg_to "βœ… Updated root-level browserstack.yml with platforms and credentials." - # 1. Navigate to the website - selenium.get('https://bstackdemo.com/') - - # 2. Use universal functions to get page data (no locators) - page_title = selenium.title - current_url = selenium.current_url - page_source = selenium.page_source - - # 3. Log the captured data to BrowserStack using 'annotate' - # This will appear in the "Text Logs" section of your Automate session - log_data = f"Page Title: {page_title} | Current URL: {current_url}" - selenium.execute_script( - 'browserstack_executor: {"action": "annotate", "arguments": {"data": "' + log_data + '", "level": "info"}}' - ) - - # 4. Perform simple, locator-free assertions - assert len(page_source) > 100 # Checks that the page has content - - # 5. Set the final session status to 'passed' - selenium.execute_script( - 'browserstack_executor: {"action": "setSessionStatus", "arguments": {"status": "passed", "reason": "Page loaded and title verified!"}}' - ) -PYEOF # Update base URL in the new sample test - # sed -i.bak "s|https://bstackdemo.com/|$CX_TEST_URL|g" tests/bstack-sample-test.py || true - sed -i.bak "s|https://bstackdemo.com|$CX_TEST_URL|g" tests/bstack-sample-test.py || true - log_msg_to "🌐 Updated base URL in tests/bstack-sample-test.py to: $CX_TEST_URL" "$PRE_RUN_LOG_FILE" + # sed -i "s|https://bstackdemo.com/|$CX_TEST_URL|g" tests/bstack-sample-test.py || true + sed -i "s|https://bstackdemo.com|$CX_TEST_URL|g" tests/bstack-sample-test.py || true + log_msg_to "🌐 Updated base URL in tests/bstack-sample-test.py to: $CX_TEST_URL" + + log_msg_to "πŸš€ Running 'browserstack-sdk pytest -s tests/bstack-sample-test.py'. This could take a few minutes. Follow the Automaton build here: https://automation.browserstack.com/" "$GLOBAL" "$WEB_LOG_FILE" # Run tests - log_msg_to "⚠️ Running tests with local=$local_flag" "$PRE_RUN_LOG_FILE" - browserstack-sdk pytest -s tests/bstack-sample-test.py >> "$log_file" 2>&1 || true + browserstack-sdk pytest -s tests/bstack-sample-test.py >> "$WEB_LOG_FILE" 2>&1 & + cmd_pid=$!|| true - # Copy first 200 lines of logs for visibility - [ -f "$log_file" ] && sed -n '1,200p' "$log_file" | while read -r l; do - log_msg_to "web (py): $l" "$PRE_RUN_LOG_FILE" - done + show_spinner "$cmd_pid" + wait "$cmd_pid" + cd "$WORKSPACE_DIR/$PROJECT_FOLDER" return 0 } - - -setup_web_js() { +setup_web_nodejs() { local local_flag=$1 local parallels=$2 - REPO="webdriverio-browserstack" + REPO="now-webdriverio-browserstack" TARGET_DIR="$WORKSPACE_DIR/$PROJECT_FOLDER/$REPO" + rm -rf $TARGET_DIR + mkdir -p "$WORKSPACE_DIR/$PROJECT_FOLDER" # === 1️⃣ Clone Repo === - if [ ! -d "$TARGET_DIR" ]; then - log_msg_to "πŸ“¦ Cloning repo $REPO (branch tra) into $TARGET_DIR" "$GLOBAL" "$WEB_LOG_FILE" - git clone -b tra https://github.com/browserstack/$REPO.git "$TARGET_DIR" >> "$WEB_LOG_FILE" 2>&1 || true - else - log_msg_to "πŸ“‚ Repo $REPO already exists at $TARGET_DIR, skipping clone." "$GLOBAL" "$WEB_LOG_FILE" - fi + log_msg_to "πŸ“¦ Cloning repo $REPO into $TARGET_DIR" "$GLOBAL" "$WEB_LOG_FILE" + git clone https://github.com/browserstackCE/$REPO.git "$TARGET_DIR" >> "$WEB_LOG_FILE" 2>&1 || true cd "$TARGET_DIR" || return 1 - validate_prereqs || return 1 # === 2️⃣ Install Dependencies === log_msg_to "βš™οΈ Running 'npm install'" "$GLOBAL" "$WEB_LOG_FILE" npm install >> "$WEB_LOG_FILE" 2>&1 || true - # # === 3️⃣ Update Base URL === - # if grep -qr "https://www.bstackdemo.com" .; then - # log_msg_to "🌐 Updating base URL to $CX_TEST_URL" "$GLOBAL" "$WEB_LOG_FILE" - # sed -i.bak "s|https://www.bstackdemo.com|$CX_TEST_URL|g" $(grep -rl "https://www.bstackdemo.com" .) - # fi # === 4️⃣ Generate Capabilities JSON === log_msg_to "🧩 Generating browser/OS capabilities" "$GLOBAL" "$WEB_LOG_FILE" local caps_json caps_json=$(generate_web_caps_json "$parallels") - # === 5️⃣ Determine buildIdentifier based on local === - if [ "$local_flag" = true ]; then - BUILD_ID="#${BUILD_NUMBER}-local" - else - BUILD_ID="#${BUILD_NUMBER}-remote" - fi - - cat > conf/base.conf.js < tests/specs/test.js < { - it("add product to cart", async () => { - await browser.url("$CX_TEST_URL"); - - await browser.waitUntil( - async () => (await browser.getTitle()).match(/StackDemo/i), - { timeout: 5000, timeoutMsg: "Title didn't match with BrowserStack" } - ); - - await browser.waitUntil( - async () => (await productInCart.getText()).match(productOnScreenText), - { timeout: 5000 } - ); - }); -}); -EOF - - + export BSTACK_PARALLELS=$parallels + + export BSTACK_CAPS_JSON=$caps_json - # === 6️⃣ Create conf/test.conf.js using template === -log_msg_to "πŸ› οΈ Creating conf/test.conf.js configuration file" "$GLOBAL" "$WEB_LOG_FILE" - -if [ "$local_flag" = true ]; then - # BUILD_ID="#${BUILD_NUMBER}-localOn" - cat > conf/test.conf.js < conf/test.conf.js <> "$WEB_LOG_FILE" 2>&1 || true # === 9️⃣ Wrap Up === @@ -1310,59 +840,52 @@ fi } - - - # ===== Web wrapper with retry logic (writes runtime logs to WEB_LOG_FILE) ===== setup_web() { log_msg_to "Starting Web setup for $TECH_STACK" "$WEB_LOG_FILE" - local local_flag=true + local local_flag=false local attempt=1 - local success=false - local log_file="$WEB_LOG_FILE" + local success=true + local log_file=$WEB_LOG_FILE # don't pre-create; file will be created on first write by log_msg_to or command output redirection local total_parallels total_parallels=$(echo "$TEAM_PARALLELS_MAX_ALLOWED_WEB * $PARALLEL_PERCENTAGE" | bc | cut -d'.' -f1) [ -z "$total_parallels" ] && total_parallels=1 local parallels_per_platform - # parallels_per_platform=$(( (total_parallels + 1) / 2 )) parallels_per_platform=$total_parallels - while [ "$attempt" -le 2 ]; do - log_msg_to "[Web Setup Attempt $attempt] browserstackLocal: $local_flag" "$WEB_LOG_FILE" + while [ "$attempt" -le 1 ]; do + log_msg_to "[Web Setup]" "$WEB_LOG_FILE" case "$TECH_STACK" in - Java) setup_web_java "$local_flag" "$parallels_per_platform" "$WEB_LOG_FILE" ;; - Python) setup_web_python "$local_flag" "$parallels_per_platform" "$WEB_LOG_FILE" ;; - JS|JavaScript) setup_web_js "$local_flag" "$parallels_per_platform" "$WEB_LOG_FILE" ;; - *) log_msg_to "Unknown TECH_STACK: $TECH_STACK" "$WEB_LOG_FILE"; return 1 ;; - esac - - LOG_CONTENT=$(<"$WEB_LOG_FILE" 2>/dev/null || true) - LOCAL_FAILURE=false - SETUP_FAILURE=false - - for pattern in "${WEB_LOCAL_ERRORS[@]}"; do - echo "$LOG_CONTENT" | grep -qiE "$pattern" && LOCAL_FAILURE=true && break - done + Java) + setup_web_java "$local_flag" "$parallels_per_platform" "$WEB_LOG_FILE" + if (grep -qiE "BUILD FAILURE" "$WEB_LOG_FILE"); then + success=false + fi + ;; + Python) + setup_web_python "$local_flag" "$parallels_per_platform" "$WEB_LOG_FILE" + if (grep -qiE "BUILD FAILURE" "$WEB_LOG_FILE"); then + success=false + fi + ;; + - for pattern in "${WEB_SETUP_ERRORS[@]}"; do - echo "$LOG_CONTENT" | grep -qiE "$pattern" && SETUP_FAILURE=true && break - done + NodeJS) setup_web_nodejs "$local_flag" "$parallels_per_platform" "$WEB_LOG_FILE" + if (grep -qiE "([1-9][0-9]*) passed, 0 failed" "$WEB_LOG_FILE"); then + success=false + fi + ;; - if echo "$LOG_CONTENT" | grep -qiE "https://[a-zA-Z0-9./?=_-]*browserstack\.com"; then - success=true - fi + *) log_msg_to "Unknown TECH_STACK: $TECH_STACK" "$WEB_LOG_FILE"; return 1 ;; + esac if [ "$success" = true ]; then - log_msg_to "βœ… Web setup succeeded" "$WEB_LOG_FILE" + log_msg_to "βœ… Web setup succeeded." "$WEB_LOG_FILE" break - elif [ "$LOCAL_FAILURE" = true ] && [ "$attempt" -eq 1 ]; then - local_flag=false - attempt=$((attempt + 1)) - log_msg_to "⚠️ Web test failed due to Local tunnel error. Retrying without browserstackLocal..." "$WEB_LOG_FILE" elif [ "$SETUP_FAILURE" = true ]; then log_msg_to "❌ Web test failed due to setup error. Check logs at: $WEB_LOG_FILE" "$WEB_LOG_FILE" break @@ -1374,8 +897,6 @@ setup_web() { } - - setup_mobile_python() { local local_flag=$1 local parallels=$2 @@ -1385,12 +906,8 @@ setup_mobile_python() { TARGET_DIR="$WORKSPACE_DIR/$PROJECT_FOLDER/$REPO" # Clone repo if not present - if [ ! -d "$TARGET_DIR" ]; then git clone https://github.com/browserstack/$REPO.git "$TARGET_DIR" log_msg_to "βœ… Cloned repository: $REPO into $TARGET_DIR" "$PRE_RUN_LOG_FILE" - else - log_msg_to "ℹ️ Repository already exists at: $TARGET_DIR (skipping clone)" "$PRE_RUN_LOG_FILE" - fi cd "$TARGET_DIR" || return 1 @@ -1493,15 +1010,19 @@ PYEOF run_dir="ios" fi + if is_domain_private; then + local_flag=true + fi + # Log local flag status if [ "$local_flag" = "true" ]; then - log_msg_to "⚠️ BrowserStack Local is ENABLED for this run." "$PRE_RUN_LOG_FILE" + log_msg_to "⚠️ BrowserStack Local is ENABLED for this run." else - log_msg_to "⚠️ BrowserStack Local is DISABLED for this run." "$PRE_RUN_LOG_FILE" + log_msg_to "⚠️ BrowserStack Local is DISABLED for this run." fi # Run pytest with BrowserStack SDK from the chosen platform directory - log_msg_to "πŸš€ Running 'cd $run_dir && browserstack-sdk pytest -s bstack_sample.py'" "$PRE_RUN_LOG_FILE" + log_msg_to "πŸš€ Running 'cd $run_dir && browserstack-sdk pytest -s bstack_sample.py'" ( cd "$run_dir" && browserstack-sdk pytest -s bstack_sample.py >> "$log_file" 2>&1 || true ) @@ -1525,17 +1046,13 @@ setup_mobile_java() { REPO="browserstack-examples-appium-testng" TARGET_DIR="$WORKSPACE_DIR/$PROJECT_FOLDER/$REPO" - if [ ! -d "$TARGET_DIR" ]; then git clone https://github.com/BrowserStackCE/$REPO.git "$TARGET_DIR" log_msg_to "βœ… Cloned repository: $REPO into $TARGET_DIR" "$GLOBAL" "$MOBILE_LOG_FILE" - else - log_msg_to "ℹ️ Repository already exists at: $TARGET_DIR (skipping clone)" "$GLOBAL" "$MOBILE_LOG_FILE" - fi # Update pom.xml β†’ browserstack-java-sdk version to LATEST pom_file="$TARGET_DIR/pom.xml" if [ -f "$pom_file" ]; then - sed -i.bak '/browserstack-java-sdk<\/artifactId>/,/<\/dependency>/ s|.*|LATEST|' "$pom_file" + sed -i '/browserstack-java-sdk<\/artifactId>/,/<\/dependency>/ s|.*|LATEST|' "$pom_file" log_msg_to "πŸ”§ Updated browserstack-java-sdk version to LATEST in pom.xml" "$GLOBAL" "$MOBILE_LOG_FILE" fi @@ -1549,7 +1066,7 @@ setup_mobile_java() { # Update TestBase.java β†’ switch AppiumDriver to AndroidDriver testbase_file=$(find src -name "TestBase.java" | head -n 1) if [ -f "$testbase_file" ]; then - sed -i.bak 's/new AppiumDriver(/new AndroidDriver(/g' "$testbase_file" + sed -i 's/new AppiumDriver(/new AndroidDriver(/g' "$testbase_file" log_msg_to "πŸ”§ Updated driver initialization in $testbase_file to use AndroidDriver" "$GLOBAL" "$MOBILE_LOG_FILE" fi @@ -1595,11 +1112,15 @@ public class OrderTest extends TestBase { } EOF + if is_domain_private; then + local_flag=true + fi + # Log local flag status if [ "$local_flag" = "true" ]; then - log_msg_to "⚠️ BrowserStack Local is ENABLED for this run." "$GLOBAL" "$MOBILE_LOG_FILE" + log_msg_to "βœ… BrowserStack Local is ENABLED for this run." "$GLOBAL" "$MOBILE_LOG_FILE" else - log_msg_to "⚠️ BrowserStack Local is DISABLED for this run." "$GLOBAL" "$MOBILE_LOG_FILE" + log_msg_to "βœ… BrowserStack Local is DISABLED for this run." "$GLOBAL" "$MOBILE_LOG_FILE" fi # Run Maven install first @@ -1620,39 +1141,32 @@ EOF } - - -setup_mobile_js() { +setup_mobile_nodejs() { local local_flag=$1 local parallels=$2 local log_file=$3 - REPO="webdriverio-appium-app-browserstack" + cd $WORKSPACE_DIR/$PROJECT_FOLDER || return 1 + + REPO="now-webdriverio-appium-app-browserstack" if [ ! -d "$REPO" ]; then - git clone -b sdk https://github.com/browserstack/$REPO + git clone -b sdk https://github.com/BrowserStackCE/$REPO fi - cd "$REPO/android/" || return 1 + + cd "$REPO/test/" || return 1 validate_prereqs || return 1 npm install >> "$log_file" 2>&1 || true - cd "examples/run-parallel-test" || return 1 - caps_file="parallel.conf.js" - - if sed --version >/dev/null 2>&1; then - sed -i "s/\(maxInstances:\)[[:space:]]*[0-9]\+/\1 $parallels/" "$caps_file" || true - else - sed -i '' "s/\(maxInstances:\)[[:space:]]*[0-9]\+/\1 $parallels/" "$caps_file" || true - fi - - caps_json=$(generate_mobile_caps_json "$parallels") - printf "%s\n" "capabilities: $caps_json," > "$caps_file".tmp || true - mv "$caps_file".tmp "$caps_file" || true + generate_mobile_caps_json "$parallels" export BROWSERSTACK_USERNAME="$BROWSERSTACK_USERNAME" export BROWSERSTACK_ACCESS_KEY="$BROWSERSTACK_ACCESS_KEY" + export BSTACK_PARALLELS=$parallels - npm run parallel > "$log_file" 2>&1 || true - [ -f "$log_file" ] && sed -n '1,200p' "$log_file" | while read -r l; do log_msg_to "mobile: $l" "$GLOBAL"; done + npm run test > "$log_file" 2>&1 || true + [ -f "$log_file" ] && sed -n '1,200p' "$log_file" | while read -r l; do log_msg_to "mobile: $l" "$GLOBAL"; done + + # rm $WORKSPACE_DIR/$PROJECT_FOLDER/usage_file.json || true return 0 } @@ -1672,12 +1186,12 @@ setup_mobile() { # parallels_per_platform=$(( (total_parallels + 2) / 3 )) parallels_per_platform=$total_parallels - while [ "$attempt" -le 2 ]; do + while [ "$attempt" -le 1 ]; do log_msg_to "[Mobile Setup Attempt $attempt] browserstackLocal: $local_flag" "$MOBILE_LOG_FILE" case "$TECH_STACK" in Java) setup_mobile_java "$local_flag" "$parallels_per_platform" "$MOBILE_LOG_FILE" ;; Python) setup_mobile_python "$local_flag" "$parallels_per_platform" "$MOBILE_LOG_FILE" ;; - JS|JavaScript) setup_mobile_js "$local_flag" "$parallels_per_platform" "$MOBILE_LOG_FILE" ;; + NodeJS) setup_mobile_nodejs "$local_flag" "$parallels_per_platform" "$MOBILE_LOG_FILE" ;; *) log_msg_to "Unknown TECH_STACK: $TECH_STACK" "$MOBILE_LOG_FILE"; return 1 ;; esac @@ -1770,9 +1284,10 @@ fetch_plan_details # Plan summary in pre-run log log_msg_to "Plan summary: WEB_PLAN_FETCHED=$WEB_PLAN_FETCHED (team max=$TEAM_PARALLELS_MAX_ALLOWED_WEB), MOBILE_PLAN_FETCHED=$MOBILE_PLAN_FETCHED (team max=$TEAM_PARALLELS_MAX_ALLOWED_MOBILE)" "$GLOBAL" - -# Run actual setup(s) +log_msg_to "Checking proxy in environment" "$GLOBAL" +chmod +x proxy-check.sh +./proxy-check.sh +log_msg_to "Starting setup run..." "$GLOBAL" run_setup -# End -log_msg_to "Setup run finished" "$GLOBAL" \ No newline at end of file +log_msg_to "Setup run finished." "$GLOBAL" \ No newline at end of file diff --git a/windows.ps1 b/win/run.ps1 similarity index 100% rename from windows.ps1 rename to win/run.ps1