diff --git a/mobile/android/base/tests/MotionEventHelper.java.in b/mobile/android/base/tests/MotionEventHelper.java.in
index 70bf0101a7a..25d9d2ee249 100644
--- a/mobile/android/base/tests/MotionEventHelper.java.in
+++ b/mobile/android/base/tests/MotionEventHelper.java.in
@@ -13,6 +13,7 @@ class MotionEventHelper {
private static final String LOGTAG = "RobocopMotionEventHelper";
private static final long DRAG_EVENTS_PER_SECOND = 20; // 20 move events per second when doing a drag
+ private static final long LONG_PRESS_DURATION = 2000;
private final Instrumentation mInstrumentation;
private final int mSurfaceOffsetX;
@@ -135,4 +136,14 @@ class MotionEventHelper {
tap(x, y);
tap(x, y);
}
+
+ public void longPress(float x, float y) {
+ long downTime = down(x, y);
+ try {
+ Thread.sleep(LONG_PRESS_DURATION);
+ } catch (InterruptedException ie) {
+ ie.printStackTrace();
+ }
+ up(downTime, x, y);
+ }
}
diff --git a/mobile/android/base/tests/robocop.ini b/mobile/android/base/tests/robocop.ini
index 6bf8e22eb0d..39f511021aa 100644
--- a/mobile/android/base/tests/robocop.ini
+++ b/mobile/android/base/tests/robocop.ini
@@ -24,6 +24,7 @@
[testAddonManager]
[testHistory]
[testVkbOverlap]
+[testAddSearchEngine]
# [testPermissions] # see bug 757475
# [testJarReader] # see bug 738890
diff --git a/mobile/android/base/tests/robocop_search_input.html b/mobile/android/base/tests/robocop_search_input.html
new file mode 100644
index 00000000000..a6cd26402f5
--- /dev/null
+++ b/mobile/android/base/tests/robocop_search_input.html
@@ -0,0 +1,17 @@
+
+
+
+TestSearch
+
+
+
+
+
+
+
diff --git a/mobile/android/base/tests/testAddSearchEngine.java.in b/mobile/android/base/tests/testAddSearchEngine.java.in
new file mode 100644
index 00000000000..e4547b4122c
--- /dev/null
+++ b/mobile/android/base/tests/testAddSearchEngine.java.in
@@ -0,0 +1,105 @@
+#filter substitution
+package @ANDROID_PACKAGE_NAME@.tests;
+
+import @ANDROID_PACKAGE_NAME@.*;
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.ListView;
+
+public class testAddSearchEngine extends BaseTest {
+ @Override
+ protected int getTestType() {
+ return TEST_MOCHITEST;
+ }
+
+ public void testAddSearchEngine() {
+ final int CONTEXT_MENU_TIMEOUT = 5000;
+ final String CONTEXT_MENU_LABEL = "Add Search Engine";
+ final String OK_LABEL = "OK";
+ final String url = getAbsoluteUrl("/robocop/robocop_search_input.html");
+
+ blockForGeckoReady();
+
+ Actions.EventExpecter loadedExpecter = mActions.expectGeckoEvent("DOMContentLoaded");
+
+ // Load page with an input field
+ loadUrl(url);
+ loadedExpecter.blockForEvent();
+
+ // Long press input field. This doesn't always work on the first try,
+ // so try again if the context menu doesn't appear.
+ boolean contextMenuAppeared = false;
+ for (int i = 0; (i < 2) && !contextMenuAppeared; ++i) {
+ MotionEventHelper meh = new MotionEventHelper(
+ getInstrumentation(), mDriver.getGeckoLeft(), mDriver.getGeckoTop());
+ meh.longPress(0, 0);
+ contextMenuAppeared = mSolo.waitForText(CONTEXT_MENU_LABEL, 0, CONTEXT_MENU_TIMEOUT);
+ }
+ mAsserter.ok(contextMenuAppeared, CONTEXT_MENU_LABEL + " appeared in context menu", null);
+ mSolo.clickOnText(CONTEXT_MENU_LABEL);
+
+ // Add the field as a search engine
+ boolean dialogAppeared = mSolo.waitForText(OK_LABEL);
+ mAsserter.ok(dialogAppeared, "dialog appeared", null);
+ mSolo.clickOnText(OK_LABEL);
+
+ // Enter search term
+ Actions.EventExpecter enginesEventExpecter = mActions.expectGeckoEvent("SearchEngines:Data");
+ clickOnAwesomeBar();
+ enginesEventExpecter.blockForEvent();
+ mActions.sendKeys("foo");
+
+ // Wait for the results to be filtered. There's no easy way to tell
+ // that the list has been updated, so we just wait an arbitrary amount
+ // of time.
+ mSolo.sleep(3000);
+
+ // Do search with custom engine
+ View customSearchView = getCustomSearchView();
+ mAsserter.isnot(customSearchView, null, "found custom search row");
+ loadedExpecter = mActions.expectGeckoEvent("DOMContentLoaded");
+ mSolo.clickOnView(customSearchView);
+ loadedExpecter.blockForEvent();
+
+ // Verify search worked
+ boolean didSearch = mSolo.waitForText("search complete");
+ mAsserter.ok(didSearch, "searched using custom engine", null);
+ }
+
+ /**
+ * Gets the view corresponding to the added custom search engine.
+ *
+ * We can identify this view by its lack of a favicon.
+ */
+ private View getCustomSearchView() {
+ final int imageId = mDriver.findElement(getActivity(), "suggestion_icon").getId();
+ ListView allPages = mSolo.getCurrentListViews().get(0);
+
+ // ListView.getChildAt() only works for children that are displayed on
+ // the screen, so we need to scroll the list incrementally until we
+ // find the view we're looking for.
+ boolean canScroll = true;
+ while (true) {
+ int first = allPages.getFirstVisiblePosition();
+ int last = allPages.getLastVisiblePosition();
+ for (int i = 0; i <= last - first; ++i) {
+ final ViewGroup searchRow = (ViewGroup) allPages.getChildAt(i);
+ ImageView image = (ImageView) searchRow.findViewById(imageId);
+ if (image.getDrawable() == null) {
+ return searchRow;
+ }
+ }
+
+ if (!canScroll) {
+ break;
+ }
+
+ canScroll = mSolo.scrollDownList(0);
+ }
+
+ return null;
+ }
+}