44import subprocess
55import tarfile
66import zipfile
7+ import shutil
78from pathlib import Path
89import json
910import requests
@@ -99,7 +100,7 @@ def install_nodejs():
99100 print ("Downloading Node.js..." )
100101 response = requests .get (url , verify = False )
101102 response .raise_for_status ()
102- with open (archive_path , 'wb' ) as out_file :
103+ with open (archive_path , "wb" ) as out_file :
103104 out_file .write (response .content )
104105
105106 try :
@@ -196,7 +197,9 @@ def check_appium_drivers():
196197 text = True ,
197198 )
198199 drivers_data = json .loads (result .stdout )
199- return [name for name , info in drivers_data .items () if info .get ("installed" , False )]
200+ return [
201+ name for name , info in drivers_data .items () if info .get ("installed" , False )
202+ ]
200203 except : # noqa: E722
201204 return []
202205
@@ -213,7 +216,9 @@ def check_installations():
213216 if npm_path .exists ():
214217 try :
215218 result = subprocess .run (
216- [str (npm_path ), "list" , "-g" , "--json" , "appium" ], capture_output = True , text = True
219+ [str (npm_path ), "list" , "-g" , "--json" , "appium" ],
220+ capture_output = True ,
221+ text = True ,
217222 )
218223 npm_data = json .loads (result .stdout )
219224 appium_installed = "appium" in npm_data .get ("dependencies" , {})
@@ -234,9 +239,73 @@ def install_missing_drivers(missing_drivers):
234239 install_drivers (missing_drivers )
235240
236241
242+ def check_and_remove_global_appium ():
243+ """Check for and remove existing global Appium installations not managed by us."""
244+ print ("Checking for conflicting global Appium installations..." )
245+
246+ # Method 1: Check using 'which appium'
247+ appium_bin = shutil .which ("appium" )
248+ if appium_bin :
249+ appium_path = Path (appium_bin ).resolve ()
250+ node_dir = get_node_dir ().resolve ()
251+
252+ try :
253+ # Check if appium is within our node directory
254+ appium_path .relative_to (node_dir )
255+ # If it is, we are good
256+ except ValueError :
257+ print (f"Found conflicting Appium at { appium_path } " )
258+ print ("Uninstalling old Appium version..." )
259+ try :
260+ is_windows = platform .system () == "Windows"
261+ subprocess .run (
262+ ["npm" , "uninstall" , "-g" , "appium" ], check = True , shell = is_windows
263+ )
264+ print ("Successfully uninstalled conflicting Appium" )
265+ except Exception as e :
266+ print (f"Warning: Failed to uninstall conflicting Appium: { e } " )
267+ return
268+
269+ # Method 2: Check using 'npm list -g appium' (if npm is available in system path)
270+ # This catches cases where appium is installed but not in PATH
271+ npm_bin = shutil .which ("npm" )
272+ if npm_bin :
273+ try :
274+ # Check if this npm is ours
275+ npm_path = Path (npm_bin ).resolve ()
276+ node_dir = get_node_dir ().resolve ()
277+ try :
278+ npm_path .relative_to (node_dir )
279+ # If it is our npm, skip this check as we handle our own appium
280+ return
281+ except ValueError :
282+ pass
283+
284+ # Check for global appium using system npm
285+ is_windows = platform .system () == "Windows"
286+ result = subprocess .run (
287+ ["npm" , "list" , "-g" , "--json" , "appium" ],
288+ capture_output = True ,
289+ text = True ,
290+ shell = is_windows ,
291+ )
292+ npm_data = json .loads (result .stdout )
293+ if "appium" in npm_data .get ("dependencies" , {}):
294+ print ("Found conflicting Appium in global npm modules" )
295+ print ("Uninstalling old Appium version..." )
296+ subprocess .run (
297+ ["npm" , "uninstall" , "-g" , "appium" ], check = True , shell = is_windows
298+ )
299+ print ("Successfully uninstalled conflicting Appium" )
300+ except Exception as e :
301+ # Don't fail if npm check fails, just log warning
302+ print (f"Warning: Failed to check/uninstall global Appium via npm: { e } " )
303+
304+
237305def setup_nodejs_appium ():
238306 """Main setup function."""
239307 try :
308+ check_and_remove_global_appium ()
240309 update_path () # Ensure Node.js is in PATH from the start
241310
242311 print ("Checking Node.js and Appium installation..." )
0 commit comments