Last active
May 6, 2025 13:04
-
-
Save fdciabdul/b1535454c3e62de527b3d0fb3f267cb6 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
Add-Type -AssemblyName System.Windows.Forms | |
Add-Type -AssemblyName System.Drawing | |
$form = New-Object System.Windows.Forms.Form | |
$form.Text = "Appium Android Setup" | |
$form.Size = New-Object System.Drawing.Size(600, 700) | |
$form.StartPosition = "CenterScreen" | |
$form.BackColor = [System.Drawing.Color]::WhiteSmoke | |
$logTextBox = New-Object System.Windows.Forms.RichTextBox | |
$logTextBox.Location = New-Object System.Drawing.Point(10, 150) | |
$logTextBox.Size = New-Object System.Drawing.Size(565, 500) | |
$logTextBox.ReadOnly = $true | |
$logTextBox.Font = New-Object System.Drawing.Font("Consolas", 9) | |
$form.Controls.Add($logTextBox) | |
$titleLabel = New-Object System.Windows.Forms.Label | |
$titleLabel.Location = New-Object System.Drawing.Point(10, 10) | |
$titleLabel.Size = New-Object System.Drawing.Size(560, 25) | |
$titleLabel.Text = "Appium Android Setup Utility" | |
$titleLabel.Font = New-Object System.Drawing.Font("Segoe UI", 14, [System.Drawing.FontStyle]::Bold) | |
$form.Controls.Add($titleLabel) | |
$descriptionLabel = New-Object System.Windows.Forms.Label | |
$descriptionLabel.Location = New-Object System.Drawing.Point(10, 40) | |
$descriptionLabel.Size = New-Object System.Drawing.Size(560, 40) | |
$descriptionLabel.Text = "This utility will install and configure everything needed for Appium Android testing." | |
$form.Controls.Add($descriptionLabel) | |
$installButton = New-Object System.Windows.Forms.Button | |
$installButton.Location = New-Object System.Drawing.Point(10, 90) | |
$installButton.Size = New-Object System.Drawing.Size(120, 40) | |
$installButton.Text = "Install All" | |
$installButton.BackColor = [System.Drawing.Color]::LightGreen | |
$form.Controls.Add($installButton) | |
$verifyButton = New-Object System.Windows.Forms.Button | |
$verifyButton.Location = New-Object System.Drawing.Point(140, 90) | |
$verifyButton.Size = New-Object System.Drawing.Size(120, 40) | |
$verifyButton.Text = "Verify Installation" | |
$verifyButton.BackColor = [System.Drawing.Color]::LightBlue | |
$form.Controls.Add($verifyButton) | |
$progressBar = New-Object System.Windows.Forms.ProgressBar | |
$progressBar.Location = New-Object System.Drawing.Point(270, 90) | |
$progressBar.Size = New-Object System.Drawing.Size(305, 40) | |
$progressBar.Style = "Continuous" | |
$form.Controls.Add($progressBar) | |
$installSteps = @( | |
"Checking administrator rights", | |
"Installing Chocolatey", | |
"Installing Node.js", | |
"Installing Appium", | |
"Installing Android Studio", | |
"Setting up Android environment variables", | |
"Installing Java", | |
"Setting up Android SDK", | |
"Creating Android Virtual Device", | |
"Setting up Appium", | |
"Installing Python" | |
) | |
$totalSteps = $installSteps.Count | |
function Write-Log { | |
param ( | |
[string]$message, | |
[string]$color = "Black" | |
) | |
$logTextBox.SelectionColor = $color | |
$logTextBox.AppendText("$message`r`n") | |
$logTextBox.ScrollToCaret() | |
$form.Refresh() | |
} | |
function Update-Progress { | |
param ( | |
[int]$step, | |
[string]$status | |
) | |
$percent = ($step / $totalSteps) * 100 | |
$progressBar.Value = $percent | |
Write-Log "[$($step)/$($totalSteps)] $status" "Blue" | |
} | |
function Test-Command { | |
param ( | |
[string]$command | |
) | |
try { | |
$null = Get-Command $command -ErrorAction Stop | |
return $true | |
} | |
catch { | |
return $false | |
} | |
} | |
function Get-CommandPath { | |
param ( | |
[string]$command | |
) | |
try { | |
if ($IsWindows -or [Environment]::OSVersion.Platform -eq "Win32NT") { | |
return (where.exe $command 2>&1) | |
} else { | |
return (which $command 2>&1) | |
} | |
} | |
catch { | |
return "Command path not found: $_" | |
} | |
} | |
function Verify-Installation { | |
Write-Log "Verifying installation..." "DarkGreen" | |
$verificationResults = @() | |
try { | |
# Check Node.js | |
Write-Log "`r`n::group::node" "DarkBlue" | |
try { | |
$nodeVersion = (node --version 2>&1) | |
if ($nodeVersion -match '\d+\.\d+\.\d+') { | |
Write-Log "Node.js version: $nodeVersion" "Green" | |
$verificationResults += "Node.js: ✅ $nodeVersion" | |
} else { | |
Write-Log "Node.js not found or version check failed!" "Red" | |
$verificationResults += "Node.js: ❌ Not installed or not working properly" | |
} | |
} | |
catch { | |
Write-Log "Error checking Node.js: $_" "Red" | |
$verificationResults += "Node.js: ❌ Not installed" | |
} | |
try { | |
$nodePath = Get-CommandPath -command "node" | |
Write-Log "Path: $nodePath" | |
} | |
catch { | |
Write-Log "Unable to find Node.js path: $_" "Yellow" | |
} | |
Write-Log "::endgroup::`r`n" | |
# Check Appium | |
Write-Log "::group::appium" "DarkBlue" | |
try { | |
$appiumVersion = (appium --version 2>&1) | |
if ($appiumVersion -match '\d+\.\d+\.\d+') { | |
Write-Log "Appium version: $appiumVersion" "Green" | |
$verificationResults += "Appium: ✅ $appiumVersion" | |
} else { | |
Write-Log "Appium not found or version check failed!" "Red" | |
$verificationResults += "Appium: ❌ Not installed or not working properly" | |
} | |
} | |
catch { | |
Write-Log "Error checking Appium: $_" "Red" | |
$verificationResults += "Appium: ❌ Not installed" | |
} | |
try { | |
$appiumPath = Get-CommandPath -command "appium" | |
Write-Log "Path: $appiumPath" | |
} | |
catch { | |
Write-Log "Unable to find Appium path: $_" "Yellow" | |
} | |
Write-Log "::endgroup::`r`n" | |
# Check Java | |
Write-Log "::group::java" "DarkBlue" | |
try { | |
# Java version typically outputs to stderr, so we need a different approach | |
$javaVersionProcess = Start-Process -FilePath "java" -ArgumentList "-version" -Wait -NoNewWindow -PassThru -RedirectStandardError "java_version.txt" | |
$javaVersion = Get-Content "java_version.txt" -ErrorAction SilentlyContinue | |
if ($javaVersion -match 'version') { | |
Write-Log "Java version: $javaVersion" "Green" | |
$verificationResults += "Java: ✅ Installed" | |
} else { | |
Write-Log "Java not found or version check failed!" "Red" | |
$verificationResults += "Java: ❌ Not installed or not working properly" | |
} | |
# Clean up temporary file | |
Remove-Item "java_version.txt" -ErrorAction SilentlyContinue | |
} | |
catch { | |
Write-Log "Error checking Java: $_" "Red" | |
$verificationResults += "Java: ❌ Not installed" | |
} | |
try { | |
$javaPath = Get-CommandPath -command "java" | |
Write-Log "Path: $javaPath" | |
} | |
catch { | |
Write-Log "Unable to find Java path: $_" "Yellow" | |
} | |
Write-Log "::endgroup::`r`n" | |
# Check SDKManager | |
Write-Log "::group::sdkmanager" "DarkBlue" | |
try { | |
# Use timeout to prevent hanging | |
$sdkManagerProcess = Start-Process -FilePath "sdkmanager" -ArgumentList "--version" -Wait -NoNewWindow -PassThru -TimeoutSec 5 | |
if ($sdkManagerProcess.ExitCode -eq 0) { | |
Write-Log "SDKManager: Available" "Green" | |
$verificationResults += "SDKManager: ✅ Installed" | |
# Don't try to get full SDK list as it can be very large | |
Write-Log "SDK Manager is installed and working" | |
} else { | |
Write-Log "SDKManager not found or failed to run!" "Red" | |
$verificationResults += "SDKManager: ❌ Not installed or not working properly" | |
} | |
} | |
catch { | |
Write-Log "Error checking SDKManager: $_" "Red" | |
$verificationResults += "SDKManager: ❌ Not installed" | |
} | |
try { | |
$sdkmanagerPath = Get-CommandPath -command "sdkmanager" | |
Write-Log "Path: $sdkmanagerPath" | |
} | |
catch { | |
Write-Log "Unable to find SDKManager path: $_" "Yellow" | |
} | |
Write-Log "::endgroup::`r`n" | |
# Check AVD Manager | |
Write-Log "::group::avdmanager" "DarkBlue" | |
try { | |
# Use timeout to prevent hanging | |
$avdProcess = Start-Process -FilePath "avdmanager" -ArgumentList "list avd -c" -Wait -NoNewWindow -PassThru -TimeoutSec 5 | |
if ($avdProcess.ExitCode -eq 0) { | |
Write-Log "AVD Manager: Available" "Green" | |
$verificationResults += "AVD Manager: ✅ Installed" | |
} else { | |
Write-Log "AVD Manager not found or failed to run!" "Red" | |
$verificationResults += "AVD Manager: ❌ Not installed or not working properly" | |
} | |
} | |
catch { | |
Write-Log "Error checking AVD Manager: $_" "Red" | |
$verificationResults += "AVD Manager: ❌ Not installed" | |
} | |
try { | |
$avdmanagerPath = Get-CommandPath -command "avdmanager" | |
Write-Log "Path: $avdmanagerPath" | |
} | |
catch { | |
Write-Log "Unable to find AVD Manager path: $_" "Yellow" | |
} | |
Write-Log "::endgroup::`r`n" | |
# Check Python | |
Write-Log "::group::python" "DarkBlue" | |
try { | |
$pythonVersion = (python --version 2>&1) | |
if ($pythonVersion -match 'Python \d+\.\d+\.\d+') { | |
Write-Log "Python version: $pythonVersion" "Green" | |
$verificationResults += "Python: ✅ $pythonVersion" | |
} else { | |
Write-Log "Python not found or version check failed!" "Red" | |
$verificationResults += "Python: ❌ Not installed or not working properly" | |
} | |
} | |
catch { | |
Write-Log "Error checking Python: $_" "Red" | |
$verificationResults += "Python: ❌ Not installed" | |
} | |
try { | |
$pythonPath = Get-CommandPath -command "python" | |
Write-Log "Path: $pythonPath" | |
} | |
catch { | |
Write-Log "Unable to find Python path: $_" "Yellow" | |
} | |
Write-Log "::endgroup::`r`n" | |
# Summary | |
Write-Log "`r`nVerification Summary:" "DarkBlue" | |
foreach ($result in $verificationResults) { | |
if ($result -like "*❌*") { | |
Write-Log $result "Red" | |
} else { | |
Write-Log $result "Green" | |
} | |
} | |
} | |
catch { | |
Write-Log "Error during verification: $_" "Red" | |
} | |
} | |
function Install-Components { | |
$androidArch = 'x86_64' | |
$androidSDkVersion = '34' | |
$androidPackage = "system-images;android-$androidSdkVersion;google_apis;$androidArch" | |
try { | |
Update-Progress 1 $installSteps[0] | |
$myWindowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent() | |
$myWindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($myWindowsID) | |
$adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator | |
if (-not $myWindowsPrincipal.IsInRole($adminRole)) { | |
Write-Log "Not running as Administrator. Please restart the script with administrative privileges." "Red" | |
[System.Windows.Forms.MessageBox]::Show("This script requires administrative privileges. Please restart the application as Administrator.", "Admin Rights Required", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Warning) | |
return | |
} | |
Write-Log "Running with administrative privileges." "Green" | |
function Add-Path { | |
param ( | |
$path | |
) | |
Write-Log "Adding to PATH: $path" | |
try { | |
if (-not (Test-Path $path -ErrorAction SilentlyContinue)) { | |
Write-Log "Warning: Path does not exist yet: $path" "Yellow" | |
} | |
[Environment]::SetEnvironmentVariable("PATH", "$env:PATH;$path", [EnvironmentVariableTarget]::Machine) | |
# Refresh current session path as well | |
$env:Path = [Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::Machine) | |
Write-Log "PATH updated successfully." "Green" | |
} | |
catch { | |
Write-Log "Error updating PATH: $_" "Red" | |
} | |
} | |
Update-Progress 2 $installSteps[1] | |
Write-Log "`r`n::group::choco" "DarkBlue" | |
Set-ExecutionPolicy Bypass -Scope Process -Force | |
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072 | |
if (-not (Test-Command -command "choco")) { | |
Write-Log "Installing Chocolatey..." | |
try { | |
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) | |
if (Test-Command -command "choco") { | |
Write-Log "Chocolatey installed successfully." "Green" | |
} | |
else { | |
Write-Log "Chocolatey installation may have failed. Continuing anyway..." "Yellow" | |
} | |
} | |
catch { | |
Write-Log "Error installing Chocolatey: $_" "Red" | |
Write-Log "Continuing with installation despite Chocolatey installation failure." "Yellow" | |
} | |
} else { | |
Write-Log "Chocolatey already installed." "Green" | |
} | |
try { | |
$env:ChocolateyInstall = Convert-Path "$((Get-Command choco -ErrorAction SilentlyContinue).Path)\..\..\" -ErrorAction SilentlyContinue | |
Import-Module "$env:ChocolateyInstall\helpers\chocolateyProfile.psm1" -ErrorAction SilentlyContinue | |
} | |
catch { | |
Write-Log "Note: Chocolatey profile module could not be loaded: $_" "Yellow" | |
} | |
Write-Log "::endgroup::" | |
Update-Progress 3 $installSteps[2] | |
Write-Log "`r`n::group::node" "DarkBlue" | |
if (-not (Test-Command -command "node")) { | |
Write-Log "Installing Node.js..." | |
try { | |
choco install -y nodejs-lts | |
if (Test-Command -command "node") { | |
Write-Log "Node.js installed successfully." "Green" | |
# Refresh environment after installation | |
$env:Path = [Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::Machine) | |
} | |
else { | |
Write-Log "Node.js installation may have failed. Continuing anyway..." "Yellow" | |
} | |
} | |
catch { | |
Write-Log "Error installing Node.js: $_" "Red" | |
Write-Log "Continuing with installation despite Node.js installation failure." "Yellow" | |
} | |
} else { | |
Write-Log "Node.js already installed." "Green" | |
} | |
Write-Log "::endgroup::" | |
Update-Progress 4 $installSteps[3] | |
Write-Log "`r`n::group::appium" "DarkBlue" | |
if (-not (Test-Command -command "appium")) { | |
Write-Log "Installing Appium..." | |
try { | |
npm i -g appium | |
if (Test-Command -command "appium") { | |
Write-Log "Appium installed successfully." "Green" | |
} | |
else { | |
Write-Log "Appium installation may have failed. Continuing anyway..." "Yellow" | |
} | |
} | |
catch { | |
Write-Log "Error installing Appium: $_" "Red" | |
Write-Log "Continuing with installation despite Appium installation failure." "Yellow" | |
} | |
} else { | |
Write-Log "Appium already installed." "Green" | |
} | |
Write-Log "::endgroup::" | |
Update-Progress 5 $installSteps[4] | |
Write-Log "`r`n::group::android" "DarkBlue" | |
try { | |
choco install -y androidstudio | |
Write-Log "Android Studio installation completed." "Green" | |
} | |
catch { | |
Write-Log "Error installing Android Studio: $_" "Red" | |
Write-Log "Continuing with installation despite Android Studio installation failure." "Yellow" | |
} | |
$androidHome = "$env:USERPROFILE\AppData\Local\Android\sdk" | |
Write-Log "Setting ANDROID_HOME to $androidHome" | |
try { | |
[Environment]::SetEnvironmentVariable("ANDROID_HOME", "$androidHome", [EnvironmentVariableTarget]::Machine) | |
# Set for current session as well | |
$env:ANDROID_HOME = $androidHome | |
Write-Log "ANDROID_HOME environment variable set successfully." "Green" | |
} | |
catch { | |
Write-Log "Error setting ANDROID_HOME: $_" "Red" | |
} | |
Update-Progress 6 $installSteps[5] | |
try { | |
Add-Path "$androidHome\emulator" | |
Add-Path "$androidHome\cmdline-tools\latest\bin" | |
Add-Path "$androidHome\tools" | |
Add-Path "$androidHome\tools\bin" | |
Add-Path "$androidHome\platform-tools" | |
Add-Path "$androidHome\build-tools" | |
Write-Log "Android paths added successfully." "Green" | |
} | |
catch { | |
Write-Log "Error adding Android paths: $_" "Red" | |
} | |
Write-Log "::endgroup::" | |
Write-Log "`r`n::group::Binaries" "DarkBlue" | |
try { | |
$env:Path.split(";") | ForEach-Object { | |
if (Test-Path $_ -ErrorAction SilentlyContinue) { | |
Get-ChildItem -Path $_ -ErrorAction SilentlyContinue | |
} | |
} | Where-Object { $env:PATHEXT.ToLower() -match $_.Extension.ToLower() } | Select-Object FullName | |
} | |
catch { | |
Write-Log "Error listing binaries: $_" "Red" | |
} | |
Write-Log "::endgroup::" | |
Write-Log "`r`n::group::Android Home" "DarkBlue" | |
if (Test-Path -Path "$androidHome" -ErrorAction SilentlyContinue) { | |
Get-Item -Path "$androidHome" -ErrorAction SilentlyContinue | |
Write-Log "Android home directory exists." "Green" | |
} | |
else { | |
Write-Log "Android home directory does not exist yet. It will be created when you run Android Studio." "Yellow" | |
} | |
Write-Log "::endgroup::" | |
Update-Progress 7 $installSteps[6] | |
Write-Log "`r`n::group::java" "DarkBlue" | |
if (-not (Test-Command -command "java")) { | |
Write-Log "Installing Java..." | |
try { | |
$temurinParams = "/ADDLOCAL=FeatureMain,FeatureEnvironment,FeatureJarFileRunWith,FeatureJavaHome /INSTALLDIR=$env:ProgramFiles\Eclipse Adoptium\" | |
choco install -y temurin --params="$temurinParams" | |
# Refresh environment variables | |
$env:Path = [Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::Machine) | |
if (Test-Command -command "java") { | |
Write-Log "Java installed successfully." "Green" | |
} | |
else { | |
Write-Log "Java installation may have failed. Continuing anyway..." "Yellow" | |
} | |
} | |
catch { | |
Write-Log "Error installing Java: $_" "Red" | |
Write-Log "Continuing with installation despite Java installation failure." "Yellow" | |
} | |
} else { | |
Write-Log "Java already installed." "Green" | |
} | |
Write-Log "::endgroup::" | |
Update-Progress 8 $installSteps[7] | |
Write-Log "`r`n::group::setup" "DarkBlue" | |
Write-Log "Installing Android SDK package: $androidPackage" | |
try { | |
# Check if sdkmanager is available | |
if (Test-Command -command "sdkmanager") { | |
# Use Start-Process with timeout to prevent hanging | |
$sdkProcess = Start-Process -FilePath "sdkmanager" -ArgumentList """$androidPackage""" -NoNewWindow -Wait -PassThru -TimeoutSec 600 | |
if ($sdkProcess.ExitCode -eq 0) { | |
Write-Log "Android SDK package installed successfully." "Green" | |
} | |
else { | |
Write-Log "Android SDK package installation may have failed. Continuing anyway..." "Yellow" | |
} | |
} | |
else { | |
Write-Log "SDKManager not found. You'll need to install Android SDK packages manually." "Yellow" | |
} | |
} | |
catch { | |
Write-Log "Error installing Android SDK package: $_" "Red" | |
Write-Log "Continuing with installation despite SDK package installation failure." "Yellow" | |
} | |
Update-Progress 9 $installSteps[8] | |
Write-Log "Creating Android Virtual Device..." | |
try { | |
# Check if avdmanager is available | |
if (Test-Command -command "avdmanager") { | |
# Use Start-Process with timeout to prevent hanging | |
$avdProcess = Start-Process -FilePath "avdmanager" -ArgumentList "create avd --name 'Appium' --force --abi ""google_apis/$androidArch"" --package ""$androidPackage"" --device 'Nexus 6P'" -NoNewWindow -Wait -PassThru -TimeoutSec 120 | |
if ($avdProcess.ExitCode -eq 0) { | |
Write-Log "Android Virtual Device created successfully." "Green" | |
} | |
else { | |
Write-Log "Android Virtual Device creation may have failed. Continuing anyway..." "Yellow" | |
} | |
} | |
else { | |
Write-Log "AVDManager not found. You'll need to create Android Virtual Devices manually." "Yellow" | |
} | |
} | |
catch { | |
Write-Log "Error creating Android Virtual Device: $_" "Red" | |
Write-Log "Continuing with installation despite AVD creation failure." "Yellow" | |
} | |
Update-Progress 10 $installSteps[9] | |
Write-Log "Setting up Appium..." | |
try { | |
# Check if appium is available | |
if (Test-Command -command "appium") { | |
# Use Start-Process with timeout to prevent hanging | |
$appiumProcess = Start-Process -FilePath "appium" -ArgumentList "setup" -NoNewWindow -Wait -PassThru -TimeoutSec 120 | |
if ($appiumProcess.ExitCode -eq 0) { | |
Write-Log "Appium setup completed successfully." "Green" | |
} | |
else { | |
Write-Log "Appium setup may have failed. Continuing anyway..." "Yellow" | |
} | |
} | |
else { | |
Write-Log "Appium not found. You'll need to set up Appium manually." "Yellow" | |
} | |
} | |
catch { | |
Write-Log "Error setting up Appium: $_" "Red" | |
Write-Log "Continuing with installation despite Appium setup failure." "Yellow" | |
} | |
Write-Log "::endgroup::" | |
Update-Progress 11 $installSteps[10] | |
Write-Log "`r`n::group::python" "DarkBlue" | |
if (-not (Test-Command -command "python")) { | |
Write-Log "Installing Python..." | |
try { | |
choco install -y python3 | |
# Refresh environment variables | |
$env:Path = [Environment]::GetEnvironmentVariable("Path", [EnvironmentVariableTarget]::Machine) | |
if (Test-Command -command "python") { | |
Write-Log "Python installed successfully." "Green" | |
} | |
else { | |
Write-Log "Python installation may have failed. Continuing anyway..." "Yellow" | |
} | |
} | |
catch { | |
Write-Log "Error installing Python: $_" "Red" | |
Write-Log "Continuing with installation despite Python installation failure." "Yellow" | |
} | |
} else { | |
Write-Log "Python already installed." "Green" | |
} | |
Write-Log "::endgroup::" | |
$progressBar.Value = 100 | |
Write-Log "`r`nInstallation complete!" "Green" | |
Write-Log "You can now verify the installation by clicking the 'Verify Installation' button." "Blue" | |
} | |
catch { | |
Write-Log "Error during installation: $_" "Red" | |
Write-Log "Installation failed. Please check the logs for details." "Red" | |
} | |
} | |
$installButton.Add_Click({ | |
$logTextBox.Clear() | |
Write-Log "Starting installation process..." "DarkGreen" | |
Install-Components | |
}) | |
$verifyButton.Add_Click({ | |
$logTextBox.Clear() | |
Verify-Installation | |
}) | |
$form.ShowDialog() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment