UIAutomation - different results from Instruments and Command Line - iphone

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.

Related

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

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

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

Interactively running code during a debugging session in Perl

Say my debugger stops at a breakpoint. Is there any way to run/send arbitrary Perl code to the debugger?
For example, say I stop the debugger at a location with the statement:
$DB::single = 1
I would like to be able to:
Type and execute general Perl statements from the debugger prompt
Run scripts
Anything you type in the debugger that isn't recognized as a debugger command is interpreted as perl and run. You can run a file using require or do, although I'm not sure what you have in mind when you say "interactively" run code from another file.

Odd behavior with Perl system() command

Note that I'm aware that this is probably not the best or most optimal way to do this but I've run into this somewhere before and I'm curious as to the answer.
I have a perl script that is called from an init that runs and occasionally dies. To quickly debug this, I put together a quick wrapper perl script that basically consists of
#$path set from library call.
while(1){
system("$path/command.pl " . join(" ",#ARGV) . " >>/var/log/outlog 2>&1");
sleep 30; #Added this one later. See below...
}
Fire this up from the command line and it runs fine and as expected. command.pl is called and the script basically halts there until the child process dies then goes around again.
However, when called from a start script (actually via start-stop-daemon), the system command returns immediately, leaving command.pl running. Then it goes around for another go. And again and again. (This was not fun without the sleep command.). ps reveals the parent of (the many) command.pl to be 1 rather than the id of the wrapper script (which it is when I run from the command line).
Anyone know what's occurring?
Maybe the command.pl is not being run successfully. Maybe the file doesn't have execute permission (do you need to say perl command.pl?). Maybe you are running the command from a different directory than you thought, and the command.pl file isn't found.
There are at least three things you can check:
standard error output of your command. For now you are swallowing it by saying 2>&1. Remove that part and observe what errors the system command produces.
the return value of system. The command may run and system may still return an exit code, but if system returns 0, you know the command was successful.
Perl's error variable $!. If there was a problem, Perl will set $!, which may or may not be helpful.
To summarize, try:
my $ec = system("command.pl >> /var/log/outlog");
if ($ec != 0) {
warn "exit code was $ec, \$! is $!";
}
Update: if multiple instance of the command keep showing up in your ps output, then it sounds like the program is forking and running itself in the background. If that is indeed what the command is supposed to do, then what you do NOT want to do is run this command in an endless loop.
Perhaps when run from a deamon the "system" command is using a different shell than the one used when you are running as yourself. Maybe the shell used by the daemon does not recognize the >& construct.
Instead of system("..."), try exec("...") function if that works for you.

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.