Bug 1348086 - Part 3 - Port selectTabAt() to TabsPanelComponent. r?gbrown
MozReview-Commit-ID: LlrgFq49Kyz
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/UITest.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/UITest.java
@@ -2,16 +2,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.tests;
import org.mozilla.gecko.Actions;
import org.mozilla.gecko.Assert;
import org.mozilla.gecko.Driver;
+import org.mozilla.gecko.RobocopUtils;
import org.mozilla.gecko.tests.components.AboutHomeComponent;
import org.mozilla.gecko.tests.components.AppMenuComponent;
import org.mozilla.gecko.tests.components.BaseComponent;
import org.mozilla.gecko.tests.components.GeckoViewComponent;
import org.mozilla.gecko.tests.components.TabStripComponent;
import org.mozilla.gecko.tests.components.TabsPanelComponent;
import org.mozilla.gecko.tests.components.ToolbarComponent;
import org.mozilla.gecko.tests.helpers.HelperInitializer;
@@ -144,16 +145,21 @@ abstract class UITest extends BaseRoboco
private String getAbsoluteUrl(final String baseUrl, final String url) {
if (!url.startsWith(baseUrl)) {
return baseUrl + "/" + url.replaceAll("(^/)", "");
}
return url;
}
+ @Override
+ public final void runOnUiThreadSync(Runnable runnable) {
+ RobocopUtils.runOnUiThreadSync(getActivity(), runnable);
+ }
+
/**
* Throws an Exception. Called from overridden JUnit methods to ensure JUnit assertions
* are not accidentally used over AssertionHelper assertions (the latter of which contains
* additional logging facilities for use in our test harnesses).
*/
private static void junit() {
throw new UnsupportedOperationException(JUNIT_FAILURE_MSG);
}
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/UITestContext.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/UITestContext.java
@@ -42,10 +42,12 @@ public interface UITestContext {
*/
public String getAbsoluteHostnameUrl(final String url);
/**
* Returns the absolute version of the given URL using the host's IP address.
*/
public String getAbsoluteIpUrl(final String url);
+ public void runOnUiThreadSync(Runnable runnable);
+
public BaseComponent getComponent(final ComponentType type);
}
--- a/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/components/TabsPanelComponent.java
+++ b/mobile/android/tests/browser/robocop/src/org/mozilla/gecko/tests/components/TabsPanelComponent.java
@@ -10,16 +10,18 @@ import org.mozilla.gecko.tabs.TabsLayout
import org.mozilla.gecko.tests.UITestContext;
import org.mozilla.gecko.tests.helpers.WaitHelper;
import java.util.List;
import static org.mozilla.gecko.tests.helpers.AssertionHelper.fAssertTrue;
public class TabsPanelComponent extends TabsPresenterComponent {
+ private static final int MAX_WAIT_MS = 4500;
+
public TabsPanelComponent(final UITestContext testContext) {
super(testContext);
}
public void openPanel() {
assertTabsPanelIsClosed();
mSolo.clickOnView(mSolo.getView(R.id.tabs));
WaitHelper.waitFor("tabs panel to open", new Condition() {
@@ -86,9 +88,68 @@ public class TabsPanelComponent extends
final View tabsPanel = getTabsPanel();
fAssertTrue("Tabs panel is open", tabsPanel != null && tabsPanel.getVisibility() == View.VISIBLE);
}
private void assertTabsPanelIsClosed() {
final View tabsPanel = getTabsPanel();
fAssertTrue("Tabs panel is closed", tabsPanel == null || tabsPanel.getVisibility() != View.VISIBLE);
}
+
+ /**
+ * Scrolls the tabs panel and then selects the tab at the specified index.
+ *
+ * @param index Index of tab to select
+ */
+ public void selectTabAt(final int index) {
+ mSolo.clickOnView(scrollAndGetTabViewAt(index));
+ }
+
+ /**
+ * Gets the view in the tabs panel at the specified index.
+ *
+ * @return View at index
+ */
+ private View scrollAndGetTabViewAt(final int index) {
+ final View[] childView = { null };
+
+ final RecyclerView view = getTabsLayout();
+
+ mTestContext.runOnUiThreadSync(new Runnable() {
+ @Override
+ public void run() {
+ view.scrollToPosition(index);
+
+ // The selection isn't updated synchronously; posting a
+ // runnable to the view's queue guarantees we'll run after the
+ // layout pass.
+ view.post(new Runnable() {
+ @Override
+ public void run() {
+ // Index is relative to all views in the list.
+ final RecyclerView.ViewHolder itemViewHolder =
+ view.findViewHolderForLayoutPosition(index);
+ childView[0] = itemViewHolder == null ? null : itemViewHolder.itemView;
+ }
+ });
+ }
+ });
+
+ WaitHelper.waitFor("list item at index " + index + " exists", new Condition() {
+ @Override
+ public boolean isSatisfied() {
+ return childView[0] != null;
+ }
+ }, MAX_WAIT_MS);
+
+ return childView[0];
+ }
+
+ /**
+ * Gets the RecyclerView of the tabs list.
+ *
+ * @return List view in the tabs panel
+ */
+ private RecyclerView getTabsLayout() {
+ openPanel();
+ return (RecyclerView) mSolo.getView(R.id.normal_tabs);
+ }
}