appium/appium — pull request #791 by tborys (2013-06-20 16:55:50+00:00)
Title: For freedom!!!! to install and uninstall the app whenever I want!

Guys,

I have been working with my colleague @snevesbarros on implementing a more flexible functionality of controlling install/uninstall process of the app for real device. Our goal was to have a stable appium server running independently with possibility to:
* deploy app to a real device as determined by the test (e.g. as part of the before class)
* delete app from a real device as determined by the test (e.g. as part of the after class)
* provide concise feedback to the test around (un)installation (and any error that might have occurred)

The biggest advantages compared to the existing solution in appium are:
* Both solutions can live side by side in appium (e.g. node-idevice
and fruistrap)
* Appium does not have to start with specified \*.ipa file (UDID is enough to run server, the rest is done from Java on webdriver side)
* \*.zip, \*.ipa and \*.app files are accepted to proceed with installation
Using the bundleID the user can uninstall app or check if the app exists on the device.
* This solution can also be applied to Android (additional changes required as we only focussed on iOS).

To get this functionality you need to have this version of fruitstrap installed on your machine in directory /usr/bin/ .
We can look to see if this can be installed automatically using e.g. grunt.

We have also added an example of the changes made to a local web driver to add the 3 additional methods to call the end points.

Below are example logs from a simple test which uninstalls the app if exists on the device, installs latest version and launches the app.

testNG

[TestNG] Running:
/private/var/folders/jr/d3hgxz6d4rqdhwdls1bcmgh471mf1z/T/testng-eclipse-63914994/testng-customsuite.xml

2013-06-20 17:00:43 REPORTER [INFO] Thread [1] - Info - Information: [Finished loading properties from file [/test.properties]]
- ##### - Starting Test [correctLoginTest] Thread [1] - ###### -
2013-06-20 17:00:44 REPORTER [INFO] Thread [1] - Info - Information: [Found the app with bundleID: my.bundleID]
2013-06-20 17:00:44 REPORTER [INFO] Thread [1] - Info - Information: [Successfully removed [my.bundleID] from device with udid [xxxxxxxxxxxxxxxa6749a675e0b853afe9]]
2013-06-20 17:00:57 REPORTER [INFO] Thread [1] - Info - Information: [Successfully unzipped and installed [http://myIPserver:8082/job/nightly-build-environments/lastSuccessfulBuild/artifact/build/Jackpotjoy.app] to device with udid [xxxxxxxxxxxxxxxa6749a675e0b853afe9]]
2013-06-20 17:01:21 REPORTER [INFO] Thread [1] - Info - Information: [webDriver instantiated using: Browser [iPad4], Hostname [127.0.0.1], Port [4723]]
- ##### - Ended Test [correctLoginTest] Thread [1] - ###### -

2013-06-20 17:01:23 REPORTER [INFO] Thread [1] - Info - Information: [Clear all properties has finished.]
PASSED: correctLoginTest

===============================================
Default test
Tests run: 1, Failures: 0, Skips: 0
===============================================

===============================================
Default suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================

[TestNG] Time taken by org.testng.reporters.JUnitReportReporter@7776cad3: 2 ms
[TestNG] Time taken by org.testng.reporters.XMLReporter@571a75a2: 38 ms
[TestNG] Time taken by org.testng.reporters.SuiteHTMLReporter@6542bece: 14 ms
[TestNG] Time taken by org.testng.reporters.EmailableReporter2@5ff06dc3: 3 ms
[TestNG] Time taken by [FailedReporter passed=0 failed=0 skipped=0]: 0 ms
[TestNG] Time taken by org.testng.reporters.jq.Main@1f8b81e3: 28 ms

Appium

/usr/local/bin/node server.js -U xxxxxxxxxxxxxxx6749a675e0b853afe9
info: Welcome to Appium v0.7.3 (REV 2801ddd41520f41945b0e985f19f3d56a67129c4)
info: Appium REST http interface listener started on 0.0.0.0:4723
info: socket.io started
debug: Appium request initiated at /wd/hub/app/installed
debug: Request received with params: {"bundleId":"my.bundleID"}
info: Sending command to terminal to terminal [fruitstrap isInstalled --id xxxxxxxxxxxxxxx6749a675e0b853afe9 --bundle my.bundleID]
info: stdout: [....] Waiting for iOS device to be connected
found device id
[ 0%] Found device (xxxxxxxxxxxxxxx6749a675e0b853afe9), beginning check
App is installed!
[100%] Check completed my.bundleID

info: child process exited with code 0
info: Responding to client with success: {"status":0,"value":true}
POST /wd/hub/app/installed 200 430ms - 34
debug: Appium request initiated at /wd/hub/app/uninstall
debug: Request received with params: {"bundleId":"com.gamesys.jackpotjoy"}
info: Sending command to terminal to terminal [fruitstrap uninstall --id xxxxxxxxxxxxxxx6749a675e0b853afe9 --bundle my.bundleID]
info: stdout: [....] Waiting for iOS device to be connected
found device id
[ 0%] Found device (xxxxxxxxxxxxxxx6749a675e0b853afe9), beginning uninstall
[ 50%] TakingInstallLock
[ 75%] RemovingApplication
[ 95%] GeneratingApplicationMap
[100%] uninstalled package my.bundleID

info: child process exited with code 0
info: Responding to client with success: {"status":0,"value":"Successfully removed [my.bundleID] from device with udid [xxxxxxxxxxxxxxx6749a675e0b853afe9]"}
POST /wd/hub/app/uninstall 200 393ms - 142
debug: Appium request initiated at /wd/hub/app/install
debug: Request received with params: {"appPath":"http://myIPserver:8082/job/nightly-build-environments/lastSuccessfulBuild/artifact/build/myAPP.zip"}
info: http://myIPserver:8082/job/nightly-build-environments/lastSuccessfulBuild/artifact/build/myAPP.zip downloaded to /var/folders/jr/d3hgxz6d4rqdhwdls1bcmgh471mf1z/T/appium-app113520-69786-fvli1f.zip
info: Unzipping /var/folders/jr/d3hgxz6d4rqdhwdls1bcmgh471mf1z/T/appium-app113520-69786-fvli1f.zip
info: Testing zip archive: /var/folders/jr/d3hgxz6d4rqdhwdls1bcmgh471mf1z/T/appium-app113520-69786-fvli1f.zip
info: Zip archive tested clean
info: Unzip successful
info: Sending command to terminal to terminal [fruitstrap install --id xxxxxxxxxxxxxxx6749a675e0b853afe9 --bundle /var/folders/jr/d3hgxz6d4rqdhwdls1bcmgh471mf1z/T/Payload/myApp.app]
info: stdout: [....] Waiting for iOS device to be connected
found device id
[ 0%] Found device (xxxxxxxxxxxxxxx6749a675e0b853afe9), beginning install
[ 5%] Copying /var/folders/jr/d3hgxz6d4rqdhwdls1bcmgh471mf1z/T/Payload/myApp.app to device
####COPYING FILES #####
[ 52%] CreatingStagingDirectory
[ 57%] ExtractingPackage
[ 60%] InspectingPackage
[ 60%] TakingInstallLock
[ 65%] PreflightingApplication
[ 65%] InstallingEmbeddedProfile
[ 70%] VerifyingApplication
[ 75%] CreatingContainer
[ 80%] InstallingApplication
[ 85%] PostflightingApplication
[ 90%] SandboxingApplication
[ 95%] GeneratingApplicationMap
[100%] Installed package /var/folders/jr/d3hgxz6d4rqdhwdls1bcmgh471mf1z/T/Payload/myApp.app

info: child process exited with code 0
info: Responding to client with success: {"status":0,"value":"Successfully unzipped and installed [http://myIPserver:8082/job/nightly-build-environments/lastSuccessfulBuild/artifact/build/myAPP.zip] to device with udid [xxxxxxxxxxxxxxx6749a675e0b853afe9]"}
POST /wd/hub/app/install 200 13032ms - 290
debug: Appium request initiated at /wd/hub/session
debug: Request received with params: {"desiredCapabilities":{"platform":"MAC","app":"http://myIPserver:8082/job/nightly-build-environments/lastSuccessfulBuild/artifact/build/myAPP.zip","acceptSslCerts":true,"browserName":"iPad4","version":"6.1.3"}}
info: Using downloadable app from desiredCaps: http://myIPserver:8082/job/nightly-build-environments/lastSuccessfulBuild/artifact/build/myAPP.zip
info: http://myIPserver:8082/job/nightly-build-environments/lastSuccessfulBuild/artifact/build/myAPP.zip downloaded to /var/folders/jr/d3hgxz6d4rqdhwdls1bcmgh471mf1z/T/appium-app113520-69786-153jarz.zip
info: Unzipping /var/folders/jr/d3hgxz6d4rqdhwdls1bcmgh471mf1z/T/appium-app113520-69786-153jarz.zip
info: Testing zip archive: /var/folders/jr/d3hgxz6d4rqdhwdls1bcmgh471mf1z/T/appium-app113520-69786-153jarz.zip
info: Zip archive tested clean
info: Unzip successful
info: Using extracted app: /var/folders/jr/d3hgxz6d4rqdhwdls1bcmgh471mf1z/T/Payload/myApp.app
info: Creating new appium session 3d0b1b71-4bcc-4c42-bcc8-5dc373626998
info: Cleaned up instruments socket /tmp/instruments_sock
info: Not setting device type since we're connected to a device
debug: No device id or app, not installing to real device.
debug: Creating instruments
info: instruments is: /Applications/Xcode.app/Contents/Developer/usr/bin/instruments
info: [INSTSERVER] Instruments socket server started at /tmp/instruments_sock
info: Attempting to run app on real device with UDID xxxxxxxxxxxxxxx6749a675e0b853afe9
info: Spawning instruments with command: /Applications/Xcode.app/Contents/Developer/usr/bin/instruments -t /Users/USER/appium/app/uiauto/Automation.tracetemplate -w xxxxxxxxxxxxxxx6749a675e0b853afe9 /var/folders/jr/d3hgxz6d4rqdhwdls1bcmgh471mf1z/T/Payload/myApp.app -e UIASCRIPT /Users/USER/appium/app/uiauto/bootstrap.js -e UIARESULTSPATH /tmp/184856ca-fe0e-4a7d-a75e-b8ff832c9fa8
info: And extra without-delay env: {}
info: 
 2013-06-20 16:01:06 +0000 Default: Instruments shell user: USER
info: 
 2013-06-20 16:01:18 +0000 Default: Found node in Appium.app
debug: Sending command to instruments: au.bundleId()
info: [INSTSERVER] Instruments is ready to receive commands
info: Instruments launched. Starting poll loop for new commands.
info: Pushing command to appium work queue: "au.bundleId()"
info: [INSTSERVER] Socket data received (15 bytes)
info: [INSTSERVER] Socket data being routed for 'cmd' event
info: [INSTSERVER] Sending command to instruments: au.bundleId()
info: 
 2013-06-20 16:01:22 +0000 Default: Got new command 0 from instruments: au.bundleId()
info: 
 2013-06-20 16:01:22 +0000 Default: Result is not protocol compliant, wrapping
info: [INSTSERVER] Socket data received (70 bytes)
info: [INSTSERVER] Socket data being routed for 'cmd' event
info: [INSTSERVER] Got result from instruments: {"status":0,"value":"com.gamesys.jackpotjoy"}
info: Bundle ID for open app is my.bundleID
info: Setting initial orientation to PORTRAIT
info: Pushing command to appium work queue: "au.setScreenOrientation('PORTRAIT')"
info: [INSTSERVER] Sending command to instruments: au.setScreenOrientation('PORTRAIT')
debug: Sending command to instruments: au.setScreenOrientation('PORTRAIT')
info: 
 2013-06-20 16:01:23 +0000 Default: Got new command 1 from instruments: au.setScreenOrientation('PORTRAIT')
info: [INSTSERVER] Socket data received (56 bytes)
info: [INSTSERVER] Socket data being routed for 'cmd' event
info: [INSTSERVER] Got result from instruments: {"status":0,"value":"PORTRAIT"}
info: Appium session started with sessionId 3d0b1b71-4bcc-4c42-bcc8-5dc373626998
POST /wd/hub/session 303 23871ms - 9
debug: Appium request initiated at /wd/hub/session/3d0b1b71-4bcc-4c42-bcc8-5dc373626998
info: Responding to client with success: {"status":0,"value":{"version":"6.0","webStorageEnabled":false,"locationContextEnabled":false,"browserName":"iOS","platform":"MAC","javascriptEnabled":true,"databaseEnabled":false,"takesScreenshot":true},"sessionId":"3d0b1b71-4bcc-4c42-bcc8-5dc373626998"}
GET /wd/hub/session/3d0b1b71-4bcc-4c42-bcc8-5dc373626998 200 2ms - 319
debug: Appium request initiated at /wd/hub/session/3d0b1b71-4bcc-4c42-bcc8-5dc373626998/timeouts/implicit_wait
debug: Request received with params: {"ms":5000}
info: Set iOS implicit wait to 5000ms
info: Responding to client with success: {"status":0,"value":null,"sessionId":"3d0b1b71-4bcc-4c42-bcc8-5dc373626998"}
POST /wd/hub/session/3d0b1b71-4bcc-4c42-bcc8-5dc373626998/timeouts/implicit_wait 200 1ms - 89
debug: Appium request initiated at /wd/hub/session/3d0b1b71-4bcc-4c42-bcc8-5dc373626998
info: Shutting down appium session...
info: 
 2013-06-20 16:01:23 +0000 Debug: target.setDeviceOrientation("1")
2013-06-20 16:01:21 +0000 Stopped: Script was stopped by the user
Instruments Trace Complete (Duration : 20.314917s; Output : /Users/USER/appium/instrumentscli0.trace)

info: [INSTSERVER] Instruments exited with code 0
info: Deleting plists for bundle: my.bundleID
info: [INSTSERVER] Socket closed forcibly due to exit
info: [INSTSERVER] Instruments socket server closed
info: No plist files found to remove
info: Deleted tracedir we heard about from instruments (/Users/USER/appium/instrumentscli0.trace)
info: Clearing out appium devices
info: Responding to client with success: {"status":0,"value":null,"sessionId":"3d0b1b71-4bcc-4c42-bcc8-5dc373626998"}
DELETE /wd/hub/session/3d0b1b71-4bcc-4c42-bcc8-5dc373626998 200 1375ms - 89