devicely 2.1.4 → 2.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/devicely.js +105 -1
- package/lib/androidDeviceDetection.js +276 -1
- package/lib/appMappings.js +337 -1
- package/lib/deviceDetection.js +394 -1
- package/lib/devices.js +54 -1
- package/lib/doctor.js +94 -1
- package/lib/executor.js +104 -1
- package/lib/logger.js +35 -1
- package/lib/scriptLoader.js +75 -1
- package/lib/server.js +3485 -1
- package/package.json +3 -12
- package/scripts/compile-shell-scripts.js +208 -0
- package/scripts/encrypt-shell-simple.js +75 -0
- package/scripts/obfuscate-shell.js +160 -0
- package/scripts/shell/android_device_control +0 -0
- package/scripts/shell/apps_presets.conf +271 -0
- package/scripts/shell/connect_android_usb +0 -0
- package/scripts/shell/connect_android_usb_multi_final +0 -0
- package/scripts/shell/connect_android_wireless +0 -0
- package/scripts/shell/connect_android_wireless_multi_final +0 -0
- package/scripts/shell/connect_ios_usb +0 -0
- package/scripts/shell/connect_ios_usb_multi_final +0 -0
- package/scripts/shell/connect_ios_wireless_multi_final +0 -0
- package/scripts/shell/create_production_scripts +0 -0
- package/scripts/shell/devices.conf +24 -0
- package/scripts/shell/diagnose_wireless_ios +0 -0
- package/scripts/shell/find_element_coordinates +0 -0
- package/scripts/shell/find_wda +0 -0
- package/scripts/shell/install_uiautomator2 +0 -0
- package/scripts/shell/ios_device_control +0 -0
- package/scripts/shell/organize_project +0 -0
- package/scripts/shell/pre-publish-check +0 -0
- package/scripts/shell/publish +0 -0
- package/scripts/shell/publish-to-npm +0 -0
- package/scripts/shell/setup +0 -0
- package/scripts/shell/setup_android +0 -0
- package/scripts/shell/start +0 -0
- package/scripts/shell/sync-to-npm-package-final +0 -0
- package/scripts/shell/test_android_locators +0 -0
- package/scripts/shell/test_connect +0 -0
- package/scripts/shell/test_device_detection +0 -0
- package/scripts/shell/test_fixes +0 -0
- package/scripts/shell/test_getlocators_fix +0 -0
- package/scripts/shell/test_recording_feature +0 -0
- package/scripts/shell/verify-shell-protection +0 -0
- package/scripts/shell/verify_distribution +0 -0
- package/lib/package-lock.json +0 -1678
- package/lib/package.json +0 -30
- package/lib/screenshots/screenshot_ios_iPhone17_20260205_225900.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhone17_20260205_225942.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhone17_20260205_231101.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhone17_20260205_232911.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhone17_20260208_095103.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhone17_20260208_095720.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115040.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115047.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115118.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115125.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_115143.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_120107.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_120118.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_120137.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_120201.png +0 -0
- package/lib/screenshots/screenshot_ios_iPhoneXR17x_20260206_134529.png +0 -0
- package/scripts/shell/android_device_control.enc +0 -1
- package/scripts/shell/connect_android_usb_multi_final.enc +0 -1
- package/scripts/shell/connect_android_wireless.enc +0 -1
- package/scripts/shell/connect_android_wireless_multi_final.enc +0 -1
- package/scripts/shell/connect_ios_usb_multi_final.enc +0 -1
- package/scripts/shell/connect_ios_wireless_multi_final.enc +0 -1
- package/scripts/shell/ios_device_control.enc +0 -1
package/lib/deviceDetection.js
CHANGED
|
@@ -1,2 +1,395 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const _0x1871dc=_0x1edb;(function(_0x5556c9,_0x46f821){const _0x5e1c04=_0x1edb,_0x36fe8a=_0x5556c9();while(!![]){try{const _0x71907=-parseInt(_0x5e1c04(0x21f))/0x1+-parseInt(_0x5e1c04(0x239))/0x2*(-parseInt(_0x5e1c04(0x1fa))/0x3)+-parseInt(_0x5e1c04(0x1ad))/0x4*(-parseInt(_0x5e1c04(0x262))/0x5)+parseInt(_0x5e1c04(0x20c))/0x6+parseInt(_0x5e1c04(0x1c0))/0x7*(-parseInt(_0x5e1c04(0x231))/0x8)+parseInt(_0x5e1c04(0x292))/0x9+-parseInt(_0x5e1c04(0x1a9))/0xa;if(_0x71907===_0x46f821)break;else _0x36fe8a['push'](_0x36fe8a['shift']());}catch(_0xeed302){_0x36fe8a['push'](_0x36fe8a['shift']());}}}(_0x4625,0x64ed4));const {spawn}=require('child_process'),fs=require('fs')['promises'],path=require(_0x1871dc(0x1f0));let DEVICE_CONFIG=path['join'](__dirname,_0x1871dc(0x1d5));!require('fs')[_0x1871dc(0x1ce)](DEVICE_CONFIG)&&(DEVICE_CONFIG=path[_0x1871dc(0x22f)](__dirname,'../config/devices.conf'));let androidDetection;try{androidDetection=require(_0x1871dc(0x1db));}catch(_0x318a19){console[_0x1871dc(0x20a)](_0x1871dc(0x1a1)),androidDetection=null;}function _0x4625(){const _0x3b79e0=['B3Lhqxi','y2HLy2Tvu0jxrefdB25Uzwn0AxzPDhLpBLbVCNq','BNDMrxy','tevSrg8','thfcu3G','u2rOCvG','tejltgi','CgH1ugi','tLvjChi','ndmZntq3ofbvrfPbvW','rhHOu1y','y29UBMvJDgLVBLr5Cgu','icaGic0GvvncigrLDMLJzxmGyxjLignVBM5Ly3rLzcbHBMqGDhj1C3rLza','ugLVA2q','DhLWzq','zxHPDa','wff3vLq','ChHWsMe','z2rewfa','rxjYB3iGzgv0zwn0Aw5NiefUzhjVAwqGvvncigrLDMLJzxm6','uw1YANO','ChvZAa','wgHyBu8','zxHPC3rZu3LUyW','rxzyqMu','tMvlA20','z2Lurw8','oxWZFdr8nxWYFdD8nNWXmhW4Fdb8mq','DNr1uNi','DhjPBq','zgv2AwnLCY5JB25M','tLnrvNK','B2rjsu8','C29Tzq','ls1TyxGTDgLTzq','sLruCKO','lI9HBMrYB2LKrgv2AwnLrgv0zwn0Aw9U','wMryvLu','B1vovfK','yMfMrKG','zgLZy292zxjbBgXezxzPy2vZ','icaGic0Grgv2AwnLigLZigf1DgHVCML6zwqGkgnOzwnRigrLDMLJzsbZy3jLzw4P','zMDruvy','ugnWBNq','rgv2AwnLtMfTztO','ze5tCee','AMHTqwy','sw16yMe','BwvZC2fNzq','tNfYsfi','yw5KCM9PzfzLCNnPB24','C3rHCNrZv2L0Aa','lhvZyGO','zKDtt2u','Dw5RBM93BG','AeTizwS','icaGvurjrdOG','Cgf0Aa','DwXUBhy','BxvdzxK','qxDoz2G','EunKAKO','wM9Kvge','BNPhzey','Ahr0CdOVlW','C3HOAfa','ufHbzfK','ntrwCervshi','C3rKB3v0','t2nhrLK','ALDXu2e','zM9YrwfJAa','Effgqxq','Cg9YDa','BMjJugq','rMjcEe0','8j+uJsbeAxnJB3zLCMLUzYbPt1mGjIbbBMrYB2LKigrLDMLJzxmUlI4k','yuj0zMi','wuPku3m','quLsEeS','DNH6vw4','CgfLDeG','s0HTvem','D2fYBG','zxLMvuC','ndy5mdK0nePMveHJEa','tLnUwgW','zKjOr3G','AfD5uxC','4P2mie5VigrLDMLJzxmGzM91BMqk','l3n0yxr1CW','ls1QC29U','D1fPAKy','zgf0yq','icaGic0GvvncigrLyNvNz2LUzYbPCYbLBMfIBgvK','DxnI','y0fWz1u','ChDnBwO','Dg9vChbLCKnHC2u','CKnWB1y','B25SAw5L','ENLpzuO','zxfkA2u','CM1uz3G','mte1odqYCg5QzMHN','B09sB0m','C05qBwy','rMfPBgvKihrVihnHDMuGvvncigrLDMLJzsb0BYbJB25MAwC6','A3HiA0y','DefQt1O','BgPPC3i','q3jIs0W','Durjy2e','BufzAxu','zNbTA2C','ifvtqIbKzxzPy2uGDg8Gy29UzMLNoIa','DfLrrhi','iYbezxzPy2uGq29UzMLNDxjHDgLVBIaOqxv0BY11CgrHDgvKkqOJiezVCM1HDdOGzgv2AwnLx25HBwuSDwrPzcXPCf9HzgrYzxnZlhbSyxrMB3jTlhr5CgukiYbqBgf0zM9YBtOGAw9ZihWGyw5KCM9PzaOJifr5Cgu6ihvZyIb8ihDPCMvSzxnZcImGcImG8j+uJcbvu0iGrevwsunfuZOGqxv0B21HDgLJywXSEsbKzxrLy3rLzcbHBMqGC2f2zwqGAgvYzqOJicaGic0GtM8Gy29UzMLNDxjHDgLVBIbUzwvKzwqGzM9YifvtqIbJB25Uzwn0Aw9UcImGicaGlsbbzgqGsvaGywrKCMvZCYb0BYbLBMfIBguGD2LYzwXLC3mGC3vWCg9YDcbSyxrLCGOJcImG8j+tOsbxsvjftevtuYbervzjq0vtoIbnyw51ywXSEsbHzgqGD2L0AcbjucbHzgrYzxnZcImGicaGlsbgB3jTyxq6igrLDMLJzv9Uyw1LlhvKAwqSAxbFywrKCMvZCYXWBgf0zM9YBsX3AxjLBgvZCWOJicaGic0GAu9toIbezxzPy2uGBxvZDcbIzsbWywLYzwqGAw4GwgnVzguSifDLyKrYAxzLCKfNzw50ihj1BM5PBMCkiYaGicaTiefUzhjVAwq6ievUywjSzsb3AxjLBgvZCYbbreiGzMLYC3qkiWOJiev4yw1WBguGzw50CMLLCZOkiYbPugHVBMuXnYWWmdaWodeZmc0Wmde5ndvdnJnfrdm0mdfflcXPB3mSDxnIicaGicaGicaGicaOAu9tifvtqIaTigf1Dg8Tzgv0zwn0zwqPcImGAvbOB25LmtzqldaWmda4mtqWltaWmumYndm2muu0mtGWmumSmtaUmtCZlJiYms4YmdqSAw9ZlhDPCMvSzxnZicaOAu9tifDPCMvSzxnZkqOJifbPEgvSocWXqtjcm0m0rdvfnKySlgfUzhjVAwqSDxnIicaGicaGicaGicaGicaGicaGicaGicHbBMrYB2LKifvtqIaTigf1Dg8Tzgv0zwn0zwqPcImGr2fSyxH5uZiZlefcq0qXmJm0lde5mI4XnJGUms4XntaSyw5KCM9PzcX3AxjLBgvZCYaGicaGkefUzhjVAwqGv2LYzwXLC3mPcGO','Awv5v04','A0HkvLO','AM9PBG','CwzkqMq','ofn5yvryEa','ls1JB25Uzwn0lxrPBwvVDxq','Aw9Z','y3vYBa','y0LnChG','B0TAufa','yMzcvgS','DxjTAhC','nZC0mtjiEfr0wei','D2LYzwXLC3m','thjxBKe','yw5KCM9Pza','EvD4t0m','uxHJrw0','v05uwgC','A1nutu8','y2HLy2TxAxjLBgvZC0nVBM5Ly3rPDML0Eq','tKzct2G','sLzerNK','sxHHvKe','rNPjBwu','vLzJv2G','AgXszMi','t1HbweS','igrLDMLJzsHZktOk','q1zjv3a','C3vIC3rYAw5N','s21SyxO','C2f2zvvtqKrLDMLJzvrVq29UzMLN','rhv2zvO','icbPt1m6','icaGic0GBgLIAw1VyMLSzwrLDMLJzsbPCYbPBNn0ywXSzwq6igjYzxCGAw5ZDgfSBcbSAwjPBw9IAwXLzgv2AwnL','EhDpzKW','rw1SqLO','EvDvDKu','C3rHDhvZ','icaGqw5KCM9PzdOG','B3nwzxjZAw9U','veX0s2u','CgXHDgzVCM0','Cw5Trvu','q3Lktei','B0LsuMW','yxj6uw8','rwDyAfO','C3rYAw5NAwz5','DMT0yuO','yNvIEMq','AwrLDMLJzwLUzM8','mtCXodbABezWEfK','y0HZEK4','Aw5JBhvKzxm','q0LOCuK','C2vYAwfS','AK95z0K','rwDgr0i','BevduuK','uhjVzhvJDfzLCNnPB246','sxvvCKe','reDOwu8','Dg9tDhjPBMC','vLL3AMq','zxHWB3j0CW','uMnWA3O','vM1PAwq','wKjHwKq','EejrvKG','su5JBMu','vLv5rvu','uw1OCNu','zxDHqu8','q3vUEuO','uuzotem','rM91BMqG','EKzwq0C','r3zVDgm','AgfZ','txDeCwO','tMLqDfC','EKHOyxa','BwfPBG','D2X0B0q','D3jPDgvgAwXL','r1zWDKG','t2Hose4','A3Hztvu','s29vAeu','icaGic0GqurcigLZigLUC3rHBgXLzdOGyNjLDYbPBNn0ywXSigfUzhjVAwqTCgXHDgzVCM0TDg9VBhmk','C3bSAxq','zxjYB3i','y29UBMvJDgvK','ue9pEKK','wMXMDKS','DfjQAwu','AvjSsLC','m3WXmhW0Fdb8mxW3FdH8mNW5Fdv8nG','EujABu0','mZu1ntqYm2HetefTrW','teXHCuy','y01kAfm','vMfkBg0','C3DIsgW','zgXswhq','zMLSDgvY','Auf6twi','twfRzsbZDxjLoG','CMvHzezPBgu','A1rQzem','uuTqALG','y2zUswC','A2LSBa','Au9tlq','wvjiqNO','Bg9HzfDPCMvSzxnZrgv2AwnLCW','wMrVqMS','ugnKEKO','Bwf0y2G','zgv0zwn0vvncrgv2AwnLCW','uLnrvwS','C0Dhu0S','vfvTBwe','wwHwvei','rejPvwy','BMfTzq','tvbOvMy','Axb2s0S','z2v0vvncrgv2AwnLsw5MBW','DwrPza','y2XVC2u','BhfKq1i','AfzIrvu','DeHJtNi','rhbHuKe','wxnfEfe','whn5r2e','C2zXExi','s0XoquG','4PYfief1Dg8TC2f2zwqG','DvnQywe','Bg9N','A25Yy2S','zgzpvNe','vLDnAeC','DxrMltG','oJGXmdaVC3rHDhvZ','icbbBMrYB2LKoG','qw5KCM9PzcbKzxrLy3rPB24GBw9KDwXLig5VDcbHDMfPBgfIBgu','t1jmuwG','BgLbDKS','B2zMBgLUzq','yxLVt24','svDUuvy','rgLICue','wKrHEK8','mti2nZG3ntbqzLz3BwO','CwPetLq','ugn4r1G','yw9Vtfm','nJmYu0fLu0HK','BwfW','uwPrtwq','iNn0yxrLiG','AwrLDMLJzv9Pza','yM9VEvy','ic0G','BgvUz3rO','zuHstKK','wuLfugC'];_0x4625=function(){return _0x3b79e0;};return _0x4625();}async function detectIOSUSBDevices(){const _0x29d562=_0x1871dc,_0x57cb43={'INcne':_0x29d562(0x233),'fZCDo':'usb','cHszN':function(_0x168296,_0x521af1){return _0x168296===_0x521af1;},'pxpJa':_0x29d562(0x223),'KSQgf':_0x29d562(0x1a5),'ZodTa':function(_0x23eefe,_0x18c5c9){return _0x23eefe(_0x18c5c9);},'PcdzJ':function(_0x34bae3,_0x9a95d2,_0x254aac){return _0x34bae3(_0x9a95d2,_0x254aac);},'YJJSs':_0x29d562(0x1b1),'cIMpx':_0x29d562(0x214),'QjQMd':_0x29d562(0x18f),'ORLQh':_0x29d562(0x28a)};return new Promise(_0x5599c3=>{const _0x14a6e6=_0x29d562,_0x177141=[],_0x521cc4=_0x57cb43[_0x14a6e6(0x182)](spawn,_0x57cb43[_0x14a6e6(0x205)],['-l']);let _0x239075='';_0x521cc4[_0x14a6e6(0x1fb)]['on'](_0x57cb43[_0x14a6e6(0x235)],_0x2b049d=>{const _0x323bbc=_0x14a6e6;_0x239075+=_0x2b049d[_0x323bbc(0x26d)]();}),_0x521cc4['on'](_0x57cb43[_0x14a6e6(0x1af)],_0x4003a2=>{const _0x1a8c18=_0x14a6e6,_0x494e84={};_0x494e84[_0x1a8c18(0x1ff)]=_0x57cb43[_0x1a8c18(0x274)],_0x494e84[_0x1a8c18(0x17b)]=_0x57cb43['fZCDo'],_0x494e84['dgkrs']=_0x1a8c18(0x1ed);const _0x556556=_0x494e84;if(_0x57cb43[_0x1a8c18(0x263)](_0x57cb43[_0x1a8c18(0x1c8)],_0x57cb43['KSQgf']))_0x51b3ae[_0x1a8c18(0x17d)](),_0xf113a3(![]);else{if(_0x4003a2===0x0&&_0x239075[_0x1a8c18(0x1d4)]()){const _0x2dbe85=_0x239075[_0x1a8c18(0x1d4)]()[_0x1a8c18(0x289)]('\x0a')[_0x1a8c18(0x176)](Boolean);_0x2dbe85['forEach'](_0x319e4f=>{const _0x272a15=_0x1a8c18;_0x177141[_0x272a15(0x1cc)]({'name':'iOS-'+_0x319e4f[_0x272a15(0x24b)](0x0,0x8),'udid':_0x319e4f['trim'](),'platform':_0x556556[_0x272a15(0x1ff)],'type':_0x556556[_0x272a15(0x17b)],'connectionType':_0x556556[_0x272a15(0x17b)],'status':_0x556556['dgkrs']});});}_0x57cb43[_0x1a8c18(0x1f5)](_0x5599c3,_0x177141);}}),_0x521cc4['on'](_0x57cb43[_0x14a6e6(0x1a2)],()=>{_0x57cb43['ZodTa'](_0x5599c3,[]);});});}async function detectUSBDevices(){const _0x1ae9ed=_0x1871dc,_0x24eba7={'kBLtH':'android','phuPb':'\x22state\x22','odIIO':function(_0x581df2){return _0x581df2();},'vtuRr':function(_0x217cb9,_0x33f635){return _0x217cb9===_0x33f635;},'nwfEv':_0x1ae9ed(0x224),'TUmma':function(_0x4cc4bc,_0x2213ca){return _0x4cc4bc!==_0x2213ca;},'oUNTY':_0x1ae9ed(0x1bc),'QxcEm':_0x1ae9ed(0x206),'zHhap':_0x1ae9ed(0x253),'WAByd':_0x1ae9ed(0x1ca)},_0x294646=await _0x24eba7[_0x1ae9ed(0x1d7)](detectIOSUSBDevices);let _0xff4984=[];if(androidDetection){if(_0x24eba7[_0x1ae9ed(0x1d3)](_0x1ae9ed(0x224),_0x24eba7[_0x1ae9ed(0x1b9)]))try{_0x24eba7[_0x1ae9ed(0x187)](_0x24eba7[_0x1ae9ed(0x1dd)],_0x24eba7[_0x1ae9ed(0x23e)])?_0xff4984=await androidDetection[_0x1ae9ed(0x184)]():_0x3942dc=_0x24eba7['kBLtH'];}catch(_0x475442){'yWUvE'!==_0x24eba7[_0x1ae9ed(0x280)]?_0x17162e(_0x59bd56[_0x1ae9ed(0x264)](_0x24eba7[_0x1ae9ed(0x1be)])):console[_0x1ae9ed(0x28a)](_0x24eba7['WAByd'],_0x475442['message']);}else _0x2e0575[_0x1ae9ed(0x256)]=_0x56eca4[_0x1ae9ed(0x289)](':')[0x1]['trim']();}return[..._0x294646,..._0xff4984];}async function getUSBDeviceInfo(_0x1ff457){const _0x5704b6=_0x1871dc,_0x2855c2={'tRjie':function(_0x728c29,_0x749207){return _0x728c29===_0x749207;},'Gvotc':_0x5704b6(0x285),'fCGnN':_0x5704b6(0x20e),'jWqSa':function(_0xaa317b,_0xb2c0e){return _0xaa317b(_0xb2c0e);},'JVDFy':_0x5704b6(0x225),'OXAXK':function(_0x468f9f,_0x54def5){return _0x468f9f===_0x54def5;},'QFNLC':function(_0x666c13,_0x45c690){return _0x666c13!==_0x45c690;},'xwOfL':_0x5704b6(0x1c9),'jVIin':function(_0x289f86,_0x27410e){return _0x289f86(_0x27410e);},'NiPtW':_0x5704b6(0x1db),'obdUu':function(_0x3fcdd3,_0x1cd0dc,_0x308ea6){return _0x3fcdd3(_0x1cd0dc,_0x308ea6);},'dCFVH':_0x5704b6(0x261),'EgFGB':_0x5704b6(0x214),'AwNgh':_0x5704b6(0x18f)};return new Promise(_0x1763c4=>{const _0x557a03=_0x5704b6,_0x25254d={'kHJVZ':function(_0x4ec496,_0x5fe62b){return _0x2855c2['tRjie'](_0x4ec496,_0x5fe62b);},'DGhYO':_0x2855c2[_0x557a03(0x243)],'vktaJ':_0x557a03(0x1fc),'hWyQw':_0x557a03(0x1e3),'RSQUk':'ProductVersion:','zyOeJ':function(_0x23f9b1,_0x6ce2e9){return _0x23f9b1(_0x6ce2e9);},'NqrHR':_0x557a03(0x1b0),'uDIca':function(_0x3db8c9,_0x2bcd80){const _0x5479ec=_0x557a03;return _0x2855c2[_0x5479ec(0x248)](_0x3db8c9,_0x2bcd80);},'CIhqI':_0x557a03(0x19c),'HkPXs':function(_0xe2796b,_0x3cb367){const _0x380516=_0x557a03;return _0x2855c2[_0x380516(0x279)](_0xe2796b,_0x3cb367);},'ulnlv':_0x2855c2[_0x557a03(0x251)],'XhXmO':function(_0x526298,_0x19c4f7){return _0x2855c2['jVIin'](_0x526298,_0x19c4f7);},'ipvKK':_0x2855c2[_0x557a03(0x27f)]},_0x1c23e6=_0x2855c2['obdUu'](spawn,_0x2855c2['dCFVH'],['-u',_0x1ff457]);let _0x473289='';_0x1c23e6[_0x557a03(0x1fb)]['on'](_0x2855c2[_0x557a03(0x268)],_0x292443=>{const _0x11be07=_0x557a03;_0x25254d[_0x11be07(0x22e)](_0x25254d[_0x11be07(0x26c)],_0x25254d[_0x11be07(0x25f)])?(_0x577396['warn']('Android\x20detection\x20module\x20not\x20available'),_0x5ed09e=null):_0x473289+=_0x292443['toString']();}),_0x1c23e6['on'](_0x2855c2[_0x557a03(0x1f3)],_0x591b39=>{const _0x596d22=_0x557a03,_0x18b81d={'WNTXg':function(_0x19ff40,_0x29c3a9){return _0x19ff40(_0x29c3a9);}};if(_0x25254d[_0x596d22(0x227)](_0x25254d[_0x596d22(0x265)],_0x25254d['CIhqI'])){if(_0x591b39===0x0&&_0x473289['trim']()){const _0x3eaeab={},_0xf9f3c9=_0x473289[_0x596d22(0x289)]('\x0a');_0xf9f3c9[_0x596d22(0x1fe)](_0x3a5c19=>{const _0x423e72=_0x596d22;_0x3a5c19['includes'](_0x25254d[_0x423e72(0x20f)])&&(_0x3eaeab[_0x423e72(0x18a)]=_0x3a5c19[_0x423e72(0x289)](':')[0x1]['trim']()),_0x3a5c19[_0x423e72(0x264)](_0x25254d[_0x423e72(0x185)])&&(_0x3eaeab[_0x423e72(0x256)]=_0x3a5c19['split'](':')[0x1][_0x423e72(0x1d4)]());}),_0x1763c4(_0x3eaeab);}else _0x25254d['HkPXs'](_0x25254d['ulnlv'],_0x25254d[_0x596d22(0x1f1)])?_0x25254d[_0x596d22(0x21c)](_0x6403ff,_0x5f180b['includes'](_0x25254d[_0x596d22(0x1e8)])):_0x25254d[_0x596d22(0x21c)](_0x1763c4,null);}else _0x18b81d[_0x596d22(0x23f)](_0x1c9156,null);}),_0x1c23e6['on']('error',()=>{const _0xe7f1ee=_0x557a03;_0x2855c2[_0xe7f1ee(0x28e)](_0x2855c2[_0xe7f1ee(0x27c)],_0x2855c2['fCGnN'])?_0x1c4d1a=ABXqrA[_0xe7f1ee(0x1cd)](_0x24bbd6,ABXqrA[_0xe7f1ee(0x18c)]):_0x2855c2[_0xe7f1ee(0x1fd)](_0x1763c4,null);});});}async function loadDevicesFromConfig(){const _0x331bbd=_0x1871dc,_0x3f433d={};_0x3f433d[_0x331bbd(0x1aa)]=_0x331bbd(0x233),_0x3f433d[_0x331bbd(0x257)]=_0x331bbd(0x23c),_0x3f433d['LBKLb']=function(_0x301dab,_0x23f1da){return _0x301dab||_0x23f1da;},_0x3f433d[_0x331bbd(0x230)]=function(_0x21afa2,_0x335378){return _0x21afa2!==_0x335378;},_0x3f433d['LLaqF']=_0x331bbd(0x26b),_0x3f433d[_0x331bbd(0x245)]=_0x331bbd(0x1b7),_0x3f433d[_0x331bbd(0x1f9)]='scsTx',_0x3f433d[_0x331bbd(0x19b)]=_0x331bbd(0x270),_0x3f433d[_0x331bbd(0x1e1)]='XIblq',_0x3f433d['YsExQ']=function(_0x32f74f,_0x28e060){return _0x32f74f>_0x28e060;},_0x3f433d[_0x331bbd(0x207)]=_0x331bbd(0x286),_0x3f433d[_0x331bbd(0x287)]=_0x331bbd(0x23a),_0x3f433d[_0x331bbd(0x1f6)]=_0x331bbd(0x216),_0x3f433d[_0x331bbd(0x1b6)]=_0x331bbd(0x1ed),_0x3f433d['kUjJG']=_0x331bbd(0x19e);const _0xaf1e1b=_0x3f433d;try{const _0x19a943=await fs[_0x331bbd(0x179)](DEVICE_CONFIG,_0xaf1e1b['kUjJG']),_0x4e5a26=_0x19a943[_0x331bbd(0x289)]('\x0a')[_0x331bbd(0x176)](_0x2901de=>_0x2901de[_0x331bbd(0x1d4)]()&&!_0x2901de[_0x331bbd(0x1ea)]('#'))[_0x331bbd(0x1ae)](_0x318a76=>{const _0x1c6f85=_0x331bbd,_0x50a352={};_0x50a352[_0x1c6f85(0x244)]=_0xaf1e1b['TLtKe'];const _0x429718=_0x50a352,_0x11eb5b=_0x318a76[_0x1c6f85(0x289)](',')[_0x1c6f85(0x1ae)](_0xfa189d=>_0xfa189d['trim']()),[_0x46ca8a,_0x301b02,_0x136635,_0x3e46dc,_0xd21c97]=_0x11eb5b;let _0x32a0db=_0xaf1e1b[_0x1c6f85(0x1bd)](_0x3e46dc,_0xaf1e1b[_0x1c6f85(0x1aa)]);if(!_0x3e46dc){if(_0xaf1e1b['qfJBd'](_0xaf1e1b[_0x1c6f85(0x293)],_0xaf1e1b[_0x1c6f85(0x293)]))_0x34fdba=_0x429718['IxaVA'];else{if(_0x301b02&&_0x301b02[_0x1c6f85(0x264)](':')&&_0x301b02['match'](/^\d+\.\d+\.\d+\.\d+:\d+$/)){if(_0xaf1e1b[_0x1c6f85(0x230)](_0xaf1e1b[_0x1c6f85(0x245)],_0xaf1e1b['PXAdY']))_0x32a0db=_0xaf1e1b[_0x1c6f85(0x257)];else{if(_0x35b086['name'])_0x59625a['name']=_0x332523[_0x1c6f85(0x18a)];if(_0x579943[_0x1c6f85(0x256)])_0x4f9340[_0x1c6f85(0x256)]=_0x5aeecb[_0x1c6f85(0x256)];}}else{if(_0x301b02&&_0x301b02[_0x1c6f85(0x1b4)]<0x14&&!_0x301b02[_0x1c6f85(0x264)]('-'))_0xaf1e1b[_0x1c6f85(0x230)](_0xaf1e1b['knrck'],_0xaf1e1b[_0x1c6f85(0x1e1)])?_0x32a0db=_0xaf1e1b[_0x1c6f85(0x257)]:_0x5df3ee[_0x1c6f85(0x18a)]=_0x47609e[_0x1c6f85(0x289)](':')[0x1][_0x1c6f85(0x1d4)]();else _0x301b02&&_0x301b02['includes']('-')&&_0xaf1e1b[_0x1c6f85(0x194)](_0x301b02[_0x1c6f85(0x1b4)],0x1e)&&(_0x1c6f85(0x286)===_0xaf1e1b[_0x1c6f85(0x207)]?_0x32a0db=_0xaf1e1b['qjDNT']:_0x3031c0=_0xaf1e1b['qjDNT']);}}}const _0x12f759=_0xd21c97||(_0x136635?_0xaf1e1b['KoUhE']:_0xaf1e1b[_0x1c6f85(0x1f6)]);return{'name':_0x46ca8a,'udid':_0x301b02,'ip':_0xaf1e1b[_0x1c6f85(0x1bd)](_0x136635,''),'platform':_0x32a0db,'type':_0x12f759,'connectionType':_0x12f759,'status':_0xaf1e1b[_0x1c6f85(0x1b6)]};});return _0x4e5a26;}catch(_0x2dbb31){return[];}}async function loadWirelessDevices(){const _0x491955=_0x1871dc,_0x322e96={'sxhhP':function(_0x22a531){return _0x22a531();}},_0xca5539=await _0x322e96[_0x491955(0x1f8)](loadDevicesFromConfig);return _0xca5539[_0x491955(0x176)](_0x182121=>_0x182121['ip']);}async function saveUSBDeviceToConfig(_0x4f6773){const _0x3a36c3=_0x1871dc,_0x389d57={'ZDazO':_0x3a36c3(0x23a),'Qmrjz':_0x3a36c3(0x28a),'VYwjd':_0x3a36c3(0x23c),'iRlJW':function(_0x4e0863,_0x4acad9){return _0x4e0863<_0x4acad9;},'rTuEV':function(_0x264825,_0x2b89c3){return _0x264825>_0x2b89c3;},'kTjdC':function(_0x29bad8,_0x4d160b){return _0x29bad8!==_0x4d160b;},'liAvK':_0x3a36c3(0x226),'sfCjo':function(_0x1ef2cf){return _0x1ef2cf();},'yBZmM':'hMuCA','XsyGa':_0x3a36c3(0x186),'aooLS':_0x3a36c3(0x1c1),'pwMmj':_0x3a36c3(0x1b5),'EmlBZ':'utf-8','NBnCi':_0x3a36c3(0x202),'DBiUf':'ios','dNSpA':_0x3a36c3(0x19d),'jhmAf':_0x3a36c3(0x222)};try{if(_0x389d57[_0x3a36c3(0x17a)](_0x389d57[_0x3a36c3(0x1a3)],_0x389d57[_0x3a36c3(0x1a3)])){const _0x1944dc={..._0x236058};return _0x1944dc[_0x3a36c3(0x1c2)]=_0x389d57[_0x3a36c3(0x1a8)],_0x1944dc['status']=_0x389d57[_0x3a36c3(0x1cb)],_0x1944dc;}else{const _0x5266ab=await _0x389d57['sfCjo'](loadDevicesFromConfig),_0x2fe7db=_0x5266ab[_0x3a36c3(0x1d8)](_0x4543eb=>_0x4543eb[_0x3a36c3(0x18e)]===_0x4f6773[_0x3a36c3(0x18e)]);if(!_0x2fe7db){if(_0x389d57[_0x3a36c3(0x291)]===_0x389d57[_0x3a36c3(0x195)]){if(_0x311f95&&_0x4f14ed[_0x3a36c3(0x264)](':')&&_0x3a5c58[_0x3a36c3(0x183)](/^\d+\.\d+\.\d+\.\d+:\d+$/))_0x4c9d69=oKYAHr[_0x3a36c3(0x26e)];else{if(_0x5723fd&&oKYAHr[_0x3a36c3(0x28f)](_0xce7011[_0x3a36c3(0x1b4)],0x14)&&!_0x11966a[_0x3a36c3(0x264)]('-'))_0x4bc52d=oKYAHr[_0x3a36c3(0x26e)];else _0x9514d5&&_0x4aca7c[_0x3a36c3(0x264)]('-')&&oKYAHr['rTuEV'](_0xae1f23['length'],0x1e)&&(_0x2accb6='ios');}}else{let _0x389042='';try{_0x389d57[_0x3a36c3(0x1ac)]===_0x389d57[_0x3a36c3(0x218)]?_0xc1a4d1=_0x3a36c3(0x22c):_0x389042=await fs[_0x3a36c3(0x179)](DEVICE_CONFIG,_0x389d57[_0x3a36c3(0x252)]);}catch(_0x2ecbf4){_0x389d57[_0x3a36c3(0x17a)](_0x389d57['NBnCi'],_0x389d57['NBnCi'])?_0x31e3a0=![]:_0x389042='#\x20Device\x20Configuration\x20(Auto-updated)\x0a#\x20Format:\x20device_name,udid,ip_address,platform,type\x0a#\x20Platform:\x20ios\x20|\x20android\x0a#\x20Type:\x20usb\x20|\x20wireless\x0a#\x20\x0a#\x20🔌\x20USB\x20DEVICES:\x20Automatically\x20detected\x20and\x20saved\x20here\x0a#\x20\x20\x20\x20-\x20No\x20configuration\x20needed\x20for\x20USB\x20connection\x0a#\x20\x20\x20\x20-\x20Add\x20IP\x20address\x20to\x20enable\x20wireless\x20support\x20later\x0a#\x0a#\x20📡\x20WIRELESS\x20DEVICES:\x20Manually\x20add\x20with\x20IP\x20address\x0a#\x20\x20\x20\x20-\x20Format:\x20device_name,udid,ip_address,platform,wireless\x0a#\x20\x20\x20\x20-\x20iOS:\x20Device\x20must\x20be\x20paired\x20in\x20Xcode,\x20WebDriverAgent\x20running\x0a#\x20\x20\x20\x20-\x20Android:\x20Enable\x20wireless\x20ADB\x20first\x0a#\x0a#\x20Example\x20entries:\x0a#\x20iPhone17,00008130-001945C63ED3401E,,ios,usb\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20(iOS\x20USB\x20-\x20auto-detected)\x0a#\x20iPhone16P,00008140-001C24361E41801C,10.173.221.204,ios,wireless\x20\x20(iOS\x20Wireless)\x0a#\x20Pixel8,1A2B3C4D5E6F,,android,usb\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20(Android\x20USB\x20-\x20auto-detected)\x0a#\x20GalaxyS23,ABCD1234,192.168.1.150,android,wireless\x20\x20\x20\x20\x20(Android\x20Wireless)\x0a\x0a';}const _0x21ddff=_0x4f6773[_0x3a36c3(0x258)]||_0x389d57[_0x3a36c3(0x189)],_0x1501af=_0x4f6773[_0x3a36c3(0x18a)]+','+_0x4f6773['udid']+',,'+_0x21ddff+_0x3a36c3(0x1eb);return _0x389042+=_0x1501af,await fs[_0x3a36c3(0x283)](DEVICE_CONFIG,_0x389042,_0x389d57[_0x3a36c3(0x252)]),console[_0x3a36c3(0x19a)](_0x3a36c3(0x198)+_0x21ddff[_0x3a36c3(0x219)]()+_0x3a36c3(0x22a)+_0x4f6773[_0x3a36c3(0x18a)]),!![];}}return![];}}catch(_0x4a9e9a){if(_0x3a36c3(0x19d)!==_0x389d57[_0x3a36c3(0x1e4)])_0x500671[_0x3a36c3(0x264)]('DeviceName:')&&(_0x2278e8[_0x3a36c3(0x18a)]=_0x59a978[_0x3a36c3(0x289)](':')[0x1][_0x3a36c3(0x1d4)]()),_0x10385a[_0x3a36c3(0x264)](_0x3a36c3(0x26a))&&(_0x338b54[_0x3a36c3(0x256)]=_0x511399['split'](':')[0x1][_0x3a36c3(0x1d4)]());else return console['error'](_0x389d57[_0x3a36c3(0x1e5)],_0x4a9e9a),![];}}function _0x1edb(_0x1488f4,_0x4d1629){_0x1488f4=_0x1488f4-0x173;const _0x462585=_0x4625();let _0x1edb41=_0x462585[_0x1488f4];if(_0x1edb['FyPYsk']===undefined){var _0x470856=function(_0x285cc1){const _0xe4206f='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x48599d='',_0x4926a1='';for(let _0x25b4d5=0x0,_0x5816cc,_0x4d00b0,_0x123d63=0x0;_0x4d00b0=_0x285cc1['charAt'](_0x123d63++);~_0x4d00b0&&(_0x5816cc=_0x25b4d5%0x4?_0x5816cc*0x40+_0x4d00b0:_0x4d00b0,_0x25b4d5++%0x4)?_0x48599d+=String['fromCharCode'](0xff&_0x5816cc>>(-0x2*_0x25b4d5&0x6)):0x0){_0x4d00b0=_0xe4206f['indexOf'](_0x4d00b0);}for(let _0x44dfda=0x0,_0x33797f=_0x48599d['length'];_0x44dfda<_0x33797f;_0x44dfda++){_0x4926a1+='%'+('00'+_0x48599d['charCodeAt'](_0x44dfda)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x4926a1);};_0x1edb['FzagYA']=_0x470856,_0x1edb['rFpvEj']={},_0x1edb['FyPYsk']=!![];}const _0x4f562c=_0x462585[0x0],_0x57a5d5=_0x1488f4+_0x4f562c,_0x3f7a2f=_0x1edb['rFpvEj'][_0x57a5d5];return!_0x3f7a2f?(_0x1edb41=_0x1edb['FzagYA'](_0x1edb41),_0x1edb['rFpvEj'][_0x57a5d5]=_0x1edb41):_0x1edb41=_0x3f7a2f,_0x1edb41;}function checkWirelessConnectivity(_0x3753a4){const _0x1a2eef=_0x1871dc,_0x534cc1={'CunyJ':_0x1a2eef(0x1e3),'KbGcu':function(_0x16bc2e,_0xb1083d){return _0x16bc2e!==_0xb1083d;},'DjBAD':_0x1a2eef(0x1bb),'POOzI':function(_0x2f78bf,_0x378cd3){return _0x2f78bf(_0x378cd3);},'oORoC':_0x1a2eef(0x1b0),'MCBAW':_0x1a2eef(0x237),'VVcWh':function(_0x4e88a5,_0x11d021){return _0x4e88a5(_0x11d021);},'NSnXl':function(_0x1d32d8,_0x1d8ba9,_0x3cca33){return _0x1d32d8(_0x1d8ba9,_0x3cca33);},'YMyrO':_0x1a2eef(0x234),'CevIs':_0x1a2eef(0x232),'NeKkm':_0x1a2eef(0x1d9),'ZdoBk':_0x1a2eef(0x214),'RmFSf':_0x1a2eef(0x18f),'CVIWp':function(_0x23600c,_0x585f7c,_0x3f17ba){return _0x23600c(_0x585f7c,_0x3f17ba);}};return new Promise(_0x2bbb42=>{const _0x36d05f=_0x1a2eef,_0x2fdd8c={'luVWx':function(_0x5b52d8,_0x5ce97c){return _0x534cc1['KbGcu'](_0x5b52d8,_0x5ce97c);},'giTEo':'sBtut','SSbLc':_0x534cc1['MCBAW'],'SVpDq':function(_0x402453,_0x1237eb){const _0xf52ed4=_0x1edb;return _0x534cc1[_0xf52ed4(0x246)](_0x402453,_0x1237eb);}},_0x1b4277=_0x534cc1[_0x36d05f(0x20d)](spawn,_0x534cc1['YMyrO'],['-s',_0x534cc1['CevIs'],'2',_0x534cc1[_0x36d05f(0x1d0)],'3',_0x36d05f(0x1f7)+_0x3753a4['ip']+_0x36d05f(0x19f)]);let _0x3f2239='';_0x1b4277['stdout']['on'](_0x534cc1[_0x36d05f(0x181)],_0x45e31b=>{const _0x3cf9a2=_0x36d05f;if(_0x2fdd8c['luVWx'](_0x2fdd8c[_0x3cf9a2(0x1d1)],_0x2fdd8c['SSbLc']))_0x3f2239+=_0x45e31b[_0x3cf9a2(0x26d)]();else return[];}),_0x1b4277['on'](_0x534cc1['RmFSf'],()=>{const _0x42af0c=_0x36d05f,_0x486f95={};_0x486f95[_0x42af0c(0x1dc)]=_0x534cc1[_0x42af0c(0x278)];const _0x3c8ab4=_0x486f95;if(_0x534cc1['KbGcu'](_0x534cc1['DjBAD'],_0x42af0c(0x1bb))){const _0x1ef5a7={},_0x4b9aa0=_0xb5f470['split']('\x0a');_0x4b9aa0['forEach'](_0x1311f4=>{const _0xbf493d=_0x42af0c;_0x1311f4[_0xbf493d(0x264)](SlveYY[_0xbf493d(0x1dc)])&&(_0x1ef5a7['name']=_0x1311f4[_0xbf493d(0x289)](':')[0x1][_0xbf493d(0x1d4)]()),_0x1311f4[_0xbf493d(0x264)]('ProductVersion:')&&(_0x1ef5a7['osVersion']=_0x1311f4[_0xbf493d(0x289)](':')[0x1]['trim']());}),myFQLf['SVpDq'](_0x4ea4dd,_0x1ef5a7);}else _0x534cc1[_0x42af0c(0x28c)](_0x2bbb42,_0x3f2239[_0x42af0c(0x264)](_0x534cc1[_0x42af0c(0x220)]));}),_0x534cc1[_0x36d05f(0x24a)](setTimeout,()=>{const _0xd13894=_0x36d05f;_0x1b4277[_0xd13894(0x17d)](),_0x534cc1[_0xd13894(0x28c)](_0x2bbb42,![]);},0xbb8);});}function checkUSBWDAConnectivityOnPort(_0x121862){const _0x203706=_0x1871dc,_0x478be6={'DpaRA':'\x22state\x22','SNmeo':function(_0x2b221f,_0xd2d9ba,_0x5c3b9a){return _0x2b221f(_0xd2d9ba,_0x5c3b9a);},'bubzd':_0x203706(0x1d9),'arzQo':'data','dlRXt':function(_0x24df6f,_0x3b4f58,_0x2d4e4e){return _0x24df6f(_0x3b4f58,_0x2d4e4e);}};return new Promise(_0x490a45=>{const _0x5c92f0=_0x203706,_0x265ba0={};_0x265ba0['WznXr']=_0x478be6[_0x5c92f0(0x193)];const _0x53996e=_0x265ba0,_0x568583=_0x478be6['SNmeo'](spawn,_0x5c92f0(0x234),['-s',_0x5c92f0(0x232),'1',_0x478be6[_0x5c92f0(0x260)],'2','http://localhost:'+_0x121862+_0x5c92f0(0x211)]);let _0x3e7fa3='';_0x568583[_0x5c92f0(0x1fb)]['on'](_0x478be6[_0x5c92f0(0x25c)],_0x1b0753=>{const _0x554ffb=_0x5c92f0;_0x3e7fa3+=_0x1b0753[_0x554ffb(0x26d)]();}),_0x568583['on'](_0x5c92f0(0x18f),()=>{_0x490a45(_0x3e7fa3['includes'](_0x53996e['WznXr']));}),_0x478be6[_0x5c92f0(0x175)](setTimeout,()=>{const _0x528636=_0x5c92f0;_0x568583[_0x528636(0x17d)](),_0x490a45(![]);},0x9c4);});}async function discoverAllDevices(){const _0x3ca579=_0x1871dc,_0x5ed526={'sNPmf':'Error\x20detecting\x20Android\x20USB\x20devices:','DibqA':'ios','MwDqj':'usb','KHmTC':_0x3ca579(0x1c3),'phRvp':'\x20\x20\x20\x20-\x20Wireless\x20devices\x20are\x20configured\x20in\x20devices.conf','yWxOC':_0x3ca579(0x215),'Vmiid':'❌\x20No\x20devices\x20found\x0a','HnkUe':'\x20\x20\x20\x20-\x20ADB\x20is\x20installed:\x20brew\x20install\x20android-platform-tools\x0a','HXswV':'\x20\x20\x20\x20-\x20Device\x20is\x20authorized\x20(check\x20device\x20screen)','zFVCG':_0x3ca579(0x178),'Imzba':function(_0x23b4f5,_0x3f47e2){return _0x23b4f5===_0x3f47e2;},'Pcpnt':_0x3ca579(0x240),'LElDo':_0x3ca579(0x22b),'ewaAO':function(_0x5a7cfb,_0x165754){return _0x5a7cfb(_0x165754);},'xBQVH':_0x3ca579(0x23c),'sfqyr':function(_0x15c3a7,_0x2bdb4e){return _0x15c3a7===_0x2bdb4e;},'ZBaZD':_0x3ca579(0x173),'eyfUG':_0x3ca579(0x21b),'EvXBe':'wireless','NFBOh':_0x3ca579(0x28a),'lECQI':function(_0x554dbb,_0x258c5d){return _0x554dbb(_0x258c5d);},'Mercy':_0x3ca579(0x1b0),'GVpvH':function(_0x3a3eba,_0x269191,_0x56c544){return _0x3a3eba(_0x269191,_0x56c544);},'iAzMb':_0x3ca579(0x234),'mAYiu':_0x3ca579(0x1d9),'aBtfb':function(_0x10a127,_0x3358a1){return _0x10a127===_0x3358a1;},'JTTrJ':function(_0x5057db,_0x34298a){return _0x5057db!==_0x34298a;},'Piokd':_0x3ca579(0x208),'yCdjJ':_0x3ca579(0x294),'EgXhZ':function(_0x4c1a94){return _0x4c1a94();},'VtTGK':function(_0xf9a153,_0x50e941){return _0xf9a153!==_0x50e941;},'NUIpr':_0x3ca579(0x275),'cfnIg':function(_0x5a843f,_0x131cda){return _0x5a843f(_0x131cda);},'bafFH':'offline','THPQF':function(_0x5e8725,_0x2e9a64){return _0x5e8725===_0x2e9a64;},'UITBQ':function(_0xa248c2,_0xa260c6){return _0xa248c2(_0xa260c6);}},_0x4edc99=await _0x5ed526[_0x3ca579(0x25d)](detectUSBDevices),_0x1f4fe7=0x1fa4;for(let _0x35c79a=0x0;_0x35c79a<_0x4edc99[_0x3ca579(0x1b4)];_0x35c79a++){const _0x204c02=_0x4edc99[_0x35c79a];if(_0x204c02[_0x3ca579(0x258)]===_0x5ed526[_0x3ca579(0x1a7)]){const _0x2b7441=await _0x5ed526[_0x3ca579(0x277)](getUSBDeviceInfo,_0x204c02[_0x3ca579(0x18e)]);if(_0x2b7441){if(_0x5ed526['VtTGK'](_0x5ed526[_0x3ca579(0x1bf)],_0x3ca579(0x282))){if(_0x2b7441[_0x3ca579(0x18a)])_0x204c02[_0x3ca579(0x18a)]=_0x2b7441[_0x3ca579(0x18a)];if(_0x2b7441[_0x3ca579(0x256)])_0x204c02[_0x3ca579(0x256)]=_0x2b7441[_0x3ca579(0x256)];}else _0x431a36[_0x3ca579(0x28a)](wEPQzr[_0x3ca579(0x221)],_0x1f0493[_0x3ca579(0x1e7)]);}_0x204c02[_0x3ca579(0x1c2)]=_0x5ed526[_0x3ca579(0x27e)];const _0x1d81d5=_0x1f4fe7+_0x35c79a,_0x356644=await _0x5ed526[_0x3ca579(0x17c)](checkUSBWDAConnectivityOnPort,_0x1d81d5);_0x204c02['status']=_0x356644?_0x5ed526[_0x3ca579(0x20b)]:_0x5ed526[_0x3ca579(0x1de)],_0x204c02[_0x3ca579(0x200)]=_0x1d81d5;}else _0x5ed526['THPQF'](_0x204c02[_0x3ca579(0x258)],_0x5ed526[_0x3ca579(0x273)])&&(_0x204c02[_0x3ca579(0x254)]=_0x204c02[_0x3ca579(0x254)]||'online');await _0x5ed526['UITBQ'](saveUSBDeviceToConfig,_0x204c02);}const _0x433467=await _0x5ed526[_0x3ca579(0x25d)](loadWirelessDevices),_0x23179d=_0x433467[_0x3ca579(0x1ae)](async _0x33b9b4=>{const _0x530f97=_0x3ca579,_0x49151b={};_0x49151b[_0x530f97(0x24c)]=_0x5ed526[_0x530f97(0x1a7)],_0x49151b[_0x530f97(0x25a)]=_0x5ed526[_0x530f97(0x27e)],_0x49151b[_0x530f97(0x192)]=_0x530f97(0x1ed),_0x49151b['hVbEU']=_0x530f97(0x290),_0x49151b[_0x530f97(0x17f)]=_0x5ed526[_0x530f97(0x209)],_0x49151b[_0x530f97(0x199)]=_0x5ed526['phRvp'],_0x49151b[_0x530f97(0x1b2)]=_0x5ed526[_0x530f97(0x23d)],_0x49151b[_0x530f97(0x22d)]=_0x5ed526[_0x530f97(0x271)],_0x49151b[_0x530f97(0x213)]=_0x5ed526['HnkUe'],_0x49151b[_0x530f97(0x236)]=_0x530f97(0x250),_0x49151b[_0x530f97(0x276)]=_0x5ed526['HXswV'],_0x49151b[_0x530f97(0x174)]=_0x5ed526[_0x530f97(0x27b)];const _0xe1f7b2=_0x49151b;try{let _0x4f7b75=![];if(_0x5ed526[_0x530f97(0x1e6)](_0x33b9b4[_0x530f97(0x258)],_0x530f97(0x233))){if(_0x5ed526[_0x530f97(0x1e2)]===_0x5ed526[_0x530f97(0x1ba)]){const _0x50f0fa=_0x3c4e0e['trim']()[_0x530f97(0x289)]('\x0a')[_0x530f97(0x176)](_0x2fa42f);_0x50f0fa[_0x530f97(0x1fe)](_0x290c44=>{const _0x2e6f79=_0x530f97;_0x2ab025[_0x2e6f79(0x1cc)]({'name':'iOS-'+_0x290c44[_0x2e6f79(0x24b)](0x0,0x8),'udid':_0x290c44[_0x2e6f79(0x1d4)](),'platform':lDOsuW[_0x2e6f79(0x24c)],'type':lDOsuW[_0x2e6f79(0x25a)],'connectionType':lDOsuW[_0x2e6f79(0x25a)],'status':lDOsuW[_0x2e6f79(0x192)]});});}else _0x4f7b75=await _0x5ed526[_0x530f97(0x277)](checkWirelessConnectivity,_0x33b9b4);}else{if(_0x33b9b4[_0x530f97(0x258)]===_0x5ed526[_0x530f97(0x273)]&&androidDetection)try{const _0x3b3fae=await androidDetection['detectWirelessDevices']();_0x4f7b75=_0x3b3fae[_0x530f97(0x1d8)](_0x1f06be=>_0x1f06be[_0x530f97(0x18e)]===_0x33b9b4[_0x530f97(0x18e)]||_0x1f06be[_0x530f97(0x266)]===_0x33b9b4['udid']);}catch(_0x2acb71){if(_0x5ed526[_0x530f97(0x196)](_0x5ed526[_0x530f97(0x272)],'uSexY')){const _0x124917=_0xe1f7b2[_0x530f97(0x191)]['split']('|');let _0x4299ee=0x0;while(!![]){switch(_0x124917[_0x4299ee++]){case'0':_0x2e136c[_0x530f97(0x19a)](_0xe1f7b2[_0x530f97(0x17f)]);continue;case'1':_0x554752[_0x530f97(0x19a)](_0xe1f7b2[_0x530f97(0x199)]);continue;case'2':_0x284177[_0x530f97(0x19a)](_0xe1f7b2[_0x530f97(0x1b2)]);continue;case'3':_0x5e4058['log'](_0xe1f7b2[_0x530f97(0x22d)]);continue;case'4':_0x23d2f6[_0x530f97(0x19a)](_0x530f97(0x24f));continue;case'5':_0x1ddabc[_0x530f97(0x19a)](_0xe1f7b2[_0x530f97(0x213)]);continue;case'6':_0x3edad2[_0x530f97(0x1c6)](0x1);continue;case'7':_0x371704[_0x530f97(0x19a)](_0xe1f7b2['oKZPP']);continue;case'8':_0x22ad1f[_0x530f97(0x19a)](_0x530f97(0x1a0));continue;case'9':_0xb60d68[_0x530f97(0x19a)](_0xe1f7b2[_0x530f97(0x276)]);continue;case'10':_0x4d2b06[_0x530f97(0x19a)](_0xe1f7b2['swbHl']);continue;}break;}}else _0x4f7b75=![];}}const _0x5943a3={..._0x33b9b4};return _0x5943a3['connectionType']='wireless',_0x5943a3['status']=_0x4f7b75?_0x5ed526[_0x530f97(0x20b)]:_0x530f97(0x1a4),_0x5943a3;}catch(_0xa85287){const _0x29828e={..._0x33b9b4};return _0x29828e[_0x530f97(0x1c2)]=_0x5ed526[_0x530f97(0x1cf)],_0x29828e[_0x530f97(0x254)]=_0x5ed526[_0x530f97(0x242)],_0x29828e;}}),_0x50c1a3=await Promise['all'](_0x23179d),_0x3dff6b=[..._0x4edc99],_0x3d4055=new Set(_0x4edc99[_0x3ca579(0x1ae)](_0x1a4118=>_0x1a4118['udid']));return _0x50c1a3['forEach'](_0x4163be=>{const _0x3d304a=_0x3ca579,_0x313865={'yODun':function(_0x564526,_0x3bdb0f){const _0xfd8030=_0x1edb;return _0x5ed526[_0xfd8030(0x269)](_0x564526,_0x3bdb0f);},'hlRfb':_0x5ed526['Mercy'],'lqdCR':function(_0x1fe901,_0x49b6ae,_0x58b6a4){const _0x200d3d=_0x1edb;return _0x5ed526[_0x200d3d(0x284)](_0x1fe901,_0x49b6ae,_0x58b6a4);},'SjrYu':_0x5ed526[_0x3d304a(0x177)],'fGSOe':_0x5ed526[_0x3d304a(0x228)],'KLNAH':_0x3d304a(0x214),'hKHek':_0x3d304a(0x18f),'LrWnA':_0x3d304a(0x216),'NSQVy':function(_0x40b853,_0x425302){const _0x56f0f9=_0x3d304a;return _0x5ed526[_0x56f0f9(0x204)](_0x40b853,_0x425302);}};if(_0x5ed526[_0x3d304a(0x1da)](_0x5ed526['Piokd'],_0x5ed526[_0x3d304a(0x1c4)])){const _0x1f3c70={'PcxGX':function(_0x58ecea,_0x3e4616){return eIyhyE['yODun'](_0x58ecea,_0x3e4616);},'ZlfvK':eIyhyE[_0x3d304a(0x247)]},_0x53f868=eIyhyE[_0x3d304a(0x190)](_0x5c38d0,eIyhyE['SjrYu'],['-s',_0x3d304a(0x232),'2',eIyhyE[_0x3d304a(0x1ec)],'3','http://'+_0x540a81['ip']+_0x3d304a(0x19f)]);let _0x158f41='';_0x53f868[_0x3d304a(0x1fb)]['on'](eIyhyE[_0x3d304a(0x197)],_0x2000e3=>{_0x158f41+=_0x2000e3['toString']();}),_0x53f868['on'](eIyhyE[_0x3d304a(0x1ee)],()=>{const _0x174b38=_0x3d304a;_0x1f3c70[_0x174b38(0x1ab)](_0x16a3e2,_0x158f41[_0x174b38(0x264)](_0x1f3c70[_0x174b38(0x28d)]));}),eIyhyE[_0x3d304a(0x190)](_0x47ffe1,()=>{const _0xe19769=_0x3d304a;_0x53f868[_0xe19769(0x17d)](),_0x30abdb(![]);},0xbb8);}else{if(!_0x3d4055[_0x3d304a(0x27d)](_0x4163be[_0x3d304a(0x18e)])){if(_0x5ed526[_0x3d304a(0x1f4)]!==_0x5ed526[_0x3d304a(0x1f4)]){const _0xdf532a={};_0xdf532a['XQwVT']=eIyhyE[_0x3d304a(0x23b)];const _0x4e104a=_0xdf532a;if(eIyhyE[_0x3d304a(0x1d6)](_0x461a0a,0x0)&&_0x425c7b[_0x3d304a(0x1d4)]()){const _0x3040e1=_0x288f01['trim']()[_0x3d304a(0x289)]('\x0a')[_0x3d304a(0x176)](_0x483966);_0x3040e1[_0x3d304a(0x1fe)](_0x2a6815=>{const _0x2557f=_0x3d304a;_0xcc43ff[_0x2557f(0x1cc)]({'name':_0x2557f(0x17e)+_0x2a6815[_0x2557f(0x24b)](0x0,0x8),'udid':_0x2a6815[_0x2557f(0x1d4)](),'platform':_0x2557f(0x233),'type':_0x4e104a[_0x2557f(0x1c7)],'connectionType':_0x4e104a[_0x2557f(0x1c7)],'status':_0x2557f(0x1ed)});});}_0x585202(_0x3ab8d0);}else _0x3dff6b[_0x3d304a(0x1cc)](_0x4163be);}}}),_0x3dff6b;}require[_0x1871dc(0x281)]===module&&((async()=>{const _0x34bbc8=_0x1871dc,_0x42f584={'rCpoV':_0x34bbc8(0x216),'qnmEU':function(_0x3a760c,_0x1b63b7){return _0x3a760c===_0x1b63b7;},'DuveZ':_0x34bbc8(0x21b),'nbcPd':_0x34bbc8(0x28b),'urmhw':_0x34bbc8(0x203),'MPhVf':function(_0x4baea4){return _0x4baea4();},'jOygI':_0x34bbc8(0x1d2),'ShfBk':_0x34bbc8(0x288),'YhVTB':'\x20\x20\x20\x20-\x20Wireless\x20devices\x20are\x20configured\x20in\x20devices.conf','rmTgx':_0x34bbc8(0x178),'IWnQV':_0x34bbc8(0x24f),'oIRRl':'\x20\x20\x20\x20-\x20USB\x20devices\x20are\x20connected\x20and\x20trusted','IwtyR':_0x34bbc8(0x250),'fpmkg':_0x34bbc8(0x1e0),'eqJke':_0x34bbc8(0x210),'muCey':_0x34bbc8(0x215),'cApgU':_0x34bbc8(0x212)};console[_0x34bbc8(0x19a)](_0x42f584[_0x34bbc8(0x238)]);const _0x558651=await _0x42f584[_0x34bbc8(0x18b)](discoverAllDevices);if(_0x42f584['qnmEU'](_0x558651[_0x34bbc8(0x1b4)],0x0)){const _0x1b6880=_0x42f584[_0x34bbc8(0x267)]['split']('|');let _0x3b8817=0x0;while(!![]){switch(_0x1b6880[_0x3b8817++]){case'0':console['log'](_0x42f584['ShfBk']);continue;case'1':process[_0x34bbc8(0x1c6)](0x1);continue;case'2':console['log'](_0x42f584[_0x34bbc8(0x188)]);continue;case'3':console[_0x34bbc8(0x19a)](_0x42f584[_0x34bbc8(0x21e)]);continue;case'4':console['log'](_0x42f584[_0x34bbc8(0x1a6)]);continue;case'5':console[_0x34bbc8(0x19a)](_0x42f584[_0x34bbc8(0x25b)]);continue;case'6':console['log'](_0x34bbc8(0x1a0));continue;case'7':console['log'](_0x42f584['IwtyR']);continue;case'8':console['log'](_0x42f584[_0x34bbc8(0x229)]);continue;case'9':console[_0x34bbc8(0x19a)](_0x42f584[_0x34bbc8(0x21d)]);continue;case'10':console[_0x34bbc8(0x19a)](_0x42f584[_0x34bbc8(0x1f2)]);continue;}break;}}console[_0x34bbc8(0x19a)](_0x34bbc8(0x27a)+_0x558651[_0x34bbc8(0x1b4)]+_0x34bbc8(0x249)),_0x558651[_0x34bbc8(0x1fe)]((_0x45e31d,_0x5b40f2)=>{const _0xd6ff56=_0x34bbc8,_0x2d66a1=_0x45e31d['platform']||_0xd6ff56(0x233),_0x2c4199=_0x45e31d[_0xd6ff56(0x1c5)]||_0x45e31d[_0xd6ff56(0x1c2)]||_0x42f584['rCpoV'],_0x3fb4f0=_0x42f584['qnmEU'](_0x2d66a1,_0xd6ff56(0x233))?'🍎':'🤖',_0x14a23c=_0x42f584[_0xd6ff56(0x259)](_0x2c4199,_0x42f584[_0xd6ff56(0x21a)])?'🔌':'📡',_0x36d0b7=_0x42f584[_0xd6ff56(0x259)](_0x45e31d[_0xd6ff56(0x254)],_0x42f584[_0xd6ff56(0x24e)])?'✅':_0x45e31d[_0xd6ff56(0x254)]===_0x42f584[_0xd6ff56(0x201)]?'✅':'⚠️';console[_0xd6ff56(0x19a)](_0x5b40f2+0x1+'.\x20'+_0x3fb4f0+'\x20'+_0x14a23c+'\x20'+_0x45e31d[_0xd6ff56(0x18a)]+'\x20('+_0x2d66a1[_0xd6ff56(0x219)]()+_0xd6ff56(0x1b3)+_0x2c4199['toUpperCase']()+')\x20'+_0x36d0b7),console['log'](_0xd6ff56(0x1ef)+(_0x45e31d['udid']||_0x45e31d[_0xd6ff56(0x266)]));if(_0x45e31d['ip'])console[_0xd6ff56(0x19a)]('\x20\x20\x20IP:\x20'+_0x45e31d['ip']);if(_0x45e31d[_0xd6ff56(0x1e9)])console[_0xd6ff56(0x19a)](_0xd6ff56(0x255)+_0x45e31d['androidVersion']);console[_0xd6ff56(0x19a)]('');}),process['argv'][_0x34bbc8(0x264)](_0x42f584[_0x34bbc8(0x217)])&&console[_0x34bbc8(0x19a)](JSON[_0x34bbc8(0x25e)](_0x558651,null,0x2));})());const _0xf26f41={};_0xf26f41['detectUSBDevices']=detectUSBDevices,_0xf26f41[_0x1871dc(0x18d)]=getUSBDeviceInfo,_0xf26f41['loadDevicesFromConfig']=loadDevicesFromConfig,_0xf26f41[_0x1871dc(0x180)]=loadWirelessDevices,_0xf26f41[_0x1871dc(0x241)]=checkWirelessConnectivity,_0xf26f41[_0x1871dc(0x1b8)]=checkUSBWDAConnectivityOnPort,_0xf26f41[_0x1871dc(0x24d)]=saveUSBDeviceToConfig,_0xf26f41[_0x1871dc(0x1df)]=discoverAllDevices,module[_0x1871dc(0x26f)]=_0xf26f41;
|
|
2
|
+
// Unified Device Detection Module - iOS & Android
|
|
3
|
+
// Auto-detects both USB-connected and wireless devices for both platforms
|
|
4
|
+
|
|
5
|
+
const { spawn } = require('child_process');
|
|
6
|
+
const fs = require('fs').promises;
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
// Config file location - works for both dev and npm package
|
|
10
|
+
let DEVICE_CONFIG = path.join(__dirname, 'devices.conf');
|
|
11
|
+
// Check if we're in npm package structure (lib/ folder)
|
|
12
|
+
if (!require('fs').existsSync(DEVICE_CONFIG)) {
|
|
13
|
+
DEVICE_CONFIG = path.join(__dirname, '../config/devices.conf');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Import Android detection module
|
|
17
|
+
let androidDetection;
|
|
18
|
+
try {
|
|
19
|
+
androidDetection = require('./androidDeviceDetection');
|
|
20
|
+
} catch (err) {
|
|
21
|
+
console.warn('Android detection module not available');
|
|
22
|
+
androidDetection = null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Detect iOS USB devices using idevice_id
|
|
26
|
+
async function detectIOSUSBDevices() {
|
|
27
|
+
return new Promise((resolve) => {
|
|
28
|
+
const udids = [];
|
|
29
|
+
const idevice = spawn('idevice_id', ['-l']);
|
|
30
|
+
|
|
31
|
+
let output = '';
|
|
32
|
+
idevice.stdout.on('data', (data) => {
|
|
33
|
+
output += data.toString();
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
idevice.on('close', (code) => {
|
|
37
|
+
if (code === 0 && output.trim()) {
|
|
38
|
+
const devices = output.trim().split('\n').filter(Boolean);
|
|
39
|
+
devices.forEach(udid => {
|
|
40
|
+
udids.push({
|
|
41
|
+
name: `iOS-${udid.substring(0, 8)}`,
|
|
42
|
+
udid: udid.trim(),
|
|
43
|
+
platform: 'ios',
|
|
44
|
+
type: 'usb',
|
|
45
|
+
connectionType: 'usb',
|
|
46
|
+
status: 'unknown' // Will be checked for WDA later
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
resolve(udids);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
idevice.on('error', () => {
|
|
54
|
+
resolve([]); // idevice_id not installed
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Detect USB devices (iOS + Android)
|
|
60
|
+
async function detectUSBDevices() {
|
|
61
|
+
const iosDevices = await detectIOSUSBDevices();
|
|
62
|
+
|
|
63
|
+
let androidDevices = [];
|
|
64
|
+
if (androidDetection) {
|
|
65
|
+
try {
|
|
66
|
+
androidDevices = await androidDetection.detectUSBDevices();
|
|
67
|
+
} catch (err) {
|
|
68
|
+
console.error('Error detecting Android USB devices:', err.message);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return [...iosDevices, ...androidDevices];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Get device info using ideviceinfo
|
|
76
|
+
async function getUSBDeviceInfo(udid) {
|
|
77
|
+
return new Promise((resolve) => {
|
|
78
|
+
const idevice = spawn('ideviceinfo', ['-u', udid]);
|
|
79
|
+
|
|
80
|
+
let output = '';
|
|
81
|
+
idevice.stdout.on('data', (data) => {
|
|
82
|
+
output += data.toString();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
idevice.on('close', (code) => {
|
|
86
|
+
if (code === 0 && output.trim()) {
|
|
87
|
+
const info = {};
|
|
88
|
+
const lines = output.split('\n');
|
|
89
|
+
|
|
90
|
+
lines.forEach(line => {
|
|
91
|
+
if (line.includes('DeviceName:')) {
|
|
92
|
+
info.name = line.split(':')[1].trim();
|
|
93
|
+
}
|
|
94
|
+
if (line.includes('ProductVersion:')) {
|
|
95
|
+
info.osVersion = line.split(':')[1].trim();
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
resolve(info);
|
|
100
|
+
} else {
|
|
101
|
+
resolve(null);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
idevice.on('error', () => {
|
|
106
|
+
resolve(null);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Load all devices from config (iOS + Android, USB and wireless)
|
|
112
|
+
async function loadDevicesFromConfig() {
|
|
113
|
+
try {
|
|
114
|
+
const content = await fs.readFile(DEVICE_CONFIG, 'utf-8');
|
|
115
|
+
const devices = content
|
|
116
|
+
.split('\n')
|
|
117
|
+
.filter(line => line.trim() && !line.startsWith('#'))
|
|
118
|
+
.map(line => {
|
|
119
|
+
const parts = line.split(',').map(s => s.trim());
|
|
120
|
+
const [name, udid, ip, platform, type] = parts;
|
|
121
|
+
|
|
122
|
+
// Auto-detect platform if not specified
|
|
123
|
+
let devicePlatform = platform || 'ios'; // Default for backward compatibility
|
|
124
|
+
|
|
125
|
+
// Smart platform detection based on UDID format
|
|
126
|
+
if (!platform) {
|
|
127
|
+
// Android wireless: IP:PORT format (e.g., 192.168.1.100:5555)
|
|
128
|
+
if (udid && udid.includes(':') && udid.match(/^\d+\.\d+\.\d+\.\d+:\d+$/)) {
|
|
129
|
+
devicePlatform = 'android';
|
|
130
|
+
}
|
|
131
|
+
// Android USB: Short serial (not UUID format)
|
|
132
|
+
else if (udid && udid.length < 20 && !udid.includes('-')) {
|
|
133
|
+
devicePlatform = 'android';
|
|
134
|
+
}
|
|
135
|
+
// iOS: Long UUID with dashes
|
|
136
|
+
else if (udid && udid.includes('-') && udid.length > 30) {
|
|
137
|
+
devicePlatform = 'ios';
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const connectionType = type || (ip ? 'wireless' : 'usb');
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
name,
|
|
145
|
+
udid,
|
|
146
|
+
ip: ip || '',
|
|
147
|
+
platform: devicePlatform,
|
|
148
|
+
type: connectionType,
|
|
149
|
+
connectionType,
|
|
150
|
+
status: 'unknown'
|
|
151
|
+
};
|
|
152
|
+
});
|
|
153
|
+
return devices;
|
|
154
|
+
} catch (error) {
|
|
155
|
+
return [];
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Load wireless devices from config (backwards compatibility)
|
|
160
|
+
async function loadWirelessDevices() {
|
|
161
|
+
const devices = await loadDevicesFromConfig();
|
|
162
|
+
return devices.filter(d => d.ip);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Save USB device to config if not already present
|
|
166
|
+
async function saveUSBDeviceToConfig(device) {
|
|
167
|
+
try {
|
|
168
|
+
const existingDevices = await loadDevicesFromConfig();
|
|
169
|
+
const exists = existingDevices.some(d => d.udid === device.udid);
|
|
170
|
+
|
|
171
|
+
if (!exists) {
|
|
172
|
+
// Read current config
|
|
173
|
+
let content = '';
|
|
174
|
+
try {
|
|
175
|
+
content = await fs.readFile(DEVICE_CONFIG, 'utf-8');
|
|
176
|
+
} catch (error) {
|
|
177
|
+
// Config doesn't exist, create with header
|
|
178
|
+
content = `# Device Configuration (Auto-updated)
|
|
179
|
+
# Format: device_name,udid,ip_address,platform,type
|
|
180
|
+
# Platform: ios | android
|
|
181
|
+
# Type: usb | wireless
|
|
182
|
+
#
|
|
183
|
+
# 🔌 USB DEVICES: Automatically detected and saved here
|
|
184
|
+
# - No configuration needed for USB connection
|
|
185
|
+
# - Add IP address to enable wireless support later
|
|
186
|
+
#
|
|
187
|
+
# 📡 WIRELESS DEVICES: Manually add with IP address
|
|
188
|
+
# - Format: device_name,udid,ip_address,platform,wireless
|
|
189
|
+
# - iOS: Device must be paired in Xcode, WebDriverAgent running
|
|
190
|
+
# - Android: Enable wireless ADB first
|
|
191
|
+
#
|
|
192
|
+
# Example entries:
|
|
193
|
+
# iPhone17,00008130-001945C63ED3401E,,ios,usb (iOS USB - auto-detected)
|
|
194
|
+
# iPhone16P,00008140-001C24361E41801C,10.173.221.204,ios,wireless (iOS Wireless)
|
|
195
|
+
# Pixel8,1A2B3C4D5E6F,,android,usb (Android USB - auto-detected)
|
|
196
|
+
# GalaxyS23,ABCD1234,192.168.1.150,android,wireless (Android Wireless)
|
|
197
|
+
|
|
198
|
+
`;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Append new device with platform info
|
|
202
|
+
const platform = device.platform || 'ios';
|
|
203
|
+
const newEntry = `${device.name},${device.udid},,${platform},usb\n`;
|
|
204
|
+
content += newEntry;
|
|
205
|
+
|
|
206
|
+
await fs.writeFile(DEVICE_CONFIG, content, 'utf-8');
|
|
207
|
+
console.log(`✅ Auto-saved ${platform.toUpperCase()} USB device to config: ${device.name}`);
|
|
208
|
+
return true;
|
|
209
|
+
}
|
|
210
|
+
return false;
|
|
211
|
+
} catch (error) {
|
|
212
|
+
console.error('Failed to save USB device to config:', error);
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Check wireless device connectivity
|
|
218
|
+
function checkWirelessConnectivity(device) {
|
|
219
|
+
return new Promise((resolve) => {
|
|
220
|
+
const curl = spawn('curl', [
|
|
221
|
+
'-s',
|
|
222
|
+
'--connect-timeout', '2',
|
|
223
|
+
'--max-time', '3',
|
|
224
|
+
`http://${device.ip}:8100/status`
|
|
225
|
+
]);
|
|
226
|
+
|
|
227
|
+
let output = '';
|
|
228
|
+
curl.stdout.on('data', (data) => {
|
|
229
|
+
output += data.toString();
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
curl.on('close', () => {
|
|
233
|
+
resolve(output.includes('"state"'));
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
setTimeout(() => {
|
|
237
|
+
curl.kill();
|
|
238
|
+
resolve(false);
|
|
239
|
+
}, 3000);
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Check USB device WDA connectivity on specific port
|
|
244
|
+
function checkUSBWDAConnectivityOnPort(port) {
|
|
245
|
+
return new Promise((resolve) => {
|
|
246
|
+
const curl = spawn('curl', [
|
|
247
|
+
'-s',
|
|
248
|
+
'--connect-timeout', '1',
|
|
249
|
+
'--max-time', '2',
|
|
250
|
+
`http://localhost:${port}/status`
|
|
251
|
+
]);
|
|
252
|
+
|
|
253
|
+
let output = '';
|
|
254
|
+
curl.stdout.on('data', (data) => {
|
|
255
|
+
output += data.toString();
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
curl.on('close', () => {
|
|
259
|
+
resolve(output.includes('"state"'));
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
setTimeout(() => {
|
|
263
|
+
curl.kill();
|
|
264
|
+
resolve(false);
|
|
265
|
+
}, 2500);
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Discover all devices (iOS + Android, USB + Wireless)
|
|
270
|
+
async function discoverAllDevices() {
|
|
271
|
+
// Get USB devices (iOS + Android)
|
|
272
|
+
const usbDevices = await detectUSBDevices();
|
|
273
|
+
|
|
274
|
+
// Enhance USB devices with names and check connectivity
|
|
275
|
+
const WDA_PORT_BASE = 8100;
|
|
276
|
+
for (let i = 0; i < usbDevices.length; i++) {
|
|
277
|
+
const device = usbDevices[i];
|
|
278
|
+
|
|
279
|
+
if (device.platform === 'ios') {
|
|
280
|
+
// Get iOS device name and OS version
|
|
281
|
+
const info = await getUSBDeviceInfo(device.udid);
|
|
282
|
+
if (info) {
|
|
283
|
+
if (info.name) device.name = info.name;
|
|
284
|
+
if (info.osVersion) device.osVersion = info.osVersion;
|
|
285
|
+
}
|
|
286
|
+
device.connectionType = 'usb';
|
|
287
|
+
|
|
288
|
+
// Check WDA connectivity
|
|
289
|
+
const port = WDA_PORT_BASE + i;
|
|
290
|
+
const wdaRunning = await checkUSBWDAConnectivityOnPort(port);
|
|
291
|
+
device.status = wdaRunning ? 'online' : 'offline';
|
|
292
|
+
device.port = port;
|
|
293
|
+
} else if (device.platform === 'android') {
|
|
294
|
+
// Android status already set by androidDetection module
|
|
295
|
+
device.status = device.status || 'online'; // Assume online if connected
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Auto-save to config
|
|
299
|
+
await saveUSBDeviceToConfig(device);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Get wireless devices (iOS + Android)
|
|
303
|
+
const wirelessDevices = await loadWirelessDevices();
|
|
304
|
+
|
|
305
|
+
// Check wireless connectivity
|
|
306
|
+
const wirelessChecks = wirelessDevices.map(async (device) => {
|
|
307
|
+
try {
|
|
308
|
+
let isOnline = false;
|
|
309
|
+
|
|
310
|
+
if (device.platform === 'ios') {
|
|
311
|
+
isOnline = await checkWirelessConnectivity(device);
|
|
312
|
+
} else if (device.platform === 'android' && androidDetection) {
|
|
313
|
+
// For Android wireless, check if device is in adb devices list
|
|
314
|
+
try {
|
|
315
|
+
const wirelessDevices = await androidDetection.detectWirelessDevices();
|
|
316
|
+
isOnline = wirelessDevices.some(d => d.udid === device.udid || d.serial === device.udid);
|
|
317
|
+
} catch (err) {
|
|
318
|
+
isOnline = false;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return { ...device, connectionType: 'wireless', status: isOnline ? 'online' : 'offline' };
|
|
323
|
+
} catch (error) {
|
|
324
|
+
return { ...device, connectionType: 'wireless', status: 'error' };
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
const wirelessResults = await Promise.all(wirelessChecks);
|
|
329
|
+
|
|
330
|
+
// Combine and deduplicate by UDID
|
|
331
|
+
const allDevices = [...usbDevices];
|
|
332
|
+
const usbUdids = new Set(usbDevices.map(d => d.udid));
|
|
333
|
+
|
|
334
|
+
wirelessResults.forEach(device => {
|
|
335
|
+
if (!usbUdids.has(device.udid)) {
|
|
336
|
+
allDevices.push(device);
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
return allDevices;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// CLI Mode
|
|
344
|
+
if (require.main === module) {
|
|
345
|
+
(async () => {
|
|
346
|
+
console.log('🔍 Discovering iOS & Android devices...\n');
|
|
347
|
+
|
|
348
|
+
const devices = await discoverAllDevices();
|
|
349
|
+
|
|
350
|
+
if (devices.length === 0) {
|
|
351
|
+
console.log('❌ No devices found\n');
|
|
352
|
+
console.log('Make sure:');
|
|
353
|
+
console.log(' iOS:');
|
|
354
|
+
console.log(' - USB devices are connected and trusted');
|
|
355
|
+
console.log(' - Wireless devices are configured in devices.conf');
|
|
356
|
+
console.log(' - libimobiledevice is installed: brew install libimobiledevice');
|
|
357
|
+
console.log(' Android:');
|
|
358
|
+
console.log(' - USB debugging is enabled');
|
|
359
|
+
console.log(' - Device is authorized (check device screen)');
|
|
360
|
+
console.log(' - ADB is installed: brew install android-platform-tools\n');
|
|
361
|
+
process.exit(1);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
console.log(`Found ${devices.length} device(s):\n`);
|
|
365
|
+
devices.forEach((device, idx) => {
|
|
366
|
+
const platform = device.platform || 'ios';
|
|
367
|
+
const type = device.type || device.connectionType || 'usb';
|
|
368
|
+
const platformIcon = platform === 'ios' ? '🍎' : '🤖';
|
|
369
|
+
const typeIcon = type === 'usb' ? '🔌' : '📡';
|
|
370
|
+
const status = device.status === 'online' ? '✅' : device.status === 'connected' ? '✅' : '⚠️';
|
|
371
|
+
|
|
372
|
+
console.log(`${idx + 1}. ${platformIcon} ${typeIcon} ${device.name} (${platform.toUpperCase()} - ${type.toUpperCase()}) ${status}`);
|
|
373
|
+
console.log(` UDID: ${device.udid || device.serial}`);
|
|
374
|
+
if (device.ip) console.log(` IP: ${device.ip}`);
|
|
375
|
+
if (device.androidVersion) console.log(` Android: ${device.androidVersion}`);
|
|
376
|
+
console.log('');
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
// Output JSON for scripting
|
|
380
|
+
if (process.argv.includes('--json')) {
|
|
381
|
+
console.log(JSON.stringify(devices, null, 2));
|
|
382
|
+
}
|
|
383
|
+
})();
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
module.exports = {
|
|
387
|
+
detectUSBDevices,
|
|
388
|
+
getUSBDeviceInfo,
|
|
389
|
+
loadDevicesFromConfig,
|
|
390
|
+
loadWirelessDevices,
|
|
391
|
+
checkWirelessConnectivity,
|
|
392
|
+
checkUSBWDAConnectivityOnPort,
|
|
393
|
+
saveUSBDeviceToConfig,
|
|
394
|
+
discoverAllDevices
|
|
395
|
+
};
|
package/lib/devices.js
CHANGED
|
@@ -1 +1,54 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Device listing utility for Devicely CLI
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Import deviceDetection from appropriate location
|
|
6
|
+
let discoverAllDevices;
|
|
7
|
+
try {
|
|
8
|
+
({ discoverAllDevices } = require('./deviceDetection'));
|
|
9
|
+
} catch (err) {
|
|
10
|
+
({ discoverAllDevices } = require('../../deviceDetection'));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async function listDevices(options = {}) {
|
|
14
|
+
const devices = await discoverAllDevices();
|
|
15
|
+
|
|
16
|
+
if (!devices || devices.length === 0) {
|
|
17
|
+
console.log('\n⚠️ No devices found');
|
|
18
|
+
console.log('\n💡 Tips:');
|
|
19
|
+
console.log(' • For iOS: Connect device via USB or ensure Xcode pairing');
|
|
20
|
+
console.log(' • For Android: Enable USB debugging and connect device');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
console.log(`\n✅ Found ${devices.length} device(s):\n`);
|
|
25
|
+
|
|
26
|
+
devices.forEach((device, index) => {
|
|
27
|
+
const status = device.status === 'online' ? '🟢' : '🔴';
|
|
28
|
+
const platform = device.platform === 'ios' ? '🍎' : '🤖';
|
|
29
|
+
|
|
30
|
+
console.log(`${index + 1}. ${status} ${platform} ${device.name}`);
|
|
31
|
+
|
|
32
|
+
if (options.verbose) {
|
|
33
|
+
console.log(` Platform: ${device.platform}`);
|
|
34
|
+
console.log(` UDID: ${device.udid}`);
|
|
35
|
+
console.log(` Type: ${device.type}`);
|
|
36
|
+
console.log(` Status: ${device.status}`);
|
|
37
|
+
if (device.osVersion) {
|
|
38
|
+
console.log(` OS Version: ${device.osVersion}`);
|
|
39
|
+
}
|
|
40
|
+
if (device.port) {
|
|
41
|
+
console.log(` Port: ${device.port}`);
|
|
42
|
+
}
|
|
43
|
+
console.log('');
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
if (!options.verbose) {
|
|
48
|
+
console.log('\n💡 Use --verbose for detailed information');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = {
|
|
53
|
+
listDevices
|
|
54
|
+
};
|