| Index: chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
 | 
| diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
 | 
| index e254222f7ad4480cdfe0f1765d17f7ddd8b8bbd3..873f95f5f5bd44d3355999a52cd5ca7ad901e7e5 100644
 | 
| --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
 | 
| +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
 | 
| @@ -307,7 +307,7 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|       * @throws InterruptedException
 | 
|       */
 | 
|      private void waitForPanelToExpandAndAssert() throws InterruptedException {
 | 
| -        assertTrue("Search Bar did not expand.", waitForPanelToEnterState(PanelState.EXPANDED));
 | 
| +        assertTrue("Search Panel did not expand.", waitForPanelToEnterState(PanelState.EXPANDED));
 | 
|      }
 | 
|  
 | 
|      /**
 | 
| @@ -315,7 +315,8 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|       * @throws InterruptedException
 | 
|       */
 | 
|      private void waitForPanelToMaximizeAndAssert() throws InterruptedException {
 | 
| -        assertTrue("Search Bar did not maximize.", waitForPanelToEnterState(PanelState.MAXIMIZED));
 | 
| +        assertTrue(
 | 
| +                "Search Panel did not maximize.", waitForPanelToEnterState(PanelState.MAXIMIZED));
 | 
|      }
 | 
|  
 | 
|      /**
 | 
| @@ -323,14 +324,16 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|       * @throws InterruptedException
 | 
|       */
 | 
|      private void waitForPanelToCloseAndAssert() throws InterruptedException {
 | 
| -        // TODO(donnd): figure out why using waitForPanelToEnterState here doesn't work.
 | 
| -        assertTrue("Search Bar did not close.",
 | 
| -                CriteriaHelper.pollForCriteria(new Criteria() {
 | 
| -                    @Override
 | 
| -                    public boolean isSatisfied() {
 | 
| -                        return !mManager.isSearchPanelShowing();
 | 
| -                    }
 | 
| -                }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL));
 | 
| +        assertTrue("Search Panel did not close.", waitForPanelToEnterState(PanelState.CLOSED));
 | 
| +    }
 | 
| +
 | 
| +    /**
 | 
| +     * Asserts that the panel was never opened.
 | 
| +     * @throws InterruptedException
 | 
| +     */
 | 
| +    private void assertPanelNeverOpened() throws InterruptedException {
 | 
| +        assertTrue(
 | 
| +                "Search Panel actually did open.", waitForPanelToEnterState(PanelState.UNDEFINED));
 | 
|      }
 | 
|  
 | 
|      /**
 | 
| @@ -392,6 +395,8 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|  
 | 
|      /**
 | 
|       * Waits for the selection to be dissolved.
 | 
| +     * Use this method any time a test repeatedly establishes and dissolves a selection to ensure
 | 
| +     * that the selection has been completely dissolved before simulating the next selection event.
 | 
|       * This is needed because the renderer's notification of a selection going away is async,
 | 
|       * and a subsequent tap may think there's a current selection until it has been dissolved.
 | 
|       */
 | 
| @@ -405,6 +410,14 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|      }
 | 
|  
 | 
|      /**
 | 
| +     * Waits for the panel to close and then waits for the selection to dissolve.
 | 
| +     */
 | 
| +    private void waitForPanelToCloseAndSelectionDissolved() throws InterruptedException {
 | 
| +        waitForPanelToCloseAndAssert();
 | 
| +        waitForSelectionDissolved();
 | 
| +    }
 | 
| +
 | 
| +    /**
 | 
|       * A ContentViewCore that has some methods stubbed out for testing.
 | 
|       */
 | 
|      private static final class StubbedContentViewCore extends ContentViewCore {
 | 
| @@ -465,20 +478,20 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|      /**
 | 
|       * Taps the base page near the top.
 | 
|       */
 | 
| -    private void tapBasePage() throws InterruptedException {
 | 
| +    private void tapBasePageToClosePanel() throws InterruptedException {
 | 
|          tapBasePage(0.1f, 0.1f);
 | 
| +        waitForPanelToCloseAndAssert();
 | 
|      }
 | 
|  
 | 
|      /**
 | 
|       * Taps the base page at the given x, y position.
 | 
|       */
 | 
| -    private void tapBasePage(float x, float y) throws InterruptedException {
 | 
| +    private void tapBasePage(float x, float y) {
 | 
|          Point size = new Point();
 | 
|          getActivity().getWindowManager().getDefaultDisplay().getSize(size);
 | 
|          x *= size.x;
 | 
|          y *= size.y;
 | 
|          singleClick(x, y);
 | 
| -        waitForPanelToCloseAndAssert();
 | 
|      }
 | 
|  
 | 
|      /**
 | 
| @@ -486,9 +499,16 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|       */
 | 
|      private void clickToExpandAndClosePanel() throws InterruptedException, TimeoutException {
 | 
|          clickWordNode("states");
 | 
| +        tapBarToExpandAndClosePanel();
 | 
| +        waitForSelectionDissolved();
 | 
| +    }
 | 
| +
 | 
| +    /**
 | 
| +     * Tap on the peeking Bar to expand the panel, then taps on the base page to close it.
 | 
| +     */
 | 
| +    private void tapBarToExpandAndClosePanel() throws InterruptedException {
 | 
|          tapPeekingBarToExpandAndAssert();
 | 
| -        tapBasePage();
 | 
| -        waitForPanelToCloseAndAssert();
 | 
| +        tapBasePageToClosePanel();
 | 
|      }
 | 
|  
 | 
|      /**
 | 
| @@ -526,7 +546,7 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|          mFakeServer.reset();
 | 
|          clickWordNode("states");
 | 
|          clickNode("states-far");
 | 
| -        waitForPanelToCloseAndAssert();
 | 
| +        waitForPanelToCloseAndSelectionDissolved();
 | 
|      }
 | 
|  
 | 
|      /**
 | 
| @@ -543,7 +563,7 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|          fakeResponse(false, 200, "States", "display-text", "alternate-term", false);
 | 
|          waitForPanelToPeekAndAssert();
 | 
|          clickNode("states-far");
 | 
| -        waitForPanelToCloseAndAssert();
 | 
| +        waitForPanelToCloseAndSelectionDissolved();
 | 
|      }
 | 
|  
 | 
|      /**
 | 
| @@ -728,8 +748,7 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|          assertEquals(1, mFakeServer.loadedUrlCount());
 | 
|  
 | 
|          // tap the base page to close.
 | 
| -        tapBasePage();
 | 
| -        waitForPanelToCloseAndAssert();
 | 
| +        tapBasePageToClosePanel();
 | 
|          assertEquals(1, mFakeServer.loadedUrlCount());
 | 
|          assertNoContentViewCore();
 | 
|      }
 | 
| @@ -772,8 +791,7 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|          assertEquals(1, mFakeServer.loadedUrlCount());
 | 
|  
 | 
|          // tap the base page to close.
 | 
| -        tapBasePage();
 | 
| -        waitForPanelToCloseAndAssert();
 | 
| +        tapBasePageToClosePanel();
 | 
|          assertEquals(1, mFakeServer.loadedUrlCount());
 | 
|          assertNoContentViewCore();
 | 
|      }
 | 
| @@ -1178,7 +1196,7 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|      @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
 | 
|      public void testTapOnRoleIgnored() throws InterruptedException, TimeoutException {
 | 
|          clickNode("role");
 | 
| -        waitForGestureToClosePanelAndAssertNoSelection();
 | 
| +        assertPanelNeverOpened();
 | 
|      }
 | 
|  
 | 
|      /**
 | 
| @@ -1189,7 +1207,7 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|      @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
 | 
|      public void testTapOnARIAIgnored() throws InterruptedException, TimeoutException {
 | 
|          clickNode("aria");
 | 
| -        waitForGestureToClosePanelAndAssertNoSelection();
 | 
| +        assertPanelNeverOpened();
 | 
|      }
 | 
|  
 | 
|      /**
 | 
| @@ -1200,7 +1218,7 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|      @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
 | 
|      public void testTapOnFocusableIgnored() throws InterruptedException, TimeoutException {
 | 
|          clickNode("focusable");
 | 
| -        waitForGestureToClosePanelAndAssertNoSelection();
 | 
| +        assertPanelNeverOpened();
 | 
|      }
 | 
|  
 | 
|      /**
 | 
| @@ -1337,10 +1355,10 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|  
 | 
|          clickWordNode("states");
 | 
|          clickNode("states-far");
 | 
| -        waitForPanelToCloseAndAssert();
 | 
| +        waitForPanelToCloseAndSelectionDissolved();
 | 
|          clickWordNode("states");
 | 
|          clickNode("states-far");
 | 
| -        waitForPanelToCloseAndAssert();
 | 
| +        waitForPanelToCloseAndSelectionDissolved();
 | 
|  
 | 
|          // 3rd click won't peek the panel.
 | 
|          clickNode("states");
 | 
| @@ -1353,18 +1371,20 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|          waitForPanelToPeekAndAssert();
 | 
|  
 | 
|          // Expanding the panel should deactivate the limit.
 | 
| -        clickToExpandAndClosePanel();
 | 
| +        tapBarToExpandAndClosePanel();
 | 
| +        // Clear the long-press selection.
 | 
| +        clickNode("states-far");
 | 
|  
 | 
|          // Three taps should work now.
 | 
|          clickWordNode("states");
 | 
|          clickNode("states-far");
 | 
| -        waitForPanelToCloseAndAssert();
 | 
| +        waitForPanelToCloseAndSelectionDissolved();
 | 
|          clickWordNode("states");
 | 
|          clickNode("states-far");
 | 
| -        waitForPanelToCloseAndAssert();
 | 
| +        waitForPanelToCloseAndSelectionDissolved();
 | 
|          clickWordNode("states");
 | 
|          clickNode("states-far");
 | 
| -        waitForPanelToCloseAndAssert();
 | 
| +        waitForPanelToCloseAndSelectionDissolved();
 | 
|      }
 | 
|  
 | 
|      /**
 | 
| @@ -1389,7 +1409,7 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|          // Expanding the panel should reset the limit.
 | 
|          swipePanelUp();
 | 
|          singleClick(0.5f, 0.5f);
 | 
| -        waitForPanelToCloseAndAssert();
 | 
| +        waitForPanelToCloseAndSelectionDissolved();
 | 
|  
 | 
|          // Click should preload again.
 | 
|          clickToTriggerPrefetch();
 | 
| @@ -1529,8 +1549,7 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|          pressAppMenuKey();
 | 
|          assertAppMenuVisibility(false);
 | 
|  
 | 
| -        tapBasePage();
 | 
| -        waitForPanelToCloseAndAssert();
 | 
| +        tapBasePageToClosePanel();
 | 
|  
 | 
|          pressAppMenuKey();
 | 
|          assertAppMenuVisibility(true);
 | 
| @@ -1594,14 +1613,13 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|  
 | 
|          // Now we're at the limit, a tap should be ignored.
 | 
|          clickNode("states");
 | 
| -        waitForPanelToCloseAndAssert();
 | 
| +        waitForPanelToCloseAndSelectionDissolved();
 | 
|          assertTapPromoCounterEnabledAt(2);
 | 
|  
 | 
|          // An open should disable the counter, but we need to use long-press (tap is now disabled).
 | 
|          longPressNode("states-far");
 | 
|          tapPeekingBarToExpandAndAssert();
 | 
| -        tapBasePage();
 | 
| -        waitForPanelToCloseAndAssert();
 | 
| +        tapBasePageToClosePanel();
 | 
|          assertTapPromoCounterDisabledAt(2);
 | 
|  
 | 
|          // Even though we closed the panel, the long-press selection is still there.
 | 
| @@ -1715,8 +1733,7 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|          longPressNode("states");
 | 
|          assertEquals(0, observer.hideCount);
 | 
|  
 | 
| -        tapBasePage();
 | 
| -        waitForPanelToCloseAndAssert();
 | 
| +        tapBasePageToClosePanel();
 | 
|          assertEquals(1, observer.hideCount);
 | 
|      }
 | 
|  
 | 
| @@ -1733,8 +1750,7 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|          clickWordNode("states");
 | 
|          assertEquals(0, observer.hideCount);
 | 
|  
 | 
| -        tapBasePage();
 | 
| -        waitForPanelToCloseAndAssert();
 | 
| +        tapBasePageToClosePanel();
 | 
|          assertEquals(1, observer.hideCount);
 | 
|      }
 | 
|  
 | 
| @@ -1808,7 +1824,7 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|  
 | 
|      /**
 | 
|       * Tests a bunch of taps in a row.
 | 
| -     * We've had reliability problems with simple taps due to async clearing
 | 
| +     * We've had reliability problems with a sequence of simple taps, due to async dissolving
 | 
|       * of selection bounds, so this helps prevent a regression with that.
 | 
|       */
 | 
|      @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
 | 
| 
 |