package com.thoughtworks.calabash.android; import org.jruby.RubyArray; import org.jruby.RubyHash; import java.io.File; import java.util.List; import java.util.Map; public class AndroidApplication { private String installedOn; private CalabashWrapper calabashWrapper; public AndroidApplication(CalabashWrapper calabashWrapper, String serial) { this.calabashWrapper = calabashWrapper; this.installedOn = serial; } public String getInstalledOnSerial() { return installedOn; } /** * returns a list of UIElements corresponding to the calabash query * * @param query calabash query * @return UIElements corresponding to the query * @throws CalabashException */ public UIElements query(String query) throws CalabashException { RubyArray array = calabashWrapper.query(query); return new UIElements(array, query, calabashWrapper); } /** * returns a list of WebElements corresponding to the calabash query * eg: application.queryWebElements("webview css:'div' textContent:'login successful'"); * * @param query calabash query * @return WebElements corresponding to the query * @throws CalabashException */ public WebElements queryWebElements(String query) throws CalabashException { RubyArray array = calabashWrapper.query(query); return new WebElements(array, query, calabashWrapper); } /** * Fetches all elements in this application and executes callback for each * of them * * @param callback Callback to be executed for each element * @throws CalabashException */ public void inspect(InspectCallback callback) throws CalabashException { List<TreeNode> tree = new TreeBuilder(calabashWrapper).createTree(); if (tree.isEmpty()) return; for (TreeNode treeNode : tree) { Utils.inspectElement(treeNode, 0, callback); } } /** * @param dir Existing directory where the screenshot is saved * @param fileName the name of the screenshot * @throws CalabashException */ public void takeScreenshot(File dir, String fileName) throws CalabashException { if (dir == null) throw new CalabashException("Empty directory name"); if (fileName == null) throw new CalabashException("Empty file name"); if (!dir.isDirectory()) throw new CalabashException(dir.getAbsolutePath() + " is not a directory"); if (!dir.canWrite()) throw new CalabashException(dir.getAbsolutePath() + " is not writeable"); calabashWrapper.takeScreenShot(dir, fileName); } /** * Read the preferences inside the shared preference denoted by <code>preferenceName</code> * * @param preferenceName name of the shared preference * @return a map of preferences in the shared preference * @throws CalabashException */ public Map<String, String> getSharedPreferences(String preferenceName) throws CalabashException { if (preferenceName == null || preferenceName.isEmpty()) { throw new CalabashException("Invalid preference name"); } return calabashWrapper.getPreferences(preferenceName); } /** * waits for specified condition for the given timeoutInSec * * @param condition Condition to wait for * @param timeoutInSec timeout in seconds * @throws CalabashException * @throws OperationTimedoutException */ public void waitFor(ICondition condition, int timeoutInSec) throws CalabashException, OperationTimedoutException { calabashWrapper.waitFor(condition, new WaitOptions(timeoutInSec)); } /** * Waits for the specified condition with the options specified * * @param condition Condition to wait for * @param options Wait options * @throws CalabashException When any calabash operations fails * @throws OperationTimedoutException When the operation elapsed the timeout period */ public void waitFor(ICondition condition, WaitOptions options) throws CalabashException, OperationTimedoutException { calabashWrapper.waitFor(condition, options); } /** * Gets the name of the current activity on the application. * * @return the name of the activity on the screen */ public String getCurrentActivity() throws CalabashException { return calabashWrapper.getCurrentActivity(); } /** * simulates the press of 'back' button * * @throws CalabashException */ public void goBack() throws CalabashException { calabashWrapper.performGoBack(); } /** * press the 'enter'(action) key on the keypad * * @throws CalabashException */ public void pressEnterKey() throws CalabashException { calabashWrapper.pressEnterKey(); } /** * Wait for an activity to come on the screen * * @param activityName the activity name which you want to wait for * @param timeout in seconds to timeout when condition fails resulting <code>CalabashException</code> * @throws CalabashException */ public void waitForActivity(final String activityName, int timeout) throws CalabashException, OperationTimedoutException { calabashWrapper.waitForActivity(activityName, timeout); } /** * Wait till an element with id appears * * @param id id of the element * @param timeoutInSec wait time in seconds * @throws OperationTimedoutException * @throws CalabashException */ public void waitForElementWithId(final String id, int timeoutInSec) throws OperationTimedoutException, CalabashException { waitFor(new ICondition() { @Override public boolean test() throws CalabashException { return calabashWrapper.elementExistsById(id); } }, timeoutInSec); } /** * Scrolls the first instance of 'android.widget.ScrollView' or 'android.widget.AbsListView' or 'android.webkit.WebView' down */ public void scrollDown() throws CalabashException { calabashWrapper.scrollDown(); } /** * Scrolls the first instance of 'android.widget.ScrollView' or 'android.widget.AbsListView' or 'android.webkit.WebView' up */ public void scrollUp() throws CalabashException { calabashWrapper.scrollUp(); } /** * Selects a menu item from the menu or com.android.internal.view.menu.ActionMenuItemView with label * * @param menuItem The name of the menu item to be selected * @throws CalabashException */ public void selectMenuItem(String menuItem) throws CalabashException { calabashWrapper.selectMenuItem(menuItem); } /** * Performs a swipe action on the screen * * @param direction the direction to swipe * @throws CalabashException */ public void swipe(Direction direction) throws CalabashException { switch (direction) { case LEFT: calabashWrapper.drag(1, 99, 50, 50, 5); break; case RIGHT: calabashWrapper.drag(99, 1, 50, 50, 5); break; case UP: calabashWrapper.drag(50, 50, 70, 90, 10); break; case DOWN: calabashWrapper.drag(50, 50, 90, 70, 10); break; } } /** * Modify the gps co-ordinates of your emulator * <pre> * Note: * you have to turn on 'Allow mock location' on the emulator * * manifest should have android.permission.ACCESS_MOCK_LOCATION permission to change the location * </pre> * * @param latitude * @param longitude * @throws CalabashException */ public void setGPSCoordinates(double latitude, double longitude) throws CalabashException { calabashWrapper.setGPSCoordinates(latitude, longitude); } /** * Modify the gps co-ordinates of your emulator. * You can specify the location like 'Bangalore, India' and set the co-ordinates with the best match using <a href="http://www.rubygeocoder.com"/>GeoCoder</a> * <pre> * Note: * you have to turn on 'Allow mock location' on the emulator * * manifest should have android.permission.ACCESS_MOCK_LOCATION permission to change the location * </pre> * * @param location * @throws CalabashException */ public void setGPSLocation(String location) throws CalabashException { calabashWrapper.setGPSLocation(location); } /** * Gets all the root elements available This can be used to make a tree view * of all the elements available in the view currently * * @return list of root elements if available, null otherwise * @throws CalabashException */ public List<TreeNode> getRootElements() throws CalabashException { final CalabashHttpClient calabashHttpClient = new CalabashHttpClient(calabashWrapper); final TreeNodeBuilder treeNodeBuilder = new TreeNodeBuilder(calabashWrapper); final TreeBuilder treeBuilder = new TreeBuilder(calabashWrapper, calabashHttpClient, treeNodeBuilder); return treeBuilder.createTree(); } /** * click and drag from (fromX, fromY) to (toX, toY) where X and Y axis start at top left corner * * @param fromX source x-coordinate normalized to screen width * @param toX destination x-coordinate normalized to screen width * @param fromY source y-coordinate normalized to screen height * @param toY destination y-coordinate normalized to screen height * @param steps no.of steps that it takes between the two points * @throws CalabashException */ public void drag(int fromX, int toX, int fromY, int toY, int steps) throws CalabashException { calabashWrapper.drag(fromX, toX, fromY, toY, steps); } /** * call calabash's perform_action function with action and its corresponding args * eg: * performCalabashAction("click_on_screen","50","100"); * * @param action action to be performed * @param args list of arguments for the action * @throws CalabashException */ public ActionResult performCalabashAction(String action, String... args) throws CalabashException { final RubyHash rubyResult = calabashWrapper.performAction(action, args); final RubyArray bonusInformationArray = (RubyArray) rubyResult.get("bonusInformation"); final String message = rubyResult.get("message").toString(); final boolean success = Boolean.parseBoolean(rubyResult.get("success").toString()); final Object[] bonusInformation = Utils.toJavaArray(bonusInformationArray); return new ActionResult(bonusInformation, message, success); } /** * execute a calabash api directly like how it is done in irb for calabash ruby * eg: * <p/> * String command = "clear_text(\"editText\")" * application.execute(command) * * @param calabashCommand calabash api command * @throws CalabashException */ public Object execute(String calabashCommand) throws CalabashException { return calabashWrapper.executeCommand(calabashCommand); } /** * hides the keyboard if shown in the screen * * @throws CalabashException */ public void hideKeyboard() throws CalabashException { calabashWrapper.hideKeyboard(); } }