Skip to content

pullFile, hideKeyboard, pushFile, background #7

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 5 commits into from
Apr 18, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions java-client.iml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<orderEntry type="library" name="flexjson-1.8" level="project" />
<orderEntry type="library" name="commons-lang-2.4" level="project" />
<orderEntry type="library" name="org.json-20131017" level="project" />
<orderEntry type="library" name="commons-codec-1.9" level="project" />
</component>
</module>

79 changes: 79 additions & 0 deletions src/io/appium/java_client/AppiumDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.openqa.selenium.*;
import org.openqa.selenium.remote.*;

import javax.xml.bind.DatatypeConverter;
import java.net.URL;
import java.util.LinkedHashSet;
import java.util.List;
Expand All @@ -45,6 +46,10 @@ public AppiumDriver(URL remoteAddress, Capabilities desiredCapabilities){
.put(KEY_EVENT, postC("/session/:sessionId/appium/device/keyevent"))
.put(CURRENT_ACTIVITY, getC("/session/:sessionId/appium/device/current_activity"))
.put(SET_VALUE, postC("/session/:sessionId/appium/element/:id/value"))
.put(PULL_FILE, postC("/session/:sessionId/appium/device/pull_file"))
.put(HIDE_KEYBOARD, postC("/session/:sessionId/appium/device/hide_keyboard"))
.put(PUSH_FILE, postC("/session/:sessionId/appium/device/push_file"))
.put(RUN_APP_IN_BACKGROUND, postC("/session/:sessionId/appium/app/background"))
;
ImmutableMap<String, CommandInfo> mobileCommands = builder.build();

Expand All @@ -71,19 +76,39 @@ protected Response execute(String command) {
}


/**
* Reset the currently running app for this session
*/
public void resetApp() {
execute(MobileCommand.RESET);
}

/**
* Get all defined Strings from an Android app
*
* @return a string of all the localized strings defined in the app
*/
public String getAppStrings() {
Response response = execute(GET_STRINGS);
return response.getValue().toString();
}

/**
* Send a key event to the device
*
* @param key code for the key pressed on the device
*/
public void sendKeyEvent(int key) {
sendKeyEvent(key, null);
}

/**
* Send a key event along with an Android metastate to an Android device
* Metastates are things like *shift* to get uppercase characters
*
* @param key code for the key pressed on the Android device
* @param metastate metastate for the keypress
*/
public void sendKeyEvent(int key, Integer metastate) {
ImmutableMap.Builder builder = ImmutableMap.builder();
builder.put("keycode", key);
Expand All @@ -92,11 +117,65 @@ public void sendKeyEvent(int key, Integer metastate) {
execute(KEY_EVENT, parameters);
}

/**
* Get the current activity being run on the mobile device
*/
public String currentActivity() {
Response response = execute(CURRENT_ACTIVITY);
return response.getValue().toString();
}

/**
*
* @param remotePath On Android and iOS, this is either the path to the file (relative to the root of the app's file system).
* On iOS only, if path starts with /AppName.app, which will be replaced with the application's .app directory
* @return A byte array of Base64 encoded data.
*/
public byte[] pullFile(String remotePath) {
Response response = execute(PULL_FILE, ImmutableMap.of("path", remotePath));
String base64String = response.getValue().toString();

return DatatypeConverter.parseBase64Binary(base64String);
}

/**
* Save base64 encoded data as a file on the remote mobile device.
* This is an Android only method.
* @param remotePath Path to file to write data to on remote device
* @param base64Data Base64 encoded byte array of data to write to remote device
*/
public void pushFile(String remotePath, byte[] base64Data) {
ImmutableMap.Builder builder = ImmutableMap.builder();
builder.put("path", remotePath).put("data", base64Data);
execute(PUSH_FILE, builder.build());
}

/**
* Hides the keyboard if it is showing.
* This is an iOS only command.
*/
public void hideKeyboard() {
execute(HIDE_KEYBOARD);
}

/**
* Hides the keyboard by pressing the button specified by keyName if it is showing.
* This is an iOS only command.
* @param keyName The button pressed by the mobile driver to attempt hiding the keyboard
*/
public void hideKeyboard(String keyName) {
execute(HIDE_KEYBOARD, ImmutableMap.of("keyName", keyName));
}

/**
* Runs the current app as a background app for the number of seconds requested.
* This is a synchronous method, it returns after the back has been returned to the foreground.
* @param seconds Number of seconds to run App in background
*/
public void runAppInBackground(int seconds) {
execute(RUN_APP_IN_BACKGROUND, ImmutableMap.of("seconds", seconds));
}


@Override
public WebDriver context(String name) {
Expand Down
4 changes: 4 additions & 0 deletions src/io/appium/java_client/MobileCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ public interface MobileCommand {
String KEY_EVENT = "keyEvent";
String CURRENT_ACTIVITY = "currentActivity";
String SET_VALUE = "setValue";
String PULL_FILE = "pullFile";
String PUSH_FILE = "pushFile";
String HIDE_KEYBOARD = "hideKeyboard";
String RUN_APP_IN_BACKGROUND = "runAppInBackground";


}
34 changes: 2 additions & 32 deletions src/io/appium/java_client/MobileDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,45 +18,15 @@
package io.appium.java_client;


import org.openqa.selenium.ContextAware;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.remote.Response;

import java.util.Map;

public interface MobileDriver extends WebDriver {
public interface MobileDriver extends WebDriver, ContextAware {


public Response execute(String driverCommand, Map<String, ?> parameters);

/**
* Reset the currently running app for this session
*/
void resetApp();

/**
* Get all defined Strings from an Android app
*/
String getAppStrings();

/**
* Send a key event to the device
*
* @param key code for the key pressed on the device
*/
void sendKeyEvent(int key);

/**
* Send a key event along with an Android metastate to an Android device
* Metastates are things like *shift* to get uppercase characters
*
* @param key code for the key pressed on the Android device
* @param metastate metastate for the keypress
*/
void sendKeyEvent(int key, Integer metastate);

/**
* Get the current activity being run on the mobile device
*/
String currentActivity();

}
10 changes: 10 additions & 0 deletions test/io/appium/java_client/AndroidUIAutomatorTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.appium.java_client;

import org.apache.commons.codec.binary.Base64;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
Expand Down Expand Up @@ -65,4 +66,13 @@ public void findElementsByTest() {
public void ErrorTest() {
driver.findElementByAndroidUIAutomator(null);
}

@Test
public void pushFileTest() {
byte[] data = Base64.encodeBase64("The eventual code is no more than the deposit of your understanding. ~E. W. Dijkstra".getBytes());
driver.pushFile("/data/local/tmp/remote.txt", data);
byte[] returnData = driver.pullFile("/data/local/tmp/remote.txt");
String returnDataDecoded = new String(Base64.decodeBase64(returnData));
assertEquals("The eventual code is no more than the deposit of your understanding. ~E. W. Dijkstra", returnDataDecoded);
}
}
23 changes: 23 additions & 0 deletions test/io/appium/java_client/MobileDriverIOSTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,27 @@ public void setValueTest() {
element.setValue("Grace Hopper");
}

@Test
public void pullFileTest() {
byte[] data = driver.pullFile("Library/AddressBook/AddressBook.sqlitedb");
assert(data.length > 0);
}

@Test
public void hideKeyboardTest() {
MobileElement element = new MobileElement((RemoteWebElement)driver.findElementByAccessibilityId("TextFields, Uses of UITextField"), driver);
element.click();
element = new MobileElement((RemoteWebElement)driver.findElementByAccessibilityId("Normal"), driver);
element.click();
driver.hideKeyboard();
}

@Test
public void runAppInBackgroundTest() {
long time = System.currentTimeMillis();
driver.runAppInBackground(4);
long timeAfter = System.currentTimeMillis();
assert(timeAfter - time > 3000);
}

}