Index: chrome/android/javatests/src/org/chromium/chrome/browser/widget/OverviewListLayoutTest.java |
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/widget/OverviewListLayoutTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/OverviewListLayoutTest.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a20ae8b654f40551079f97dd35f67826c4569553 |
--- /dev/null |
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/widget/OverviewListLayoutTest.java |
@@ -0,0 +1,366 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.chrome.browser.widget; |
+ |
+import static org.chromium.base.test.util.Restriction.RESTRICTION_TYPE_PHONE; |
+ |
+import android.os.SystemClock; |
+import android.test.suitebuilder.annotation.MediumTest; |
+import android.view.View; |
+import android.view.ViewGroup; |
+import android.widget.ListView; |
+ |
+import com.google.android.apps.chrome.R; |
+ |
+import org.chromium.base.CommandLine; |
+import org.chromium.base.ThreadUtils; |
+import org.chromium.base.test.util.Feature; |
+import org.chromium.base.test.util.Restriction; |
+import org.chromium.chrome.browser.ChromeSwitches; |
+import org.chromium.chrome.browser.Tab; |
+import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; |
+import org.chromium.chrome.browser.tabmodel.TabModel; |
+import org.chromium.chrome.browser.widget.accessibility.AccessibilityTabModelListItem; |
+import org.chromium.chrome.test.ChromeTabbedActivityTestBase; |
+import org.chromium.chrome.test.util.ChromeTabUtils; |
+import org.chromium.chrome.test.util.MenuUtils; |
+import org.chromium.content.browser.test.util.CallbackHelper; |
+import org.chromium.content.browser.test.util.Criteria; |
+import org.chromium.content.browser.test.util.CriteriaHelper; |
+import org.chromium.content.browser.test.util.TestTouchUtils; |
+ |
+import java.util.concurrent.Callable; |
+import java.util.concurrent.TimeoutException; |
+ |
+/** |
+ * Tests accessibility UI. |
+ */ |
+public class OverviewListLayoutTest extends ChromeTabbedActivityTestBase { |
+ private static final int SWIPE_START_X_OFFSET = 10; |
+ private static final int SWIPE_START_Y_OFFSET = 10; |
+ private static final int SWIPE_END_X = 20; |
+ |
+ private class ChildCountCriteria implements Criteria { |
+ private final int mChildCount; |
+ |
+ public ChildCountCriteria(int count) { |
+ mChildCount = count; |
+ } |
+ |
+ @Override |
+ public boolean isSatisfied() { |
+ return mChildCount == ThreadUtils.runOnUiThreadBlockingNoException( |
+ new Callable<Integer>() { |
+ @Override |
+ public Integer call() { |
+ return getList().getChildCount(); |
+ } |
+ }); |
+ } |
+ } |
+ |
+ private class TabModelCountCountCriteria implements Criteria { |
+ private final boolean mIncognito; |
+ private final int mTabCount; |
+ |
+ public TabModelCountCountCriteria(boolean incognito, int count) { |
+ mIncognito = incognito; |
+ mTabCount = count; |
+ } |
+ |
+ @Override |
+ public boolean isSatisfied() { |
+ return mTabCount == ThreadUtils.runOnUiThreadBlockingNoException( |
+ new Callable<Integer>() { |
+ @Override |
+ public Integer call() { |
+ return getActivity().getTabModelSelector() |
+ .getModel(mIncognito).getCount(); |
+ } |
+ }); |
+ } |
+ } |
+ |
+ @Override |
+ public void startMainActivity() throws InterruptedException { |
+ CommandLine.getInstance().appendSwitch(ChromeSwitches.ENABLE_ACCESSIBILITY_TAB_SWITCHER); |
+ startMainActivityFromLauncher(); |
+ } |
+ |
+ private ViewGroup getContainer() { |
+ return ((OverviewListLayout) getActivity().getOverviewListLayout()).getContainer(); |
+ } |
+ |
+ private ListView getList() { |
+ return (ListView) getContainer().findViewById(R.id.list_view); |
+ } |
+ |
+ private void setupTabs() throws InterruptedException { |
+ ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 3); |
+ |
+ TestTouchUtils.performClickOnMainSync( |
+ getInstrumentation(), getActivity().findViewById(R.id.tab_switcher_button)); |
+ |
+ assertTrue( |
+ "Wrong number of tabs", CriteriaHelper.pollForCriteria(new ChildCountCriteria(4))); |
+ } |
+ |
+ private AccessibilityTabModelListItem getListItemAndDisableAnimations(int index) { |
+ AccessibilityTabModelListItem item = getListItem(index); |
+ item.disableAnimations(); |
+ return item; |
+ } |
+ |
+ private AccessibilityTabModelListItem getListItem(int index) { |
+ AccessibilityTabModelListItem item = |
+ (AccessibilityTabModelListItem) getList().getChildAt(index); |
+ return item; |
+ } |
+ |
+ @Restriction(RESTRICTION_TYPE_PHONE) |
+ @MediumTest |
+ @Feature({"Accessibility"}) |
+ public void testCanEnterSwitcher() { |
+ TestTouchUtils.performClickOnMainSync( |
+ getInstrumentation(), getActivity().findViewById(R.id.tab_switcher_button)); |
+ |
+ assertNotNull("Accessibility container was not initialized", getContainer()); |
+ assertNotNull("Accessibility container was not visible", getContainer().getParent()); |
+ } |
+ |
+ @Restriction(RESTRICTION_TYPE_PHONE) |
+ @MediumTest |
+ @Feature({"Accessibility"}) |
+ public void testCanLeaveSwitcher() { |
+ TestTouchUtils.performClickOnMainSync( |
+ getInstrumentation(), getActivity().findViewById(R.id.tab_switcher_button)); |
+ |
+ assertNotNull("Accessibility container was not initialized", getContainer()); |
+ assertNotNull("Accessibility container was not visible", getContainer().getParent()); |
+ |
+ TestTouchUtils.performClickOnMainSync( |
+ getInstrumentation(), getActivity().findViewById(R.id.tab_switcher_button)); |
+ assertNull("Accessibility container was not visible", getContainer().getParent()); |
+ } |
+ |
+ @Restriction(RESTRICTION_TYPE_PHONE) |
+ @MediumTest |
+ @Feature({"Accessibility"}) |
+ public void testCanCloseWithCloseButton() throws InterruptedException, TimeoutException { |
+ setupTabs(); |
+ |
+ AccessibilityTabModelListItem item = getListItemAndDisableAnimations(0); |
+ |
+ final CallbackHelper didReceiveClosureCommittedHelper = new CallbackHelper(); |
+ final TabModel model = getActivity().getCurrentTabModel(); |
+ model.addObserver(new EmptyTabModelObserver() { |
+ @Override |
+ public void tabClosureCommitted(Tab tab) { |
+ didReceiveClosureCommittedHelper.notifyCalled(); |
+ } |
+ }); |
+ |
+ TestTouchUtils.performClickOnMainSync( |
+ getInstrumentation(), item.findViewById(R.id.close_btn)); |
+ |
+ didReceiveClosureCommittedHelper.waitForCallback(0); |
+ |
+ ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
+ @Override |
+ public void run() { |
+ assertEquals("Tab not closed", 3, getList().getChildCount()); |
+ } |
+ }); |
+ } |
+ |
+ @Restriction(RESTRICTION_TYPE_PHONE) |
+ @MediumTest |
+ @Feature({"Accessibility"}) |
+ public void testCanSwipeClosed() throws InterruptedException, TimeoutException { |
+ setupTabs(); |
+ |
+ AccessibilityTabModelListItem item = getListItemAndDisableAnimations(1); |
+ |
+ int[] location = TestTouchUtils.getAbsoluteLocationFromRelative( |
+ item, SWIPE_START_X_OFFSET, SWIPE_START_Y_OFFSET); |
+ |
+ final CallbackHelper didReceiveClosureCommittedHelper = new CallbackHelper(); |
+ final TabModel model = getActivity().getCurrentTabModel(); |
+ model.addObserver(new EmptyTabModelObserver() { |
+ @Override |
+ public void tabClosureCommitted(Tab tab) { |
+ didReceiveClosureCommittedHelper.notifyCalled(); |
+ } |
+ }); |
+ |
+ long downTime = SystemClock.uptimeMillis(); |
+ dragStart(location[0], location[1], downTime); |
+ dragTo(location[0], (int) (item.getWidth() / 1.5), location[1], location[1], 20, downTime); |
+ dragEnd(400, location[1], downTime); |
+ |
+ didReceiveClosureCommittedHelper.waitForCallback(0); |
+ |
+ ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
+ @Override |
+ public void run() { |
+ assertEquals("Tab not closed", 3, getList().getChildCount()); |
+ } |
+ }); |
+ } |
+ |
+ @Restriction(RESTRICTION_TYPE_PHONE) |
+ @MediumTest |
+ @Feature({"Accessibility"}) |
+ public void testResetSwipe() throws InterruptedException { |
+ setupTabs(); |
+ |
+ AccessibilityTabModelListItem item = getListItemAndDisableAnimations(0); |
+ |
+ int[] location = TestTouchUtils.getAbsoluteLocationFromRelative( |
+ item, SWIPE_START_X_OFFSET, SWIPE_START_Y_OFFSET); |
+ |
+ dragTo(location[0], SWIPE_END_X, location[1], location[1], 20, SystemClock.uptimeMillis()); |
+ |
+ ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
+ @Override |
+ public void run() { |
+ assertEquals("Tab not reset as expected", 4, getList().getChildCount()); |
+ } |
+ }); |
+ } |
+ |
+ @Restriction(RESTRICTION_TYPE_PHONE) |
+ @MediumTest |
+ @Feature({"Accessibility"}) |
+ public void testCloseAndUndo() throws InterruptedException, TimeoutException { |
+ setupTabs(); |
+ |
+ final AccessibilityTabModelListItem item = getListItem(0); |
+ |
+ final CallbackHelper didReceivePendingClosureHelper = new CallbackHelper(); |
+ final TabModel model = getActivity().getCurrentTabModel(); |
+ model.addObserver(new EmptyTabModelObserver() { |
+ @Override |
+ public void tabPendingClosure(Tab tab) { |
+ didReceivePendingClosureHelper.notifyCalled(); |
+ } |
+ }); |
+ |
+ TestTouchUtils.performClickOnMainSync( |
+ getInstrumentation(), item.findViewById(R.id.close_btn)); |
+ |
+ didReceivePendingClosureHelper.waitForCallback(0); |
+ |
+ TestTouchUtils.performClickOnMainSync( |
+ getInstrumentation(), item.findViewById(R.id.undo_button)); |
+ |
+ assertFalse("Close not undone", item.hasPendingClosure()); |
+ |
+ ThreadUtils.runOnUiThreadBlocking(new Runnable() { |
+ @Override |
+ public void run() { |
+ assertEquals("Tab closure not undone", 4, getList().getChildCount()); |
+ } |
+ }); |
+ } |
+ |
+ @Restriction(RESTRICTION_TYPE_PHONE) |
+ @MediumTest |
+ @Feature({"Accessibility"}) |
+ public void testCloseAll() throws InterruptedException { |
+ setupTabs(); |
+ |
+ MenuUtils.invokeCustomMenuActionSync( |
+ getInstrumentation(), getActivity(), R.id.close_all_tabs_menu_id); |
+ |
+ assertTrue( |
+ "Wrong number of tabs", CriteriaHelper.pollForCriteria(new ChildCountCriteria(0))); |
+ assertTrue("Tabs not closed on the model", |
+ CriteriaHelper.pollForCriteria(new TabModelCountCountCriteria(false, 0))); |
+ assertFalse(getActivity().findViewById(R.id.tab_switcher_button).isEnabled()); |
+ } |
+ |
+ @Restriction(RESTRICTION_TYPE_PHONE) |
+ @MediumTest |
+ @Feature({"Accessibility"}) |
+ public void testCloseAllIncognito() throws InterruptedException { |
+ setupTabs(); |
+ newIncognitoTabsFromMenu(2); |
+ TestTouchUtils.performClickOnMainSync( |
+ getInstrumentation(), getActivity().findViewById(R.id.tab_switcher_button)); |
+ assertTrue( |
+ "Wrong number of tabs", CriteriaHelper.pollForCriteria(new ChildCountCriteria(2))); |
+ |
+ MenuUtils.invokeCustomMenuActionSync( |
+ getInstrumentation(), getActivity(), R.id.close_all_incognito_tabs_menu_id); |
+ assertTrue("Tabs not closed on the model", |
+ CriteriaHelper.pollForCriteria(new TabModelCountCountCriteria(true, 0))); |
+ |
+ assertTrue( |
+ "Wrong number of tabs", CriteriaHelper.pollForCriteria(new ChildCountCriteria(4))); |
+ assertTrue(getActivity().findViewById(R.id.tab_switcher_button).isEnabled()); |
+ |
+ MenuUtils.invokeCustomMenuActionSync( |
+ getInstrumentation(), getActivity(), R.id.close_all_tabs_menu_id); |
+ |
+ assertTrue( |
+ "Wrong number of tabs", CriteriaHelper.pollForCriteria(new ChildCountCriteria(0))); |
+ assertTrue("Tabs not closed on the model", |
+ CriteriaHelper.pollForCriteria(new TabModelCountCountCriteria(false, 0))); |
+ assertFalse(getActivity().findViewById(R.id.tab_switcher_button).isEnabled()); |
+ } |
+ |
+ @Restriction(RESTRICTION_TYPE_PHONE) |
+ @MediumTest |
+ @Feature({"Accessibility"}) |
+ public void testModelSwitcherVisibility() throws InterruptedException { |
+ setupTabs(); |
+ |
+ View switcherButtons = getContainer().findViewById(R.id.button_wrapper); |
+ |
+ assertEquals( |
+ "Tab Model Switcher buttons visible", View.GONE, switcherButtons.getVisibility()); |
+ |
+ newIncognitoTabsFromMenu(2); |
+ |
+ TestTouchUtils.performClickOnMainSync( |
+ getInstrumentation(), getActivity().findViewById(R.id.tab_switcher_button)); |
+ |
+ assertEquals("Tab Model switcher buttons not visible", View.VISIBLE, |
+ switcherButtons.getVisibility()); |
+ } |
+ |
+ @Restriction(RESTRICTION_TYPE_PHONE) |
+ @MediumTest |
+ @Feature({"Accessibility"}) |
+ public void testModelSwitcherFunctionality() throws InterruptedException { |
+ newIncognitoTabsFromMenu(2); |
+ |
+ ChromeTabUtils.newTabsFromMenu(getInstrumentation(), getActivity(), 3); |
+ |
+ TestTouchUtils.performClickOnMainSync( |
+ getInstrumentation(), getActivity().findViewById(R.id.tab_switcher_button)); |
+ |
+ View switcherButtons = getContainer().findViewById(R.id.button_wrapper); |
+ |
+ assertEquals("Tab Model Switcher buttons visible", View.VISIBLE, |
+ switcherButtons.getVisibility()); |
+ |
+ View incognitoButton = switcherButtons.findViewById(R.id.incognito_tabs_button); |
+ |
+ assertNotNull("IncognitoButton is null", incognitoButton); |
+ |
+ TestTouchUtils.performClickOnMainSync(getInstrumentation(), incognitoButton); |
+ |
+ assertTrue( |
+ "Wrong number of tabs", CriteriaHelper.pollForCriteria(new ChildCountCriteria(2))); |
+ |
+ TestTouchUtils.performClickOnMainSync( |
+ getInstrumentation(), switcherButtons.findViewById(R.id.standard_tabs_button)); |
+ |
+ assertTrue( |
+ "Wrong number of tabs", CriteriaHelper.pollForCriteria(new ChildCountCriteria(4))); |
+ } |
+} |