mirror of
https://github.com/appium/appium.git
synced 2026-05-01 07:51:30 -05:00
Merge pull request #2673 from paymand/long_press_keycode
Renamed keyevent to press_keycode and added long_press_keycode.
This commit is contained in:
@@ -24,10 +24,19 @@ var NATIVE_WIN = "NATIVE_APP";
|
||||
var WEBVIEW_WIN = "WEBVIEW";
|
||||
var WEBVIEW_BASE = WEBVIEW_WIN + "_";
|
||||
|
||||
androidController.keyevent = function (keycode, metastate, cb) {
|
||||
androidController.pressKeyCode = function (keycode, metastate, cb) {
|
||||
this.proxy(["pressKeyCode", {keycode: keycode, metastate: metastate}], cb);
|
||||
};
|
||||
|
||||
androidController.longPressKeyCode = function (keycode, metastate, cb) {
|
||||
this.proxy(["longPressKeyCode", {keycode: keycode, metastate: metastate}], cb);
|
||||
};
|
||||
|
||||
androidController.keyevent = function (keycode, metastate, cb) {
|
||||
warnDeprecated('function', 'keyevent', 'pressKeyCode');
|
||||
this.pressKeyCode(keycode, metastate, cb);
|
||||
};
|
||||
|
||||
androidController.defaultContext = function () {
|
||||
return NATIVE_WIN;
|
||||
};
|
||||
|
||||
+23
-32
@@ -1,23 +1,15 @@
|
||||
package io.appium.android.bootstrap.handler;
|
||||
package com.android.uiautomator.common;
|
||||
|
||||
import io.appium.android.bootstrap.CommandHandler;
|
||||
import io.appium.android.bootstrap.Logger;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
import android.view.MotionEvent.PointerCoords;
|
||||
|
||||
import com.android.uiautomator.core.UiDevice;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* This handler is and abstract class that contains all the common code for
|
||||
* touch event handlers.
|
||||
*
|
||||
*/
|
||||
public abstract class TouchableEvent extends CommandHandler {
|
||||
import android.os.Build;
|
||||
|
||||
import com.android.uiautomator.core.UiDevice;
|
||||
|
||||
public class ReflectionUtils {
|
||||
private static Field enableField(final Class<?> clazz, final String field)
|
||||
throws SecurityException, NoSuchFieldException {
|
||||
Logger.debug("Updating class \"" + clazz + "\" to enable field \"" + field
|
||||
@@ -27,40 +19,39 @@ public abstract class TouchableEvent extends CommandHandler {
|
||||
return fieldObject;
|
||||
}
|
||||
|
||||
/*
|
||||
* getAutomatorBridge is private so we access the bridge via reflection to use
|
||||
* the touchDown / touchUp / touchMove methods.
|
||||
*/
|
||||
protected Object getController() throws IllegalArgumentException,
|
||||
private Object controller = null;
|
||||
|
||||
public ReflectionUtils() throws IllegalArgumentException,
|
||||
IllegalAccessException, SecurityException, NoSuchFieldException {
|
||||
final UiDevice device = UiDevice.getInstance();
|
||||
final Object bridge = enableField(device.getClass(), "mUiAutomationBridge")
|
||||
.get(device);
|
||||
Object controller = null;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||
controller = enableField(bridge.getClass().getSuperclass(),
|
||||
"mInteractionController").get(bridge);
|
||||
} else {
|
||||
controller = enableField(bridge.getClass(),
|
||||
"mInteractionController").get(bridge);
|
||||
controller = enableField(bridge.getClass(), "mInteractionController")
|
||||
.get(bridge);
|
||||
}
|
||||
return controller;
|
||||
|
||||
}
|
||||
|
||||
protected Method getMethod(final String name, final Object controller)
|
||||
/*
|
||||
* getAutomatorBridge is private so we access the bridge via reflection to use
|
||||
* the touchDown / touchUp / touchMove methods.
|
||||
*/
|
||||
public Object getController() throws IllegalArgumentException,
|
||||
IllegalAccessException, SecurityException, NoSuchFieldException {
|
||||
return controller;
|
||||
}
|
||||
|
||||
public Method getMethod(final String name, final Class<?>... parameterTypes)
|
||||
throws NoSuchMethodException, SecurityException {
|
||||
final Class<?> controllerClass = controller.getClass();
|
||||
|
||||
Logger.debug("Finding methods on class: " + controllerClass);
|
||||
final Method method;
|
||||
if (name.equals("performMultiPointerGesture")) {
|
||||
// multi pointer gestures take a 2d array of coordinates
|
||||
method = controllerClass.getDeclaredMethod(name, PointerCoords[][].class);
|
||||
} else {
|
||||
// all the other touch events send two ints
|
||||
method = controllerClass.getDeclaredMethod(name, int.class, int.class);
|
||||
}
|
||||
method = controllerClass.getDeclaredMethod(name, parameterTypes);
|
||||
|
||||
method.setAccessible(true);
|
||||
return method;
|
||||
}
|
||||
+2
@@ -14,6 +14,7 @@ import io.appium.android.bootstrap.handler.GetLocation;
|
||||
import io.appium.android.bootstrap.handler.GetName;
|
||||
import io.appium.android.bootstrap.handler.GetSize;
|
||||
import io.appium.android.bootstrap.handler.GetText;
|
||||
import io.appium.android.bootstrap.handler.LongPressKeyCode;
|
||||
import io.appium.android.bootstrap.handler.MultiPointerGesture;
|
||||
import io.appium.android.bootstrap.handler.Orientation;
|
||||
import io.appium.android.bootstrap.handler.Pinch;
|
||||
@@ -70,6 +71,7 @@ class AndroidCommandExecutor {
|
||||
map.put("pressBack", new PressBack());
|
||||
map.put("dumpWindowHierarchy", new DumpWindowHierarchy());
|
||||
map.put("pressKeyCode", new PressKeyCode());
|
||||
map.put("longPressKeyCode", new LongPressKeyCode());
|
||||
map.put("takeScreenshot", new TakeScreenshot());
|
||||
map.put("updateStrings", new UpdateStrings());
|
||||
map.put("getDataDir", new GetDataDir());
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
package io.appium.android.bootstrap.handler;
|
||||
|
||||
import io.appium.android.bootstrap.AndroidCommand;
|
||||
import io.appium.android.bootstrap.AndroidCommandResult;
|
||||
import io.appium.android.bootstrap.CommandHandler;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import android.view.InputDevice;
|
||||
import android.view.InputEvent;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import com.android.uiautomator.common.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* This handler is used to LongPressKeyCode.
|
||||
*
|
||||
*/
|
||||
public class LongPressKeyCode extends CommandHandler {
|
||||
public Integer keyCode;
|
||||
|
||||
public Integer metaState;
|
||||
|
||||
/*
|
||||
* @param command The {@link AndroidCommand} used for this handler.
|
||||
*
|
||||
* @return {@link AndroidCommandResult}
|
||||
*
|
||||
* @throws JSONException
|
||||
*
|
||||
* @see io.appium.android.bootstrap.CommandHandler#execute(io.appium.android.
|
||||
* bootstrap.AndroidCommand)
|
||||
*/
|
||||
@Override
|
||||
public AndroidCommandResult execute(final AndroidCommand command)
|
||||
throws JSONException {
|
||||
try {
|
||||
final ReflectionUtils utils = new ReflectionUtils();
|
||||
final Method injectEventSync = utils.getMethod("injectEventSync",
|
||||
InputEvent.class);
|
||||
final Hashtable<String, Object> params = command.params();
|
||||
keyCode = (Integer) params.get("keycode");
|
||||
metaState = params.get("metastate") != JSONObject.NULL ? (Integer) params
|
||||
.get("metastate") : 0;
|
||||
final long eventTime = SystemClock.uptimeMillis();
|
||||
// Send an initial down event
|
||||
final KeyEvent downEvent = new KeyEvent(eventTime, eventTime,
|
||||
KeyEvent.ACTION_DOWN, keyCode, 0, metaState,
|
||||
KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD);
|
||||
if ((Boolean) injectEventSync.invoke(utils.getController(), downEvent)) {
|
||||
// Send a repeat event. This will cause the FLAG_LONG_PRESS to be set.
|
||||
final KeyEvent repeatEvent = KeyEvent.changeTimeRepeat(downEvent,
|
||||
eventTime, 1);
|
||||
injectEventSync.invoke(utils.getController(), repeatEvent);
|
||||
// Finally, send the up event
|
||||
final KeyEvent upEvent = new KeyEvent(eventTime, eventTime,
|
||||
KeyEvent.ACTION_UP, keyCode, 0, metaState,
|
||||
KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD);
|
||||
injectEventSync.invoke(utils.getController(), upEvent);
|
||||
}
|
||||
return getSuccessResult(true);
|
||||
} catch (final Exception e) {
|
||||
return getErrorResult(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
+67
-67
@@ -1,18 +1,5 @@
|
||||
package io.appium.android.bootstrap.handler;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
import android.view.MotionEvent.PointerCoords;
|
||||
|
||||
import com.android.uiautomator.core.UiObject;
|
||||
import com.android.uiautomator.core.UiObjectNotFoundException;
|
||||
import com.android.uiautomator.core.UiScrollable;
|
||||
import com.android.uiautomator.core.UiSelector;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import io.appium.android.bootstrap.AndroidCommand;
|
||||
import io.appium.android.bootstrap.AndroidCommandResult;
|
||||
import io.appium.android.bootstrap.AndroidElement;
|
||||
@@ -23,14 +10,53 @@ import io.appium.android.bootstrap.exceptions.ElementNotInHashException;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class MultiPointerGesture extends TouchableEvent {
|
||||
import android.os.Build;
|
||||
import android.view.MotionEvent.PointerCoords;
|
||||
|
||||
import com.android.uiautomator.common.ReflectionUtils;
|
||||
|
||||
public class MultiPointerGesture extends CommandHandler {
|
||||
|
||||
private double computeLongestTime(final JSONArray actions)
|
||||
throws JSONException {
|
||||
double max = 0.0;
|
||||
for (int i = 0; i < actions.length(); i++) {
|
||||
final JSONArray gestures = actions.getJSONArray(i);
|
||||
final double endTime = gestures.getJSONObject(gestures.length() - 1)
|
||||
.getDouble("time");
|
||||
if (endTime > max) {
|
||||
max = endTime;
|
||||
}
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
private PointerCoords createPointerCoords(final JSONObject obj)
|
||||
throws JSONException {
|
||||
final JSONObject o = obj.getJSONObject("touch");
|
||||
|
||||
final int x = o.getInt("x");
|
||||
final int y = o.getInt("y");
|
||||
|
||||
final PointerCoords p = new PointerCoords();
|
||||
p.size = 1;
|
||||
p.pressure = 1;
|
||||
p.x = x;
|
||||
p.y = y;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AndroidCommandResult execute(final AndroidCommand command)
|
||||
throws JSONException {
|
||||
try {
|
||||
PointerCoords[][] pcs = parsePointerCoords(command);
|
||||
final PointerCoords[][] pcs = parsePointerCoords(command);
|
||||
|
||||
if (command.isElementCommand()) {
|
||||
final AndroidElement el = command.getElement();
|
||||
@@ -40,10 +66,12 @@ public class MultiPointerGesture extends TouchableEvent {
|
||||
return getErrorResult("Unable to perform multi pointer gesture");
|
||||
}
|
||||
} else {
|
||||
Object controller = getController();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||
final Method pmpg = getMethod("performMultiPointerGesture", controller);
|
||||
Boolean rt = (Boolean)pmpg.invoke(controller, (Object)pcs);
|
||||
final ReflectionUtils utils = new ReflectionUtils();
|
||||
final Method pmpg = utils.getMethod("performMultiPointerGesture",
|
||||
PointerCoords[][].class);
|
||||
final Boolean rt = (Boolean) pmpg.invoke(utils.getController(),
|
||||
(Object) pcs);
|
||||
if (rt.booleanValue()) {
|
||||
return getSuccessResult("OK");
|
||||
} else {
|
||||
@@ -64,45 +92,28 @@ public class MultiPointerGesture extends TouchableEvent {
|
||||
}
|
||||
}
|
||||
|
||||
private PointerCoords[][] parsePointerCoords(AndroidCommand command)
|
||||
throws JSONException {
|
||||
JSONArray actions = (org.json.JSONArray)command.params().get("actions");
|
||||
|
||||
double time = computeLongestTime(actions);
|
||||
|
||||
PointerCoords[][] pcs = new PointerCoords[actions.length()][];
|
||||
for (int i = 0; i < actions.length(); i++) {
|
||||
JSONArray gestures = actions.getJSONArray(i);
|
||||
|
||||
pcs[i] = gesturesToPointerCoords(time, gestures);
|
||||
}
|
||||
|
||||
return pcs;
|
||||
}
|
||||
|
||||
private PointerCoords[] gesturesToPointerCoords(double maxTime, JSONArray gestures)
|
||||
throws JSONException {
|
||||
private PointerCoords[] gesturesToPointerCoords(final double maxTime,
|
||||
final JSONArray gestures) throws JSONException {
|
||||
// gestures, e.g.:
|
||||
// [
|
||||
// {"touch":{"y":529.5,"x":120},"time":0.2},
|
||||
// {"touch":{"y":529.5,"x":130},"time":0.4},
|
||||
// {"touch":{"y":454.5,"x":140},"time":0.6},
|
||||
// {"touch":{"y":304.5,"x":150},"time":0.8}
|
||||
// ]
|
||||
|
||||
// [
|
||||
// {"touch":{"y":529.5,"x":120},"time":0.2},
|
||||
// {"touch":{"y":529.5,"x":130},"time":0.4},
|
||||
// {"touch":{"y":454.5,"x":140},"time":0.6},
|
||||
// {"touch":{"y":304.5,"x":150},"time":0.8}
|
||||
// ]
|
||||
|
||||
// From the docs:
|
||||
// "Steps are injected about 5 milliseconds apart, so 100 steps may take
|
||||
// around 0.5 seconds to complete."
|
||||
int steps = (int)(maxTime * 200) + 2;
|
||||
final int steps = (int) (maxTime * 200) + 2;
|
||||
|
||||
PointerCoords[] pc = new PointerCoords[steps];
|
||||
final PointerCoords[] pc = new PointerCoords[steps];
|
||||
|
||||
int i = 1;
|
||||
JSONObject current = gestures.getJSONObject(0);
|
||||
double currentTime = current.getDouble("time");
|
||||
double runningTime = 0.0;
|
||||
int gesturesLength = gestures.length();
|
||||
final int gesturesLength = gestures.length();
|
||||
for (int j = 0; j < steps; j++) {
|
||||
if (runningTime > currentTime && i < gesturesLength) {
|
||||
current = gestures.getJSONObject(i++);
|
||||
@@ -117,31 +128,20 @@ public class MultiPointerGesture extends TouchableEvent {
|
||||
return pc;
|
||||
}
|
||||
|
||||
private PointerCoords createPointerCoords(JSONObject obj) throws JSONException {
|
||||
JSONObject o = obj.getJSONObject("touch");
|
||||
private PointerCoords[][] parsePointerCoords(final AndroidCommand command)
|
||||
throws JSONException {
|
||||
final JSONArray actions = (org.json.JSONArray) command.params().get(
|
||||
"actions");
|
||||
|
||||
int x = o.getInt("x");
|
||||
int y = o.getInt("y");
|
||||
final double time = computeLongestTime(actions);
|
||||
|
||||
PointerCoords p = new PointerCoords();
|
||||
p.size = 1;
|
||||
p.pressure = 1;
|
||||
p.x = x;
|
||||
p.y = y;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
private double computeLongestTime(JSONArray actions) throws JSONException {
|
||||
double max = 0.0;
|
||||
final PointerCoords[][] pcs = new PointerCoords[actions.length()][];
|
||||
for (int i = 0; i < actions.length(); i++) {
|
||||
JSONArray gestures = actions.getJSONArray(i);
|
||||
double endTime = gestures.getJSONObject(gestures.length()-1).getDouble("time");
|
||||
if (endTime > max) {
|
||||
max = endTime;
|
||||
}
|
||||
final JSONArray gestures = actions.getJSONArray(i);
|
||||
|
||||
pcs[i] = gesturesToPointerCoords(time, gestures);
|
||||
}
|
||||
|
||||
return max;
|
||||
return pcs;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -4,6 +4,7 @@ import io.appium.android.bootstrap.Logger;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.android.uiautomator.common.ReflectionUtils;
|
||||
import com.android.uiautomator.core.UiObjectNotFoundException;
|
||||
|
||||
/**
|
||||
@@ -17,9 +18,10 @@ public class TouchDown extends TouchEvent {
|
||||
protected boolean executeTouchEvent() throws UiObjectNotFoundException {
|
||||
printEventDebugLine("TouchDown");
|
||||
try {
|
||||
final Object controller = getController();
|
||||
final Method touchDown = getMethod("touchDown", controller);
|
||||
return (Boolean) touchDown.invoke(controller, clickX, clickY);
|
||||
final ReflectionUtils utils = new ReflectionUtils();
|
||||
final Method touchDown = utils.getMethod("touchDown", int.class,
|
||||
int.class);
|
||||
return (Boolean) touchDown.invoke(utils.getController(), clickX, clickY);
|
||||
} catch (final Exception e) {
|
||||
Logger.debug("Problem invoking touchDown: " + e);
|
||||
return false;
|
||||
|
||||
+3
-6
@@ -8,8 +8,6 @@ import io.appium.android.bootstrap.Logger;
|
||||
import io.appium.android.bootstrap.WDStatus;
|
||||
import io.appium.android.bootstrap.exceptions.ElementNotInHashException;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Hashtable;
|
||||
|
||||
@@ -17,15 +15,14 @@ import org.json.JSONException;
|
||||
|
||||
import android.graphics.Rect;
|
||||
|
||||
import com.android.uiautomator.core.UiDevice;
|
||||
import com.android.uiautomator.core.UiObjectNotFoundException;
|
||||
|
||||
/**
|
||||
* This handler is and abstract class that contains all the common code for
|
||||
* touch event handlers.
|
||||
*
|
||||
*
|
||||
*/
|
||||
public abstract class TouchEvent extends TouchableEvent {
|
||||
public abstract class TouchEvent extends CommandHandler {
|
||||
protected AndroidElement el;
|
||||
|
||||
protected int clickX;
|
||||
@@ -37,7 +34,7 @@ public abstract class TouchEvent extends TouchableEvent {
|
||||
protected boolean isElement;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param command
|
||||
* The {@link AndroidCommand}
|
||||
* @return {@link AndroidCommandResult}
|
||||
|
||||
+7
-5
@@ -6,6 +6,7 @@ import java.lang.reflect.Method;
|
||||
|
||||
import android.os.SystemClock;
|
||||
|
||||
import com.android.uiautomator.common.ReflectionUtils;
|
||||
import com.android.uiautomator.core.UiObjectNotFoundException;
|
||||
|
||||
/**
|
||||
@@ -24,13 +25,14 @@ public class TouchLongClick extends TouchEvent {
|
||||
* the super class.
|
||||
*/
|
||||
|
||||
final Object controller = getController();
|
||||
final Method touchDown = getMethod("touchDown", controller);
|
||||
final Method touchUp = getMethod("touchUp", controller);
|
||||
final ReflectionUtils utils = new ReflectionUtils();
|
||||
final Method touchDown = utils.getMethod("touchDown", int.class,
|
||||
int.class);
|
||||
final Method touchUp = utils.getMethod("touchUp", int.class, int.class);
|
||||
|
||||
if ((Boolean) touchDown.invoke(controller, x, y)) {
|
||||
if ((Boolean) touchDown.invoke(utils.getController(), x, y)) {
|
||||
SystemClock.sleep(duration);
|
||||
if ((Boolean) touchUp.invoke(controller, x, y)) {
|
||||
if ((Boolean) touchUp.invoke(utils.getController(), x, y)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-3
@@ -4,6 +4,7 @@ import io.appium.android.bootstrap.Logger;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.android.uiautomator.common.ReflectionUtils;
|
||||
import com.android.uiautomator.core.UiObjectNotFoundException;
|
||||
|
||||
/**
|
||||
@@ -17,9 +18,10 @@ public class TouchMove extends TouchEvent {
|
||||
protected boolean executeTouchEvent() throws UiObjectNotFoundException {
|
||||
printEventDebugLine("TouchMove");
|
||||
try {
|
||||
final Object controller = getController();
|
||||
final Method touchMove = getMethod("touchMove", controller);
|
||||
return (Boolean) touchMove.invoke(controller, clickX, clickY);
|
||||
final ReflectionUtils utils = new ReflectionUtils();
|
||||
final Method touchMove = utils.getMethod("touchMove", int.class,
|
||||
int.class);
|
||||
return (Boolean) touchMove.invoke(utils.getController(), clickX, clickY);
|
||||
} catch (final Exception e) {
|
||||
Logger.debug("Problem invoking touchMove: " + e);
|
||||
return false;
|
||||
|
||||
@@ -4,6 +4,7 @@ import io.appium.android.bootstrap.Logger;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.android.uiautomator.common.ReflectionUtils;
|
||||
import com.android.uiautomator.core.UiObjectNotFoundException;
|
||||
|
||||
/**
|
||||
@@ -17,9 +18,9 @@ public class TouchUp extends TouchEvent {
|
||||
protected boolean executeTouchEvent() throws UiObjectNotFoundException {
|
||||
printEventDebugLine("TouchUp");
|
||||
try {
|
||||
final Object controller = getController();
|
||||
final Method touchUp = getMethod("touchUp", controller);
|
||||
return (Boolean) touchUp.invoke(controller, clickX, clickY);
|
||||
final ReflectionUtils utils = new ReflectionUtils();
|
||||
final Method touchUp = utils.getMethod("touchUp", int.class, int.class);
|
||||
return (Boolean) touchUp.invoke(utils.getController(), clickX, clickY);
|
||||
} catch (final Exception e) {
|
||||
Logger.debug("Problem invoking touchUp: " + e);
|
||||
return false;
|
||||
|
||||
@@ -260,6 +260,8 @@ Firefox.prototype.notImplementedCmds = function () {
|
||||
, 'getSize'
|
||||
, 'getWindowSize'
|
||||
, 'getPageIndex'
|
||||
, 'pressKeyCode'
|
||||
, 'longPressKeyCode'
|
||||
, 'keyevent'
|
||||
, 'back'
|
||||
, 'forward'
|
||||
|
||||
@@ -657,6 +657,14 @@ iOSController.submit = function (elementId, cb) {
|
||||
}
|
||||
};
|
||||
|
||||
iOSController.pressKeyCode = function (keycode, metastate, cb) {
|
||||
cb(new NotImplementedError(), null);
|
||||
};
|
||||
|
||||
iOSController.longPressKeyCode = function (keycode, metastate, cb) {
|
||||
cb(new NotImplementedError(), null);
|
||||
};
|
||||
|
||||
iOSController.keyevent = function (keycode, metastate, cb) {
|
||||
cb(new NotImplementedError(), null);
|
||||
};
|
||||
|
||||
@@ -614,6 +614,26 @@ exports.getPageIndex = function (req, res) {
|
||||
req.device.getPageIndex(elementId, getResponseHandler(req, res));
|
||||
};
|
||||
|
||||
exports.pressKeyCode = function (req, res) {
|
||||
req.body = _.defaults(req.body, {
|
||||
keycode: null
|
||||
, metastate: null
|
||||
});
|
||||
var keycode = req.body.keycode
|
||||
, metastate = req.body.metastate;
|
||||
req.device.pressKeyCode(keycode, metastate, getResponseHandler(req, res));
|
||||
};
|
||||
|
||||
exports.longPressKeyCode = function (req, res) {
|
||||
req.body = _.defaults(req.body, {
|
||||
keycode: null
|
||||
, metastate: null
|
||||
});
|
||||
var keycode = req.body.keycode
|
||||
, metastate = req.body.metastate;
|
||||
req.device.longPressKeyCode(keycode, metastate, getResponseHandler(req, res));
|
||||
};
|
||||
|
||||
exports.keyevent = function (req, res) {
|
||||
req.body = _.defaults(req.body, {
|
||||
keycode: null
|
||||
|
||||
@@ -94,6 +94,8 @@ module.exports = function (appium) {
|
||||
// appium-specific extensions to JSONWP
|
||||
rest.post('/wd/hub/session/:sessionId?/appium/device/shake', controller.mobileShake);
|
||||
rest.post('/wd/hub/session/:sessionId?/appium/device/lock', controller.lock);
|
||||
rest.post('/wd/hub/session/:sessionId?/appium/device/press_keycode', controller.pressKeyCode);
|
||||
rest.post('/wd/hub/session/:sessionId?/appium/device/long_press_keycode', controller.longPressKeyCode);
|
||||
rest.post('/wd/hub/session/:sessionId?/appium/device/keyevent', controller.keyevent);
|
||||
rest.post('/wd/hub/session/:sessionId?/appium/device/rotate', controller.mobileRotation);
|
||||
rest.get('/wd/hub/session/:sessionId?/appium/device/current_activity', controller.getCurrentActivity);
|
||||
|
||||
@@ -44,7 +44,7 @@ class ContactsAndroidTests(unittest.TestCase):
|
||||
# no way to handle alerts in Android
|
||||
self.driver.find_element_by_android_uiautomator('new UiSelector().clickable(true)').click()
|
||||
|
||||
self.driver.keyevent(3)
|
||||
self.driver.press_keycode(3)
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user