@SmallTest
  @Feature({"AndroidWebView"})
  public void testUiScrollReflectedInJs() throws Throwable {
    final TestAwContentsClient contentsClient = new TestAwContentsClient();
    final ScrollTestContainerView testContainerView =
        (ScrollTestContainerView) createAwTestContainerViewOnMainSync(contentsClient);
    enableJavaScriptOnUiThread(testContainerView.getAwContents());

    final double deviceDIPScale =
        DeviceDisplayInfo.create(testContainerView.getContext()).getDIPScale();
    final int targetScrollXCss = 233;
    final int targetScrollYCss = 322;
    final int targetScrollXPix = (int) Math.ceil(targetScrollXCss * deviceDIPScale);
    final int targetScrollYPix = (int) Math.ceil(targetScrollYCss * deviceDIPScale);
    final JavascriptEventObserver onscrollObserver = new JavascriptEventObserver();

    getInstrumentation()
        .runOnMainSync(
            new Runnable() {
              @Override
              public void run() {
                onscrollObserver.register(
                    testContainerView.getContentViewCore(), "onscrollObserver");
              }
            });

    loadTestPageAndWaitForFirstFrame(testContainerView, contentsClient, "onscrollObserver", "");

    scrollToOnMainSync(testContainerView, targetScrollXPix, targetScrollYPix);

    onscrollObserver.waitForEvent(WAIT_TIMEOUT_MS);
    assertScrollInJs(
        testContainerView.getAwContents(), contentsClient, targetScrollXCss, targetScrollYCss);
  }
  private void loadTestPageAndWaitForFirstFrame(
      final ScrollTestContainerView testContainerView,
      final TestAwContentsClient contentsClient,
      final String onscrollObserverName,
      final String extraContent)
      throws Exception {
    final JavascriptEventObserver firstFrameObserver = new JavascriptEventObserver();
    final String firstFrameObserverName = "firstFrameObserver";
    enableJavaScriptOnUiThread(testContainerView.getAwContents());

    getInstrumentation()
        .runOnMainSync(
            new Runnable() {
              @Override
              public void run() {
                firstFrameObserver.register(
                    testContainerView.getContentViewCore(), firstFrameObserverName);
              }
            });

    loadDataSync(
        testContainerView.getAwContents(),
        contentsClient.getOnPageFinishedHelper(),
        makeTestPage(onscrollObserverName, firstFrameObserverName, extraContent),
        "text/html",
        false);

    // We wait for "a couple" of frames for the active tree in CC to stabilize and for pending
    // tree activations to stop clobbering the root scroll layer's scroll offset. This wait
    // doesn't strictly guarantee that but there isn't a good alternative and this seems to
    // work fine.
    firstFrameObserver.waitForEvent(WAIT_TIMEOUT_MS);
  }