Can you automate the App UDID when running a test from the command line? - iphone

I run a command line test that runs Instruments on the iPhone Simulator. Unfortunately, every time I do a Build the UDID changes which means I have to update my script. E.g. see this error message:
Instruments Usage Error : Specified target process is invalid: /Path/To/Library/Developer/CoreSimulator/Devices/9B0DF4D4-941C-4B65-84E0-ETC/data/Containers/Bundle/Application/8EE5CBCA-3107-48B5-8A54-ETC/myApp.app
Is there any way to avoid copying/pasting this UDID all the time?

You can write a bash script that reads the most recent UDID from the folder where they are being generated, stores that to a variable and calls instruments using that variable. It would look something like
cd parentFolderOfUDIDs
mostRecentUDID = "$(\ls -1dt */ | head -n 1)"
instruments /path/to/app/$mostRecentUDID/myApp.app

Related

Swift 4 launchedProcess launch path not accessible

I am writing a swift based macOS app in Xcode 9 to be used on my computer (not distributed). I have EXIFtool installed (independent of the app) in /usr/local/bin and can use it successfully from the Terminal app. I am trying to access EXIFtool from my app.
My app has a button that when clicked should run the EXIFtool command by executing this script.
#IBAction func arrowClicked(_ sender: Any) {
arrow.isEnabled = false
let task = Process.launchedProcess(launchPath: "/usr/local/bin/exiftool", arguments: [rawURL])
task.waitUntilExit()
arrow.isEnabled = true
}
The script fails with a "launch path not accessible" error. It doesn't matter what I enter as the arguments (in the above snippet, rawURL is a string that contains the path to a user identified image file.
The responses I have found for similar questions here focus on the format of the path (e.g., must be the full path, begin with /, etc). My launch path comes from what Terminal gives a response to "which exiftool", so I thought it was correct.
UPDATE: I followed the link Matt provided and rewrote the code to utilize a shell script. I made the script executable and successfully ran it through Terminal and TextWrangler. But accessing it within Xcode resulted in an "operation not permitted" message.
Turning off the App Sandbox resolves both the original "launch path not accessible" message and the revised attempt's "operation not permitted" message.
There are unfortunately numerous reasons why one binary may not run inside a sandboxed environment, whilst another binary may run just fine.
In your case you were able to disable sandboxing, so that was an easy (and sensible) fix, but for anyone without that luxury, below is some information that documents some relevant factors.
There is a question here which asks why /sbin/ping runs fine, yet /usr/sbin/traceroute does not.
From one of the answers there:
ping vs. traceroute - the former is a non-priviledged program, the latter is priviledged and runs as root
You can see the difference in their permissions:
$ ls /sbin/ping
-r-xr-xr-x 1 root wheel 41K 30 May 11:36 /sbin/ping
$ ls /usr/sbin/traceroute
-r-sr-xr-x 1 root wheel 37K 30 May 11:36 /usr/sbin/traceroute
The s on the trace route means it will be executed as root, which naturally is not going to be allowed inside a sandboxed environment. The following may be helpful, from https://coderanch.com/t/110770/os/permissions-meaning#558594:
"s", for files, means "setuid exec." If a file has s permission, then it's executable, and furthermore, the user id and/or group id of the process is set to the user or group id of the owner of the file, depending on whether it's the user or group "s" that's set. This is a way to give limited root powers to a user -- a program that runs as root when an ordinary user executes it.
Somewhat beyond my comprehension, but potentially also relevant is the following Apple Technical Q&A QA1773 called Common app sandboxing issues which discusses whether a binary is a Mach-O executable:
You can check if a binary is a Mach-O executable using the file command. If any slice of the binary identifies itself as Mach-O executable or Mach-O 64-bit executable, the binary must be sandboxed.
For ping that would look like:
$ file /sbin/ping
/sbin/ping: Mach-O 64-bit executable x86_64
My take is that if the binary is a Mach-O executable and you want to run it from a sandboxed app, you are going to have to either:
compile the binary yourself from source, giving it appropriate entitlements, or
import the code into your app and compile it directly into your app

How to capture iPhone app debug logs

I was researching libimobiledevice to basically capture the specific iPhone app logs. I have tried with the idevicesyslog command, but it gives me all the system logs along with my app.
I tried with idevicesyslog -d | grep com.example.Example but does not give me the info I am looking for.
I am interested in the debug logs of my app.
I know there is a way to capture it from the organizer in Xcode but I don't want to do it that way. I am planning to do it programmatically and then integrate with Appium automation script.
I was able to achieve this with idevicesyslog -d | grep '"https://ac.XYZ.COM" >& t' write to the file "t" and then clear the file and move on to the next step.
This I was able to achieve but the only issue I am facing here is that I need to update the command, like it wont write to log on real time basis when I am interacting with the device. If someone can suggest a way where it log to the file in a real time that would be great.
You can use -m option from idevicesyslog, this option is for "only print messages that contain STRING"
Example:
idevicesyslog -m "Vantage"
Hope this method is work for you :)

UIAutomation test invocation from the command line with Xcode 6

Running UIAutomation tests from the command line seems to break often with new Xcode releases (judging by past posts). Having never used the command line scripting for this, I found this post from 2012: Automation Instrument from the Command Line.
The Problem: My command returns without error, without output results and without anything logged to the system console. The simulator does not even launch!
Checking some of the paths for updates (notably, the Automation trace instrument path), I came up with this command. Note the path in the first parameter (it's different than in past Xcode releases):
instruments -t "/Applications/Xcode.app/Contents/Applications/Instruments.app/Contents/PlugIns/AutomationInstrument.xrplugin/Contents/Resources/Automation.tracetemplate"
"/Users/sohail/Library/Developer/CoreSimulator/Devices/7232A640-A9D2-4626-A2AD-37AFFF706718/data/Containers/Bundle/Application/D07FEC4B-76AD-4844-8362-08E771B81053/MyAppName.app"
-e UIASCRIPT "/Users/sohail/source/MyAppName/MyAppNameAutomationTests/TestRunner.js"
-e UIARESULTSPATH "Users/sohail/source/MyAppName/MyAppNameAutomationTests/TestResults"
This might be easier to read by selecting "raw" from this gist.
Of course:
I validated that the path specified to my .app actually exists; it came into being after a successful build and run.
I validated that in my specified output folder ("TestResults") that in fact, nothing got logged.
I validated that the aforementioned TestRunner.js file I specified, could be found at the path specified, and successfully runs in the Automation Instrument interactively with the Instruments app.
I've checked Apple's Xcode6/iOS8 pre-release documentation (login required; see section title, "Executing an Automation Instrument Script from the Command Line"), and nothing jumps out at me as wrong, since I'm just targeting the simulator.
My suspicion
I'm missing some flag or switch somewhere.
Thoughts anyone?
I saw the exact same issue, after explicitly provided -w $DEVICE parameter, my tests finally got started
instruments -t /Applications/Xcode6.app/Contents/Applications/Instruments.app/Contents/PlugIns/AutomationInstrument.xrplugin/Contents/Resources/Automation.tracetemplate
-w "iPhone 5s (8.0 Simulator)" /path/to/my/TestApp.app -e UIASCRIPT /tmp/script.js -e UIARESULTSPATH /tmp

UIAutomation - different results from Instruments and Command Line

When I run a UIAutomation script in Instruments, everything works fine but when I run the exact same script from the command line, I get this error :
Cannot perform action on invalid element: UIAElementNil from target.frontMostApp().mainWindow().tableViews()[0].cells()["ID number, Required"].textFields()[0]
Here is the Instruments command I'm using to launch the test
instruments -t /Applications/Xcode.app/Contents/Applications/Instruments.app/Contents/PlugIns/AutomationInstrument.bundle/Contents/Resources/Automation.tracetemplate /Users/johan/Library/Developer/Xcode/DerivedData/Brokers-etvmwznhcjprybdekgtixzzsnbrw/Build/Products/Release-iphonesimulator/MyApp -e UIASCRIPT /Users/johan/Desktop/Script.js
The reason might be that UIAutomation under instruments is much slower than when run from the command line. So it might be that under instruments the element target.frontMostApp().mainWindow().tableViews()[0].cells()["ID number, Required"].textFields()[0]
exists, i.e. is valid, but from the console not yet.
Maybe you should try to wait for the element to become valid, before you perform an action on it, of to check its validity (isValid) and log it to be sure about its status.

iphone redirect shell command

I am working on an jail broken iphone app that calls a shell command. To read the output I redirect the output of the command to file. That is where my problem lies. When I attempt to do the redirect sh reports that the operation is not permitted.this is the exact output of gdb: sh: ./tmp/tmp.out: Operation not permitted Also I call my command using the system() function. thank you in advance
You might instead want to use NSTask which is built for these sorts of things.