FONEMONKEY
-
Upload
vuonglamtrum -
Category
Documents
-
view
108 -
download
1
Transcript of FONEMONKEY
FONEMONKEY
QUICK TUTORIAL
This QuickStart demonstrates using FoneMonkey with Apple's sample application, TheElements. By following along,
you should be you up and running with FoneMonkey in a matter of minutes!Preparing Your Appl icat ion For Test ing
Before you can begin using FoneMonkey, you must link the FoneMonkey framework into your application.Start ing FoneMonkey with Your Appl icat ion
Once your application has been linked with the framework, whenever you launch your application the FoneMonkey
console will "drop down" in front.
Recording
Click the Record button to hide the console and begin recording. FoneMonkey will record most user interface event
types including touching, dragging, scrolling, and typing. If you stop interacting with the application for more than the
timeout interval (2.5 seconds by default), the FoneMonkey console will again be displayed.
Touch the More button to display the recorded commands.
Playing
Touch the Play button to play the script. The FoneMonkey console will hide and FoneMonkey will generate user
interactions corresponding to each recorded command. It is important to note that FoneMonkey will not automatically
restore your application to its starting state before playing a script. The application must be in a state such that the
script makes sense. For example,TheElements has tabs that display the table sorted by element name or symbol. If
you record a script that assumes the application is displaying the the Name tab when it begins, you must ensure
the Name tab is being displayed before playing the recorded script. One way to do this is to record touching
the Name tab as the first action in the script.
You can touch the Pause button to hide the console and manipulate your application without recording.Video of Recording and PlaybackAdding Ver i f icat ion to The Scr ipt
You can add Verify commands to a script to test the values UI component properties or the values of associated
object properties (ie, you can use a key-value encoded key path) . To insert a Verify command, touch the More button
to display the current script and then touch the Insert (+) button on the toolbar. Next touch the Insert (+) button on a
row to insert a new Verify command and display it in the command editor.
In TheElements sample application, a custom class called AtomicElementView is used to display data for the
currently selected element. The AtomicElementView has a property called element that references an instance of
the AtomicElement class, which in turn as a property called name. In the Verify command below, we test that the
current AtomicElementView's element.name has a value of "Lead".
Touch the Play button to run the script. When the script finishes running, any faiiled verifications will be displayed in
red with along with explanatory text.
You can save a script for later replay by clicking on the Save button (the downarrow) on the toolbar.Video of Insert ing a Ver i f icat ion Command And Saving a Scr ipt
Wait ing for Some Condit ion to Become True
The WaitFor command is similar to the Verify command, except it pauses script execution until the specified condition
becomes true.
SET UP AND BUILD
Add FoneMonkey to project
1. Download and unzip the FoneMonkey.zip file.
2. Open your application's project in xcode.
3. Duplicate your application's build target by right-clicking on it and selecting Duplicate from the menu. A
new target will be created called YourApp copy.
Rename YourApp copy to something like YourAppMonkey.
so it looks like this:
4. Add the downloaded FoneMonkey folder to your project by right-clicking on the project and
selecting Add > Existing Files...from the menu.
5. When the dialog box appears, navigate to the directory where you unzipped the FoneMonkey.zip file,
and select the FoneMonkey directory.
6. Recursively create groups for any added folders option. Note: It is up to you whether or not you
want to Copy items into destination group's folder.
7. In the Add to Targets box, deselect YourApp and select YourAppMonkey.
8. Click Add.
9. The FoneMonkey folder should now be visible in your project.
Configure library and build setting
1. Right-click on the YourAppMonkey build target, and select the Build Phases tab.
2. On the Link Binaries With Libraries tab, you will need to
add CoreGraphics.framework and QuartzCore.framework if your application is not already using them. (These
frameworks are required by the FoneMonkey console.)
3. XCode will have added references to the libFoneMonkey.a and libFoneMonkeyOCUnit.a library. If you do not plan to
use OCUnit for automated testing, you can remove the libFoneMonkeyOCUnit..a library.
If you do not remove libFoneMonkeyOCUnit.a, you will also need to
include libxml2.dylib and SenTestingKitFramework. SenTestingKitFramework is included with Xcode but will not
be listed in the dialog where you add frameworks and libs to your project. You must instead click "Add Other..." and
navigate to /Developer/Library/Frameworks where you can select the SenTestingKitFramework folder.
4. On the Build Settings tab, scroll down to the Linking section and set Other Linker Flags to:
-all_load
Build and go
Select the YourAppMonkey Scheme for building in the drop-down. (If you did not rename this scheme, it may still be
calledYourApp copy)
Right-click on YourAppMonkey build target and select Clean from the menu.
Right-click on YourAppMonkey build target again and select the Run button (or Build and Run or Build and
Debug from the menu). FoneMonkey can be launched in either the simulator or on an iPhone device.
Your application should start. Immediately after it displays, the FoneMonkey console should drop down in front of
your application's window.
Start testing!
USER GUIDE
You use the FoneMonkey Console to create, manage, and run FoneMonkey tests.
When you launch an application that has been linked with FoneMonkey, the FoneMonkey Console is displayed on
top of the application’s window.
RECORDING AND PLAYBACK
You use the FoneMonkey console to create, manage and run test scripts.
Record
To begin recording, touch the Record button. The FoneMonkey console will hide and you can manually test your
application. As you interact with it, FoneMonkey records FoneMonkey commands corresponding to each user
interface gesture.
Pause
If you stop interacting with the application for longer than the timeout interval (by default, 2.5 seconds), the
FoneMonkey console will reappear on top of your application window.
If you are not yet done recording, click any where over the application to hide the FoneMonkey console and resume
recording.
Touching the Pause button hides the FoneMonkey window and lets you interact with your application without
recording. The console will reappear after the timeout interval. Touch anywhere on your application to re-hide the
console and continue without recording.
Playback
Touch the Play button to play back a script. The console will hide and FoneMonkey will generate user interface
interactions corresponding to each command. When playback is complete, the console will be redisplayed.
Adding verification
You can add Verify commands to a script to test the values UI component properties or the values of associated
object properties (ie, you can use a key-value encoded key path) . To insert a Verify command, touch the More button
to display the current script and then touch the Insert (+) button on the toolbar. Next touch the Insert (+) button on a
row to insert a new Verify command and display it in the command editor.
Use the first argument to specify a string-valued property expression and the second argument to specify the
expected value.
Playback option
To manage your playback options, simply tap on the “Playback Options” button from within the console. The default
selection is “Recorded Speed”, which uses per command values as a guide to the rate of playback. Once you have
set your playback options, they will be remembered for future tests.Recorded Speed
When you record your scripts with FoneMonkey, we timestamp each command and set the playback speed of each
command based on the timestamp. You can specify a percentage value and the script will playback at that speed. If
no value is specified, the script will play at 100%. Fixed Speed
“Fixed Speed” overrides per command options, therefore per command playback options are only used when using
the “Recorded Speed” playback option. When you choose Fixed Speed playback, your script will playback with a set
interval between commands (fixed speed) with a set timeout before failure. Values are set in milliseconds and if you
do not set a value, fixed speed defaults to 500 milliseconds with a 0 millisecond timeout.
Wait for True condition
The WaitFor command will pause execution until some condition becomes true. For example, if your application
makes a requests remote data, and when that remote data is returned a Done button appears on the screen, you
could force your script to wait for the button to appear before continuing execution with a command such as:
WaitFor UIButton "Done"
You can add a WaitFor by adding a Verify command, and then change the command name from Verify to WaitFor.
The first and second arguments specify a property-value pair . The third argument is optional and specifies a timeout
in milliseconds. The default timeout is 500 milliseconds. If you are waiting for some component to appear without
regard for any particular property-value pair, you can specify no arguments, or just the first argument if you wish to
set a timeout value.
SCRIPT EDITTING
Touch the More button to view the list of recorded commands.
Commands are displayed in the Command List table.
Set timeout interval
When recording or pausing, FoneMonkey waits for a period of inactivity equal to the timeout interval before
redisplaying the FoneMonkey console.
The Timeout slider can be used to set the timeout interval anywhere from 2 to 10 seconds. If the console is
reappearing more quickly than you want it to while the console is recording or paused, make the timeout longer.
Edit commands
To edit a command, touch the Edit button on the row in the command list to be edited. The Command Editor will be
displayed.
Using the command editor, you can change the Command, Component Class, Monkey ID, or any of the associated
parameters. When you’re finished editing, touch the Done button.
Insert & Edit commands
Commands can be inserted and deleted using the Insert and Delete toolbar buttons, which display the Insert or Delete buttons in each row of the displayed script.
Save a script
To save a script, touch the Save Script button. The Save Script dialog will be displayed.
Enter a name for the script and hit the Save button. Scripts are saved in the application's Documents directory.
Run a saved script
To run a saved script, touch the Open Script button. The Saved Script List will open displaying all saved scripts.
To open a script, touch its name in the list. The script will open in the console and can be played and edited.
Record new script
To clear the currently opened script and begin creating a new one, click the Open Script button and then touch the New button displayed above the Saved Script List.
Delete a saved script
To delete a saved script, touch the Open Script button and then click the Edit button displayed above the Saved Script List. You may then delete a saved script by touching the associated Delete Icon.
RUNING FONEMONKEY WITH OCUNIT
OCUnit (also known as SenTestingKit) is a unit testing framework for Objective-C that's bundled with the XCode
IDE. As a member of the xUnit family of testing frameworks, OCUnit is similar to other popular frameworks such as
JUnit (for Java), and FlexUnit (for Adobe Flex).
Using OCUnit, you can combine FoneMonkey- and non-FoneMonkey-based tests into comprehensive test suites that
can be invoked interactively, as well as from build scripts, and from continuous integration frameworks such
as Hudson or Cruise Control. It is also possible to combine OCUnit tests with non-OCUnit (for example, JUnit) tests,
and combine the output so as to provide considated test reporting across all front- and back-end components of your
application.
Please note that to run FoneMonkey with OCUnit, you should not create a testing bundle. Instead, you use
the FoneMonkeyOCUnitplug-in to launch your OCUnit tests cases, as described later in this section.
OCUnit test output will be written to the console. You can optionally write out the results in XML format.
Adding OCUnit to project
You add OCUnit to your project much in the same way you add any framework.
Right click on the target that includes FoneMonkey, and select Get Info from the menu. The Target Info dialog will
be displayed.
Add a new entry to the Linked Libraries by clicking the add (+) button at the bottom of the dialog window. A
selection dialog will open.
Click the Add Other... button. A file selection dialog will open.
Navigate to the /Developer/Library/Frameworks folder. Select SenTestingKit.framework.
Click the Add button.
Add FoneMonkeyOCUnit plug-in
The FoneMonkey distribution includes libFoneMonkeyOCUnit.a which is a static library that extends FoneMonkey with an OCUnit test launcher. To run tests under OCUnit, add this library to your project's linked libraries. You will also need to add SenTestingKit.framework to your project.
Write a test case
You write your test cases for FoneMonkey in the same way you write any OCUnit test. To create a test case, simply
subclass SenTestCase and use STAssertions to test for expected results. For more information on OCUnit
(SenTestingKit), see Apple's Documentation.
Using the FoneMonkey API, you can run FoneMonkey commands from within your test case, and you use OCUnit
Let's look at an example:
#import <SenTestingKit/SenTestingKit.h> #import <UIKit/UIKit.h>#import "FoneMonkeyAPI.h"
@interface SampleTest : SenTestCase
- (void) testSample;
@end
@implementation SampleTest
- (void) testSample { NSString* lastResult = [FoneMonkeyAPI playFile:@"Test1"]; STAssertNil(lastResult, lastResult);}
@end
FoneMonkeyAPI.h can be found in the include folder of the FoneMonkey distribution download.
You run a FoneMonkey script from a test case by calling runScript:(NSString*)script, where script is the name of a
FoneMonkey script stored in your application's Documents directory. runScript: returns nil if the script runs
successfully. For example, in the script above we call: NSString* lastResult = [FoneMonkeyAPI playFile:@"Test1"];
If the script fails for any reason, runScript: returns the message generated from a failed Verify command, or other
error message. You need to explicitly add an assertion to test for a non-nil result, and display the returned message if
it's non-nil as follows:
STAssertNil(lastResult, lastResult);
You can of course do more in your test case than simply run a script and test its result. You can include addition
programming logic and assertions, and run multiple scripts.
Using the FoneMonkey API, It is also possible to build scripts programatically at run time, rather than running a script
previously saved.
Create XML result files and screenshots
When running FoneMonkey under OCUnit, test results will be written to the console. You can also create XML
formatted test results and save screenshots of your running tests as described below.Saving Test Results as XML
Setting the FM_ENABLE_XML_REPORT environment variable will result in FoneMonkey saving test results in XML
format to your application's Documents directory.Saving Screenshots of Running Tests
FoneMonkey will write out screenshots of your running application by setting the FM_ENABLE_SCREENSHOT
environment variable. Three values are currently supported:
FAILURE - writes out a screenshot each time a script failure occurs
ALL - writes out a screeshot after each command is executed
NONE - no screenshots will be written
Create test runner target
You can create an Xcode target that builds your app and then runs your FoneMonkey OCUnit tests. You can run this
target from the command line within external build management systems or continuous integration environments
without having to start Xcode.
Create a duplicate target of your FoneMonkey test target. If your test target did not already include
libFoneMonkeyOCunit.a, you must add it to the new target as described here.
Name the new target something like MyAppTestRunner.
Open the Build Phases tab for the newly created target.
Click on Add Build Phase and then Add Run Script.
'
Copy the following into the new script body:
export FONEMONKEY_HOME=~/Documents/Projects/fonemonkey/FoneMonkey/Dist/FoneMonkey export FAMILY=ipad export LOG_FILE="$PROJECT_DIR/$TARGETNAME.log"export FONEMONKEY_ENV=$FONEMONKEY_HOME/FoneMonkeyRunner.plist
rm -f "$LOG_FILE"
$FONEMONKEY_HOME/bin/iphonesim launch "$CODESIGNING_FOLDER_PATH" -verbose -sdk
$IPHONEOS_DEPLOYMENT_TARGET -family $FAMILY -stderr "$LOG_FILE" -env "$FONEMONKEY_ENV"
Change FONEMONKEY_HOME to point to your unzipped FoneMonkey.zip folder
The results will be written a file called YourTargetName.log in your project's root directory. You can change
LOG_FILE to point to any preferred name or location for the output results.
Build (don't Run) the target
Your application will build, and then the new script step will invoke the open source utility iphonesim to install and run
your app in the simulator. Your tests will run immediately after the app is opened in the simulator.
If you want the application to terminate after the tests have run, define the environment variable
FM_ENABLE_AUTOEXIT. Although this won't terminate the simulator, it will terminate the build step so that you can
rerun without having to stop the previous build first. Environment variables are set via the plist file specified by
FONEMONKEY_ENV. The script above points to a plist file located in the FoneMonkey distribution directory. You can
edit this file directly using Xcode's plist editor, and you can of course change the name or location of the file and then
update the environment variable in the script accordingly.
Environment variables must be set by using Xcode's property list editor to modify the FoneMonkeyRunner.plist file
located in the root of FONEMONKEY_HOME. If you'd prefer a different plist name or location, modify the location
referenced by the -env argument in the above script. Setting FM_ENABLE_XML_REPORT will save the test results
in XML format in your application's Documents directory.
In addition to running the target from within xcode, you can also run the target from the command line using
the xcodebuild command.
Running with QUnit
QUnit is a JavaScript test suite similar to JUnit with distinguishing functionality allowing FoneMonkey to execute tests
written in JavaScript from a UIWebView.
QUnit facilitates the ability to create comprehensive test suites in JavaScript that can be attached to build targets and
invoked interactively, via build scripts or from continuous integration frameworks (Hudson or Cruise Control).
Test output from QUnit tests is written to the console. Setting the FM_ENABLE_XML_REPORT environment variable
to YES will write out the results in XML format.
When the QUnit test is completed on the device or in the simulator, results from the test will be presented in the
console. A script button will also be added to the timer toolbar to access those results from the console.
Writing a QUnit test case
You write QUnit tests for FoneMonkey the same way you would write any other QUnit test. Using the FoneMonkey
QUnit API, you can run FoneMonkey commands from within test cases. For simplicity, the API will handle assertions
associated with the results from playing commands. Here is an example:$(document).ready(function(){module("SampleTest");asyncTest('testSomething', function() { commandList = new CommandList(); commandList.add("Touch", "UITableViewCell", "Buttons", "5", "20"); commandList.add("TouchLeft", "UINavigationBar", "Buttons", null); commandList.play();})});
In this example:commandList = new CommandList();
- creates a new CommandList object to add commands to / play those commandscommandList.add("Touch", "UITableViewCell", "Buttons", "5", "20");
- adds "Touch" command to the "UITableViewCell" with the MonkeyID "Buttons" with arguments "5" and "20"commandList.play();
- plays the list of commands in the commandList object
A continuation function can be added to commandList.play() as an argument which will be played once the
commands are done playing. As an example:// Within asyncTestcommandList.play(playAnotherList);function playAnotherList(){ newList = new CommandList(); newList.add("Touch", "UITableViewCell", "NotButtons", null); newList.add("TouchLeft", "UINavigationBar", " NotButtons ", null); newList.play();}
You can also get property values of objects in your command list at specific points during playback, specifying a
variable that can be used later in your command list. Continue to the next section for more information.
Running QUnit tests
Adding your JavaScript test to your test target is simple and does not require adding any additional frameworks.
First, make sure you place your JavaScript file in the Documents directory of your application (FoneMonkey logs the
path to this directory when your test target runs)
Add the environment variable FM_ENABLE_QUNIT to your test target and set the file name as the value, including
the file extension: example.js
Your test target will now run the tests within example.js
CREATING A SCRIPT PROGRAMMATICALLY
You can use the FoneMonkey API to create a script. Use the FoneMonkeyAPI static playCommands method to add
commands to the current script.
/**
Play the supplied array of FMCommandEvents.
@return nil if all comamnds run successfully and an error or failure message otherwise.
*/
+ (NSString*) playCommands:(NSArray*)commands;
You can create an FMCommandEvent with following FMCommandEvent static method.
/**
Create a new FMCommandEvent
*/
+ (FMCommandEvent*) command:(NSString*)cmd className:(NSString*)name monkeyID:(NSString*)id args:
(NSArray*)array;Example
- (void) testSomething {
NSMutableArray* array = [NSMutableArray array];
[array addObject:[FMCommandEvent command:@"Touch" className:@"UITabBarButton"
monkeyID:@"GLPaint" args:nil]];
NSString* lastResult = [FoneMonkeyAPI playCommands:array];
STAssertNil(lastResult, lastResult);
}
UNDERSTAND FONEMONKEY COMMANDS
FoneMonkey records and plays FoneMonkey commands. For each kind of user interface action there is a
corresponding command. Some examples of commands are Touch, Scroll, and Shake. FoneMonkey commands
can be stored and run from script files, or can be created programatically via the FoneMonkey API.
Commands are written as:
CommandName ComponentType "MonkeyID" Parameters, ...
where
CommandName identifies the command to be executed.
ComponentType is the Objective-C class name (or any super class name) of the component to receive the
command. If componentType is omitted, it defaults to UIView (ie, any component).
"MonkeyID" is a quoted string that uniquely identifies which instance of the component's class should receive the
command. If there is only one instance of a particular type, monkeyID may be omitted.
Parameters, .... are zero or more command-specific parameter values in CSV format.
Parameters are often optional for a particular command. For example, the Touch command takes 2 arguments
corresponding to the x,y coordinate of the touch event within the view. If you specify a Touch command without any
parameters, the Touch will be located in the center of the view.
If you're unsure of what command to use to generate a desired UI operation, simply start the FoneMonkey recorder
and record the action.
By overriding recording and playback methods, it's easy to add your own commands to FoneMonkey or customize
existing commands. See the FoneMonkey Extension Guide for more information.
Some Command Examples
Touch the "Done" button:
Touch UIButton "Done"
Touch the PaintingView at coordinate (25, 75):
Touch PaintingView 25, 75
Enter fred into the "First Name" field:
InputText UITextField "First Name" fred
Identify components in commands
Commands correspond to user interface actions, and actions are directed to components. For example, a command
might specify toTouch a UIButton. If there is only one UIButton on the screen, FoneMonkey knows which button the
command is referring to. If there are multiple buttons, however, we must tell FoneMonkey which one we mean. In
addition to the component's Objective-C class name, and a unique identifier called a monkeyID (generated by
FoneMonkey). For any command, you can specify just a className or a monkeyID, or you can specify both.
Component Identification Examples
If there are multiple buttons on the screen:
Touch UIButton "Done"
If there is just one button on the screen:
Touch UIButton
If threre is just one button on the screen with a monkeyID of "Done":
Touch "Done"
Understanding MonkeyID's
FoneMonkey's UIView extensions provide the default monkeyID for all components. By default, the monkeyID of a
component is the value of its:
accessbilityLabel property, if one exists
its tag property, if it's non-zero
and otherwise FoneMonkey generates a unique identifier as explained below.
Many component types provide specialized monkeyID's. For example, UIButton returns its titleLabel.text as its
monkeyID, and UITextField returns its placeholder value.
See the FoneMonkey Command Reference for a description of the monkeyID's returned by each component type.
If a component provides no monkeyID, FoneMoney generates an identifier by assigning an ordinal to each instance
of each class on the screen. FoneMonkey generated monkeyID's are prefix with a #-sign.
Examples of Generated MonkeyID's
Touch the first button:
Touch UIButton #0
Touch the second button:
Touch UIButton #1
Understanding MonkeyID’s
FoneMonkey's UIView extensions provide the default monkeyID for all components. By default, the monkeyID of a
component is the value of its:
accessbilityLabel property, if one exists
its tag property, if it's less than 0
and otherwise FoneMonkey generates a unique identifier as explained below.
Many component types provide specialized monkeyID's. For example, UIButton returns its titleLabel.text as its
monkeyID, and UITextField returns its placeholder value.
Please note that for the accessibilityLabel to be recognized, you must enable accessibility by editing the
file ~/Library/Application Support/iPhone
Simulator/User/Library/Preferences/com.apple.Accessibility.plist and setting
the AccessibilityEnabled andApplicationAccessibilityEnabled properties to true. You also need to edit the same
settings in ~/Library/Application Support/iPhone
Simulator/<YourSDKVersion>/Library/Preferences/com.apple.Accessibility.plist. Some users have additionally
reported needing to open the Settings application on the simulator and set General>>Accessibility>Accessibility
Inspector to On.
If setting the accessibility label programmatically, you also need to enable accessibiility for the element, for example:
myTextField.accessibilityLabel = @"someID";
myTextField.isAccessibilityElement = YES;
See the FoneMonkey Command Reference for a description of the monkeyID's returned by each component type.
If a component provides no monkeyID, FoneMoney generates an identifier by assigning an ordinal to each instance
of each class on the screen. FoneMonkey generated monkeyID's are prefix with a #-sign. The generated ordinal of a
component does not necessarily correspond to its sequential position on the screen.
Generated id's are dependent on the order in which a particular component type is added to a view, and so can
change across application runs if you rebuild your application with a modified view after recording a script. For this
reason, you should try to avoid saving scripts with generated monkeyID's. You should instead specify an
accessibilityLabel, a non-zero tag value, or override the monkeyID method as described in the next section.
Examples of Generated MonkeyID's
Touch a button:
Touch UIButton #2
Touch another button:
Touch UIButton #4
Overriding a class’s monkeyID
If a component's monkeyID is non-unique or FoneMonkey-generated (begins with a #), or if a different identifier will
make commands more readable, you can customize the monkeyID returned by a component by overriding
the monkeyID method.
For example, if your application has a custom view class, you can add a monkeyID method in a category extension
like this one:#import <UIKit/UIEvent.h>#import "FoneMonkey.h""#import "MyCustomView.h"
@implementation MyCustomerView (FoneMonkey)
- (NSString*) monkeyID { return self.lastName;}
@end
By locating the method in a class category, you can compile it into your your application's FoneMonkey test build, and
omit it from your release build.
Understanding Command Recording and Playback
Commands are sent to UI components to be executed (by the component's FoneMonkey extensions). When a
UI component receives a command, it will either handle it or send it to its superclass for handling.
UIView extensions provide the default implementations of recording and playback for common gestures, such as
Touch and Move, for all subclasses. Because all Cocoa Touch components inherit from UIView, its implementations
provide default recording and playback functionality for most UIKit UI components. In addition, various classes
override command implementations to specialize recording and playback for their component types.
A particular command can be implemented by mutliple component classes. During playback a command is sent to
the component identified by a supplied class name and monkeyID. The receiving component either handles the
command itself or sends it to its superclass for execution, with the default for all components being provided
by UIView Commands.
Argument interpretation is made by the component that executes the command, and so the number and purpose of
arguments can differ according to what component the command is being sent to. For example, when used with most
types of UIViews, the Touch command takes x and y parameters. When used with a UISegmentControl, however, the
Touch command takes just one argument, which specifies the label of the segment to be touched.
You can customize command processing for some component class or add entirely new commands by implementing
one or moreFoneMonkey extensions for the class.
ENABLING RECORDING OF IGNORE EVENTS
In order to prevent the recording of spurious events, FoneMonkey, by default, filters various types of events for
various components. For example, UIView by default only records UITouchPhaseEnded events.
To enable recording of additional events for a particular class, add a shouldRecordMonkeyTouch method to the class
(or category).
For example, let's say you have a subclass of UIView called PaintingView that requires recording TouchBegin and
TouchMoved events. You could add a category method to the class as follows:#import "PaintingView.h"@interface PaintingView (FMReady)
@end
@implementation PaintingView (FMReady)
- (BOOL) shouldRecordMonkeyTouch:(UITouch*)touch { return ([touch phase] && (UITouchPhaseBegan | UITouchPhaseMoved));}
@end
GENERATING TESTS
Whenever you save a script from the FoneMonkey console, three files are created:
Native FoneMonkey script file - A Cocoa Property List XML file called YourScriptName.fm that can be open and run
with the FoneMonkey console.
OCUnit source file - An Objective-C source file called YourScriptName.m that can be executed with
an OCUnit runner. You can extend the generated code with Objective-C logic to do things like looping, conditional
branching, or data-driving of your tests.
QUnit source file – A JavaScript source file called YourScriptName.js that can be executed by setting
FM_ENABLE_QUNIT environment variable with the value: YourScriptName.js – As with the OCUnit source file, you
can extend the generated code with JavaScript logic.
UIAutomation source file (DEPRECATED in FoneMonkey 5.2a – Set the FM_ENABLE_UIAUTOMATION
environment variable to generate this source file instead of the QUnit source file) - A generated JavaScript source file
called YourScriptName.js that can be executed with Apple's Automation Instrument. As with OCUnit tests,
UIAutomation tests can be customized and extended with additional control or data-driven logic. Executing
FoneMonkey's generated UIAutomation scripts does not require linking any of the FoneMonkey or OCUnit libraries
into your iOS app, so UIAutomation scripts can be run directly against applications built for release.
In addition to the three script files, FoneMonkey also copies the FoneMonkey UIAutomation support library,
FoneMonkey.js to your documents directory. This file is required for running generated UIAutomation scripts.
Please note that the FoneMonkey console can only read and run native FoneMonkey (.fm) files. Any changes you
make to generated (.m or .js) source files are invisible to the FoneMonkey console. You can however modify the .fm
file directly with a text, xml, or property list editor, and then open and run the resulting script in the FoneMonkey
console.
The three scripts are saved under your application's Documents directory.
The names and locations of the files being written when you save a script are displayed in the XCode console, for
example:2011-02-03 19:22:42.611 FoneMonkeyTestApp[35019:207] saving script "sampletest" to /Users/sstern/Library/Application Support/iPhone Simulator/4.2/Applications/C8875700-37D8-47C2-ABFC-B01B7CF3DE2C/Documents
2011-02-03 19:22:42.612 FoneMonkeyTestApp[35019:207] Writing /Users/sstern/Library/Application Support/iPhone Simulator/4.2/Applications/C8875700-37D8-47C2-ABFC-B01B7CF3DE2C/Documents/FoneMonkey.js
2011-02-03 19:22:42.614 FoneMonkeyTestApp[35019:207] Writing /Users/sstern/Library/Application Support/iPhone Simulator/4.2/Applications/C8875700-37D8-47C2-ABFC-B01B7CF3DE2C/Documents/sampletest.js
2011-02-03 19:22:42.616 FoneMonkeyTestApp[35019:207] Writing /Users/sstern/Library/Application Support/iPhone Simulator/4.2/Applications/C8875700-37D8-47C2-ABFC-B01B7CF3DE2C/Documents/sampletest.m
Although the Property List XML files can be easily edited by hand in any text or XML editor, it is not possible to
specify anything but sequential logic in this format. If you need to create more complex testing flows or read data from
a file or database to drive your test scripts, you need to extend your scripts by editing the generated Objective-C or
JavaScript source files.
Script Language File RunnerCan be data-driven or
extended with control logicRequires FoneMonkey Libraries for Execution
XMLYourScriptName.fm
Console No Yes
Objective-C YourScriptName.m OCUnit Yes YesJavaScript YourScriptName.js QUnit Yes Yes
JavaScriptDEPRECATED YourScriptName.jsInstruments
Yes No
Understanding generated Object-C code
Here is a sample of a FoneMonkey-generated OCUnit test:#import <SenTestingKit/SenTestingKit.h>#import <UIKit/UIKit.h>#import "FoneMonkeyAPI.h"
@interface SomeScript : SenTestCase {}- (void) testSomething; @end
@implementation SomeScript- (void) testSomething {// NSString* lastResult = [FoneMonkeyAPI playFile:@"SomeScript"];
NSMutableArray* array = [NSMutableArray array];[array addObject:[FMCommandEvent command:@"Touch" className:@"UITableViewCell"
monkeyID:@"Buttons" delay:@"500" timeout:@"0" args:[NSArray arrayWithObjects:@"98", @"21", nil]]];
[array addObject:[FMCommandEvent command:@"Touch" className:@"FunkyButton" monkeyID:@"Gray" delay:@"1182" timeout:@"0" args:[NSArray arrayWithObjects:@"40", @"24", nil]]];
[array addObject:[FMCommandEvent command:@"Verify" className:@"FunkyButton" monkeyID:@"GRAY!" delay:@"1546" timeout:@"0" args:[NSArray arrayWithObjects:nil]]];
[array addObject:[FMCommandEvent command:@"Touch" className:@"FunkyButton" monkeyID:@"GRAY!" delay:@"675" timeout:@"0" args:[NSArray arrayWithObjects:@"40", @"24", nil]]];
[array addObject:[FMCommandEvent command:@"TouchLeft" className:@"UINavigationBar" monkeyID:@"Buttons" delay:@"1443" timeout:@"0" args:nil]];
NSString* lastResult = [FoneMonkeyAPI playCommands:array];STAssertNil(lastResult, lastResult);
}@end
The script was generated when saving the script, SomeScript.fm. The generated code includes a commented out line
that, if uncommented, would run SomeScript.fm directly:// NSString* lastResult = [FoneMonkeyAPI playFile:@"SomeScript"];
The following lines creates an array of FMCommandEvents. One FMCommandEvent is created for each command
contained SomeScript.fm.NSMutableArray* array = [NSMutableArray array];[array addObject:[FMCommandEvent command:@"Touch" className:@"UITableViewCell"
monkeyID:@"Buttons" speed:@"500" timeout:@"0" args:[NSArray arrayWithObjects:@"98", @"21", nil]]];
[array addObject:[FMCommandEvent command:@"Touch" className:@"FunkyButton" monkeyID:@"Gray" speed:@"1182" timeout:@"0" args:[NSArray arrayWithObjects:@"40", @"24", nil]]];
[array addObject:[FMCommandEvent command:@"Verify" className:@"FunkyButton" monkeyID:@"GRAY!" speed:@"1546" timeout:@"0" args:[NSArray arrayWithObjects:nil]]];
[array addObject:[FMCommandEvent command:@"Touch" className:@"FunkyButton" monkeyID:@"GRAY!" speed:@"675" timeout:@"0" args:[NSArray arrayWithObjects:@"40", @"24", nil]]];
[array addObject:[FMCommandEvent command:@"TouchLeft" className:@"UINavigationBar" monkeyID:@"Buttons" speed:@"1443" timeout:@"0" args:nil]];
The next line runs the commands: NSString* lastResult = [FoneMonkeyAPI playCommands:array];
The playCommands method returns nil if the test completes successfully. The next line of code tests for a nil return
value: STAssertNil(lastResult, lastResult);
Running generated Object-C
To run the generated .m file, simply drag and drop it into your Xcode project, being sure to add it to your test target
when prompted.
The tests will run automatically under OCUnit whenever you start up your app. You can find more information about
running OCUnit-based tests here.
Understand generated JavaScript (QUnit)
Here is an example of a FoneMonkey-generated QUnit test: $(document).ready(function(){module("SampleTest")asyncTest('testSomething', function() { // myCommandList = new CommandList(); FM.commandList.addRetry("Touch", "UITableViewCell", "Buttons", "500", "0", "5", "20"); FM.commandList.addRetry("Touch", "UIRoundedRectButton", "BUTTON", "1872", "0", "130", "22"); FM.commandList.addRetry("TouchLeft", "UINavigationBar", "Buttons", "771", "0", null); FM.commandList.play();}) function continuationFunction(){ // Additional logic after commands are done playing
}});
In this example:
FM.commandList is a CommandList object created by the FoneMonkey QUnit API.FM.commandList.addRetry("Touch", "UITableViewCell", "Buttons", "500", "0", "5", "20");
- adds "Touch" command to the "UITableViewCell" with the MonkeyID "Buttons" with speed "500" (milliseconds) and
a timeout of "0" (milliseconds) with arguments "5" and "20" FM.commandList.play();
- plays the list of commands in the commandList objectcontinuationFunction()
- is a continuation function that simply replays the FM.commandList
- pass continuationFunction as an argument in FM.commandList.play to add additional logic to be run once the
commands are done playing: FM.commandList.play(continuationFunction);
Running generated JavaScript (QUnit)
Add the environment variable FM_ENABLE_QUNIT to your test target and set the file name as the value, including
the file extension:YourScriptName.js
Your test target will now run the tests within YourScriptName.js
Understanding generated JavaScript (UIAutomation)
FoneMonkey generates JavaScript code that scripts application interactions via Apple's UIAutomation Framework,
and which can be run using Apple's Automation Instrument.
It's important to note that Apple's UIAutomation Framework requires that all application components you plan to
automate can be identified via accessibility labels. Like UIAutomation, FoneMonkey will identify a UIComponent by
using it's accessibility label if one is present. Unlike UIAutomation, FoneMonkey generates an identifier if no
accessibility label is available. These generated identifiersare not valid for use with UIAutomation.
Ideally, you should add all required accessibility labels to your application components prior to recording a test script.
If you record a script and find that some component is missing a good identifier, you can give it an accessibility label
and then, rather than re-record your script, you can edit the script to replace the generated identifier with the newly
specified label.
Another difference between UIAutomation and FoneMonkey is that UIAutomation accessess elements via
hierarchically traversing your application's component tree, whereas FoneMonkey accesses a component via
its monkeyID. In addition, FoneMonkey commands are not always semantically equivalent to their UIAutomation
counterparts, For example, the FoneMonkey command for scrolling a UITableView specifies the section and row
number to which you wish to scroll, while UIAutomation specifies instead the accessibility label of the cell you wish to
scroll to.
To accomodte these differences, FoneMonkey-generated scripts depend on the FoneMonkey.js script which defines
an API that adapts FoneMonkey commands for execution by UIAutomation. Whenever you create a script with
FoneMonkey, the FoneMonkey.js script is added to the application's Documents directory, from where it can be easily
imported into the generated script.
Let's look at an example of a generated script. The script below enters values into the UserID and Password fields of
the application being tested, and then taps a button labeled "OK". It then verifies thsat the LoginResponseMsg field
contains the value "Welcome, User123".#import "FoneMonkey.js"
FoneMonkey.elementNamed("UserID").setValue("User123");FoneMonkey.elementNamed("Password").setValue("password123");FoneMonkey.elementNamed("OK").tap();FoneMonkey.assertElementValue("LoginResponseMsg", "Welcome, User123", 5);
The line#import "FoneMonkey.js"
imports the FoneMonkey UIAutomation JavaScript library that provides various UIAutomation helper functions. You
invoke functions from the library by qualifying the function names with the "FoneMonkey" namespace identifier. For
example, the next line of the script is:FoneMonkey.elementNamed("UserID").setValue("User123");
Here, we are invoking the library's elementNamed function. This function searches the component tree for an
element named "UserID". The elementNamed function returns a UIAElement, and we use the UIAElement setValue
method to set the component's value to "User123".Ident i fy ing Elements
Note that elementNamed provides the ability to reference a component by name, directly, regardless of where it
resides in the component hierarchy. This is in contrast to how elements are identified in the native UIAutomation API,
where it is necessary to navigte the component hierarchy to identify an element.
For example, with native UIAutomation, if the UserID field were contained within a cell of the application window's first
table, you would need to specify something similar to the following:
UIATarget.UIALocal().tableViews[0].cells["Login"].textFields["UserID"].setValue("User123");Interact ing With Components
After setting values for the UserID and Password fields, the script taps on the application's OK button with the script
line:FoneMonkey.elementNamed("OK").tap();
Here again, elementNamed returns a UIAElement, so we can use any method from the UIAElement API to interact
with the component. In this case, we use the tap method to simulate tapping a UIButton.Veri fy ing Expected Results
The next line of the script is:FoneMonkey.assertElementValue("LoginResponseMsg", "Welcome, User123", 5);
This assertElementValue function tests that a component with the supplied name, in this case
"LoginResponseMsg", matches the supplied value, "User123". If the expected value is found, the script will log a
successful test. If not, it will log a test failure. The last argument in the example assertElementValue call above, "5",
specifies a timeout, in seconds, and causes the script to wait for a maximum period of time for the element with the
expected name and value to appear in the application.Wait ing For Expected Results
Most FoneMonkey UIAutomation helper functions accept a timeout value. Specifying a value for this argument
causes the script to wait for the corresponding number of seconds. For example, we can cause our script to wait a
maximum of 10 seconds for a Button named "OK" to appear by specifying:FoneMonkey.assertElement("OK", 10);
The elementNamed function accepts a timeout value, so we can specify statements like:FoneMonkey.elementNamed("OK", 10).tap();
The above statement waits a maximum of 10 seconds for the "OK" button to appear, and then taps the returned
button. If the button is not found in the allotted time, then the script logs a test failure.
If no timeout value is specified, FoneMonkey will use the current value of UIATarget.UIALocal().timeout().Running UIAutomation Scr ipts
See Apple's documentation on Running the Automation Instrument.
GETTING OBJECT PROPERTY DURING PLAYBACK
To get the property of an object during playback, use the CommandList.addGet function. As an example:
commandList.addGet("UITextField", "OneField", "text", "changeVar");
- gets the "text" property for "UITextField" with the MonkeyID " OneField" and creates the variable "changeVar"
You can reference changeVar in the continuation function as a JavaScript variable:
// JavaScript
if (changeVar == "ExpectedText")
// Do something
Or later during playback as a MonkeyID or an argument for the command using ${ } delimiters:
commandList.add("Return", "UITextField", "AnotherField", " ${changeVar}");
MANAGING SCRIPT FILES
FoneMonkey scripts and generated code files are stored within your application's Documents Directory. (Learn more
aboutgenerated script files.)Running in the Simulator
When running in the simulator, the Documents directory is located in your Application Home directory located at:
~/Library/Application Support/iPhone Simulator/<SDK
Version>/Applications/<ApplicationID>
where SDK Version is the version of the SDK you're running with, and ApplicationID is the unique identifier created
for you when you install your application in the simulator. For example:
~/Library/Application Support/iPhone Simulator/4.2/Applications/16F183BB-A209-408A-
A91D-E4DF99DD42F4/Documents
Each time you re-install your app, a new ApplicationID will be assigned and a new Application Home directory will be
created. Anything stored in your previous Documents directory should be copied to a newly created one in the new
Application Home.Editing Script Files Directly
FoneMonkey currently stores "native" scripts as standard Mac Property List (.plist) files. You can edit a script as you
would any other .plist by using the Mac Property List Editor.Transferring Scripts Between the Simulator and Device
Scripts files can be transfered back and forth from an iOS device in the same way you would share any application
data file.
FONEMONKEY ENVIRONMENT VARIABLES
Environment Variable Value Description
FM_ENABLE_AUTOEXIT YES Set application to terminate after OCUnit tests have run
FM_ENABLE_XML_REPORT YESSave test results in XML format to application's Documents Directory
FM_ENABLE_SCREENSHOT
FAILURE
ALL
NONE
Writes out a screenshot each time a script failure occurs
Writes out a screenshot after each command is executed
No screenshots will be written
FM_ENABLE_QUNIT ScriptName.js Set application to run QUnit test in ScriptName.js
FM_ENABLE_UIAUTOMATION
YES Generate UIAutomation JavaScript file instead
DATA DRIVE WITH FONEMONKEY
Using the DataDrive command introduced in FoneMonkey 5.3a, you can specify a CSV (Comma Separated Value)
file containing data you would like to drive your tests with. The CSV file must be located within your
application's Documents Directory and must be saved as Windows Comma Seperated (.csv) in Excel. Values in the
first row of your CSV file will serve as variables that can be referenced later in your command list using the syntax $
{variable}. By specifying your CSV file at the beginning of your command list, your test will run for each row in the
file. Screenshots below will help you to understand how to implement a data driver into your tests.
JS Sample Test:
$(document).ready(function(){ module("Simple Module"); asyncTest("Simple Test", function() { // Add a data driver to the command list // CSVdemo.csv is located in documents directory FM.commandList.addDriver("CSVdemo"); // Build the command list // FM.commandList.addRetry("Command", "Class Name", "Monkey ID", "Delay (ms)", "Timeout (ms)", "Arg1", "Arg2", "ArgX");
FM.commandList.addRetry("Touch", "UITableViewCell", "TextFields", "500", "100", "99", "31");
FM.commandList.addRetry("Touch", "UITextField", "Normal", "1094.26", "100", "142", "20");FM.commandList.addRetry("InputText", "UITextField", "Normal", "84.458", "100", "$
{firstVar} ${secVar}");FM.commandList.addRetry("Clear", "UITextField", "Normal", "1188.06", "100", null);FM.commandList.addRetry("Return", "UITextField", "Normal", "1425.48", "100", "");FM.commandList.addRetry("TouchLeft", "UINavigationBar", "TextFields", "1192.54", "100", n
ull); // Play commandList with CSVdemo data driver
FM.commandList.play(); })
FONEMONKEY COMMAND REFERENCE
This reference organizes commands by component class. FoneMonkey commands are implemented by various class
extensions and those implementations are inherited by subclasses. If a particular component type is not listed here, it
is because it inherits its recording and playback behavior from one or more of its superclasses.
A command can specify either the class that should receive the command or any if its superclasses. For example, to
push a UIButton subclass called CustomButton you could specify:
Touch CustomButton
or
Touch UIButton
The specified class is used by FoneMonkey at runtime in conjunction with an optional monkeyID to identify a
component to receive a command. The command will be executed the same way by the receiving component
regardless of what class name was actually specified on the command itself.
GLOBAL COMMANDS
DataDrive fileName:stringSets the data driver for a set of commands. Add the DataDrive command to the beginning of your list of commands
and your test will iterate through the rows in your Comma Separated Value file you specify. Values in the first row of
the CSV file will serve as variables and can be accessed from command arguments and MonkeyID's later within the
command list using ${variable} syntax.Arguments
fileName:string (Required) - Filename of CSV file to data drive your test (must be in your application's Documents
Directory).Examples
DataDrive myCsvFile
Pause milliseconds:integerPauses playback for the specified number of milliseconds. You can use this command if you need to increase the
delay between the execution of two commands. This is a global command. If a class name or monkeyID is specified,
it will be ignored.Arguments
milliseconds:integer (Required) - The number of milliseconds to pause playback.Examples
Pause 1000
RotateShakes the phone. This is a global command. If a class name or monkeyID is specified, it will be ignored.Arguments
orientation:integer (Optional)- The integer value corresponding to the UIDeviceOrientation enumeration.Examples
The following example rotates the phone orientation right to landscape and left back to portrait.
Rotate 4
Rotate 0
ShakeShakes the phone. This is a global command. If a class name or monkeyID is specified, it will be ignored.Arguments
None.Examples
Shake
UIBUTTON COMMANDS
UIButton adds no new command handling, but overrides monkeyID.
MonkeyID
UIButton's monkeyID is its titleLabel property (the button's display text) value if it exists, otherwise it is the default
monkeyID.
UINAVIGATION COMMANDS
MonkeyID
UINavigationBar's monkeyID is its topItem.title property, if it exists. Otherwise it is the default monkeyID.
TouchLeft UINavigationBar
TouchRight UINavigationBar
TouchLeft UINavigationBar ["monkeyID"] Touches the left side of the navigation bar, which will touch the leftside (or back) button if one is present.Arguments
None.
TouchRight UINavigationBar ["monkeyID"] Touches the right side of the navigation bar, which will touch the rightside button if one is present.Arguments
None.
UISCROLLVIEW COMMANDS
UIScrollView records the upper-left coordinate visible within a view whenever scrolling comes to a stop.
Scroll UIScrollView ["monkeyID"] x:integer, y:integerScrolls the specified coordinate to the upper left corner of the view.Arguments
x:integer (Required)- The x coordinate to scroll to.
y:integer (Required) - The y coordinate to scroll to.
UISEGMENTED CONTROL COMMANDS
UISegmentedControl specializes the Touch command and the monkeyID.MonkeyID
A UISegmentedControl's monkeyID is the concatenation of its segment labels if it has any. Otherwise it's the default
monkeyID.
Touch UISegmentedControl ["monkeyID"] label:string
Touches the segment with the specified label.Arguments
label:string (Required)- The label of the segment to touch. If the segmented control displays images rather than text
labels, the label is interpreted as the ordinal position (beginning with zero) of the segment to touch.Examples
To touch a segment called "Settings":
Touch UISegmentedControl Settings
To touch the third segment (if it's an image):
Touch UISegmentedControl 2
UISLIDER COMMANDS
Slide UISlider ["monkeyID"] value:floatSlide the slider to the specified value.Arguments
value:float (Required)- The value to slide to.
UISWITCH COMMANDS
Switch UISwitch ["monkeyID"] Toggle the slider on or off from its present state.Arguments
None.
UITABLEVIEW COMMANDS
UITableView defines the VScroll command for table scrolling.
VScroll UITableView ["monkeyID"] [row:integer, section:integer]Scrolls the table to the specified row and section.Arguments
row:integer (Optional)- The row to scroll to. Defaults to 0.
section:integer (Optional) - The section to scroll to. Defaults to 0.
UITABLEVIEWCELL COMMANDS
UITableViewCell adds no new commands, but customizes monkeyID.
MonkeyID
A UITableViewCell's monkeyID is:
its textLabel.text property value, if one exits, else
its detailTextLabel.text property value, if one exists, else
its text property value, if one exists, of a child of the cell's contentView, else
its default monkieyID.
Note - You cannot "touch" a UITableViewCell unless it's visible on the screen. In other words, you can't "touch" a cell
that is currently scrolleld off the display. You must scroll to it into view first with the Scroll UITableView command.Example
Touch UITableViewCell "Playlists"
UITEXTFIELD COMMANDS
UITextField records touch and input events. Input value recording occurs whenever a textfield edit is completed. The
value recorded is the updated field value.MonkeyID
UITextField's monkeyID is its placeholder property value (the field's prompt text) if it has one. Otherwise it is the
default monkeyID.
InputText UITextField ["monkeyID"] value:stringEnters the specified text value into the field.Arguments
value:string (Required)- The string value to enter into the text field.Examples
InputText UITextField "Last Name" Smith
Touch UITextField ["monkeyID"] Sets input focus (firstResponder) to the text field.Arguments
noneExamples
Touch UITextField "First Name"
UITOOLBAR COMMANDS
UIToolBar adds no new commands or monkeyID customization.
Although you add UIBarButtonItems for each button to display on a toolbar, each UIBarButtonItem is actually
implemented by by an undocumented Cocoa Touch class called UIToolBarTextButton. For this reason, when you
record touching a UIBarButtonItem, the command will be recorded with a class of UIToolBarTextButton rather than
UIBarButtonItem.For example, to touch the "Settings" button on a toolbar:
Touch UIToolBarTextButton "Settings"
UITOOLBARTEXTBUTTON COMMANDS
UIToolBarTextButton is an undocumented Cocoa Touch class that provides the implementation of UIBarButtonItems
within a UIToolBar. UIToolBarTextButton adds no new commands, but it does override monkeyID.MonkeyID
The text property value from the UIToolBarTextButton's corresponding UIBarButtonItem.
UIVIEW COMMANDS
All Cocoa Touch UI components inherit from UIView, and UIView provides the default handling for the most common
FoneMonkey commands including Touch, Move, Scroll, Shake, and Verify. While most component classes forward
commands to UIView for handling, many component classes do override or specialize the handling of these
commands.MonkeyID
UIView also provides the default implementation of monkeyID for all components, although again, many subclasses
override to provide their own, and you can easily do so for your own custom components.
The default monkeyID for a component is:
its accessibilityLabel if it exists (and accessibility is enabled),
its tag if it is less than zero and there is no accessbilityLabel,
and otherwise a unique identifier generated by FoneMonkey.
FoneMoney generates a monkeyID by assigning an ordinal to each instance of each class on the screen.
FoneMonkey generated monkeyID's are prefix with a #-sign.
Generated id's are dependent on the order in which a particular component type is added to a view, and so can
change across application runs if you rebuild your application with a modified view after recording a script. For this
reason, you should try to avoid saving scripts with generated monkeyID's. You should instead specify an
accessibilityLabel, a negative tag value, or override the monkeyID method.
Touch UIView ["monkeyID"] [x:integer, y:integer][, tapCount:integer]Touches the view at the specified coordinate, or in the center if no coordinate is specified.Arguments
x:integer (Optional)- The x coordinate of the touch in the view.
y:integer (Required if x is specified) - The y coordinate of the touch in the view.
tapCount:integer (Optional) - The number of taps (eg,1 = single tap, 2 = double tap). Defaults to 1.
tapCount:
Examples
Touch UIButton "Done"
Touch UIPaintingView 100,100
Double touch:
Touch UIPaintingView 100,100,2
Move UIView ["monkeyID"] x0:integer, y0:integer[, x1,y1:integer...]
Generates a touch that drags along the path specified by the supplied sequence of x,y coordinate pairs.Arguments
A sequence of one-or-more points specified as x,y coordinate pairs.
xn:integer (At least one required)- The x coordinate of a point along the path.
yn:integer (A corresponding y must be specified for each x) - The x coordinate of a point along the path.Examples
Move PaintingView 0,0,1,1,2,2,3,3,44
Verify UIView ["monkeyID"] [property:string, expectedValue:string]Tests whether the component exists and wether the specified property is equal to some expected value.Arguments
property:string (Optional)- The name or path of the property whose value is to be verified.If no property is specified,
Verify tests only for the existence of the specified component.
expected:string (Required if property is specified) - The expected string value of the specified property.Examples
Verify UILabel "message" text, Welcome
Verify UITableViewCell "Songs" detailTextLabel.text, "Total time: More than 9 Days"
WaitFor UIView ["monkeyID"] [timeout:integer property:string,expectedValue:string]Pauses script execution until the specified view is found.Arguments
timeount:integer (Required)- Maximum time to wait for the view to be found.
property:string (Optional)- The name or path of the property whose value is to be verified.If no property is specified,
WaitFor waits only for the existence of the specified component.
expected:string (Required if property is specified) - The expected string value of the specified property.Examples
WaitFor UILabel "message" 5000
WaitFor UITableViewCell "Songs" 5000, detailTextLabel.text, "Total time: More than 9 Days"
UIWEBVIEWS COMMANDS
New in FoneMonkey 5.5a, you can now run HTML Selenese scripts to test your UIWebView implementation. To
enable this functionality, you will need to:
1. Unzip the extralibs folder within the FoneMonkey folder
2. If you are not using MediaPlayer in your app, you can remove libFoneMonkeyMediaPlayer from the extralibs folder
3. Drag the FoneMonkey folder into your project (if you already have FoneMonkey linked into your project, remove the
folder and then drag the new version in)
4. Continue basic setup steps (add QuartzCore and libxml)
5. Add the following frameworks/libs to your test target (if not already linked)
1. CFNetwork.framework
2. CoreLocation.framework
3. Foundation.framework
4. Libsqlite3.dylib
5. From the Build Settings tab in your test target, add -lstdc++ to your Other Linker Flags
6. Build your test target
Run (Scr ipt ) Command
The WebDriver command is the command used to link your Selenese HTML test to a UIWebView in your application.
You can use the Firefox Selenium IDE plugin to record your HTML test, or you can write it from scratch. To set up
your test:
1. Make sure the HTML file is in your applications Document Directory
2. Record a script to navigate to your UIWebView (if it is not within the default view)
3. Add the Run command (from the console you can do this by pressing the “+” button in the top right)
4. See screenshot for an example of the a complete command
5. Add the HTML file as the first argument for the command
6. Run your test