Adding functions to query the state of a WebElement.
Change-Id: I85dbbfbf6b6172d6a8cf6e437f414ecef0872e36
This commit is contained in:
@@ -7260,7 +7260,10 @@ public class WebView extends AbsoluteLayout
|
||||
cursorData(), 1000);
|
||||
}
|
||||
|
||||
/* package */ synchronized WebViewCore getWebViewCore() {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public synchronized WebViewCore getWebViewCore() {
|
||||
return mWebViewCore;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,10 @@ import java.util.Set;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
final class WebViewCore {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public final class WebViewCore {
|
||||
|
||||
private static final String LOGTAG = "webcore";
|
||||
|
||||
@@ -905,7 +908,10 @@ final class WebViewCore {
|
||||
"REMOVE_JS_INTERFACE", // = 149;
|
||||
};
|
||||
|
||||
class EventHub {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class EventHub {
|
||||
// Message Ids
|
||||
static final int REVEAL_SELECTION = 96;
|
||||
static final int REQUEST_LABEL = 97;
|
||||
@@ -936,7 +942,7 @@ final class WebViewCore {
|
||||
static final int DELETE_SELECTION = 122;
|
||||
static final int LISTBOX_CHOICES = 123;
|
||||
static final int SINGLE_LISTBOX_CHOICE = 124;
|
||||
static final int MESSAGE_RELAY = 125;
|
||||
public static final int MESSAGE_RELAY = 125;
|
||||
static final int SET_BACKGROUND_COLOR = 126;
|
||||
static final int SET_MOVE_FOCUS = 127;
|
||||
static final int SAVE_DOCUMENT_STATE = 128;
|
||||
@@ -1702,7 +1708,10 @@ final class WebViewCore {
|
||||
// If it needs WebCore, it has to send message.
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
void sendMessage(Message msg) {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void sendMessage(Message msg) {
|
||||
mEventHub.sendMessage(msg);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,15 +16,22 @@
|
||||
|
||||
package android.webkit.webdriver;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyCharacterMap;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import com.android.internal.R;
|
||||
import android.webkit.WebViewCore;
|
||||
|
||||
import com.google.android.collect.Lists;
|
||||
import com.google.android.collect.Maps;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
@@ -91,10 +98,24 @@ public class WebDriver {
|
||||
private static final int LOADING_TIMEOUT = 30000;
|
||||
// Timeout for executing JavaScript in the WebView in milliseconds.
|
||||
private static final int JS_EXECUTION_TIMEOUT = 10000;
|
||||
// Timeout for the MotionEvent to be completely handled
|
||||
private static final int MOTION_EVENT_TIMEOUT = 1000;
|
||||
// Timeout for detecting a new page load
|
||||
private static final int PAGE_STARTED_LOADING = 500;
|
||||
// Timeout for handling KeyEvents
|
||||
private static final int KEY_EVENT_TIMEOUT = 2000;
|
||||
|
||||
// Commands posted to the handler
|
||||
private static final int CMD_GET_URL = 1;
|
||||
private static final int CMD_EXECUTE_SCRIPT = 2;
|
||||
private static final int CMD_SEND_TOUCH = 3;
|
||||
private static final int CMD_SEND_KEYS = 4;
|
||||
private static final int CMD_NAV_REFRESH = 5;
|
||||
private static final int CMD_NAV_BACK = 6;
|
||||
private static final int CMD_NAV_FORWARD = 7;
|
||||
private static final int CMD_SEND_KEYCODE = 8;
|
||||
private static final int CMD_MOVE_CURSOR_RIGHTMOST_POS = 9;
|
||||
private static final int CMD_MESSAGE_RELAY_ECHO = 10;
|
||||
|
||||
private static final String ELEMENT_KEY = "ELEMENT";
|
||||
private static final String STATUS = "status";
|
||||
@@ -107,24 +128,62 @@ public class WebDriver {
|
||||
|
||||
// Used for synchronization
|
||||
private final Object mSyncObject;
|
||||
private final Object mSyncPageLoad;
|
||||
|
||||
// Updated when the command is done executing in the main thread.
|
||||
private volatile boolean mCommandDone;
|
||||
|
||||
// Used by WebViewClientWrapper.onPageStarted() to notify that
|
||||
// a page started loading.
|
||||
private volatile boolean mPageStartedLoading;
|
||||
// Used by WebChromeClientWrapper.onProgressChanged to notify when
|
||||
// a page finished loading.
|
||||
private volatile boolean mPageFinishedLoading;
|
||||
private WebView mWebView;
|
||||
|
||||
private Navigation mNavigation;
|
||||
// This WebElement represents the object document.documentElement
|
||||
private WebElement mDocumentElement;
|
||||
|
||||
|
||||
// This Handler runs in the main UI thread.
|
||||
private final Handler mHandler = new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
if (msg.what == CMD_GET_URL) {
|
||||
final String url = (String) msg.obj;
|
||||
mWebView.loadUrl(url);
|
||||
} else if (msg.what == CMD_EXECUTE_SCRIPT) {
|
||||
mWebView.loadUrl("javascript:" + (String) msg.obj);
|
||||
switch (msg.what) {
|
||||
case CMD_GET_URL:
|
||||
final String url = (String) msg.obj;
|
||||
mWebView.loadUrl(url);
|
||||
break;
|
||||
case CMD_EXECUTE_SCRIPT:
|
||||
mWebView.loadUrl("javascript:" + (String) msg.obj);
|
||||
break;
|
||||
case CMD_MESSAGE_RELAY_ECHO:
|
||||
notifyCommandDone();
|
||||
break;
|
||||
case CMD_SEND_TOUCH:
|
||||
touchScreen((Point) msg.obj);
|
||||
notifyCommandDone();
|
||||
break;
|
||||
case CMD_SEND_KEYS:
|
||||
dispatchKeys((CharSequence[]) msg.obj);
|
||||
notifyCommandDone();
|
||||
break;
|
||||
case CMD_NAV_REFRESH:
|
||||
mWebView.reload();
|
||||
break;
|
||||
case CMD_NAV_BACK:
|
||||
mWebView.goBack();
|
||||
break;
|
||||
case CMD_NAV_FORWARD:
|
||||
mWebView.goForward();
|
||||
break;
|
||||
case CMD_SEND_KEYCODE:
|
||||
dispatchKeyCodes((int[]) msg.obj);
|
||||
notifyCommandDone();
|
||||
break;
|
||||
case CMD_MOVE_CURSOR_RIGHTMOST_POS:
|
||||
moveCursorToLeftMostPos((String) msg.obj);
|
||||
notifyCommandDone();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -169,13 +228,13 @@ public class WebDriver {
|
||||
return values[i];
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(intValue
|
||||
+ " does not map to any ErrorCode.");
|
||||
return UNKNOWN_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
public WebDriver(WebView webview) {
|
||||
this.mWebView = webview;
|
||||
mWebView.requestFocus();
|
||||
if (mWebView == null) {
|
||||
throw new IllegalArgumentException("WebView cannot be null");
|
||||
}
|
||||
@@ -186,12 +245,25 @@ public class WebDriver {
|
||||
shouldRunInMainThread(true);
|
||||
|
||||
mSyncObject = new Object();
|
||||
mSyncPageLoad = new Object();
|
||||
this.mWebView = webview;
|
||||
WebchromeClientWrapper chromeWrapper = new WebchromeClientWrapper(
|
||||
WebChromeClientWrapper chromeWrapper = new WebChromeClientWrapper(
|
||||
webview.getWebChromeClient(), this);
|
||||
mWebView.setWebChromeClient(chromeWrapper);
|
||||
WebViewClientWrapper viewWrapper = new WebViewClientWrapper(
|
||||
webview.getWebViewClient(), this);
|
||||
mWebView.setWebViewClient(viewWrapper);
|
||||
mWebView.addJavascriptInterface(new JavascriptResultReady(),
|
||||
"webdriver");
|
||||
mDocumentElement = new WebElement(this, "");
|
||||
mNavigation = new Navigation();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The title of the current page, null if not set.
|
||||
*/
|
||||
public String getTitle() {
|
||||
return mWebView.getTitle();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -201,8 +273,7 @@ public class WebDriver {
|
||||
* @param url The URL to load.
|
||||
*/
|
||||
public void get(String url) {
|
||||
executeCommand(CMD_GET_URL, url, LOADING_TIMEOUT);
|
||||
mDocumentElement = (WebElement) executeScript("return document.body;");
|
||||
mNavigation.to(url);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -243,7 +314,7 @@ public class WebDriver {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the WebView.
|
||||
* Clears the WebView's state and closes associated views.
|
||||
*/
|
||||
public void quit() {
|
||||
mWebView.clearCache(true);
|
||||
@@ -251,6 +322,7 @@ public class WebDriver {
|
||||
mWebView.clearHistory();
|
||||
mWebView.clearSslPreferences();
|
||||
mWebView.clearView();
|
||||
mWebView.removeAllViewsInLayout();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -287,13 +359,51 @@ public class WebDriver {
|
||||
")(" + escapeAndQuote(script) + ", " + scriptArgs + ", true)");
|
||||
}
|
||||
|
||||
public Navigation navigate() {
|
||||
return mNavigation;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public class Navigation {
|
||||
/* package */ Navigation () {}
|
||||
|
||||
public void back() {
|
||||
navigate(CMD_NAV_BACK, null);
|
||||
}
|
||||
|
||||
public void forward() {
|
||||
navigate(CMD_NAV_FORWARD, null);
|
||||
}
|
||||
|
||||
public void to(String url) {
|
||||
navigate(CMD_GET_URL, url);
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
navigate(CMD_NAV_REFRESH, null);
|
||||
}
|
||||
|
||||
private void navigate(int command, String url) {
|
||||
synchronized (mSyncPageLoad) {
|
||||
mPageFinishedLoading = false;
|
||||
Message msg = mHandler.obtainMessage(command);
|
||||
msg.obj = url;
|
||||
mHandler.sendMessage(msg);
|
||||
waitForPageLoad();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the arguments passed to a JavaScript friendly format.
|
||||
*
|
||||
* @param args The arguments to convert.
|
||||
* @return Comma separated Strings containing the arguments.
|
||||
*/
|
||||
/*package*/ String convertToJsArgs(final Object... args) {
|
||||
/* package */ String convertToJsArgs(final Object... args) {
|
||||
StringBuilder toReturn = new StringBuilder();
|
||||
int length = args.length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
@@ -337,10 +447,20 @@ public class WebDriver {
|
||||
return toReturn.toString();
|
||||
}
|
||||
|
||||
/*package*/ Object executeRawJavascript(final String script) {
|
||||
/* package */ Object executeRawJavascript(final String script) {
|
||||
if (mWebView.getUrl() == null) {
|
||||
throw new WebDriverException("Cannot operate on a blank page. "
|
||||
+ "Load a page using WebDriver.get().");
|
||||
}
|
||||
String result = executeCommand(CMD_EXECUTE_SCRIPT,
|
||||
"if (!window.webdriver || !window.webdriver.resultReady) {" +
|
||||
" return;" +
|
||||
"}" +
|
||||
"window.webdriver.resultReady(" + script + ")",
|
||||
JS_EXECUTION_TIMEOUT);
|
||||
if (result == null || "undefined".equals(result)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
JSONObject json = new JSONObject(result);
|
||||
throwIfError(json);
|
||||
@@ -352,7 +472,7 @@ public class WebDriver {
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ String getResourceAsString(final int resourceId) {
|
||||
/* package */ String getResourceAsString(final int resourceId) {
|
||||
InputStream is = mWebView.getResources().openRawResource(resourceId);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(is));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@@ -369,6 +489,177 @@ public class WebDriver {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/* package */ void sendTouchScreen(Point coords) {
|
||||
// Reset state
|
||||
resetPageLoadState();
|
||||
executeCommand(CMD_SEND_TOUCH, coords,LOADING_TIMEOUT);
|
||||
// Wait for the events to be fully handled
|
||||
waitForMessageRelay(MOTION_EVENT_TIMEOUT);
|
||||
|
||||
// If a page started loading, block until page finishes loading
|
||||
waitForPageLoadIfNeeded();
|
||||
}
|
||||
|
||||
/* package */ void resetPageLoadState() {
|
||||
synchronized (mSyncPageLoad) {
|
||||
mPageStartedLoading = false;
|
||||
mPageFinishedLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ void waitForPageLoadIfNeeded() {
|
||||
synchronized (mSyncPageLoad) {
|
||||
Long end = System.currentTimeMillis() + PAGE_STARTED_LOADING;
|
||||
// Wait PAGE_STARTED_LOADING milliseconds to see if we detect a
|
||||
// page load.
|
||||
while (!mPageStartedLoading && (System.currentTimeMillis() <= end)) {
|
||||
try {
|
||||
// This is notified by WebChromeClientWrapper#onProgressChanged
|
||||
// when the page finished loading.
|
||||
mSyncPageLoad.wait(PAGE_STARTED_LOADING);
|
||||
} catch (InterruptedException e) {
|
||||
new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
if (mPageStartedLoading) {
|
||||
waitForPageLoad();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void touchScreen(Point coords) {
|
||||
// Convert to screen coords
|
||||
// screen = JS x zoom - offset
|
||||
float zoom = mWebView.getScale();
|
||||
float xOffset = mWebView.getX();
|
||||
float yOffset = mWebView.getY();
|
||||
Point screenCoords = new Point( (int)(coords.x*zoom - xOffset),
|
||||
(int)(coords.y*zoom - yOffset));
|
||||
|
||||
long downTime = SystemClock.uptimeMillis();
|
||||
MotionEvent down = MotionEvent.obtain(downTime,
|
||||
SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, screenCoords.x,
|
||||
screenCoords.y, 0);
|
||||
down.setSource(InputDevice.SOURCE_TOUCHSCREEN);
|
||||
MotionEvent up = MotionEvent.obtain(downTime,
|
||||
SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, screenCoords.x,
|
||||
screenCoords.y, 0);
|
||||
up.setSource(InputDevice.SOURCE_TOUCHSCREEN);
|
||||
// Dispatch the events to WebView
|
||||
mWebView.dispatchTouchEvent(down);
|
||||
mWebView.dispatchTouchEvent(up);
|
||||
}
|
||||
|
||||
/* package */ void notifyPageStartedLoading() {
|
||||
synchronized (mSyncPageLoad) {
|
||||
mPageStartedLoading = true;
|
||||
mSyncPageLoad.notify();
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ void notifyPageFinishedLoading() {
|
||||
synchronized (mSyncPageLoad) {
|
||||
mPageFinishedLoading = true;
|
||||
mSyncPageLoad.notify();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param keys The first element of the CharSequence should be the
|
||||
* existing value in the text input, or the empty string if none.
|
||||
*/
|
||||
/* package */ void sendKeys(CharSequence[] keys) {
|
||||
executeCommand(CMD_SEND_KEYS, keys, KEY_EVENT_TIMEOUT);
|
||||
// Wait for all KeyEvents to be handled
|
||||
waitForMessageRelay(KEY_EVENT_TIMEOUT);
|
||||
}
|
||||
|
||||
/* package */ void sendKeyCodes(int[] keycodes) {
|
||||
executeCommand(CMD_SEND_KEYCODE, keycodes, KEY_EVENT_TIMEOUT);
|
||||
// Wait for all KeyEvents to be handled
|
||||
waitForMessageRelay(KEY_EVENT_TIMEOUT);
|
||||
}
|
||||
|
||||
/* package */ void moveCursorToRightMostPosition(String value) {
|
||||
executeCommand(CMD_MOVE_CURSOR_RIGHTMOST_POS, value, KEY_EVENT_TIMEOUT);
|
||||
waitForMessageRelay(KEY_EVENT_TIMEOUT);
|
||||
}
|
||||
|
||||
private void moveCursorToLeftMostPos(String value) {
|
||||
// If there is text, move the cursor to the rightmost position
|
||||
if (value != null && !value.equals("")) {
|
||||
long downTime = SystemClock.uptimeMillis();
|
||||
KeyEvent down = new KeyEvent(downTime, SystemClock.uptimeMillis(),
|
||||
KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT, 0);
|
||||
KeyEvent up = new KeyEvent(downTime, SystemClock.uptimeMillis(),
|
||||
KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_RIGHT,
|
||||
value.length());
|
||||
mWebView.dispatchKeyEvent(down);
|
||||
mWebView.dispatchKeyEvent(up);
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchKeyCodes(int[] keycodes) {
|
||||
for (int i = 0; i < keycodes.length; i++) {
|
||||
KeyEvent down = new KeyEvent(KeyEvent.ACTION_DOWN, keycodes[i]);
|
||||
KeyEvent up = new KeyEvent(KeyEvent.ACTION_UP, keycodes[i]);
|
||||
mWebView.dispatchKeyEvent(down);
|
||||
mWebView.dispatchKeyEvent(up);
|
||||
}
|
||||
}
|
||||
|
||||
private void dispatchKeys(CharSequence[] keys) {
|
||||
KeyCharacterMap chararcterMap = KeyCharacterMap.load(
|
||||
KeyCharacterMap.VIRTUAL_KEYBOARD);
|
||||
for (int i = 0; i < keys.length; i++) {
|
||||
CharSequence s = keys[i];
|
||||
for (int j = 0; j < s.length(); j++) {
|
||||
KeyEvent[] events =
|
||||
chararcterMap.getEvents(new char[]{s.charAt(j)});
|
||||
for (KeyEvent e : events) {
|
||||
mWebView.dispatchKeyEvent(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void waitForMessageRelay(long timeout) {
|
||||
synchronized (mSyncObject) {
|
||||
mCommandDone = false;
|
||||
}
|
||||
Message msg = Message.obtain();
|
||||
msg.what = WebViewCore.EventHub.MESSAGE_RELAY;
|
||||
Message echo = mHandler.obtainMessage(CMD_MESSAGE_RELAY_ECHO);
|
||||
msg.obj = echo;
|
||||
|
||||
mWebView.getWebViewCore().sendMessage(msg);
|
||||
synchronized (mSyncObject) {
|
||||
long end = System.currentTimeMillis() + timeout;
|
||||
while (!mCommandDone && (System.currentTimeMillis() <= end)) {
|
||||
try {
|
||||
// This is notifed by the mHandler when it receives the
|
||||
// MESSAGE_RELAY back
|
||||
mSyncObject.wait(timeout);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void waitForPageLoad() {
|
||||
long endLoad = System.currentTimeMillis() + LOADING_TIMEOUT;
|
||||
while (!mPageFinishedLoading
|
||||
&& (System.currentTimeMillis() <= endLoad)) {
|
||||
try {
|
||||
mSyncPageLoad.wait(LOADING_TIMEOUT);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps the given string into quotes and escape existing quotes
|
||||
* and backslashes.
|
||||
@@ -531,7 +822,8 @@ public class WebDriver {
|
||||
long end = System.currentTimeMillis() + timeout;
|
||||
while (!mCommandDone) {
|
||||
if (System.currentTimeMillis() >= end) {
|
||||
throw new RuntimeException("Timeout executing command.");
|
||||
throw new RuntimeException("Timeout executing command: "
|
||||
+ command);
|
||||
}
|
||||
try {
|
||||
mSyncObject.wait(timeout);
|
||||
|
||||
@@ -16,9 +16,13 @@
|
||||
|
||||
package android.webkit.webdriver;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents an HTML element. Typically most interactions with a web page
|
||||
@@ -158,6 +162,124 @@ public class WebElement {
|
||||
return (Boolean) executeAtom(toggle, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the KeyEvents for the given sequence of characters to the
|
||||
* WebElement to simulate typing. The KeyEvents are generated using the
|
||||
* device's {@link android.view.KeyCharacterMap.VIRTUAL_KEYBOARD}.
|
||||
*
|
||||
* @param keys The keys to send to this WebElement
|
||||
*/
|
||||
public void sendKeys(CharSequence... keys) {
|
||||
if (keys == null || keys.length == 0) {
|
||||
return;
|
||||
}
|
||||
click();
|
||||
mDriver.moveCursorToRightMostPosition(getAttribute("value"));
|
||||
mDriver.sendKeys(keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this to send one of the key code constants defined in
|
||||
* {@link android.view.KeyEvent}
|
||||
*
|
||||
* @param keys
|
||||
*/
|
||||
public void sendKeyCodes(int... keys) {
|
||||
if (keys == null || keys.length == 0) {
|
||||
return;
|
||||
}
|
||||
click();
|
||||
mDriver.moveCursorToRightMostPosition(getAttribute("value"));
|
||||
mDriver.sendKeyCodes(keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a touch event to the center coordinates of this WebElement.
|
||||
*/
|
||||
public void click() {
|
||||
Point topLeft = getLocation();
|
||||
Point size = getSize();
|
||||
int jsX = topLeft.x + size.x/2;
|
||||
int jsY = topLeft.y + size.y/2;
|
||||
Point center = new Point(jsX, jsY);
|
||||
mDriver.sendTouchScreen(center);
|
||||
}
|
||||
|
||||
/**
|
||||
* Submits the form containing this WebElement.
|
||||
*/
|
||||
public void submit() {
|
||||
mDriver.resetPageLoadState();
|
||||
String submit = mDriver.getResourceAsString(R.raw.submit_android);
|
||||
executeAtom(submit, this);
|
||||
mDriver.waitForPageLoadIfNeeded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the text value if this is a text entry element. Does nothing
|
||||
* otherwise.
|
||||
*/
|
||||
public void clear() {
|
||||
String value = getAttribute("value");
|
||||
if (value == null || value.equals("")) {
|
||||
return;
|
||||
}
|
||||
int length = value.length();
|
||||
int[] keys = new int[length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
keys[i] = KeyEvent.KEYCODE_DEL;
|
||||
}
|
||||
sendKeyCodes(keys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value of the given CSS property if found, null otherwise.
|
||||
*/
|
||||
public String getCssValue(String cssProperty) {
|
||||
String getCssProp = mDriver.getResourceAsString(
|
||||
R.raw.get_value_of_css_property_android);
|
||||
return (String) executeAtom(getCssProp, this, cssProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width and height of the rendered element.
|
||||
*
|
||||
* @return a {@link android.graphics.Point}, where Point.x represents the
|
||||
* width, and Point.y represents the height of the element.
|
||||
*/
|
||||
public Point getSize() {
|
||||
String getSize = mDriver.getResourceAsString(R.raw.get_size_android);
|
||||
Map<String, Long> map = (Map<String, Long>) executeAtom(getSize, this);
|
||||
return new Point(map.get("width").intValue(),
|
||||
map.get("height").intValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location of the top left corner of this element on the screen.
|
||||
* If the element is not visisble, this will scroll to get the element into
|
||||
* the visisble screen.
|
||||
*
|
||||
* @return a {@link android.graphics.Point} containing the x and y
|
||||
* coordinates of the top left corner of this element.
|
||||
*/
|
||||
public Point getLocation() {
|
||||
String getLocation = mDriver.getResourceAsString(
|
||||
R.raw.get_top_left_coordinates_android);
|
||||
Map<String,Long> map = (Map<String, Long>) executeAtom(getLocation,
|
||||
this);
|
||||
return new Point(map.get("x").intValue(), map.get("y").intValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if the WebElement is displayed on the screen,
|
||||
* false otherwise.
|
||||
*/
|
||||
public boolean isDisplayed() {
|
||||
String isDisplayed = mDriver.getResourceAsString(
|
||||
R.raw.is_displayed_android);
|
||||
return (Boolean) executeAtom(isDisplayed, this);
|
||||
}
|
||||
|
||||
/*package*/ String getId() {
|
||||
return mId;
|
||||
}
|
||||
@@ -237,15 +359,26 @@ public class WebElement {
|
||||
private List<WebElement> findElements(String strategy, String locator) {
|
||||
String findElements = mDriver.getResourceAsString(
|
||||
R.raw.find_elements_android);
|
||||
return (List<WebElement>) executeAtom(findElements,
|
||||
strategy, locator, this);
|
||||
if (mId.equals("")) {
|
||||
return (List<WebElement>) executeAtom(findElements,
|
||||
strategy, locator);
|
||||
} else {
|
||||
return (List<WebElement>) executeAtom(findElements,
|
||||
strategy, locator, this);
|
||||
}
|
||||
}
|
||||
|
||||
private WebElement findElement(String strategy, String locator) {
|
||||
String findElement = mDriver.getResourceAsString(
|
||||
R.raw.find_element_android);
|
||||
WebElement el = (WebElement) executeAtom(findElement,
|
||||
strategy, locator, this);
|
||||
WebElement el;
|
||||
if (mId.equals("")) {
|
||||
el = (WebElement) executeAtom(findElement,
|
||||
strategy, locator);
|
||||
} else {
|
||||
el = (WebElement) executeAtom(findElement,
|
||||
strategy, locator, this);
|
||||
}
|
||||
if (el == null) {
|
||||
throw new WebElementNotFoundException("Could not find element "
|
||||
+ "with " + strategy + ": " + locator);
|
||||
|
||||
125
core/java/android/webkit/webdriver/WebViewClient.java
Normal file
125
core/java/android/webkit/webdriver/WebViewClient.java
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.webkit.webdriver;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.http.SslError;
|
||||
import android.os.Message;
|
||||
import android.view.KeyEvent;
|
||||
import android.webkit.HttpAuthHandler;
|
||||
import android.webkit.SslErrorHandler;
|
||||
import android.webkit.WebResourceResponse;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
|
||||
/* package */ class WebViewClientWrapper extends WebViewClient {
|
||||
private final WebViewClient mDelegate;
|
||||
private final WebDriver mDriver;
|
||||
|
||||
public WebViewClientWrapper(WebViewClient delegate, WebDriver driver) {
|
||||
if (delegate == null) {
|
||||
mDelegate = new WebViewClient();
|
||||
} else {
|
||||
mDelegate = delegate;
|
||||
}
|
||||
this.mDriver = driver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
||||
return mDelegate.shouldOverrideUrlLoading(view, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
||||
mDriver.notifyPageStartedLoading();
|
||||
mDelegate.onPageStarted(view, url, favicon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
mDelegate.onPageFinished(view, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadResource(WebView view, String url) {
|
||||
mDelegate.onLoadResource(view, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebResourceResponse shouldInterceptRequest(WebView view,
|
||||
String url) {
|
||||
return mDelegate.shouldInterceptRequest(view, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTooManyRedirects(WebView view, Message cancelMsg,
|
||||
Message continueMsg) {
|
||||
mDelegate.onTooManyRedirects(view, cancelMsg, continueMsg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceivedError(WebView view, int errorCode, String description,
|
||||
String failingUrl) {
|
||||
mDelegate.onReceivedError(view, errorCode, description, failingUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFormResubmission(WebView view, Message dontResend,
|
||||
Message resend) {
|
||||
mDelegate.onFormResubmission(view, dontResend, resend);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doUpdateVisitedHistory(WebView view, String url,
|
||||
boolean isReload) {
|
||||
mDelegate.doUpdateVisitedHistory(view, url, isReload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceivedSslError(WebView view, SslErrorHandler handler,
|
||||
SslError error) {
|
||||
mDelegate.onReceivedSslError(view, handler, error);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler,
|
||||
String host, String realm) {
|
||||
mDelegate.onReceivedHttpAuthRequest(view, handler, host, realm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
|
||||
return mDelegate.shouldOverrideKeyEvent(view, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
|
||||
mDelegate.onUnhandledKeyEvent(view, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScaleChanged(WebView view, float oldScale, float newScale) {
|
||||
mDelegate.onScaleChanged(view, oldScale, newScale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceivedLoginRequest(WebView view, String realm,
|
||||
String account, String args) {
|
||||
mDelegate.onReceivedLoginRequest(view, realm, account, args);
|
||||
}
|
||||
}
|
||||
@@ -29,12 +29,12 @@ import android.webkit.WebChromeClient;
|
||||
import android.webkit.WebStorage;
|
||||
import android.webkit.WebView;
|
||||
|
||||
/* package */ class WebchromeClientWrapper extends WebChromeClient {
|
||||
/* package */ class WebChromeClientWrapper extends WebChromeClient {
|
||||
|
||||
private final WebChromeClient mDelegate;
|
||||
private final WebDriver mDriver;
|
||||
|
||||
public WebchromeClientWrapper(WebChromeClient delegate, WebDriver driver) {
|
||||
public WebChromeClientWrapper(WebChromeClient delegate, WebDriver driver) {
|
||||
if (delegate == null) {
|
||||
this.mDelegate = new WebChromeClient();
|
||||
} else {
|
||||
@@ -46,7 +46,7 @@ import android.webkit.WebView;
|
||||
@Override
|
||||
public void onProgressChanged(WebView view, int newProgress) {
|
||||
if (newProgress == 100) {
|
||||
mDriver.notifyCommandDone();
|
||||
mDriver.notifyPageFinishedLoading();
|
||||
}
|
||||
mDelegate.onProgressChanged(view, newProgress);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user