Skip to content

Commit 639cde9

Browse files
committed
Merge pull request #7 from Jonahss/pullFile
pullFile, hideKeyboard, pushFile, background
2 parents cd842f7 + f665896 commit 639cde9

File tree

6 files changed

+119
-32
lines changed

6 files changed

+119
-32
lines changed

java-client.iml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<orderEntry type="library" name="flexjson-1.8" level="project" />
2020
<orderEntry type="library" name="commons-lang-2.4" level="project" />
2121
<orderEntry type="library" name="org.json-20131017" level="project" />
22+
<orderEntry type="library" name="commons-codec-1.9" level="project" />
2223
</component>
2324
</module>
2425

src/io/appium/java_client/AppiumDriver.java

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.openqa.selenium.*;
2222
import org.openqa.selenium.remote.*;
2323

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

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

7378

79+
/**
80+
* Reset the currently running app for this session
81+
*/
7482
public void resetApp() {
7583
execute(MobileCommand.RESET);
7684
}
7785

86+
/**
87+
* Get all defined Strings from an Android app
88+
*
89+
* @return a string of all the localized strings defined in the app
90+
*/
7891
public String getAppStrings() {
7992
Response response = execute(GET_STRINGS);
8093
return response.getValue().toString();
8194
}
8295

96+
/**
97+
* Send a key event to the device
98+
*
99+
* @param key code for the key pressed on the device
100+
*/
83101
public void sendKeyEvent(int key) {
84102
sendKeyEvent(key, null);
85103
}
86104

105+
/**
106+
* Send a key event along with an Android metastate to an Android device
107+
* Metastates are things like *shift* to get uppercase characters
108+
*
109+
* @param key code for the key pressed on the Android device
110+
* @param metastate metastate for the keypress
111+
*/
87112
public void sendKeyEvent(int key, Integer metastate) {
88113
ImmutableMap.Builder builder = ImmutableMap.builder();
89114
builder.put("keycode", key);
@@ -92,11 +117,65 @@ public void sendKeyEvent(int key, Integer metastate) {
92117
execute(KEY_EVENT, parameters);
93118
}
94119

120+
/**
121+
* Get the current activity being run on the mobile device
122+
*/
95123
public String currentActivity() {
96124
Response response = execute(CURRENT_ACTIVITY);
97125
return response.getValue().toString();
98126
}
99127

128+
/**
129+
*
130+
* @param remotePath On Android and iOS, this is either the path to the file (relative to the root of the app's file system).
131+
* On iOS only, if path starts with /AppName.app, which will be replaced with the application's .app directory
132+
* @return A byte array of Base64 encoded data.
133+
*/
134+
public byte[] pullFile(String remotePath) {
135+
Response response = execute(PULL_FILE, ImmutableMap.of("path", remotePath));
136+
String base64String = response.getValue().toString();
137+
138+
return DatatypeConverter.parseBase64Binary(base64String);
139+
}
140+
141+
/**
142+
* Save base64 encoded data as a file on the remote mobile device.
143+
* This is an Android only method.
144+
* @param remotePath Path to file to write data to on remote device
145+
* @param base64Data Base64 encoded byte array of data to write to remote device
146+
*/
147+
public void pushFile(String remotePath, byte[] base64Data) {
148+
ImmutableMap.Builder builder = ImmutableMap.builder();
149+
builder.put("path", remotePath).put("data", base64Data);
150+
execute(PUSH_FILE, builder.build());
151+
}
152+
153+
/**
154+
* Hides the keyboard if it is showing.
155+
* This is an iOS only command.
156+
*/
157+
public void hideKeyboard() {
158+
execute(HIDE_KEYBOARD);
159+
}
160+
161+
/**
162+
* Hides the keyboard by pressing the button specified by keyName if it is showing.
163+
* This is an iOS only command.
164+
* @param keyName The button pressed by the mobile driver to attempt hiding the keyboard
165+
*/
166+
public void hideKeyboard(String keyName) {
167+
execute(HIDE_KEYBOARD, ImmutableMap.of("keyName", keyName));
168+
}
169+
170+
/**
171+
* Runs the current app as a background app for the number of seconds requested.
172+
* This is a synchronous method, it returns after the back has been returned to the foreground.
173+
* @param seconds Number of seconds to run App in background
174+
*/
175+
public void runAppInBackground(int seconds) {
176+
execute(RUN_APP_IN_BACKGROUND, ImmutableMap.of("seconds", seconds));
177+
}
178+
100179

101180
@Override
102181
public WebDriver context(String name) {

src/io/appium/java_client/MobileCommand.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ public interface MobileCommand {
2929
String KEY_EVENT = "keyEvent";
3030
String CURRENT_ACTIVITY = "currentActivity";
3131
String SET_VALUE = "setValue";
32+
String PULL_FILE = "pullFile";
33+
String PUSH_FILE = "pushFile";
34+
String HIDE_KEYBOARD = "hideKeyboard";
35+
String RUN_APP_IN_BACKGROUND = "runAppInBackground";
3236

3337

3438
}

src/io/appium/java_client/MobileDriver.java

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,45 +18,15 @@
1818
package io.appium.java_client;
1919

2020

21+
import org.openqa.selenium.ContextAware;
2122
import org.openqa.selenium.WebDriver;
2223
import org.openqa.selenium.remote.Response;
2324

2425
import java.util.Map;
2526

26-
public interface MobileDriver extends WebDriver {
27+
public interface MobileDriver extends WebDriver, ContextAware {
2728

2829

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

31-
/**
32-
* Reset the currently running app for this session
33-
*/
34-
void resetApp();
35-
36-
/**
37-
* Get all defined Strings from an Android app
38-
*/
39-
String getAppStrings();
40-
41-
/**
42-
* Send a key event to the device
43-
*
44-
* @param key code for the key pressed on the device
45-
*/
46-
void sendKeyEvent(int key);
47-
48-
/**
49-
* Send a key event along with an Android metastate to an Android device
50-
* Metastates are things like *shift* to get uppercase characters
51-
*
52-
* @param key code for the key pressed on the Android device
53-
* @param metastate metastate for the keypress
54-
*/
55-
void sendKeyEvent(int key, Integer metastate);
56-
57-
/**
58-
* Get the current activity being run on the mobile device
59-
*/
60-
String currentActivity();
61-
6232
}

test/io/appium/java_client/AndroidUIAutomatorTest.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.appium.java_client;
22

3+
import org.apache.commons.codec.binary.Base64;
34
import org.junit.After;
45
import org.junit.Before;
56
import org.junit.Test;
@@ -65,4 +66,13 @@ public void findElementsByTest() {
6566
public void ErrorTest() {
6667
driver.findElementByAndroidUIAutomator(null);
6768
}
69+
70+
@Test
71+
public void pushFileTest() {
72+
byte[] data = Base64.encodeBase64("The eventual code is no more than the deposit of your understanding. ~E. W. Dijkstra".getBytes());
73+
driver.pushFile("/data/local/tmp/remote.txt", data);
74+
byte[] returnData = driver.pullFile("/data/local/tmp/remote.txt");
75+
String returnDataDecoded = new String(Base64.decodeBase64(returnData));
76+
assertEquals("The eventual code is no more than the deposit of your understanding. ~E. W. Dijkstra", returnDataDecoded);
77+
}
6878
}

test/io/appium/java_client/MobileDriverIOSTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,27 @@ public void setValueTest() {
6565
element.setValue("Grace Hopper");
6666
}
6767

68+
@Test
69+
public void pullFileTest() {
70+
byte[] data = driver.pullFile("Library/AddressBook/AddressBook.sqlitedb");
71+
assert(data.length > 0);
72+
}
73+
74+
@Test
75+
public void hideKeyboardTest() {
76+
MobileElement element = new MobileElement((RemoteWebElement)driver.findElementByAccessibilityId("TextFields, Uses of UITextField"), driver);
77+
element.click();
78+
element = new MobileElement((RemoteWebElement)driver.findElementByAccessibilityId("Normal"), driver);
79+
element.click();
80+
driver.hideKeyboard();
81+
}
82+
83+
@Test
84+
public void runAppInBackgroundTest() {
85+
long time = System.currentTimeMillis();
86+
driver.runAppInBackground(4);
87+
long timeAfter = System.currentTimeMillis();
88+
assert(timeAfter - time > 3000);
89+
}
90+
6891
}

0 commit comments

Comments
 (0)