| 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 4c9bd963185374f319246dffdad67c4effab5969..166dbbabce1331e136c468fc841db633e89a6427 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
 | 
| @@ -391,6 +391,20 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|      }
 | 
|  
 | 
|      /**
 | 
| +     * Waits for the selection to be dissolved.
 | 
| +     * 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.
 | 
| +     */
 | 
| +    private void waitForSelectionDissolved() throws InterruptedException {
 | 
| +        assertTrue("Selection never dissolved.", CriteriaHelper.pollForCriteria(new Criteria() {
 | 
| +            @Override
 | 
| +            public boolean isSatisfied() {
 | 
| +                return mSelectionController.isSelectionDissolved();
 | 
| +            }
 | 
| +        }, TEST_TIMEOUT, DEFAULT_POLLING_INTERVAL));
 | 
| +    }
 | 
| +
 | 
| +    /**
 | 
|       * A ContentViewCore that has some methods stubbed out for testing.
 | 
|       */
 | 
|      private static final class StubbedContentViewCore extends ContentViewCore {
 | 
| @@ -1783,12 +1797,30 @@ public class ContextualSearchManagerTest extends ChromeActivityTestCaseBase<Chro
 | 
|          assertEquals("Intelligence", getSelectedText());
 | 
|  
 | 
|          // Simulate a selection change event and assert that the panel has not reappeared.
 | 
| -        mManager.onSelectionEvent(SelectionEventType.SELECTION_DRAG_STARTED, 333, 450);
 | 
| -        mManager.onSelectionEvent(SelectionEventType.SELECTION_DRAG_STOPPED, 303, 450);
 | 
| +        mManager.onSelectionEvent(SelectionEventType.SELECTION_HANDLE_DRAG_STARTED, 333, 450);
 | 
| +        mManager.onSelectionEvent(SelectionEventType.SELECTION_HANDLE_DRAG_STOPPED, 303, 450);
 | 
|          assertPanelClosedOrUndefined();
 | 
|  
 | 
|          // Select a different word and assert that the panel has appeared.
 | 
|          longPressNode("states-far");
 | 
|          waitForPanelToPeekAndAssert();
 | 
|      }
 | 
| +
 | 
| +    /**
 | 
| +     * Tests a bunch of taps in a row.
 | 
| +     * We've had reliability problems with simple taps due to async clearing
 | 
| +     * of selection bounds, so this helps prevent a regression with that.
 | 
| +     */
 | 
| +    @Restriction({RESTRICTION_TYPE_PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
 | 
| +    @CommandLineFlags.Add({ContextualSearchFieldTrial.TAP_RESOLVE_LIMIT_FOR_DECIDED + "=200",
 | 
| +            ContextualSearchFieldTrial.TAP_RESOLVE_LIMIT_FOR_UNDECIDED + "=200",
 | 
| +            ContextualSearchFieldTrial.TAP_PREFETCH_LIMIT_FOR_DECIDED + "=200",
 | 
| +            ContextualSearchFieldTrial.TAP_PREFETCH_LIMIT_FOR_UNDECIDED + "=200"})
 | 
| +    public void testTapALot() throws InterruptedException, TimeoutException {
 | 
| +        for (int i = 0; i < 50; i++) {
 | 
| +            clickToTriggerSearchTermResolution();
 | 
| +            waitForSelectionDissolved();
 | 
| +            assertSearchTermRequested();
 | 
| +        }
 | 
| +    }
 | 
|  }
 | 
| 
 |