/*
 * Copyright (C) 2010 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "public/web/WebFrame.h"

#include "SkBitmap.h"
#include "SkCanvas.h"
#include "bindings/core/v8/SerializedScriptValueFactory.h"
#include "bindings/core/v8/V8Node.h"
#include "core/clipboard/DataTransfer.h"
#include "core/css/StyleSheetContents.h"
#include "core/css/resolver/StyleResolver.h"
#include "core/css/resolver/ViewportStyleResolver.h"
#include "core/dom/Document.h"
#include "core/dom/Fullscreen.h"
#include "core/dom/NodeComputedStyle.h"
#include "core/dom/Range.h"
#include "core/editing/Editor.h"
#include "core/editing/EphemeralRange.h"
#include "core/editing/FrameSelection.h"
#include "core/editing/VisiblePosition.h"
#include "core/editing/markers/DocumentMarkerController.h"
#include "core/editing/spellcheck/SpellChecker.h"
#include "core/events/MouseEvent.h"
#include "core/fetch/FetchRequest.h"
#include "core/fetch/MemoryCache.h"
#include "core/fetch/ResourceFetcher.h"
#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/RemoteFrame.h"
#include "core/frame/Settings.h"
#include "core/frame/VisualViewport.h"
#include "core/html/HTMLBodyElement.h"
#include "core/html/HTMLFormElement.h"
#include "core/html/HTMLMediaElement.h"
#include "core/html/ImageDocument.h"
#include "core/input/EventHandler.h"
#include "core/layout/HitTestResult.h"
#include "core/layout/LayoutFullScreen.h"
#include "core/layout/api/LayoutViewItem.h"
#include "core/layout/compositing/PaintLayerCompositor.h"
#include "core/loader/DocumentLoader.h"
#include "core/loader/DocumentThreadableLoader.h"
#include "core/loader/DocumentThreadableLoaderClient.h"
#include "core/loader/FrameLoadRequest.h"
#include "core/loader/ThreadableLoader.h"
#include "core/page/Page.h"
#include "core/page/ScopedPageLoadDeferrer.h"
#include "core/paint/PaintLayer.h"
#include "core/testing/NullExecutionContext.h"
#include "modules/mediastream/MediaStream.h"
#include "modules/mediastream/MediaStreamRegistry.h"
#include "platform/DragImage.h"
#include "platform/PlatformResourceLoader.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "platform/UserGestureIndicator.h"
#include "platform/geometry/FloatRect.h"
#include "platform/network/ResourceError.h"
#include "platform/scroll/ScrollbarTheme.h"
#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
#include "platform/testing/URLTestHelpers.h"
#include "platform/testing/UnitTestHelpers.h"
#include "platform/weborigin/KURLHash.h"
#include "platform/weborigin/SchemeRegistry.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "public/platform/Platform.h"
#include "public/platform/WebCachePolicy.h"
#include "public/platform/WebClipboard.h"
#include "public/platform/WebFloatRect.h"
#include "public/platform/WebMockClipboard.h"
#include "public/platform/WebSecurityOrigin.h"
#include "public/platform/WebThread.h"
#include "public/platform/WebURL.h"
#include "public/platform/WebURLLoaderClient.h"
#include "public/platform/WebURLLoaderMockFactory.h"
#include "public/platform/WebURLResponse.h"
#include "public/web/WebCache.h"
#include "public/web/WebConsoleMessage.h"
#include "public/web/WebDataSource.h"
#include "public/web/WebDeviceEmulationParams.h"
#include "public/web/WebDocument.h"
#include "public/web/WebFindOptions.h"
#include "public/web/WebFormElement.h"
#include "public/web/WebFrameClient.h"
#include "public/web/WebFrameContentDumper.h"
#include "public/web/WebFrameWidget.h"
#include "public/web/WebHistoryItem.h"
#include "public/web/WebPrintParams.h"
#include "public/web/WebRange.h"
#include "public/web/WebRemoteFrame.h"
#include "public/web/WebScriptExecutionCallback.h"
#include "public/web/WebScriptSource.h"
#include "public/web/WebSearchableFormData.h"
#include "public/web/WebSecurityPolicy.h"
#include "public/web/WebSelection.h"
#include "public/web/WebSettings.h"
#include "public/web/WebSpellCheckClient.h"
#include "public/web/WebTextCheckingCompletion.h"
#include "public/web/WebTextCheckingResult.h"
#include "public/web/WebViewClient.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "web/TextFinder.h"
#include "web/WebLocalFrameImpl.h"
#include "web/WebRemoteFrameImpl.h"
#include "web/WebViewImpl.h"
#include "web/tests/FrameTestHelpers.h"
#include "wtf/Forward.h"
#include "wtf/PtrUtil.h"
#include "wtf/dtoa/utils.h"
#include <map>
#include <memory>
#include <stdarg.h>
#include <v8.h>

using blink::URLTestHelpers::toKURL;
using blink::testing::runPendingTasks;
using testing::ElementsAre;
using testing::Mock;
using testing::_;

namespace blink {

::std::ostream& operator<<(::std::ostream& os, const WebFloatSize& size) {
  return os << "WebFloatSize: [" << size.width << ", " << size.height << "]";
}

::std::ostream& operator<<(::std::ostream& os, const WebFloatPoint& point) {
  return os << "WebFloatPoint: [" << point.x << ", " << point.y << "]";
}

const int touchPointPadding = 32;

#define EXPECT_RECT_EQ(expected, actual)           \
  do {                                             \
    EXPECT_EQ(expected.x(), actual.x());           \
    EXPECT_EQ(expected.y(), actual.y());           \
    EXPECT_EQ(expected.width(), actual.width());   \
    EXPECT_EQ(expected.height(), actual.height()); \
  } while (false)

#define EXPECT_SIZE_EQ(expected, actual)           \
  do {                                             \
    EXPECT_EQ(expected.width(), actual.width());   \
    EXPECT_EQ(expected.height(), actual.height()); \
  } while (false)

#define EXPECT_FLOAT_POINT_EQ(expected, actual) \
  do {                                          \
    EXPECT_FLOAT_EQ(expected.x(), actual.x());  \
    EXPECT_FLOAT_EQ(expected.y(), actual.y());  \
  } while (false)

class WebFrameTest : public ::testing::Test {
 protected:
  WebFrameTest()
      : m_baseURL("http://internal.test/"),
        m_notBaseURL("http://external.test/"),
        m_chromeURL("chrome://") {}

  ~WebFrameTest() override {
    Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
    WebCache::clear();
  }

  void registerMockedHttpURLLoad(const std::string& fileName) {
    URLTestHelpers::registerMockedURLFromBaseURL(
        WebString::fromUTF8(m_baseURL.c_str()),
        WebString::fromUTF8(fileName.c_str()));
  }

  void registerMockedChromeURLLoad(const std::string& fileName) {
    URLTestHelpers::registerMockedURLFromBaseURL(
        WebString::fromUTF8(m_chromeURL.c_str()),
        WebString::fromUTF8(fileName.c_str()));
  }

  void registerMockedHttpURLLoadWithCSP(const std::string& fileName,
                                        const std::string& csp,
                                        bool reportOnly = false) {
    WebURLResponse response;
    response.setMIMEType("text/html");
    response.addHTTPHeaderField(
        reportOnly ? WebString("Content-Security-Policy-Report-Only")
                   : WebString("Content-Security-Policy"),
        WebString::fromUTF8(csp));
    std::string fullString = m_baseURL + fileName;
    URLTestHelpers::registerMockedURLLoadWithCustomResponse(
        toKURL(fullString.c_str()), WebString::fromUTF8(fileName.c_str()),
        WebString::fromUTF8(""), response);
  }

  void registerMockedHttpURLLoadWithMimeType(const std::string& fileName,
                                             const std::string& mimeType) {
    URLTestHelpers::registerMockedURLFromBaseURL(
        WebString::fromUTF8(m_baseURL.c_str()),
        WebString::fromUTF8(fileName.c_str()), WebString::fromUTF8(mimeType));
  }

  void applyViewportStyleOverride(
      FrameTestHelpers::WebViewHelper* webViewHelper) {
    webViewHelper->webView()->settings()->setViewportStyle(
        WebViewportStyle::Mobile);
  }

  static void configureCompositingWebView(WebSettings* settings) {
    settings->setAcceleratedCompositingEnabled(true);
    settings->setPreferCompositingToLCDTextEnabled(true);
  }

  static void configureAndroid(WebSettings* settings) {
    settings->setViewportMetaEnabled(true);
    settings->setViewportEnabled(true);
    settings->setMainFrameResizesAreOrientationChanges(true);
    settings->setShrinksViewportContentToFit(true);
  }

  static void configureLoadsImagesAutomatically(WebSettings* settings) {
    settings->setLoadsImagesAutomatically(true);
  }

  void initializeTextSelectionWebView(
      const std::string& url,
      FrameTestHelpers::WebViewHelper* webViewHelper) {
    webViewHelper->initializeAndLoad(url, true);
    webViewHelper->webView()->settings()->setDefaultFontSize(12);
    webViewHelper->resize(WebSize(640, 480));
  }

  std::unique_ptr<DragImage> nodeImageTestSetup(
      FrameTestHelpers::WebViewHelper* webViewHelper,
      const std::string& testcase) {
    registerMockedHttpURLLoad("nodeimage.html");
    webViewHelper->initializeAndLoad(m_baseURL + "nodeimage.html");
    webViewHelper->resize(WebSize(640, 480));
    LocalFrame* frame =
        toLocalFrame(webViewHelper->webView()->page()->mainFrame());
    DCHECK(frame);
    Element* element = frame->document()->getElementById(testcase.c_str());
    return frame->nodeImage(*element);
  }

  void removeElementById(WebLocalFrameImpl* frame, const AtomicString& id) {
    Element* element = frame->frame()->document()->getElementById(id);
    DCHECK(element);
    element->remove();
  }

  std::string m_baseURL;
  std::string m_notBaseURL;
  std::string m_chromeURL;
};

typedef bool TestParamRootLayerScrolling;
class ParameterizedWebFrameTest
    : public ::testing::WithParamInterface<TestParamRootLayerScrolling>,
      private ScopedRootLayerScrollingForTest,
      public WebFrameTest {
 public:
  ParameterizedWebFrameTest() : ScopedRootLayerScrollingForTest(GetParam()) {}
};

INSTANTIATE_TEST_CASE_P(All, ParameterizedWebFrameTest, ::testing::Bool());

TEST_P(ParameterizedWebFrameTest, ContentText) {
  registerMockedHttpURLLoad("iframes_test.html");
  registerMockedHttpURLLoad("visible_iframe.html");
  registerMockedHttpURLLoad("invisible_iframe.html");
  registerMockedHttpURLLoad("zero_sized_iframe.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "iframes_test.html");

  // Now retrieve the frames text and test it only includes visible elements.
  std::string content =
      WebFrameContentDumper::dumpWebViewAsText(webViewHelper.webView(), 1024)
          .utf8();
  EXPECT_NE(std::string::npos, content.find(" visible paragraph"));
  EXPECT_NE(std::string::npos, content.find(" visible iframe"));
  EXPECT_EQ(std::string::npos, content.find(" invisible pararaph"));
  EXPECT_EQ(std::string::npos, content.find(" invisible iframe"));
  EXPECT_EQ(std::string::npos, content.find("iframe with zero size"));
}

TEST_P(ParameterizedWebFrameTest, FrameForEnteredContext) {
  registerMockedHttpURLLoad("iframes_test.html");
  registerMockedHttpURLLoad("visible_iframe.html");
  registerMockedHttpURLLoad("invisible_iframe.html");
  registerMockedHttpURLLoad("zero_sized_iframe.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "iframes_test.html", true);

  v8::HandleScope scope(v8::Isolate::GetCurrent());
  EXPECT_EQ(
      webViewHelper.webView()->mainFrame(),
      WebLocalFrame::frameForContext(
          webViewHelper.webView()->mainFrame()->mainWorldScriptContext()));
  EXPECT_EQ(webViewHelper.webView()->mainFrame()->firstChild(),
            WebLocalFrame::frameForContext(webViewHelper.webView()
                                               ->mainFrame()
                                               ->firstChild()
                                               ->mainWorldScriptContext()));
}

class ScriptExecutionCallbackHelper : public WebScriptExecutionCallback {
 public:
  explicit ScriptExecutionCallbackHelper(v8::Local<v8::Context> context)
      : m_didComplete(false), m_context(context) {}
  ~ScriptExecutionCallbackHelper() {}

  bool didComplete() const { return m_didComplete; }
  const String& stringValue() const { return m_stringValue; }

 private:
  void completed(const WebVector<v8::Local<v8::Value>>& values) override {
    m_didComplete = true;
    if (!values.isEmpty() && values[0]->IsString()) {
      m_stringValue =
          toCoreString(values[0]->ToString(m_context).ToLocalChecked());
    }
  }

  bool m_didComplete;
  String m_stringValue;
  v8::Local<v8::Context> m_context;
};

TEST_P(ParameterizedWebFrameTest, RequestExecuteScript) {
  registerMockedHttpURLLoad("foo.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "foo.html", true);

  v8::HandleScope scope(v8::Isolate::GetCurrent());
  ScriptExecutionCallbackHelper callbackHelper(
      webViewHelper.webView()->mainFrame()->mainWorldScriptContext());
  webViewHelper.webView()
      ->mainFrame()
      ->toWebLocalFrame()
      ->requestExecuteScriptAndReturnValue(
          WebScriptSource(WebString("'hello';")), false, &callbackHelper);
  runPendingTasks();
  EXPECT_TRUE(callbackHelper.didComplete());
  EXPECT_EQ("hello", callbackHelper.stringValue());
}

TEST_P(ParameterizedWebFrameTest, SuspendedRequestExecuteScript) {
  registerMockedHttpURLLoad("foo.html");
  registerMockedHttpURLLoad("bar.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "foo.html", true);

  v8::HandleScope scope(v8::Isolate::GetCurrent());
  ScriptExecutionCallbackHelper callbackHelper(
      webViewHelper.webView()->mainFrame()->mainWorldScriptContext());

  // Suspend scheduled tasks so the script doesn't run.
  webViewHelper.webView()
      ->mainFrameImpl()
      ->frame()
      ->document()
      ->suspendScheduledTasks();
  webViewHelper.webView()->mainFrameImpl()->requestExecuteScriptAndReturnValue(
      WebScriptSource(WebString("'hello';")), false, &callbackHelper);
  runPendingTasks();
  EXPECT_FALSE(callbackHelper.didComplete());

  // If the frame navigates, pending scripts should be removed, but the callback
  // should always be ran.
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "bar.html");
  EXPECT_TRUE(callbackHelper.didComplete());
  EXPECT_EQ(String(), callbackHelper.stringValue());
}

TEST_P(ParameterizedWebFrameTest, IframeScriptRemovesSelf) {
  registerMockedHttpURLLoad("single_iframe.html");
  registerMockedHttpURLLoad("visible_iframe.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "single_iframe.html", true);

  v8::HandleScope scope(v8::Isolate::GetCurrent());
  ScriptExecutionCallbackHelper callbackHelper(
      webViewHelper.webView()->mainFrame()->mainWorldScriptContext());
  webViewHelper.webView()
      ->mainFrame()
      ->firstChild()
      ->toWebLocalFrame()
      ->requestExecuteScriptAndReturnValue(
          WebScriptSource(WebString(
              "var iframe = "
              "window.top.document.getElementsByTagName('iframe')[0]; "
              "window.top.document.body.removeChild(iframe); 'hello';")),
          false, &callbackHelper);
  runPendingTasks();
  EXPECT_TRUE(callbackHelper.didComplete());
  EXPECT_EQ(String(), callbackHelper.stringValue());
}

TEST_P(ParameterizedWebFrameTest, FormWithNullFrame) {
  registerMockedHttpURLLoad("form.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "form.html");

  WebVector<WebFormElement> forms;
  webViewHelper.webView()->mainFrame()->document().forms(forms);
  webViewHelper.reset();

  EXPECT_EQ(forms.size(), 1U);

  // This test passes if this doesn't crash.
  WebSearchableFormData searchableDataForm(forms[0]);
}

TEST_P(ParameterizedWebFrameTest, ChromePageJavascript) {
  registerMockedChromeURLLoad("history.html");

  // Pass true to enable JavaScript.
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_chromeURL + "history.html", true);

  // Try to run JS against the chrome-style URL.
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              "javascript:document.body.appendChild(document."
                              "createTextNode('Clobbered'))");

  // Now retrieve the frame's text and ensure it was modified by running
  // javascript.
  std::string content =
      WebFrameContentDumper::dumpWebViewAsText(webViewHelper.webView(), 1024)
          .utf8();
  EXPECT_NE(std::string::npos, content.find("Clobbered"));
}

TEST_P(ParameterizedWebFrameTest, ChromePageNoJavascript) {
  registerMockedChromeURLLoad("history.html");

  /// Pass true to enable JavaScript.
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_chromeURL + "history.html", true);

  // Try to run JS against the chrome-style URL after prohibiting it.
  WebSecurityPolicy::registerURLSchemeAsNotAllowingJavascriptURLs("chrome");
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              "javascript:document.body.appendChild(document."
                              "createTextNode('Clobbered'))");

  // Now retrieve the frame's text and ensure it wasn't modified by running
  // javascript.
  std::string content =
      WebFrameContentDumper::dumpWebViewAsText(webViewHelper.webView(), 1024)
          .utf8();
  EXPECT_EQ(std::string::npos, content.find("Clobbered"));
}

TEST_P(ParameterizedWebFrameTest, LocationSetHostWithMissingPort) {
  std::string fileName = "print-location-href.html";
  registerMockedHttpURLLoad(fileName);
  URLTestHelpers::registerMockedURLLoad(
      toKURL("http://internal.test:0/" + fileName),
      WebString::fromUTF8(fileName));

  FrameTestHelpers::WebViewHelper webViewHelper;

  /// Pass true to enable JavaScript.
  webViewHelper.initializeAndLoad(m_baseURL + fileName, true);

  // Setting host to "hostname:" should be treated as "hostname:0".
  FrameTestHelpers::loadFrame(
      webViewHelper.webView()->mainFrame(),
      "javascript:location.host = 'internal.test:'; void 0;");

  FrameTestHelpers::loadFrame(
      webViewHelper.webView()->mainFrame(),
      "javascript:document.body.textContent = location.href; void 0;");

  std::string content =
      WebFrameContentDumper::dumpWebViewAsText(webViewHelper.webView(), 1024)
          .utf8();
  EXPECT_EQ("http://internal.test:0/" + fileName, content);
}

TEST_P(ParameterizedWebFrameTest, LocationSetEmptyPort) {
  std::string fileName = "print-location-href.html";
  registerMockedHttpURLLoad(fileName);
  URLTestHelpers::registerMockedURLLoad(
      toKURL("http://internal.test:0/" + fileName),
      WebString::fromUTF8(fileName));

  FrameTestHelpers::WebViewHelper webViewHelper;

  /// Pass true to enable JavaScript.
  webViewHelper.initializeAndLoad(m_baseURL + fileName, true);

  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              "javascript:location.port = ''; void 0;");

  FrameTestHelpers::loadFrame(
      webViewHelper.webView()->mainFrame(),
      "javascript:document.body.textContent = location.href; void 0;");

  std::string content =
      WebFrameContentDumper::dumpWebViewAsText(webViewHelper.webView(), 1024)
          .utf8();
  EXPECT_EQ("http://internal.test:0/" + fileName, content);
}

class EvaluateOnLoadWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  EvaluateOnLoadWebFrameClient() : m_executing(false), m_wasExecuted(false) {}

  void didClearWindowObject(WebLocalFrame* frame) override {
    EXPECT_FALSE(m_executing);
    m_wasExecuted = true;
    m_executing = true;
    v8::HandleScope handleScope(v8::Isolate::GetCurrent());
    frame->executeScriptAndReturnValue(
        WebScriptSource(WebString("window.someProperty = 42;")));
    m_executing = false;
  }

  bool m_executing;
  bool m_wasExecuted;
};

TEST_P(ParameterizedWebFrameTest, DidClearWindowObjectIsNotRecursive) {
  EvaluateOnLoadWebFrameClient webFrameClient;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad("about:blank", true, &webFrameClient);
  EXPECT_TRUE(webFrameClient.m_wasExecuted);
}

class CSSCallbackWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
 public:
  CSSCallbackWebFrameClient() : m_updateCount(0) {}
  void didMatchCSS(
      WebLocalFrame*,
      const WebVector<WebString>& newlyMatchingSelectors,
      const WebVector<WebString>& stoppedMatchingSelectors) override;

  std::map<WebLocalFrame*, std::set<std::string>> m_matchedSelectors;
  int m_updateCount;
};

void CSSCallbackWebFrameClient::didMatchCSS(
    WebLocalFrame* frame,
    const WebVector<WebString>& newlyMatchingSelectors,
    const WebVector<WebString>& stoppedMatchingSelectors) {
  ++m_updateCount;
  std::set<std::string>& frameSelectors = m_matchedSelectors[frame];
  for (size_t i = 0; i < newlyMatchingSelectors.size(); ++i) {
    std::string selector = newlyMatchingSelectors[i].utf8();
    EXPECT_EQ(0U, frameSelectors.count(selector)) << selector;
    frameSelectors.insert(selector);
  }
  for (size_t i = 0; i < stoppedMatchingSelectors.size(); ++i) {
    std::string selector = stoppedMatchingSelectors[i].utf8();
    EXPECT_EQ(1U, frameSelectors.count(selector)) << selector;
    frameSelectors.erase(selector);
  }
}

class WebFrameCSSCallbackTest : public ::testing::Test {
 protected:
  WebFrameCSSCallbackTest() {
    m_frame = m_helper.initializeAndLoad("about:blank", true, &m_client)
                  ->mainFrame()
                  ->toWebLocalFrame();
  }

  ~WebFrameCSSCallbackTest() {
    EXPECT_EQ(1U, m_client.m_matchedSelectors.size());
  }

  WebDocument doc() const { return m_frame->document(); }

  int updateCount() const { return m_client.m_updateCount; }

  const std::set<std::string>& matchedSelectors() {
    return m_client.m_matchedSelectors[m_frame];
  }

  void loadHTML(const std::string& html) {
    FrameTestHelpers::loadHTMLString(m_frame, html, toKURL("about:blank"));
  }

  void executeScript(const WebString& code) {
    m_frame->executeScript(WebScriptSource(code));
    m_frame->view()->updateAllLifecyclePhases();
    runPendingTasks();
  }

  CSSCallbackWebFrameClient m_client;
  FrameTestHelpers::WebViewHelper m_helper;
  WebLocalFrame* m_frame;
};

TEST_F(WebFrameCSSCallbackTest, AuthorStyleSheet) {
  loadHTML(
      "<style>"
      // This stylesheet checks that the internal property and value can't be
      // set by a stylesheet, only WebDocument::watchCSSSelectors().
      "div.initial_on { -internal-callback: none; }"
      "div.initial_off { -internal-callback: -internal-presence; }"
      "</style>"
      "<div class=\"initial_on\"></div>"
      "<div class=\"initial_off\"></div>");

  Vector<WebString> selectors;
  selectors.append(WebString::fromUTF8("div.initial_on"));
  m_frame->document().watchCSSSelectors(WebVector<WebString>(selectors));
  m_frame->view()->updateAllLifecyclePhases();
  runPendingTasks();
  EXPECT_EQ(1, updateCount());
  EXPECT_THAT(matchedSelectors(), ElementsAre("div.initial_on"));

  // Check that adding a watched selector calls back for already-present nodes.
  selectors.append(WebString::fromUTF8("div.initial_off"));
  doc().watchCSSSelectors(WebVector<WebString>(selectors));
  m_frame->view()->updateAllLifecyclePhases();
  runPendingTasks();
  EXPECT_EQ(2, updateCount());
  EXPECT_THAT(matchedSelectors(),
              ElementsAre("div.initial_off", "div.initial_on"));

  // Check that we can turn off callbacks for certain selectors.
  doc().watchCSSSelectors(WebVector<WebString>());
  m_frame->view()->updateAllLifecyclePhases();
  runPendingTasks();
  EXPECT_EQ(3, updateCount());
  EXPECT_THAT(matchedSelectors(), ElementsAre());
}

TEST_F(WebFrameCSSCallbackTest, SharedComputedStyle) {
  // Check that adding an element calls back when it matches an existing rule.
  Vector<WebString> selectors;
  selectors.append(WebString::fromUTF8("span"));
  doc().watchCSSSelectors(WebVector<WebString>(selectors));

  executeScript(
      "i1 = document.createElement('span');"
      "i1.id = 'first_span';"
      "document.body.appendChild(i1)");
  EXPECT_EQ(1, updateCount());
  EXPECT_THAT(matchedSelectors(), ElementsAre("span"));

  // Adding a second element that shares a ComputedStyle shouldn't call back.
  // We use <span>s to avoid default style rules that can set
  // ComputedStyle::unique().
  executeScript(
      "i2 = document.createElement('span');"
      "i2.id = 'second_span';"
      "i1 = document.getElementById('first_span');"
      "i1.parentNode.insertBefore(i2, i1.nextSibling);");
  EXPECT_EQ(1, updateCount());
  EXPECT_THAT(matchedSelectors(), ElementsAre("span"));

  // Removing the first element shouldn't call back.
  executeScript(
      "i1 = document.getElementById('first_span');"
      "i1.parentNode.removeChild(i1);");
  EXPECT_EQ(1, updateCount());
  EXPECT_THAT(matchedSelectors(), ElementsAre("span"));

  // But removing the second element *should* call back.
  executeScript(
      "i2 = document.getElementById('second_span');"
      "i2.parentNode.removeChild(i2);");
  EXPECT_EQ(2, updateCount());
  EXPECT_THAT(matchedSelectors(), ElementsAre());
}

TEST_F(WebFrameCSSCallbackTest, CatchesAttributeChange) {
  loadHTML("<span></span>");

  Vector<WebString> selectors;
  selectors.append(WebString::fromUTF8("span[attr=\"value\"]"));
  doc().watchCSSSelectors(WebVector<WebString>(selectors));
  runPendingTasks();

  EXPECT_EQ(0, updateCount());
  EXPECT_THAT(matchedSelectors(), ElementsAre());

  executeScript(
      "document.querySelector('span').setAttribute('attr', 'value');");
  EXPECT_EQ(1, updateCount());
  EXPECT_THAT(matchedSelectors(), ElementsAre("span[attr=\"value\"]"));
}

TEST_F(WebFrameCSSCallbackTest, DisplayNone) {
  loadHTML("<div style='display:none'><span></span></div>");

  Vector<WebString> selectors;
  selectors.append(WebString::fromUTF8("span"));
  doc().watchCSSSelectors(WebVector<WebString>(selectors));
  runPendingTasks();

  EXPECT_EQ(0, updateCount()) << "Don't match elements in display:none trees.";

  executeScript(
      "d = document.querySelector('div');"
      "d.style.display = 'block';");
  EXPECT_EQ(1, updateCount()) << "Match elements when they become displayed.";
  EXPECT_THAT(matchedSelectors(), ElementsAre("span"));

  executeScript(
      "d = document.querySelector('div');"
      "d.style.display = 'none';");
  EXPECT_EQ(2, updateCount())
      << "Unmatch elements when they become undisplayed.";
  EXPECT_THAT(matchedSelectors(), ElementsAre());

  executeScript(
      "s = document.querySelector('span');"
      "s.style.display = 'none';");
  EXPECT_EQ(2, updateCount())
      << "No effect from no-display'ing a span that's already undisplayed.";

  executeScript(
      "d = document.querySelector('div');"
      "d.style.display = 'block';");
  EXPECT_EQ(2, updateCount())
      << "No effect from displaying a div whose span is display:none.";

  executeScript(
      "s = document.querySelector('span');"
      "s.style.display = 'inline';");
  EXPECT_EQ(3, updateCount())
      << "Now the span is visible and produces a callback.";
  EXPECT_THAT(matchedSelectors(), ElementsAre("span"));

  executeScript(
      "s = document.querySelector('span');"
      "s.style.display = 'none';");
  EXPECT_EQ(4, updateCount())
      << "Undisplaying the span directly should produce another callback.";
  EXPECT_THAT(matchedSelectors(), ElementsAre());
}

TEST_F(WebFrameCSSCallbackTest, Reparenting) {
  loadHTML(
      "<div id='d1'><span></span></div>"
      "<div id='d2'></div>");

  Vector<WebString> selectors;
  selectors.append(WebString::fromUTF8("span"));
  doc().watchCSSSelectors(WebVector<WebString>(selectors));
  m_frame->view()->updateAllLifecyclePhases();
  runPendingTasks();

  EXPECT_EQ(1, updateCount());
  EXPECT_THAT(matchedSelectors(), ElementsAre("span"));

  executeScript(
      "s = document.querySelector('span');"
      "d2 = document.getElementById('d2');"
      "d2.appendChild(s);");
  EXPECT_EQ(1, updateCount()) << "Just moving an element that continues to "
                                 "match shouldn't send a spurious callback.";
  EXPECT_THAT(matchedSelectors(), ElementsAre("span"));
}

TEST_F(WebFrameCSSCallbackTest, MultiSelector) {
  loadHTML("<span></span>");

  // Check that selector lists match as the whole list, not as each element
  // independently.
  Vector<WebString> selectors;
  selectors.append(WebString::fromUTF8("span"));
  selectors.append(WebString::fromUTF8("span,p"));
  doc().watchCSSSelectors(WebVector<WebString>(selectors));
  m_frame->view()->updateAllLifecyclePhases();
  runPendingTasks();

  EXPECT_EQ(1, updateCount());
  EXPECT_THAT(matchedSelectors(), ElementsAre("span", "span, p"));
}

TEST_F(WebFrameCSSCallbackTest, InvalidSelector) {
  loadHTML("<p><span></span></p>");

  // Build a list with one valid selector and one invalid.
  Vector<WebString> selectors;
  selectors.append(WebString::fromUTF8("span"));
  selectors.append(WebString::fromUTF8("["));       // Invalid.
  selectors.append(WebString::fromUTF8("p span"));  // Not compound.
  doc().watchCSSSelectors(WebVector<WebString>(selectors));
  m_frame->view()->updateAllLifecyclePhases();
  runPendingTasks();

  EXPECT_EQ(1, updateCount());
  EXPECT_THAT(matchedSelectors(), ElementsAre("span"))
      << "An invalid selector shouldn't prevent other selectors from matching.";
}

TEST_P(ParameterizedWebFrameTest, DispatchMessageEventWithOriginCheck) {
  registerMockedHttpURLLoad("postmessage_test.html");

  // Pass true to enable JavaScript.
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "postmessage_test.html", true);

  // Send a message with the correct origin.
  WebSecurityOrigin correctOrigin(WebSecurityOrigin::create(toKURL(m_baseURL)));
  WebDocument document = webViewHelper.webView()->mainFrame()->document();
  WebSerializedScriptValue data(WebSerializedScriptValue::fromString("foo"));
  WebDOMMessageEvent message(data, "http://origin.com");
  webViewHelper.webView()->mainFrame()->dispatchMessageEventWithOriginCheck(
      correctOrigin, message);

  // Send another message with incorrect origin.
  WebSecurityOrigin incorrectOrigin(
      WebSecurityOrigin::create(toKURL(m_chromeURL)));
  webViewHelper.webView()->mainFrame()->dispatchMessageEventWithOriginCheck(
      incorrectOrigin, message);

  // Verify that only the first addition is in the body of the page.
  std::string content =
      WebFrameContentDumper::dumpWebViewAsText(webViewHelper.webView(), 1024)
          .utf8();
  EXPECT_NE(std::string::npos, content.find("Message 1."));
  EXPECT_EQ(std::string::npos, content.find("Message 2."));
}

TEST_P(ParameterizedWebFrameTest, PostMessageThenDetach) {
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad("about:blank");

  LocalFrame* frame =
      toLocalFrame(webViewHelper.webView()->page()->mainFrame());
  NonThrowableExceptionState exceptionState;
  MessagePortArray messagePorts;
  frame->domWindow()->postMessage(SerializedScriptValue::serialize("message"),
                                  messagePorts, "*", frame->localDOMWindow(),
                                  exceptionState);
  webViewHelper.reset();
  EXPECT_FALSE(exceptionState.hadException());

  // Success is not crashing.
  runPendingTasks();
}

namespace {

class FixedLayoutTestWebViewClient
    : public FrameTestHelpers::TestWebViewClient {
 public:
  WebScreenInfo screenInfo() override { return m_screenInfo; }

  WebScreenInfo m_screenInfo;
};

class FakeCompositingWebViewClient : public FixedLayoutTestWebViewClient {};

// Viewport settings need to be set before the page gets loaded
void enableViewportSettings(WebSettings* settings) {
  settings->setViewportMetaEnabled(true);
  settings->setViewportEnabled(true);
  settings->setMainFrameResizesAreOrientationChanges(true);
  settings->setShrinksViewportContentToFit(true);
}

// Helper function to set autosizing multipliers on a document.
bool setTextAutosizingMultiplier(Document* document, float multiplier) {
  bool multiplierSet = false;
  for (LayoutItem layoutItem = document->layoutViewItem(); !layoutItem.isNull();
       layoutItem = layoutItem.nextInPreOrder()) {
    if (layoutItem.style()) {
      layoutItem.mutableStyleRef().setTextAutosizingMultiplier(multiplier);

      EXPECT_EQ(multiplier, layoutItem.style()->textAutosizingMultiplier());
      multiplierSet = true;
    }
  }
  return multiplierSet;
}

// Helper function to check autosizing multipliers on a document.
bool checkTextAutosizingMultiplier(Document* document, float multiplier) {
  bool multiplierChecked = false;
  for (LayoutItem layoutItem = document->layoutViewItem(); !layoutItem.isNull();
       layoutItem = layoutItem.nextInPreOrder()) {
    if (layoutItem.style() && layoutItem.isText()) {
      EXPECT_EQ(multiplier, layoutItem.style()->textAutosizingMultiplier());
      multiplierChecked = true;
    }
  }
  return multiplierChecked;
}

}  // anonymous namespace

TEST_P(ParameterizedWebFrameTest,
       ChangeInFixedLayoutResetsTextAutosizingMultipliers) {
  registerMockedHttpURLLoad("fixed_layout.html");

  FixedLayoutTestWebViewClient client;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true,
                                  nullptr, &client, nullptr,
                                  enableViewportSettings);

  Document* document =
      toLocalFrame(webViewHelper.webView()->page()->mainFrame())->document();
  document->settings()->setTextAutosizingEnabled(true);
  EXPECT_TRUE(document->settings()->textAutosizingEnabled());
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_TRUE(setTextAutosizingMultiplier(document, 2));

  ViewportDescription description = document->viewportDescription();
  // Choose a width that's not going match the viewport width of the loaded
  // document.
  description.minWidth = Length(100, blink::Fixed);
  description.maxWidth = Length(100, blink::Fixed);
  webViewHelper.webView()->updatePageDefinedViewportConstraints(description);

  EXPECT_TRUE(checkTextAutosizingMultiplier(document, 1));
}

TEST_P(ParameterizedWebFrameTest,
       WorkingTextAutosizingMultipliers_VirtualViewport) {
  const std::string htmlFile = "fixed_layout.html";
  registerMockedHttpURLLoad(htmlFile);

  FixedLayoutTestWebViewClient client;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, nullptr, &client,
                                  nullptr, configureAndroid);

  Document* document =
      toLocalFrame(webViewHelper.webView()->page()->mainFrame())->document();
  document->settings()->setTextAutosizingEnabled(true);
  EXPECT_TRUE(document->settings()->textAutosizingEnabled());

  webViewHelper.resize(WebSize(490, 800));

  // Multiplier: 980 / 490 = 2.0
  EXPECT_TRUE(checkTextAutosizingMultiplier(document, 2.0));
}

TEST_P(ParameterizedWebFrameTest,
       VisualViewportSetSizeInvalidatesTextAutosizingMultipliers) {
  registerMockedHttpURLLoad("iframe_reload.html");
  registerMockedHttpURLLoad("visible_iframe.html");

  FixedLayoutTestWebViewClient client;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "iframe_reload.html", true,
                                  nullptr, &client, nullptr,
                                  enableViewportSettings);

  LocalFrame* mainFrame =
      toLocalFrame(webViewHelper.webView()->page()->mainFrame());
  Document* document = mainFrame->document();
  FrameView* frameView = webViewHelper.webView()->mainFrameImpl()->frameView();
  document->settings()->setTextAutosizingEnabled(true);
  EXPECT_TRUE(document->settings()->textAutosizingEnabled());
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  for (Frame* frame = mainFrame; frame; frame = frame->tree().traverseNext()) {
    if (!frame->isLocalFrame())
      continue;
    EXPECT_TRUE(
        setTextAutosizingMultiplier(toLocalFrame(frame)->document(), 2));
    for (LayoutItem layoutItem =
             toLocalFrame(frame)->document()->layoutViewItem();
         !layoutItem.isNull(); layoutItem = layoutItem.nextInPreOrder()) {
      if (layoutItem.isText())
        EXPECT_FALSE(layoutItem.needsLayout());
    }
  }

  frameView->page()->frameHost().visualViewport().setSize(IntSize(200, 200));

  for (Frame* frame = mainFrame; frame; frame = frame->tree().traverseNext()) {
    if (!frame->isLocalFrame())
      continue;
    for (LayoutItem layoutItem =
             toLocalFrame(frame)->document()->layoutViewItem();
         !layoutItem.isNull(); layoutItem = layoutItem.nextInPreOrder()) {
      if (layoutItem.isText())
        EXPECT_TRUE(layoutItem.needsLayout());
    }
  }
}

TEST_P(ParameterizedWebFrameTest, ZeroHeightPositiveWidthNotIgnored) {
  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 1280;
  int viewportHeight = 0;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, nullptr, &client, nullptr,
                           enableViewportSettings);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_EQ(viewportWidth, webViewHelper.webView()
                               ->mainFrameImpl()
                               ->frameView()
                               ->layoutSize()
                               .width());
  EXPECT_EQ(viewportHeight, webViewHelper.webView()
                                ->mainFrameImpl()
                                ->frameView()
                                ->layoutSize()
                                .height());
}

TEST_P(ParameterizedWebFrameTest,
       DeviceScaleFactorUsesDefaultWithoutViewportTag) {
  registerMockedHttpURLLoad("no_viewport_tag.html");

  int viewportWidth = 640;
  int viewportHeight = 480;

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 2;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true,
                                  nullptr, &client, nullptr,
                                  enableViewportSettings);

  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_EQ(2, webViewHelper.webView()->page()->deviceScaleFactor());

  // Device scale factor should be independent of page scale.
  webViewHelper.webView()->setDefaultPageScaleLimits(1, 2);
  webViewHelper.webView()->setPageScaleFactor(0.5);
  webViewHelper.webView()->updateAllLifecyclePhases();
  EXPECT_EQ(1, webViewHelper.webView()->pageScaleFactor());

  // Force the layout to happen before leaving the test.
  webViewHelper.webView()->updateAllLifecyclePhases();
}

TEST_P(ParameterizedWebFrameTest, FixedLayoutInitializeAtMinimumScale) {
  registerMockedHttpURLLoad("fixed_layout.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  // Make sure we initialize to minimum scale, even if the window size
  // only becomes available after the load begins.
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, nullptr, &client, nullptr,
                           enableViewportSettings);
  webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 5);
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "fixed_layout.html");
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  int defaultFixedLayoutWidth = 980;
  float minimumPageScaleFactor = viewportWidth / (float)defaultFixedLayoutWidth;
  EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
  EXPECT_EQ(minimumPageScaleFactor,
            webViewHelper.webView()->minimumPageScaleFactor());

  // Assume the user has pinch zoomed to page scale factor 2.
  float userPinchPageScaleFactor = 2;
  webViewHelper.webView()->setPageScaleFactor(userPinchPageScaleFactor);
  webViewHelper.webView()->updateAllLifecyclePhases();

  // Make sure we don't reset to initial scale if the page continues to load.
  webViewHelper.webView()->didCommitLoad(false, false);
  webViewHelper.webView()->didChangeContentsSize();
  EXPECT_EQ(userPinchPageScaleFactor,
            webViewHelper.webView()->pageScaleFactor());

  // Make sure we don't reset to initial scale if the viewport size changes.
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight + 100));
  EXPECT_EQ(userPinchPageScaleFactor,
            webViewHelper.webView()->pageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest, WideDocumentInitializeAtMinimumScale) {
  registerMockedHttpURLLoad("wide_document.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  // Make sure we initialize to minimum scale, even if the window size
  // only becomes available after the load begins.
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, nullptr, &client, nullptr,
                           enableViewportSettings);
  webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 5);
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "wide_document.html");
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  int wideDocumentWidth = 1500;
  float minimumPageScaleFactor = viewportWidth / (float)wideDocumentWidth;
  EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
  EXPECT_EQ(minimumPageScaleFactor,
            webViewHelper.webView()->minimumPageScaleFactor());

  // Assume the user has pinch zoomed to page scale factor 2.
  float userPinchPageScaleFactor = 2;
  webViewHelper.webView()->setPageScaleFactor(userPinchPageScaleFactor);
  webViewHelper.webView()->updateAllLifecyclePhases();

  // Make sure we don't reset to initial scale if the page continues to load.
  webViewHelper.webView()->didCommitLoad(false, false);
  webViewHelper.webView()->didChangeContentsSize();
  EXPECT_EQ(userPinchPageScaleFactor,
            webViewHelper.webView()->pageScaleFactor());

  // Make sure we don't reset to initial scale if the viewport size changes.
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight + 100));
  EXPECT_EQ(userPinchPageScaleFactor,
            webViewHelper.webView()->pageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest, DelayedViewportInitialScale) {
  registerMockedHttpURLLoad("viewport-auto-initial-scale.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "viewport-auto-initial-scale.html", true, nullptr, &client,
      nullptr, enableViewportSettings);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_EQ(0.25f, webViewHelper.webView()->pageScaleFactor());

  Document* document =
      toLocalFrame(webViewHelper.webView()->page()->mainFrame())->document();
  ViewportDescription description = document->viewportDescription();
  description.zoom = 2;
  document->setViewportDescription(description);
  webViewHelper.webView()->updateAllLifecyclePhases();
  EXPECT_EQ(2, webViewHelper.webView()->pageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest, setLoadWithOverviewModeToFalse) {
  registerMockedHttpURLLoad("viewport-auto-initial-scale.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "viewport-auto-initial-scale.html", true, nullptr, &client,
      nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  // The page must be displayed at 100% zoom.
  EXPECT_EQ(1.0f, webViewHelper.webView()->pageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest,
       SetLoadWithOverviewModeToFalseAndNoWideViewport) {
  registerMockedHttpURLLoad("large-div.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, nullptr,
                                  &client, nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(false);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  // The page must be displayed at 100% zoom, despite that it hosts a wide div
  // element.
  EXPECT_EQ(1.0f, webViewHelper.webView()->pageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest, NoWideViewportIgnoresPageViewportWidth) {
  registerMockedHttpURLLoad("viewport-auto-initial-scale.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "viewport-auto-initial-scale.html", true, nullptr, &client,
      nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(false);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  // The page sets viewport width to 3000, but with UseWideViewport == false is
  // must be ignored.
  EXPECT_EQ(viewportWidth, webViewHelper.webView()
                               ->mainFrameImpl()
                               ->frameView()
                               ->contentsSize()
                               .width());
  EXPECT_EQ(viewportHeight, webViewHelper.webView()
                                ->mainFrameImpl()
                                ->frameView()
                                ->contentsSize()
                                .height());
}

TEST_P(ParameterizedWebFrameTest,
       NoWideViewportIgnoresPageViewportWidthButAccountsScale) {
  registerMockedHttpURLLoad("viewport-wide-2x-initial-scale.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "viewport-wide-2x-initial-scale.html", true, nullptr, &client,
      nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(false);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  // The page sets viewport width to 3000, but with UseWideViewport == false it
  // must be ignored while the initial scale specified by the page must be
  // accounted.
  EXPECT_EQ(viewportWidth / 2, webViewHelper.webView()
                                   ->mainFrameImpl()
                                   ->frameView()
                                   ->contentsSize()
                                   .width());
  EXPECT_EQ(viewportHeight / 2, webViewHelper.webView()
                                    ->mainFrameImpl()
                                    ->frameView()
                                    ->contentsSize()
                                    .height());
}

TEST_P(ParameterizedWebFrameTest, WideViewportSetsTo980WithoutViewportTag) {
  registerMockedHttpURLLoad("no_viewport_tag.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true,
                                  nullptr, &client, nullptr,
                                  enableViewportSettings);
  applyViewportStyleOverride(&webViewHelper);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(true);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_EQ(980, webViewHelper.webView()
                     ->mainFrameImpl()
                     ->frameView()
                     ->contentsSize()
                     .width());
  EXPECT_EQ(980.0 / viewportWidth * viewportHeight, webViewHelper.webView()
                                                        ->mainFrameImpl()
                                                        ->frameView()
                                                        ->contentsSize()
                                                        .height());
}

TEST_P(ParameterizedWebFrameTest, WideViewportSetsTo980WithXhtmlMp) {
  registerMockedHttpURLLoad("viewport/viewport-legacy-xhtmlmp.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, nullptr, &client, nullptr,
                           enableViewportSettings);
  applyViewportStyleOverride(&webViewHelper);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(true);
  FrameTestHelpers::loadFrame(
      webViewHelper.webView()->mainFrame(),
      m_baseURL + "viewport/viewport-legacy-xhtmlmp.html");

  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  EXPECT_EQ(viewportWidth, webViewHelper.webView()
                               ->mainFrameImpl()
                               ->frameView()
                               ->contentsSize()
                               .width());
  EXPECT_EQ(viewportHeight, webViewHelper.webView()
                                ->mainFrameImpl()
                                ->frameView()
                                ->contentsSize()
                                .height());
}

TEST_P(ParameterizedWebFrameTest, NoWideViewportAndHeightInMeta) {
  registerMockedHttpURLLoad("viewport-height-1000.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "viewport-height-1000.html", true,
                                  nullptr, &client, nullptr,
                                  enableViewportSettings);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(false);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_EQ(viewportWidth, webViewHelper.webView()
                               ->mainFrameImpl()
                               ->frameView()
                               ->contentsSize()
                               .width());
}

TEST_P(ParameterizedWebFrameTest, WideViewportSetsTo980WithAutoWidth) {
  registerMockedHttpURLLoad("viewport-2x-initial-scale.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "viewport-2x-initial-scale.html",
                                  true, nullptr, &client, nullptr,
                                  enableViewportSettings);
  applyViewportStyleOverride(&webViewHelper);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(true);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_EQ(980, webViewHelper.webView()
                     ->mainFrameImpl()
                     ->frameView()
                     ->contentsSize()
                     .width());
  EXPECT_EQ(980.0 / viewportWidth * viewportHeight, webViewHelper.webView()
                                                        ->mainFrameImpl()
                                                        ->frameView()
                                                        ->contentsSize()
                                                        .height());
}

TEST_P(ParameterizedWebFrameTest,
       PageViewportInitialScaleOverridesLoadWithOverviewMode) {
  registerMockedHttpURLLoad("viewport-wide-2x-initial-scale.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "viewport-wide-2x-initial-scale.html", true, nullptr, &client,
      nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  // The page must be displayed at 200% zoom, as specified in its viewport meta
  // tag.
  EXPECT_EQ(2.0f, webViewHelper.webView()->pageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest, setInitialPageScaleFactorPermanently) {
  registerMockedHttpURLLoad("fixed_layout.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  float enforcedPageScaleFactor = 2.0f;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true,
                                  nullptr, &client, nullptr,
                                  enableViewportSettings);
  applyViewportStyleOverride(&webViewHelper);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
  webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
  webViewHelper.webView()->updateAllLifecyclePhases();

  EXPECT_EQ(enforcedPageScaleFactor,
            webViewHelper.webView()->pageScaleFactor());

  int viewportWidth = 640;
  int viewportHeight = 480;
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_EQ(enforcedPageScaleFactor,
            webViewHelper.webView()->pageScaleFactor());

  webViewHelper.webView()->setInitialPageScaleOverride(-1);
  webViewHelper.webView()->updateAllLifecyclePhases();
  EXPECT_EQ(1.0, webViewHelper.webView()->pageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest,
       PermanentInitialPageScaleFactorOverridesLoadWithOverviewMode) {
  registerMockedHttpURLLoad("viewport-auto-initial-scale.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;
  float enforcedPageScaleFactor = 0.5f;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "viewport-auto-initial-scale.html", true, nullptr, &client,
      nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
  webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_EQ(enforcedPageScaleFactor,
            webViewHelper.webView()->pageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest,
       PermanentInitialPageScaleFactorOverridesPageViewportInitialScale) {
  registerMockedHttpURLLoad("viewport-wide-2x-initial-scale.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;
  float enforcedPageScaleFactor = 0.5f;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "viewport-wide-2x-initial-scale.html", true, nullptr, &client,
      nullptr, enableViewportSettings);
  webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_EQ(enforcedPageScaleFactor,
            webViewHelper.webView()->pageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest,
       SmallPermanentInitialPageScaleFactorIsClobbered) {
  const char* pages[] = {
      // These pages trigger the clobbering condition. There must be a matching
      // item in "pageScaleFactors" array.
      "viewport-device-0.5x-initial-scale.html",
      "viewport-initial-scale-1.html",
      // These ones do not.
      "viewport-auto-initial-scale.html",
      "viewport-target-densitydpi-device-and-fixed-width.html"};
  float pageScaleFactors[] = {0.5f, 1.0f};
  for (size_t i = 0; i < WTF_ARRAY_LENGTH(pages); ++i)
    registerMockedHttpURLLoad(pages[i]);

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 400;
  int viewportHeight = 300;
  float enforcedPageScaleFactor = 0.75f;

  for (size_t i = 0; i < WTF_ARRAY_LENGTH(pages); ++i) {
    for (int quirkEnabled = 0; quirkEnabled <= 1; ++quirkEnabled) {
      FrameTestHelpers::WebViewHelper webViewHelper;
      webViewHelper.initializeAndLoad(m_baseURL + pages[i], true, nullptr,
                                      &client, nullptr, enableViewportSettings);
      applyViewportStyleOverride(&webViewHelper);
      webViewHelper.webView()->settings()->setClobberUserAgentInitialScaleQuirk(
          quirkEnabled);
      webViewHelper.webView()->setInitialPageScaleOverride(
          enforcedPageScaleFactor);
      webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

      float expectedPageScaleFactor =
          quirkEnabled && i < WTF_ARRAY_LENGTH(pageScaleFactors)
              ? pageScaleFactors[i]
              : enforcedPageScaleFactor;
      EXPECT_EQ(expectedPageScaleFactor,
                webViewHelper.webView()->pageScaleFactor());
    }
  }
}

TEST_P(ParameterizedWebFrameTest,
       PermanentInitialPageScaleFactorAffectsLayoutWidth) {
  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;
  float enforcedPageScaleFactor = 0.5;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad("about:blank", true, nullptr, &client,
                                  nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(false);
  webViewHelper.webView()->settings()->setLoadWithOverviewMode(false);
  webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_EQ(viewportWidth / enforcedPageScaleFactor, webViewHelper.webView()
                                                         ->mainFrameImpl()
                                                         ->frameView()
                                                         ->contentsSize()
                                                         .width());
  EXPECT_EQ(enforcedPageScaleFactor,
            webViewHelper.webView()->pageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest,
       DocumentElementClientHeightWorksWithWrapContentMode) {
  registerMockedHttpURLLoad("0-by-0.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;

  webViewHelper.initializeAndLoad(m_baseURL + "0-by-0.html", true, nullptr,
                                  &client, nullptr, configureAndroid);
  webViewHelper.webView()->settings()->setForceZeroLayoutHeight(true);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  LocalFrame* frame = webViewHelper.webView()->mainFrameImpl()->frame();
  Document* document = frame->document();
  EXPECT_EQ(viewportHeight, document->documentElement()->clientHeight());
  EXPECT_EQ(viewportWidth, document->documentElement()->clientWidth());
}

TEST_P(ParameterizedWebFrameTest,
       SetForceZeroLayoutHeightWorksWithWrapContentMode) {
  registerMockedHttpURLLoad("0-by-0.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;

  webViewHelper.initializeAndLoad(m_baseURL + "0-by-0.html", true, nullptr,
                                  &client, nullptr, configureAndroid);
  webViewHelper.webView()->settings()->setForceZeroLayoutHeight(true);
  PaintLayerCompositor* compositor = webViewHelper.webView()->compositor();
  EXPECT_EQ(0, webViewHelper.webView()
                   ->mainFrameImpl()
                   ->frameView()
                   ->layoutSize()
                   .width());
  EXPECT_EQ(0, webViewHelper.webView()
                   ->mainFrameImpl()
                   ->frameView()
                   ->layoutSize()
                   .height());
  EXPECT_EQ(0.0, compositor->containerLayer()->size().width());
  EXPECT_EQ(0.0, compositor->containerLayer()->size().height());

  webViewHelper.resize(WebSize(viewportWidth, 0));
  EXPECT_EQ(viewportWidth, webViewHelper.webView()
                               ->mainFrameImpl()
                               ->frameView()
                               ->layoutSize()
                               .width());
  EXPECT_EQ(0, webViewHelper.webView()
                   ->mainFrameImpl()
                   ->frameView()
                   ->layoutSize()
                   .height());
  EXPECT_EQ(viewportWidth, compositor->containerLayer()->size().width());
  EXPECT_EQ(0.0, compositor->containerLayer()->size().height());

  // The flag ForceZeroLayoutHeight will cause the following resize of viewport
  // height to be ignored by the outer viewport (the container layer of
  // LayerCompositor). The height of the visualViewport, however, is not
  // affected.
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  EXPECT_FALSE(
      webViewHelper.webView()->mainFrameImpl()->frameView()->needsLayout());
  EXPECT_EQ(viewportWidth, webViewHelper.webView()
                               ->mainFrameImpl()
                               ->frameView()
                               ->layoutSize()
                               .width());
  EXPECT_EQ(0, webViewHelper.webView()
                   ->mainFrameImpl()
                   ->frameView()
                   ->layoutSize()
                   .height());
  EXPECT_EQ(viewportWidth, compositor->containerLayer()->size().width());
  EXPECT_EQ(viewportHeight, compositor->containerLayer()->size().height());

  LocalFrame* frame = webViewHelper.webView()->mainFrameImpl()->frame();
  VisualViewport& visualViewport = frame->page()->frameHost().visualViewport();
  EXPECT_EQ(viewportHeight, visualViewport.containerLayer()->size().height());
  EXPECT_TRUE(
      visualViewport.containerLayer()->platformLayer()->masksToBounds());
  EXPECT_FALSE(compositor->containerLayer()->platformLayer()->masksToBounds());
}

TEST_P(ParameterizedWebFrameTest, SetForceZeroLayoutHeight) {
  registerMockedHttpURLLoad("200-by-300.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;

  webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html", true, nullptr,
                                  &client, nullptr, enableViewportSettings);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_LE(viewportHeight, webViewHelper.webView()
                                ->mainFrameImpl()
                                ->frameView()
                                ->layoutSize()
                                .height());
  webViewHelper.webView()->settings()->setForceZeroLayoutHeight(true);
  EXPECT_TRUE(
      webViewHelper.webView()->mainFrameImpl()->frameView()->needsLayout());

  EXPECT_EQ(0, webViewHelper.webView()
                   ->mainFrameImpl()
                   ->frameView()
                   ->layoutSize()
                   .height());

  webViewHelper.resize(WebSize(viewportWidth, viewportHeight * 2));
  EXPECT_FALSE(
      webViewHelper.webView()->mainFrameImpl()->frameView()->needsLayout());
  EXPECT_EQ(0, webViewHelper.webView()
                   ->mainFrameImpl()
                   ->frameView()
                   ->layoutSize()
                   .height());

  webViewHelper.resize(WebSize(viewportWidth * 2, viewportHeight));
  EXPECT_EQ(0, webViewHelper.webView()
                   ->mainFrameImpl()
                   ->frameView()
                   ->layoutSize()
                   .height());

  webViewHelper.webView()->settings()->setForceZeroLayoutHeight(false);
  EXPECT_LE(viewportHeight, webViewHelper.webView()
                                ->mainFrameImpl()
                                ->frameView()
                                ->layoutSize()
                                .height());
}

TEST_F(WebFrameTest, ToggleViewportMetaOnOff) {
  registerMockedHttpURLLoad("viewport-device-width.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "viewport-device-width.html",
                                  true, 0, &client);
  WebSettings* settings = webViewHelper.webView()->settings();
  settings->setViewportMetaEnabled(false);
  settings->setViewportEnabled(true);
  settings->setMainFrameResizesAreOrientationChanges(true);
  settings->setShrinksViewportContentToFit(true);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  Document* document =
      toLocalFrame(webViewHelper.webView()->page()->mainFrame())->document();
  EXPECT_FALSE(document->viewportDescription().isLegacyViewportType());

  settings->setViewportMetaEnabled(true);
  EXPECT_TRUE(document->viewportDescription().isLegacyViewportType());

  settings->setViewportMetaEnabled(false);
  EXPECT_FALSE(document->viewportDescription().isLegacyViewportType());
}

TEST_F(WebFrameTest,
       SetForceZeroLayoutHeightWorksWithRelayoutsWhenHeightChanged) {
  // this unit test is an attempt to target a real world case where an app could
  // 1. call resize(width, 0) and setForceZeroLayoutHeight(true)
  // 2. load content (hoping that the viewport height would increase
  // as more content is added)
  // 3. fail to register touch events aimed at the loaded content
  // because the layout is only updated if either width or height is changed
  registerMockedHttpURLLoad("button.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;

  webViewHelper.initializeAndLoad(m_baseURL + "button.html", true, nullptr,
                                  &client, nullptr, configureAndroid);
  // set view height to zero so that if the height of the view is not
  // successfully updated during later resizes touch events will fail
  // (as in not hit content included in the view)
  webViewHelper.resize(WebSize(viewportWidth, 0));

  webViewHelper.webView()->settings()->setForceZeroLayoutHeight(true);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  IntPoint hitPoint = IntPoint(30, 30);  // button size is 100x100

  WebLocalFrameImpl* frame = webViewHelper.webView()->mainFrameImpl();
  Document* document = frame->frame()->document();
  Element* element = document->getElementById("tap_button");

  ASSERT_NE(nullptr, element);
  EXPECT_EQ(String("oldValue"), element->innerText());

  PlatformGestureEvent gestureEvent(
      PlatformEvent::EventType::GestureTap, hitPoint, hitPoint, IntSize(0, 0),
      0, PlatformEvent::NoModifiers, PlatformGestureSourceTouchscreen);
  webViewHelper.webView()
      ->mainFrameImpl()
      ->frame()
      ->eventHandler()
      .handleGestureEvent(gestureEvent);
  // when pressed, the button changes its own text to "updatedValue"
  EXPECT_EQ(String("updatedValue"), element->innerText());
}

TEST_F(WebFrameTest, FrameOwnerPropertiesMargin) {
  FrameTestHelpers::TestWebViewClient viewClient;
  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebView* view = WebView::create(&viewClient, WebPageVisibilityStateVisible);
  view->settings()->setJavaScriptEnabled(true);
  view->setMainFrame(remoteClient.frame());
  WebRemoteFrame* root = view->mainFrame()->toWebRemoteFrame();
  root->setReplicatedOrigin(SecurityOrigin::createUnique());

  WebFrameOwnerProperties properties;
  properties.marginWidth = 11;
  properties.marginHeight = 22;
  WebLocalFrameImpl* localFrame = FrameTestHelpers::createLocalChild(
      root, "frameName", nullptr, nullptr, nullptr, properties);

  registerMockedHttpURLLoad("frame_owner_properties.html");
  FrameTestHelpers::loadFrame(localFrame,
                              m_baseURL + "frame_owner_properties.html");

  // Check if the LocalFrame has seen the marginwidth and marginheight
  // properties.
  Document* childDocument = localFrame->frame()->document();
  EXPECT_EQ(11, childDocument->firstBodyElement()->getIntegralAttribute(
                    HTMLNames::marginwidthAttr));
  EXPECT_EQ(22, childDocument->firstBodyElement()->getIntegralAttribute(
                    HTMLNames::marginheightAttr));

  FrameView* frameView = localFrame->frameView();
  // Expect scrollbars to be enabled by default.
  EXPECT_NE(nullptr, frameView->horizontalScrollbar());
  EXPECT_NE(nullptr, frameView->verticalScrollbar());

  view->close();
}

TEST_F(WebFrameTest, FrameOwnerPropertiesScrolling) {
  FrameTestHelpers::TestWebViewClient viewClient;
  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebView* view = WebView::create(&viewClient, WebPageVisibilityStateVisible);
  view->settings()->setJavaScriptEnabled(true);
  view->setMainFrame(remoteClient.frame());
  WebRemoteFrame* root = view->mainFrame()->toWebRemoteFrame();
  root->setReplicatedOrigin(SecurityOrigin::createUnique());

  WebFrameOwnerProperties properties;
  // Turn off scrolling in the subframe.
  properties.scrollingMode = WebFrameOwnerProperties::ScrollingMode::AlwaysOff;
  WebLocalFrameImpl* localFrame = FrameTestHelpers::createLocalChild(
      root, "frameName", nullptr, nullptr, nullptr, properties);

  registerMockedHttpURLLoad("frame_owner_properties.html");
  FrameTestHelpers::loadFrame(localFrame,
                              m_baseURL + "frame_owner_properties.html");

  Document* childDocument = localFrame->frame()->document();
  EXPECT_EQ(0, childDocument->firstBodyElement()->getIntegralAttribute(
                   HTMLNames::marginwidthAttr));
  EXPECT_EQ(0, childDocument->firstBodyElement()->getIntegralAttribute(
                   HTMLNames::marginheightAttr));

  FrameView* frameView =
      static_cast<WebLocalFrameImpl*>(localFrame)->frameView();
  EXPECT_EQ(nullptr, frameView->horizontalScrollbar());
  EXPECT_EQ(nullptr, frameView->verticalScrollbar());

  view->close();
}

TEST_P(ParameterizedWebFrameTest,
       SetForceZeroLayoutHeightWorksAcrossNavigations) {
  registerMockedHttpURLLoad("200-by-300.html");
  registerMockedHttpURLLoad("large-div.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;

  webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html", true, nullptr,
                                  &client, nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setForceZeroLayoutHeight(true);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "large-div.html");
  webViewHelper.webView()->updateAllLifecyclePhases();

  EXPECT_EQ(0, webViewHelper.webView()
                   ->mainFrameImpl()
                   ->frameView()
                   ->layoutSize()
                   .height());
}

TEST_P(ParameterizedWebFrameTest,
       SetForceZeroLayoutHeightWithWideViewportQuirk) {
  registerMockedHttpURLLoad("200-by-300.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;

  webViewHelper.initializeAndLoad(m_baseURL + "200-by-300.html", true, nullptr,
                                  &client, nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(true);
  webViewHelper.webView()->settings()->setForceZeroLayoutHeight(true);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_EQ(0, webViewHelper.webView()
                   ->mainFrameImpl()
                   ->frameView()
                   ->layoutSize()
                   .height());
}

TEST_P(ParameterizedWebFrameTest, WideViewportAndWideContentWithInitialScale) {
  registerMockedHttpURLLoad("wide_document_width_viewport.html");
  registerMockedHttpURLLoad("white-1x1.png");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 600;
  int viewportHeight = 800;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad("about:blank", true, nullptr, &client,
                                  nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(true);
  webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "wide_document_width_viewport.html");
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  int wideDocumentWidth = 800;
  float minimumPageScaleFactor = viewportWidth / (float)wideDocumentWidth;
  EXPECT_EQ(minimumPageScaleFactor, webViewHelper.webView()->pageScaleFactor());
  EXPECT_EQ(minimumPageScaleFactor,
            webViewHelper.webView()->minimumPageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest, WideViewportQuirkClobbersHeight) {
  registerMockedHttpURLLoad("viewport-height-1000.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 600;
  int viewportHeight = 800;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad("about:blank", true, nullptr, &client,
                                  nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(false);
  webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "viewport-height-1000.html");
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_EQ(800, webViewHelper.webView()
                     ->mainFrameImpl()
                     ->frameView()
                     ->layoutSize()
                     .height());
  EXPECT_EQ(1, webViewHelper.webView()->pageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest, LayoutSize320Quirk) {
  registerMockedHttpURLLoad("viewport/viewport-30.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 600;
  int viewportHeight = 800;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad("about:blank", true, nullptr, &client,
                                  nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(true);
  webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "viewport/viewport-30.html");
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_EQ(600, webViewHelper.webView()
                     ->mainFrameImpl()
                     ->frameView()
                     ->layoutSize()
                     .width());
  EXPECT_EQ(800, webViewHelper.webView()
                     ->mainFrameImpl()
                     ->frameView()
                     ->layoutSize()
                     .height());
  EXPECT_EQ(1, webViewHelper.webView()->pageScaleFactor());

  // The magic number to snap to device-width is 320, so test that 321 is
  // respected.
  Document* document =
      toLocalFrame(webViewHelper.webView()->page()->mainFrame())->document();
  ViewportDescription description = document->viewportDescription();
  description.minWidth = Length(321, blink::Fixed);
  description.maxWidth = Length(321, blink::Fixed);
  document->setViewportDescription(description);
  webViewHelper.webView()->updateAllLifecyclePhases();
  EXPECT_EQ(321, webViewHelper.webView()
                     ->mainFrameImpl()
                     ->frameView()
                     ->layoutSize()
                     .width());

  description.minWidth = Length(320, blink::Fixed);
  description.maxWidth = Length(320, blink::Fixed);
  document->setViewportDescription(description);
  webViewHelper.webView()->updateAllLifecyclePhases();
  EXPECT_EQ(600, webViewHelper.webView()
                     ->mainFrameImpl()
                     ->frameView()
                     ->layoutSize()
                     .width());

  description = document->viewportDescription();
  description.maxHeight = Length(1000, blink::Fixed);
  document->setViewportDescription(description);
  webViewHelper.webView()->updateAllLifecyclePhases();
  EXPECT_EQ(1000, webViewHelper.webView()
                      ->mainFrameImpl()
                      ->frameView()
                      ->layoutSize()
                      .height());

  description.maxHeight = Length(320, blink::Fixed);
  document->setViewportDescription(description);
  webViewHelper.webView()->updateAllLifecyclePhases();
  EXPECT_EQ(800, webViewHelper.webView()
                     ->mainFrameImpl()
                     ->frameView()
                     ->layoutSize()
                     .height());
}

TEST_P(ParameterizedWebFrameTest, ZeroValuesQuirk) {
  registerMockedHttpURLLoad("viewport-zero-values.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, nullptr, &client, nullptr,
                           enableViewportSettings);
  webViewHelper.webView()->settings()->setViewportMetaZeroValuesQuirk(true);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setViewportMetaLayoutSizeQuirk(true);
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "viewport-zero-values.html");
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_EQ(viewportWidth, webViewHelper.webView()
                               ->mainFrameImpl()
                               ->frameView()
                               ->layoutSize()
                               .width());
  EXPECT_EQ(1.0f, webViewHelper.webView()->pageScaleFactor());

  webViewHelper.webView()->settings()->setUseWideViewport(true);
  webViewHelper.webView()->updateAllLifecyclePhases();
  EXPECT_EQ(viewportWidth, webViewHelper.webView()
                               ->mainFrameImpl()
                               ->frameView()
                               ->layoutSize()
                               .width());
  EXPECT_EQ(1.0f, webViewHelper.webView()->pageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest, OverflowHiddenDisablesScrolling) {
  registerMockedHttpURLLoad("body-overflow-hidden.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, nullptr, &client, nullptr);
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "body-overflow-hidden.html");
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  FrameView* view = webViewHelper.webView()->mainFrameImpl()->frameView();
  EXPECT_FALSE(view->userInputScrollable(VerticalScrollbar));
  EXPECT_FALSE(view->userInputScrollable(HorizontalScrollbar));
}

TEST_P(ParameterizedWebFrameTest,
       OverflowHiddenDisablesScrollingWithSetCanHaveScrollbars) {
  registerMockedHttpURLLoad("body-overflow-hidden-short.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, nullptr, &client, nullptr);
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "body-overflow-hidden-short.html");
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  FrameView* view = webViewHelper.webView()->mainFrameImpl()->frameView();
  EXPECT_FALSE(view->userInputScrollable(VerticalScrollbar));
  EXPECT_FALSE(view->userInputScrollable(HorizontalScrollbar));

  webViewHelper.webView()->mainFrameImpl()->setCanHaveScrollbars(true);
  EXPECT_FALSE(view->userInputScrollable(VerticalScrollbar));
  EXPECT_FALSE(view->userInputScrollable(HorizontalScrollbar));
}

TEST_F(WebFrameTest, IgnoreOverflowHiddenQuirk) {
  registerMockedHttpURLLoad("body-overflow-hidden.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, nullptr, &client, nullptr);
  webViewHelper.webView()->settings()->setIgnoreMainFrameOverflowHiddenQuirk(
      true);
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "body-overflow-hidden.html");
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  FrameView* view = webViewHelper.webView()->mainFrameImpl()->frameView();
  EXPECT_TRUE(view->userInputScrollable(VerticalScrollbar));
}

TEST_P(ParameterizedWebFrameTest, NonZeroValuesNoQuirk) {
  registerMockedHttpURLLoad("viewport-nonzero-values.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;
  float expectedPageScaleFactor = 0.5f;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, nullptr, &client, nullptr,
                           enableViewportSettings);
  webViewHelper.webView()->settings()->setViewportMetaZeroValuesQuirk(true);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "viewport-nonzero-values.html");
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_EQ(viewportWidth / expectedPageScaleFactor, webViewHelper.webView()
                                                         ->mainFrameImpl()
                                                         ->frameView()
                                                         ->layoutSize()
                                                         .width());
  EXPECT_EQ(expectedPageScaleFactor,
            webViewHelper.webView()->pageScaleFactor());

  webViewHelper.webView()->settings()->setUseWideViewport(true);
  webViewHelper.webView()->updateAllLifecyclePhases();
  EXPECT_EQ(viewportWidth / expectedPageScaleFactor, webViewHelper.webView()
                                                         ->mainFrameImpl()
                                                         ->frameView()
                                                         ->layoutSize()
                                                         .width());
  EXPECT_EQ(expectedPageScaleFactor,
            webViewHelper.webView()->pageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest, setPageScaleFactorDoesNotLayout) {
  registerMockedHttpURLLoad("fixed_layout.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  // Small viewport to ensure there are always scrollbars.
  int viewportWidth = 64;
  int viewportHeight = 48;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true,
                                  nullptr, &client, nullptr,
                                  enableViewportSettings);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  int prevLayoutCount =
      webViewHelper.webView()->mainFrameImpl()->frameView()->layoutCount();
  webViewHelper.webView()->setPageScaleFactor(3);
  EXPECT_FALSE(
      webViewHelper.webView()->mainFrameImpl()->frameView()->needsLayout());
  EXPECT_EQ(
      prevLayoutCount,
      webViewHelper.webView()->mainFrameImpl()->frameView()->layoutCount());
}

TEST_P(ParameterizedWebFrameTest,
       setPageScaleFactorWithOverlayScrollbarsDoesNotLayout) {
  registerMockedHttpURLLoad("fixed_layout.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true,
                                  nullptr, &client, nullptr,
                                  enableViewportSettings);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  int prevLayoutCount =
      webViewHelper.webView()->mainFrameImpl()->frameView()->layoutCount();
  webViewHelper.webView()->setPageScaleFactor(30);
  EXPECT_FALSE(
      webViewHelper.webView()->mainFrameImpl()->frameView()->needsLayout());
  EXPECT_EQ(
      prevLayoutCount,
      webViewHelper.webView()->mainFrameImpl()->frameView()->layoutCount());
}

TEST_P(ParameterizedWebFrameTest, pageScaleFactorWrittenToHistoryItem) {
  registerMockedHttpURLLoad("fixed_layout.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true,
                                  nullptr, &client, nullptr,
                                  enableViewportSettings);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  webViewHelper.webView()->setPageScaleFactor(3);
  EXPECT_EQ(3, toLocalFrame(webViewHelper.webView()->page()->mainFrame())
                   ->loader()
                   .currentItem()
                   ->pageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest, initialScaleWrittenToHistoryItem) {
  registerMockedHttpURLLoad("fixed_layout.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, nullptr, &client, nullptr,
                           enableViewportSettings);
  webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 5);
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "fixed_layout.html");
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  int defaultFixedLayoutWidth = 980;
  float minimumPageScaleFactor = viewportWidth / (float)defaultFixedLayoutWidth;
  EXPECT_EQ(minimumPageScaleFactor,
            toLocalFrame(webViewHelper.webView()->page()->mainFrame())
                ->loader()
                .currentItem()
                ->pageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest, pageScaleFactorDoesntShrinkFrameView) {
  registerMockedHttpURLLoad("large-div.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  // Small viewport to ensure there are always scrollbars.
  int viewportWidth = 64;
  int viewportHeight = 48;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, nullptr,
                                  &client, nullptr, enableViewportSettings);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  FrameView* view = webViewHelper.webView()->mainFrameImpl()->frameView();
  int viewportWidthMinusScrollbar = viewportWidth;
  int viewportHeightMinusScrollbar = viewportHeight;

  if (view->verticalScrollbar() &&
      !view->verticalScrollbar()->isOverlayScrollbar())
    viewportWidthMinusScrollbar -= 15;

  if (view->horizontalScrollbar() &&
      !view->horizontalScrollbar()->isOverlayScrollbar())
    viewportHeightMinusScrollbar -= 15;

  webViewHelper.webView()->setPageScaleFactor(2);

  IntSize unscaledSize = view->visibleContentSize(IncludeScrollbars);
  EXPECT_EQ(viewportWidth, unscaledSize.width());
  EXPECT_EQ(viewportHeight, unscaledSize.height());

  IntSize unscaledSizeMinusScrollbar =
      view->visibleContentSize(ExcludeScrollbars);
  EXPECT_EQ(viewportWidthMinusScrollbar, unscaledSizeMinusScrollbar.width());
  EXPECT_EQ(viewportHeightMinusScrollbar, unscaledSizeMinusScrollbar.height());

  IntSize frameViewSize = view->visibleContentRect().size();
  EXPECT_EQ(viewportWidthMinusScrollbar, frameViewSize.width());
  EXPECT_EQ(viewportHeightMinusScrollbar, frameViewSize.height());
}

TEST_P(ParameterizedWebFrameTest, pageScaleFactorDoesNotApplyCssTransform) {
  registerMockedHttpURLLoad("fixed_layout.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true,
                                  nullptr, &client, nullptr,
                                  enableViewportSettings);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  webViewHelper.webView()->setPageScaleFactor(2);

  EXPECT_EQ(980, toLocalFrame(webViewHelper.webView()->page()->mainFrame())
                     ->contentLayoutItem()
                     .documentRect()
                     .width());
  EXPECT_EQ(980, webViewHelper.webView()
                     ->mainFrameImpl()
                     ->frameView()
                     ->contentsSize()
                     .width());
}

TEST_P(ParameterizedWebFrameTest, targetDensityDpiHigh) {
  registerMockedHttpURLLoad("viewport-target-densitydpi-high.html");

  FixedLayoutTestWebViewClient client;
  // high-dpi = 240
  float targetDpi = 240.0f;
  float deviceScaleFactors[] = {1.0f, 4.0f / 3.0f, 2.0f};
  int viewportWidth = 640;
  int viewportHeight = 480;

  for (size_t i = 0; i < WTF_ARRAY_LENGTH(deviceScaleFactors); ++i) {
    float deviceScaleFactor = deviceScaleFactors[i];
    float deviceDpi = deviceScaleFactor * 160.0f;
    client.m_screenInfo.deviceScaleFactor = deviceScaleFactor;

    FrameTestHelpers::WebViewHelper webViewHelper;
    webViewHelper.initializeAndLoad(
        m_baseURL + "viewport-target-densitydpi-high.html", true, nullptr,
        &client, nullptr, enableViewportSettings);
    webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
    webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(
        true);
    webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

    // We need to account for the fact that logical pixels are unconditionally
    // multiplied by deviceScaleFactor to produce physical pixels.
    float densityDpiScaleRatio = deviceScaleFactor * targetDpi / deviceDpi;
    EXPECT_NEAR(viewportWidth * densityDpiScaleRatio, webViewHelper.webView()
                                                          ->mainFrameImpl()
                                                          ->frameView()
                                                          ->layoutSize()
                                                          .width(),
                1.0f);
    EXPECT_NEAR(viewportHeight * densityDpiScaleRatio, webViewHelper.webView()
                                                           ->mainFrameImpl()
                                                           ->frameView()
                                                           ->layoutSize()
                                                           .height(),
                1.0f);
    EXPECT_NEAR(1.0f / densityDpiScaleRatio,
                webViewHelper.webView()->pageScaleFactor(), 0.01f);
  }
}

TEST_P(ParameterizedWebFrameTest, targetDensityDpiDevice) {
  registerMockedHttpURLLoad("viewport-target-densitydpi-device.html");

  float deviceScaleFactors[] = {1.0f, 4.0f / 3.0f, 2.0f};

  FixedLayoutTestWebViewClient client;
  int viewportWidth = 640;
  int viewportHeight = 480;

  for (size_t i = 0; i < WTF_ARRAY_LENGTH(deviceScaleFactors); ++i) {
    client.m_screenInfo.deviceScaleFactor = deviceScaleFactors[i];

    FrameTestHelpers::WebViewHelper webViewHelper;
    webViewHelper.initializeAndLoad(
        m_baseURL + "viewport-target-densitydpi-device.html", true, nullptr,
        &client, nullptr, enableViewportSettings);
    webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
    webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(
        true);
    webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

    EXPECT_NEAR(viewportWidth * client.m_screenInfo.deviceScaleFactor,
                webViewHelper.webView()
                    ->mainFrameImpl()
                    ->frameView()
                    ->layoutSize()
                    .width(),
                1.0f);
    EXPECT_NEAR(viewportHeight * client.m_screenInfo.deviceScaleFactor,
                webViewHelper.webView()
                    ->mainFrameImpl()
                    ->frameView()
                    ->layoutSize()
                    .height(),
                1.0f);
    EXPECT_NEAR(1.0f / client.m_screenInfo.deviceScaleFactor,
                webViewHelper.webView()->pageScaleFactor(), 0.01f);
  }
}

TEST_P(ParameterizedWebFrameTest, targetDensityDpiDeviceAndFixedWidth) {
  registerMockedHttpURLLoad(
      "viewport-target-densitydpi-device-and-fixed-width.html");

  float deviceScaleFactors[] = {1.0f, 4.0f / 3.0f, 2.0f};

  FixedLayoutTestWebViewClient client;
  int viewportWidth = 640;
  int viewportHeight = 480;

  for (size_t i = 0; i < WTF_ARRAY_LENGTH(deviceScaleFactors); ++i) {
    client.m_screenInfo.deviceScaleFactor = deviceScaleFactors[i];

    FrameTestHelpers::WebViewHelper webViewHelper;
    webViewHelper.initializeAndLoad(
        m_baseURL + "viewport-target-densitydpi-device-and-fixed-width.html",
        true, nullptr, &client, nullptr, enableViewportSettings);
    webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
    webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(
        true);
    webViewHelper.webView()->settings()->setUseWideViewport(true);
    webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

    EXPECT_NEAR(viewportWidth, webViewHelper.webView()
                                   ->mainFrameImpl()
                                   ->frameView()
                                   ->layoutSize()
                                   .width(),
                1.0f);
    EXPECT_NEAR(viewportHeight, webViewHelper.webView()
                                    ->mainFrameImpl()
                                    ->frameView()
                                    ->layoutSize()
                                    .height(),
                1.0f);
    EXPECT_NEAR(1.0f, webViewHelper.webView()->pageScaleFactor(), 0.01f);
  }
}

TEST_P(ParameterizedWebFrameTest, NoWideViewportAndScaleLessThanOne) {
  registerMockedHttpURLLoad("viewport-initial-scale-less-than-1.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1.33f;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "viewport-initial-scale-less-than-1.html", true, nullptr,
      &client, nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(
      true);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(false);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_NEAR(viewportWidth * client.m_screenInfo.deviceScaleFactor,
              webViewHelper.webView()
                  ->mainFrameImpl()
                  ->frameView()
                  ->layoutSize()
                  .width(),
              1.0f);
  EXPECT_NEAR(viewportHeight * client.m_screenInfo.deviceScaleFactor,
              webViewHelper.webView()
                  ->mainFrameImpl()
                  ->frameView()
                  ->layoutSize()
                  .height(),
              1.0f);
  EXPECT_NEAR(1.0f / client.m_screenInfo.deviceScaleFactor,
              webViewHelper.webView()->pageScaleFactor(), 0.01f);
}

TEST_P(ParameterizedWebFrameTest,
       NoWideViewportAndScaleLessThanOneWithDeviceWidth) {
  registerMockedHttpURLLoad(
      "viewport-initial-scale-less-than-1-device-width.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1.33f;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "viewport-initial-scale-less-than-1-device-width.html", true,
      nullptr, &client, nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(
      true);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(false);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  const float pageZoom = 0.25f;
  EXPECT_NEAR(viewportWidth * client.m_screenInfo.deviceScaleFactor / pageZoom,
              webViewHelper.webView()
                  ->mainFrameImpl()
                  ->frameView()
                  ->layoutSize()
                  .width(),
              1.0f);
  EXPECT_NEAR(viewportHeight * client.m_screenInfo.deviceScaleFactor / pageZoom,
              webViewHelper.webView()
                  ->mainFrameImpl()
                  ->frameView()
                  ->layoutSize()
                  .height(),
              1.0f);
  EXPECT_NEAR(1.0f / client.m_screenInfo.deviceScaleFactor,
              webViewHelper.webView()->pageScaleFactor(), 0.01f);
}

TEST_P(ParameterizedWebFrameTest,
       NoWideViewportAndNoViewportWithInitialPageScaleOverride) {
  registerMockedHttpURLLoad("large-div.html");

  FixedLayoutTestWebViewClient client;
  int viewportWidth = 640;
  int viewportHeight = 480;
  float enforcedPageScaleFactor = 5.0f;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "large-div.html", true, nullptr,
                                  &client, nullptr, enableViewportSettings);
  webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 5);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(false);
  webViewHelper.webView()->setInitialPageScaleOverride(enforcedPageScaleFactor);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_NEAR(viewportWidth / enforcedPageScaleFactor, webViewHelper.webView()
                                                           ->mainFrameImpl()
                                                           ->frameView()
                                                           ->layoutSize()
                                                           .width(),
              1.0f);
  EXPECT_NEAR(viewportHeight / enforcedPageScaleFactor, webViewHelper.webView()
                                                            ->mainFrameImpl()
                                                            ->frameView()
                                                            ->layoutSize()
                                                            .height(),
              1.0f);
  EXPECT_NEAR(enforcedPageScaleFactor,
              webViewHelper.webView()->pageScaleFactor(), 0.01f);
}

TEST_P(ParameterizedWebFrameTest, NoUserScalableQuirkIgnoresViewportScale) {
  registerMockedHttpURLLoad("viewport-initial-scale-and-user-scalable-no.html");

  FixedLayoutTestWebViewClient client;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "viewport-initial-scale-and-user-scalable-no.html", true,
      nullptr, &client, nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setViewportMetaNonUserScalableQuirk(
      true);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_NEAR(viewportWidth, webViewHelper.webView()
                                 ->mainFrameImpl()
                                 ->frameView()
                                 ->layoutSize()
                                 .width(),
              1.0f);
  EXPECT_NEAR(viewportHeight, webViewHelper.webView()
                                  ->mainFrameImpl()
                                  ->frameView()
                                  ->layoutSize()
                                  .height(),
              1.0f);
  EXPECT_NEAR(1.0f, webViewHelper.webView()->pageScaleFactor(), 0.01f);
}

TEST_P(ParameterizedWebFrameTest,
       NoUserScalableQuirkIgnoresViewportScaleForNonWideViewport) {
  registerMockedHttpURLLoad("viewport-initial-scale-and-user-scalable-no.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1.33f;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "viewport-initial-scale-and-user-scalable-no.html", true,
      nullptr, &client, nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setSupportDeprecatedTargetDensityDPI(
      true);
  webViewHelper.webView()->settings()->setViewportMetaNonUserScalableQuirk(
      true);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(false);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_NEAR(viewportWidth * client.m_screenInfo.deviceScaleFactor,
              webViewHelper.webView()
                  ->mainFrameImpl()
                  ->frameView()
                  ->layoutSize()
                  .width(),
              1.0f);
  EXPECT_NEAR(viewportHeight * client.m_screenInfo.deviceScaleFactor,
              webViewHelper.webView()
                  ->mainFrameImpl()
                  ->frameView()
                  ->layoutSize()
                  .height(),
              1.0f);
  EXPECT_NEAR(1.0f / client.m_screenInfo.deviceScaleFactor,
              webViewHelper.webView()->pageScaleFactor(), 0.01f);
}

TEST_P(ParameterizedWebFrameTest,
       NoUserScalableQuirkIgnoresViewportScaleForWideViewport) {
  registerMockedHttpURLLoad("viewport-2x-initial-scale-non-user-scalable.html");

  FixedLayoutTestWebViewClient client;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "viewport-2x-initial-scale-non-user-scalable.html", true,
      nullptr, &client, nullptr, enableViewportSettings);
  webViewHelper.webView()->settings()->setViewportMetaNonUserScalableQuirk(
      true);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(true);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_NEAR(viewportWidth, webViewHelper.webView()
                                 ->mainFrameImpl()
                                 ->frameView()
                                 ->layoutSize()
                                 .width(),
              1.0f);
  EXPECT_NEAR(viewportHeight, webViewHelper.webView()
                                  ->mainFrameImpl()
                                  ->frameView()
                                  ->layoutSize()
                                  .height(),
              1.0f);
  EXPECT_NEAR(1.0f, webViewHelper.webView()->pageScaleFactor(), 0.01f);
}

TEST_P(ParameterizedWebFrameTest,
       DesktopPageCanBeZoomedInWhenWideViewportIsTurnedOff) {
  registerMockedHttpURLLoad("no_viewport_tag.html");

  FixedLayoutTestWebViewClient client;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "no_viewport_tag.html", true,
                                  nullptr, &client, nullptr,
                                  enableViewportSettings);
  webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 5);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setUseWideViewport(false);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_NEAR(1.0f, webViewHelper.webView()->pageScaleFactor(), 0.01f);
  EXPECT_NEAR(1.0f, webViewHelper.webView()->minimumPageScaleFactor(), 0.01f);
  EXPECT_NEAR(5.0f, webViewHelper.webView()->maximumPageScaleFactor(), 0.01f);
}

TEST_P(ParameterizedWebFrameTest, AtViewportInsideAtMediaInitialViewport) {
  registerMockedHttpURLLoad("viewport-inside-media.html");

  FixedLayoutTestWebViewClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "viewport-inside-media.html",
                                  true, nullptr, &client, nullptr,
                                  enableViewportSettings);
  webViewHelper.resize(WebSize(640, 480));

  EXPECT_EQ(2000, webViewHelper.webView()
                      ->mainFrameImpl()
                      ->frameView()
                      ->layoutSize()
                      .width());
}

TEST_P(ParameterizedWebFrameTest, AtViewportAffectingAtMediaRecalcCount) {
  registerMockedHttpURLLoad("viewport-and-media.html");

  FixedLayoutTestWebViewClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, nullptr, &client, nullptr,
                           enableViewportSettings);
  webViewHelper.resize(WebSize(640, 480));
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "viewport-and-media.html");

  Document* document =
      webViewHelper.webView()->mainFrameImpl()->frame()->document();
  EXPECT_EQ(2000, webViewHelper.webView()
                      ->mainFrameImpl()
                      ->frameView()
                      ->layoutSize()
                      .width());

  // The styleForElementCount() should match the number of elements for a single
  // pass of computed styles construction for the document.
  EXPECT_EQ(10u, document->styleEngine().styleForElementCount());
  EXPECT_EQ(Color(0, 128, 0),
            document->body()->computedStyle()->visitedDependentColor(
                CSSPropertyColor));
}

TEST_P(ParameterizedWebFrameTest, AtViewportWithViewportLengths) {
  registerMockedHttpURLLoad("viewport-lengths.html");

  FixedLayoutTestWebViewClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, nullptr, &client, nullptr,
                           enableViewportSettings);
  webViewHelper.resize(WebSize(800, 600));
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "viewport-lengths.html");

  FrameView* view = webViewHelper.webView()->mainFrameImpl()->frameView();
  EXPECT_EQ(400, view->layoutSize().width());
  EXPECT_EQ(300, view->layoutSize().height());

  webViewHelper.resize(WebSize(1000, 400));

  EXPECT_EQ(500, view->layoutSize().width());
  EXPECT_EQ(200, view->layoutSize().height());
}

class WebFrameResizeTest : public ParameterizedWebFrameTest {
 protected:
  static FloatSize computeRelativeOffset(const IntPoint& absoluteOffset,
                                         const LayoutRect& rect) {
    FloatSize relativeOffset =
        FloatPoint(absoluteOffset) - FloatPoint(rect.location());
    relativeOffset.scale(1.f / rect.width(), 1.f / rect.height());
    return relativeOffset;
  }

  void testResizeYieldsCorrectScrollAndScale(
      const char* url,
      const float initialPageScaleFactor,
      const WebSize scrollOffset,
      const WebSize viewportSize,
      const bool shouldScaleRelativeToViewportWidth) {
    registerMockedHttpURLLoad(url);

    const float aspectRatio =
        static_cast<float>(viewportSize.width) / viewportSize.height;

    FrameTestHelpers::WebViewHelper webViewHelper;
    webViewHelper.initializeAndLoad(m_baseURL + url, true, nullptr, nullptr,
                                    nullptr, enableViewportSettings);
    webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 5);

    // Origin scrollOffsets preserved under resize.
    {
      webViewHelper.resize(WebSize(viewportSize.width, viewportSize.height));
      webViewHelper.webView()->setPageScaleFactor(initialPageScaleFactor);
      ASSERT_EQ(viewportSize, webViewHelper.webView()->size());
      ASSERT_EQ(initialPageScaleFactor,
                webViewHelper.webView()->pageScaleFactor());
      webViewHelper.resize(WebSize(viewportSize.height, viewportSize.width));
      float expectedPageScaleFactor =
          initialPageScaleFactor *
          (shouldScaleRelativeToViewportWidth ? 1 / aspectRatio : 1);
      EXPECT_NEAR(expectedPageScaleFactor,
                  webViewHelper.webView()->pageScaleFactor(), 0.05f);
      EXPECT_EQ(WebSize(),
                webViewHelper.webView()->mainFrame()->scrollOffset());
    }

    // Resizing just the height should not affect pageScaleFactor or
    // scrollOffset.
    {
      webViewHelper.resize(WebSize(viewportSize.width, viewportSize.height));
      webViewHelper.webView()->setPageScaleFactor(initialPageScaleFactor);
      webViewHelper.webView()->mainFrame()->setScrollOffset(scrollOffset);
      webViewHelper.webView()->updateAllLifecyclePhases();
      const WebSize expectedScrollOffset =
          webViewHelper.webView()->mainFrame()->scrollOffset();
      webViewHelper.resize(
          WebSize(viewportSize.width, viewportSize.height * 0.8f));
      EXPECT_EQ(initialPageScaleFactor,
                webViewHelper.webView()->pageScaleFactor());
      EXPECT_EQ(expectedScrollOffset,
                webViewHelper.webView()->mainFrame()->scrollOffset());
      webViewHelper.resize(
          WebSize(viewportSize.width, viewportSize.height * 0.8f));
      EXPECT_EQ(initialPageScaleFactor,
                webViewHelper.webView()->pageScaleFactor());
      EXPECT_EQ(expectedScrollOffset,
                webViewHelper.webView()->mainFrame()->scrollOffset());
    }
  }
};

INSTANTIATE_TEST_CASE_P(All, WebFrameResizeTest, ::testing::Bool());

TEST_P(WebFrameResizeTest,
       ResizeYieldsCorrectScrollAndScaleForWidthEqualsDeviceWidth) {
  // With width=device-width, pageScaleFactor is preserved across resizes as
  // long as the content adjusts according to the device-width.
  const char* url = "resize_scroll_mobile.html";
  const float initialPageScaleFactor = 1;
  const WebSize scrollOffset(0, 50);
  const WebSize viewportSize(120, 160);
  const bool shouldScaleRelativeToViewportWidth = true;

  testResizeYieldsCorrectScrollAndScale(url, initialPageScaleFactor,
                                        scrollOffset, viewportSize,
                                        shouldScaleRelativeToViewportWidth);
}

TEST_P(WebFrameResizeTest, ResizeYieldsCorrectScrollAndScaleForMinimumScale) {
  // This tests a scenario where minimum-scale is set to 1.0, but some element
  // on the page is slightly larger than the portrait width, so our "natural"
  // minimum-scale would be lower. In that case, we should stick to 1.0 scale
  // on rotation and not do anything strange.
  const char* url = "resize_scroll_minimum_scale.html";
  const float initialPageScaleFactor = 1;
  const WebSize scrollOffset(0, 0);
  const WebSize viewportSize(240, 320);
  const bool shouldScaleRelativeToViewportWidth = false;

  testResizeYieldsCorrectScrollAndScale(url, initialPageScaleFactor,
                                        scrollOffset, viewportSize,
                                        shouldScaleRelativeToViewportWidth);
}

TEST_P(WebFrameResizeTest, ResizeYieldsCorrectScrollAndScaleForFixedWidth) {
  // With a fixed width, pageScaleFactor scales by the relative change in
  // viewport width.
  const char* url = "resize_scroll_fixed_width.html";
  const float initialPageScaleFactor = 2;
  const WebSize scrollOffset(0, 200);
  const WebSize viewportSize(240, 320);
  const bool shouldScaleRelativeToViewportWidth = true;

  testResizeYieldsCorrectScrollAndScale(url, initialPageScaleFactor,
                                        scrollOffset, viewportSize,
                                        shouldScaleRelativeToViewportWidth);
}

TEST_P(WebFrameResizeTest, ResizeYieldsCorrectScrollAndScaleForFixedLayout) {
  // With a fixed layout, pageScaleFactor scales by the relative change in
  // viewport width.
  const char* url = "resize_scroll_fixed_layout.html";
  const float initialPageScaleFactor = 2;
  const WebSize scrollOffset(200, 400);
  const WebSize viewportSize(320, 240);
  const bool shouldScaleRelativeToViewportWidth = true;

  testResizeYieldsCorrectScrollAndScale(url, initialPageScaleFactor,
                                        scrollOffset, viewportSize,
                                        shouldScaleRelativeToViewportWidth);
}

TEST_P(ParameterizedWebFrameTest, pageScaleFactorUpdatesScrollbars) {
  registerMockedHttpURLLoad("fixed_layout.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "fixed_layout.html", true,
                                  nullptr, &client, nullptr,
                                  enableViewportSettings);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  FrameView* view = webViewHelper.webView()->mainFrameImpl()->frameView();
  EXPECT_EQ(view->scrollSize(HorizontalScrollbar),
            view->contentsSize().width() - view->visibleContentRect().width());
  EXPECT_EQ(
      view->scrollSize(VerticalScrollbar),
      view->contentsSize().height() - view->visibleContentRect().height());

  webViewHelper.webView()->setPageScaleFactor(10);

  EXPECT_EQ(view->scrollSize(HorizontalScrollbar),
            view->contentsSize().width() - view->visibleContentRect().width());
  EXPECT_EQ(
      view->scrollSize(VerticalScrollbar),
      view->contentsSize().height() - view->visibleContentRect().height());
}

TEST_P(ParameterizedWebFrameTest, CanOverrideScaleLimits) {
  registerMockedHttpURLLoad("no_scale_for_you.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "no_scale_for_you.html", true,
                                  nullptr, &client, nullptr,
                                  enableViewportSettings);
  webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 5);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  EXPECT_EQ(2.0f, webViewHelper.webView()->minimumPageScaleFactor());
  EXPECT_EQ(2.0f, webViewHelper.webView()->maximumPageScaleFactor());

  webViewHelper.webView()->setIgnoreViewportTagScaleLimits(true);
  webViewHelper.webView()->updateAllLifecyclePhases();

  EXPECT_EQ(1.0f, webViewHelper.webView()->minimumPageScaleFactor());
  EXPECT_EQ(5.0f, webViewHelper.webView()->maximumPageScaleFactor());

  webViewHelper.webView()->setIgnoreViewportTagScaleLimits(false);
  webViewHelper.webView()->updateAllLifecyclePhases();

  EXPECT_EQ(2.0f, webViewHelper.webView()->minimumPageScaleFactor());
  EXPECT_EQ(2.0f, webViewHelper.webView()->maximumPageScaleFactor());
}

// Android doesn't have scrollbars on the main FrameView
#if OS(ANDROID)
TEST_F(WebFrameTest, DISABLED_updateOverlayScrollbarLayers)
#else
TEST_F(WebFrameTest, updateOverlayScrollbarLayers)
#endif
{
  registerMockedHttpURLLoad("large-div.html");

  int viewWidth = 500;
  int viewHeight = 500;

  std::unique_ptr<FakeCompositingWebViewClient> fakeCompositingWebViewClient =
      wrapUnique(new FakeCompositingWebViewClient());
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, nullptr, fakeCompositingWebViewClient.get(),
                           nullptr, &configureCompositingWebView);

  webViewHelper.resize(WebSize(viewWidth, viewHeight));
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "large-div.html");

  FrameView* view = webViewHelper.webView()->mainFrameImpl()->frameView();
  EXPECT_TRUE(
      view->layoutViewItem().compositor()->layerForHorizontalScrollbar());
  EXPECT_TRUE(view->layoutViewItem().compositor()->layerForVerticalScrollbar());

  webViewHelper.resize(WebSize(viewWidth * 10, viewHeight * 10));
  EXPECT_FALSE(
      view->layoutViewItem().compositor()->layerForHorizontalScrollbar());
  EXPECT_FALSE(
      view->layoutViewItem().compositor()->layerForVerticalScrollbar());
}

void setScaleAndScrollAndLayout(WebViewImpl* webView,
                                WebPoint scroll,
                                float scale) {
  webView->setPageScaleFactor(scale);
  webView->mainFrame()->setScrollOffset(WebSize(scroll.x, scroll.y));
  webView->updateAllLifecyclePhases();
}

void simulatePageScale(WebViewImpl* webViewImpl, float& scale) {
  ScrollOffset scrollDelta =
      toScrollOffset(
          webViewImpl->fakePageScaleAnimationTargetPositionForTesting()) -
      webViewImpl->mainFrameImpl()->frameView()->scrollOffset();
  float scaleDelta = webViewImpl->fakePageScaleAnimationPageScaleForTesting() /
                     webViewImpl->pageScaleFactor();
  webViewImpl->applyViewportDeltas(WebFloatSize(), FloatSize(scrollDelta),
                                   WebFloatSize(), scaleDelta, 0);
  scale = webViewImpl->pageScaleFactor();
}

void simulateMultiTargetZoom(WebViewImpl* webViewImpl,
                             const WebRect& rect,
                             float& scale) {
  if (webViewImpl->zoomToMultipleTargetsRect(rect))
    simulatePageScale(webViewImpl, scale);
}

void simulateDoubleTap(WebViewImpl* webViewImpl,
                       WebPoint& point,
                       float& scale) {
  webViewImpl->animateDoubleTapZoom(point);
  EXPECT_TRUE(webViewImpl->fakeDoubleTapAnimationPendingForTesting());
  simulatePageScale(webViewImpl, scale);
}

TEST_P(ParameterizedWebFrameTest, DivAutoZoomParamsTest) {
  registerMockedHttpURLLoad("get_scale_for_auto_zoom_into_div_test.html");

  const float deviceScaleFactor = 2.0f;
  int viewportWidth = 640 / deviceScaleFactor;
  int viewportHeight = 1280 / deviceScaleFactor;
  float doubleTapZoomAlreadyLegibleRatio = 1.2f;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "get_scale_for_auto_zoom_into_div_test.html", false, nullptr,
      nullptr, nullptr, configureAndroid);
  webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
  webViewHelper.webView()->setDefaultPageScaleLimits(0.01f, 4);
  webViewHelper.webView()->setPageScaleFactor(0.5f);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  WebRect wideDiv(200, 100, 400, 150);
  WebRect tallDiv(200, 300, 400, 800);
  WebPoint doubleTapPointWide(wideDiv.x + 50, wideDiv.y + 50);
  WebPoint doubleTapPointTall(tallDiv.x + 50, tallDiv.y + 50);
  float scale;
  WebPoint scroll;

  float doubleTapZoomAlreadyLegibleScale =
      webViewHelper.webView()->minimumPageScaleFactor() *
      doubleTapZoomAlreadyLegibleRatio;

  // Test double-tap zooming into wide div.
  WebRect wideBlockBound =
      webViewHelper.webView()->computeBlockBound(doubleTapPointWide, false);
  webViewHelper.webView()->computeScaleAndScrollForBlockRect(
      WebPoint(doubleTapPointWide.x, doubleTapPointWide.y), wideBlockBound,
      touchPointPadding, doubleTapZoomAlreadyLegibleScale, scale, scroll);
  // The div should horizontally fill the screen (modulo margins), and
  // vertically centered (modulo integer rounding).
  EXPECT_NEAR(viewportWidth / (float)wideDiv.width, scale, 0.1);
  EXPECT_NEAR(wideDiv.x, scroll.x, 20);
  EXPECT_EQ(0, scroll.y);

  setScaleAndScrollAndLayout(webViewHelper.webView(), scroll, scale);

  // Test zoom out back to minimum scale.
  wideBlockBound =
      webViewHelper.webView()->computeBlockBound(doubleTapPointWide, false);
  webViewHelper.webView()->computeScaleAndScrollForBlockRect(
      WebPoint(doubleTapPointWide.x, doubleTapPointWide.y), wideBlockBound,
      touchPointPadding, doubleTapZoomAlreadyLegibleScale, scale, scroll);
  // FIXME: Looks like we are missing EXPECTs here.

  scale = webViewHelper.webView()->minimumPageScaleFactor();
  setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(0, 0), scale);

  // Test double-tap zooming into tall div.
  WebRect tallBlockBound =
      webViewHelper.webView()->computeBlockBound(doubleTapPointTall, false);
  webViewHelper.webView()->computeScaleAndScrollForBlockRect(
      WebPoint(doubleTapPointTall.x, doubleTapPointTall.y), tallBlockBound,
      touchPointPadding, doubleTapZoomAlreadyLegibleScale, scale, scroll);
  // The div should start at the top left of the viewport.
  EXPECT_NEAR(viewportWidth / (float)tallDiv.width, scale, 0.1);
  EXPECT_NEAR(tallDiv.x, scroll.x, 20);
  EXPECT_NEAR(tallDiv.y, scroll.y, 20);
}

TEST_P(ParameterizedWebFrameTest, DivAutoZoomWideDivTest) {
  registerMockedHttpURLLoad("get_wide_div_for_auto_zoom_test.html");

  const float deviceScaleFactor = 2.0f;
  int viewportWidth = 640 / deviceScaleFactor;
  int viewportHeight = 1280 / deviceScaleFactor;
  float doubleTapZoomAlreadyLegibleRatio = 1.2f;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "get_wide_div_for_auto_zoom_test.html", false, nullptr,
      nullptr, nullptr, configureAndroid);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
  webViewHelper.webView()->setPageScaleFactor(1.0f);
  webViewHelper.webView()->updateAllLifecyclePhases();

  webViewHelper.webView()->enableFakePageScaleAnimationForTesting(true);

  float doubleTapZoomAlreadyLegibleScale =
      webViewHelper.webView()->minimumPageScaleFactor() *
      doubleTapZoomAlreadyLegibleRatio;

  WebRect div(0, 100, viewportWidth, 150);
  WebPoint point(div.x + 50, div.y + 50);
  float scale;
  setScaleAndScrollAndLayout(
      webViewHelper.webView(), WebPoint(0, 0),
      (webViewHelper.webView()->minimumPageScaleFactor()) *
          (1 + doubleTapZoomAlreadyLegibleRatio) / 2);

  simulateDoubleTap(webViewHelper.webView(), point, scale);
  EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
  simulateDoubleTap(webViewHelper.webView(), point, scale);
  EXPECT_FLOAT_EQ(webViewHelper.webView()->minimumPageScaleFactor(), scale);
}

TEST_P(ParameterizedWebFrameTest, DivAutoZoomVeryTallTest) {
  // When a block is taller than the viewport and a zoom targets a lower part
  // of it, then we should keep the target point onscreen instead of snapping
  // back up the top of the block.
  registerMockedHttpURLLoad("very_tall_div.html");

  const float deviceScaleFactor = 2.0f;
  int viewportWidth = 640 / deviceScaleFactor;
  int viewportHeight = 1280 / deviceScaleFactor;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "very_tall_div.html", true,
                                  nullptr, nullptr, nullptr, configureAndroid);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
  webViewHelper.webView()->setPageScaleFactor(1.0f);
  webViewHelper.webView()->updateAllLifecyclePhases();

  WebRect div(200, 300, 400, 5000);
  WebPoint point(div.x + 50, div.y + 3000);
  float scale;
  WebPoint scroll;

  WebRect blockBound = webViewHelper.webView()->computeBlockBound(point, true);
  webViewHelper.webView()->computeScaleAndScrollForBlockRect(
      point, blockBound, 0, 1.0f, scale, scroll);
  EXPECT_EQ(scale, 1.0f);
  EXPECT_EQ(scroll.y, 2660);
}

TEST_F(WebFrameTest, DivAutoZoomMultipleDivsTest) {
  registerMockedHttpURLLoad("get_multiple_divs_for_auto_zoom_test.html");

  const float deviceScaleFactor = 2.0f;
  int viewportWidth = 640 / deviceScaleFactor;
  int viewportHeight = 1280 / deviceScaleFactor;
  float doubleTapZoomAlreadyLegibleRatio = 1.2f;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "get_multiple_divs_for_auto_zoom_test.html", false, nullptr,
      nullptr, nullptr, configureAndroid);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewHelper.webView()->setDefaultPageScaleLimits(0.5f, 4);
  webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
  webViewHelper.webView()->setPageScaleFactor(0.5f);
  webViewHelper.webView()->setMaximumLegibleScale(1.f);
  webViewHelper.webView()->updateAllLifecyclePhases();

  webViewHelper.webView()->enableFakePageScaleAnimationForTesting(true);

  WebRect topDiv(200, 100, 200, 150);
  WebRect bottomDiv(200, 300, 200, 150);
  WebPoint topPoint(topDiv.x + 50, topDiv.y + 50);
  WebPoint bottomPoint(bottomDiv.x + 50, bottomDiv.y + 50);
  float scale;
  setScaleAndScrollAndLayout(
      webViewHelper.webView(), WebPoint(0, 0),
      (webViewHelper.webView()->minimumPageScaleFactor()) *
          (1 + doubleTapZoomAlreadyLegibleRatio) / 2);

  // Test double tap on two different divs.  After first zoom, we should go back
  // to minimum page scale with a second double tap.
  simulateDoubleTap(webViewHelper.webView(), topPoint, scale);
  EXPECT_FLOAT_EQ(1, scale);
  simulateDoubleTap(webViewHelper.webView(), bottomPoint, scale);
  EXPECT_FLOAT_EQ(webViewHelper.webView()->minimumPageScaleFactor(), scale);

  // If the user pinch zooms after double tap, a second double tap should zoom
  // back to the div.
  simulateDoubleTap(webViewHelper.webView(), topPoint, scale);
  EXPECT_FLOAT_EQ(1, scale);
  webViewHelper.webView()->applyViewportDeltas(WebFloatSize(), WebFloatSize(),
                                               WebFloatSize(), 0.6f, 0);
  simulateDoubleTap(webViewHelper.webView(), bottomPoint, scale);
  EXPECT_FLOAT_EQ(1, scale);
  simulateDoubleTap(webViewHelper.webView(), bottomPoint, scale);
  EXPECT_FLOAT_EQ(webViewHelper.webView()->minimumPageScaleFactor(), scale);

  // If we didn't yet get an auto-zoom update and a second double-tap arrives,
  // should go back to minimum scale.
  webViewHelper.webView()->applyViewportDeltas(WebFloatSize(), WebFloatSize(),
                                               WebFloatSize(), 1.1f, 0);
  webViewHelper.webView()->animateDoubleTapZoom(topPoint);
  EXPECT_TRUE(
      webViewHelper.webView()->fakeDoubleTapAnimationPendingForTesting());
  simulateDoubleTap(webViewHelper.webView(), bottomPoint, scale);
  EXPECT_FLOAT_EQ(webViewHelper.webView()->minimumPageScaleFactor(), scale);
}

TEST_F(WebFrameTest, DivAutoZoomScaleBoundsTest) {
  registerMockedHttpURLLoad("get_scale_bounds_check_for_auto_zoom_test.html");

  int viewportWidth = 320;
  int viewportHeight = 480;
  float doubleTapZoomAlreadyLegibleRatio = 1.2f;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "get_scale_bounds_check_for_auto_zoom_test.html", false,
      nullptr, nullptr, nullptr, configureAndroid);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewHelper.webView()->setDeviceScaleFactor(1.5f);
  webViewHelper.webView()->setMaximumLegibleScale(1.f);
  webViewHelper.webView()->updateAllLifecyclePhases();

  webViewHelper.webView()->enableFakePageScaleAnimationForTesting(true);

  WebRect div(200, 100, 200, 150);
  WebPoint doubleTapPoint(div.x + 50, div.y + 50);
  float scale;

  // Test double tap scale bounds.
  // minimumPageScale < doubleTapZoomAlreadyLegibleScale < 1
  webViewHelper.webView()->setDefaultPageScaleLimits(0.5f, 4);
  webViewHelper.webView()->updateAllLifecyclePhases();
  float doubleTapZoomAlreadyLegibleScale =
      webViewHelper.webView()->minimumPageScaleFactor() *
      doubleTapZoomAlreadyLegibleRatio;
  setScaleAndScrollAndLayout(
      webViewHelper.webView(), WebPoint(0, 0),
      (webViewHelper.webView()->minimumPageScaleFactor()) *
          (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(1, scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(webViewHelper.webView()->minimumPageScaleFactor(), scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(1, scale);

  // Zoom in to reset double_tap_zoom_in_effect flag.
  webViewHelper.webView()->applyViewportDeltas(WebFloatSize(), WebFloatSize(),
                                               WebFloatSize(), 1.1f, 0);
  // 1 < minimumPageScale < doubleTapZoomAlreadyLegibleScale
  webViewHelper.webView()->setDefaultPageScaleLimits(1.1f, 4);
  webViewHelper.webView()->updateAllLifecyclePhases();
  doubleTapZoomAlreadyLegibleScale =
      webViewHelper.webView()->minimumPageScaleFactor() *
      doubleTapZoomAlreadyLegibleRatio;
  setScaleAndScrollAndLayout(
      webViewHelper.webView(), WebPoint(0, 0),
      (webViewHelper.webView()->minimumPageScaleFactor()) *
          (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(webViewHelper.webView()->minimumPageScaleFactor(), scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);

  // Zoom in to reset double_tap_zoom_in_effect flag.
  webViewHelper.webView()->applyViewportDeltas(WebFloatSize(), WebFloatSize(),
                                               WebFloatSize(), 1.1f, 0);
  // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale
  webViewHelper.webView()->setDefaultPageScaleLimits(0.95f, 4);
  webViewHelper.webView()->updateAllLifecyclePhases();
  doubleTapZoomAlreadyLegibleScale =
      webViewHelper.webView()->minimumPageScaleFactor() *
      doubleTapZoomAlreadyLegibleRatio;
  setScaleAndScrollAndLayout(
      webViewHelper.webView(), WebPoint(0, 0),
      (webViewHelper.webView()->minimumPageScaleFactor()) *
          (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(webViewHelper.webView()->minimumPageScaleFactor(), scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
}

TEST_F(WebFrameTest, DivAutoZoomScaleLegibleScaleTest) {
  registerMockedHttpURLLoad("get_scale_bounds_check_for_auto_zoom_test.html");

  int viewportWidth = 320;
  int viewportHeight = 480;
  float doubleTapZoomAlreadyLegibleRatio = 1.2f;
  float maximumLegibleScaleFactor = 1.13f;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "get_scale_bounds_check_for_auto_zoom_test.html", false,
      nullptr, nullptr, nullptr, configureAndroid);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewHelper.webView()->setMaximumLegibleScale(maximumLegibleScaleFactor);
  webViewHelper.webView()->updateAllLifecyclePhases();

  webViewHelper.webView()->enableFakePageScaleAnimationForTesting(true);
  webViewHelper.webView()->page()->settings().setTextAutosizingEnabled(true);

  WebRect div(200, 100, 200, 150);
  WebPoint doubleTapPoint(div.x + 50, div.y + 50);
  float scale;

  // Test double tap scale bounds.
  // minimumPageScale < doubleTapZoomAlreadyLegibleScale < 1 <
  //     maximumLegibleScaleFactor
  float legibleScale = maximumLegibleScaleFactor;
  setScaleAndScrollAndLayout(
      webViewHelper.webView(), WebPoint(0, 0),
      (webViewHelper.webView()->minimumPageScaleFactor()) *
          (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
  float doubleTapZoomAlreadyLegibleScale =
      webViewHelper.webView()->minimumPageScaleFactor() *
      doubleTapZoomAlreadyLegibleRatio;
  webViewHelper.webView()->setDefaultPageScaleLimits(0.5f, 4);
  webViewHelper.webView()->updateAllLifecyclePhases();
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(legibleScale, scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(webViewHelper.webView()->minimumPageScaleFactor(), scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(legibleScale, scale);

  // Zoom in to reset double_tap_zoom_in_effect flag.
  webViewHelper.webView()->applyViewportDeltas(WebFloatSize(), WebFloatSize(),
                                               WebFloatSize(), 1.1f, 0);
  // 1 < maximumLegibleScaleFactor < minimumPageScale <
  //     doubleTapZoomAlreadyLegibleScale
  webViewHelper.webView()->setDefaultPageScaleLimits(1.0f, 4);
  webViewHelper.webView()->updateAllLifecyclePhases();
  doubleTapZoomAlreadyLegibleScale =
      webViewHelper.webView()->minimumPageScaleFactor() *
      doubleTapZoomAlreadyLegibleRatio;
  setScaleAndScrollAndLayout(
      webViewHelper.webView(), WebPoint(0, 0),
      (webViewHelper.webView()->minimumPageScaleFactor()) *
          (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(webViewHelper.webView()->minimumPageScaleFactor(), scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);

  // Zoom in to reset double_tap_zoom_in_effect flag.
  webViewHelper.webView()->applyViewportDeltas(WebFloatSize(), WebFloatSize(),
                                               WebFloatSize(), 1.1f, 0);
  // minimumPageScale < 1 < maximumLegibleScaleFactor <
  //     doubleTapZoomAlreadyLegibleScale
  webViewHelper.webView()->setDefaultPageScaleLimits(0.95f, 4);
  webViewHelper.webView()->updateAllLifecyclePhases();
  doubleTapZoomAlreadyLegibleScale =
      webViewHelper.webView()->minimumPageScaleFactor() *
      doubleTapZoomAlreadyLegibleRatio;
  setScaleAndScrollAndLayout(
      webViewHelper.webView(), WebPoint(0, 0),
      (webViewHelper.webView()->minimumPageScaleFactor()) *
          (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(webViewHelper.webView()->minimumPageScaleFactor(), scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);

  // Zoom in to reset double_tap_zoom_in_effect flag.
  webViewHelper.webView()->applyViewportDeltas(WebFloatSize(), WebFloatSize(),
                                               WebFloatSize(), 1.1f, 0);
  // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale <
  //     maximumLegibleScaleFactor
  webViewHelper.webView()->setDefaultPageScaleLimits(0.9f, 4);
  webViewHelper.webView()->updateAllLifecyclePhases();
  doubleTapZoomAlreadyLegibleScale =
      webViewHelper.webView()->minimumPageScaleFactor() *
      doubleTapZoomAlreadyLegibleRatio;
  setScaleAndScrollAndLayout(
      webViewHelper.webView(), WebPoint(0, 0),
      (webViewHelper.webView()->minimumPageScaleFactor()) *
          (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(legibleScale, scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(webViewHelper.webView()->minimumPageScaleFactor(), scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(legibleScale, scale);
}

TEST_F(WebFrameTest, DivAutoZoomScaleFontScaleFactorTest) {
  registerMockedHttpURLLoad("get_scale_bounds_check_for_auto_zoom_test.html");

  int viewportWidth = 320;
  int viewportHeight = 480;
  float doubleTapZoomAlreadyLegibleRatio = 1.2f;
  float accessibilityFontScaleFactor = 1.13f;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "get_scale_bounds_check_for_auto_zoom_test.html", false,
      nullptr, nullptr, nullptr, configureAndroid);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewHelper.webView()->setMaximumLegibleScale(1.f);
  webViewHelper.webView()->updateAllLifecyclePhases();

  webViewHelper.webView()->enableFakePageScaleAnimationForTesting(true);
  webViewHelper.webView()->page()->settings().setTextAutosizingEnabled(true);
  webViewHelper.webView()->page()->settings().setAccessibilityFontScaleFactor(
      accessibilityFontScaleFactor);

  WebRect div(200, 100, 200, 150);
  WebPoint doubleTapPoint(div.x + 50, div.y + 50);
  float scale;

  // Test double tap scale bounds.
  // minimumPageScale < doubleTapZoomAlreadyLegibleScale < 1 <
  //     accessibilityFontScaleFactor
  float legibleScale = accessibilityFontScaleFactor;
  setScaleAndScrollAndLayout(
      webViewHelper.webView(), WebPoint(0, 0),
      (webViewHelper.webView()->minimumPageScaleFactor()) *
          (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
  float doubleTapZoomAlreadyLegibleScale =
      webViewHelper.webView()->minimumPageScaleFactor() *
      doubleTapZoomAlreadyLegibleRatio;
  webViewHelper.webView()->setDefaultPageScaleLimits(0.5f, 4);
  webViewHelper.webView()->updateAllLifecyclePhases();
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(legibleScale, scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(webViewHelper.webView()->minimumPageScaleFactor(), scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(legibleScale, scale);

  // Zoom in to reset double_tap_zoom_in_effect flag.
  webViewHelper.webView()->applyViewportDeltas(WebFloatSize(), WebFloatSize(),
                                               WebFloatSize(), 1.1f, 0);
  // 1 < accessibilityFontScaleFactor < minimumPageScale <
  //     doubleTapZoomAlreadyLegibleScale
  webViewHelper.webView()->setDefaultPageScaleLimits(1.0f, 4);
  webViewHelper.webView()->updateAllLifecyclePhases();
  doubleTapZoomAlreadyLegibleScale =
      webViewHelper.webView()->minimumPageScaleFactor() *
      doubleTapZoomAlreadyLegibleRatio;
  setScaleAndScrollAndLayout(
      webViewHelper.webView(), WebPoint(0, 0),
      (webViewHelper.webView()->minimumPageScaleFactor()) *
          (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(webViewHelper.webView()->minimumPageScaleFactor(), scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);

  // Zoom in to reset double_tap_zoom_in_effect flag.
  webViewHelper.webView()->applyViewportDeltas(WebFloatSize(), WebFloatSize(),
                                               WebFloatSize(), 1.1f, 0);
  // minimumPageScale < 1 < accessibilityFontScaleFactor <
  //     doubleTapZoomAlreadyLegibleScale
  webViewHelper.webView()->setDefaultPageScaleLimits(0.95f, 4);
  webViewHelper.webView()->updateAllLifecyclePhases();
  doubleTapZoomAlreadyLegibleScale =
      webViewHelper.webView()->minimumPageScaleFactor() *
      doubleTapZoomAlreadyLegibleRatio;
  setScaleAndScrollAndLayout(
      webViewHelper.webView(), WebPoint(0, 0),
      (webViewHelper.webView()->minimumPageScaleFactor()) *
          (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(webViewHelper.webView()->minimumPageScaleFactor(), scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(doubleTapZoomAlreadyLegibleScale, scale);

  // Zoom in to reset double_tap_zoom_in_effect flag.
  webViewHelper.webView()->applyViewportDeltas(WebFloatSize(), WebFloatSize(),
                                               WebFloatSize(), 1.1f, 0);
  // minimumPageScale < 1 < doubleTapZoomAlreadyLegibleScale <
  //     accessibilityFontScaleFactor
  webViewHelper.webView()->setDefaultPageScaleLimits(0.9f, 4);
  webViewHelper.webView()->updateAllLifecyclePhases();
  doubleTapZoomAlreadyLegibleScale =
      webViewHelper.webView()->minimumPageScaleFactor() *
      doubleTapZoomAlreadyLegibleRatio;
  setScaleAndScrollAndLayout(
      webViewHelper.webView(), WebPoint(0, 0),
      (webViewHelper.webView()->minimumPageScaleFactor()) *
          (1 + doubleTapZoomAlreadyLegibleRatio) / 2);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(legibleScale, scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(webViewHelper.webView()->minimumPageScaleFactor(), scale);
  simulateDoubleTap(webViewHelper.webView(), doubleTapPoint, scale);
  EXPECT_FLOAT_EQ(legibleScale, scale);
}

TEST_P(ParameterizedWebFrameTest, BlockBoundTest) {
  registerMockedHttpURLLoad("block_bound.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "block_bound.html", false,
                                  nullptr, nullptr, nullptr, configureAndroid);

  IntRect rectBack = IntRect(0, 0, 200, 200);
  IntRect rectLeftTop = IntRect(10, 10, 80, 80);
  IntRect rectRightBottom = IntRect(110, 110, 80, 80);
  IntRect blockBound;

  blockBound =
      IntRect(webViewHelper.webView()->computeBlockBound(WebPoint(9, 9), true));
  EXPECT_RECT_EQ(rectBack, blockBound);

  blockBound = IntRect(
      webViewHelper.webView()->computeBlockBound(WebPoint(10, 10), true));
  EXPECT_RECT_EQ(rectLeftTop, blockBound);

  blockBound = IntRect(
      webViewHelper.webView()->computeBlockBound(WebPoint(50, 50), true));
  EXPECT_RECT_EQ(rectLeftTop, blockBound);

  blockBound = IntRect(
      webViewHelper.webView()->computeBlockBound(WebPoint(89, 89), true));
  EXPECT_RECT_EQ(rectLeftTop, blockBound);

  blockBound = IntRect(
      webViewHelper.webView()->computeBlockBound(WebPoint(90, 90), true));
  EXPECT_RECT_EQ(rectBack, blockBound);

  blockBound = IntRect(
      webViewHelper.webView()->computeBlockBound(WebPoint(109, 109), true));
  EXPECT_RECT_EQ(rectBack, blockBound);

  blockBound = IntRect(
      webViewHelper.webView()->computeBlockBound(WebPoint(110, 110), true));
  EXPECT_RECT_EQ(rectRightBottom, blockBound);
}

TEST_P(ParameterizedWebFrameTest, DivMultipleTargetZoomMultipleDivsTest) {
  registerMockedHttpURLLoad("get_multiple_divs_for_auto_zoom_test.html");

  const float deviceScaleFactor = 2.0f;
  int viewportWidth = 640 / deviceScaleFactor;
  int viewportHeight = 1280 / deviceScaleFactor;
  float doubleTapZoomAlreadyLegibleRatio = 1.2f;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL +
                                  "get_multiple_divs_for_auto_zoom_test.html");
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewHelper.webView()->setDefaultPageScaleLimits(0.5f, 4);
  webViewHelper.webView()->setDeviceScaleFactor(deviceScaleFactor);
  webViewHelper.webView()->setPageScaleFactor(0.5f);
  webViewHelper.webView()->setMaximumLegibleScale(1.f);
  webViewHelper.webView()->updateAllLifecyclePhases();

  webViewHelper.webView()->enableFakePageScaleAnimationForTesting(true);

  WebRect viewportRect(0, 0, viewportWidth, viewportHeight);
  WebRect topDiv(200, 100, 200, 150);
  WebRect bottomDiv(200, 300, 200, 150);
  float scale;
  setScaleAndScrollAndLayout(
      webViewHelper.webView(), WebPoint(0, 0),
      (webViewHelper.webView()->minimumPageScaleFactor()) *
          (1 + doubleTapZoomAlreadyLegibleRatio) / 2);

  simulateMultiTargetZoom(webViewHelper.webView(), topDiv, scale);
  EXPECT_FLOAT_EQ(1, scale);
  simulateMultiTargetZoom(webViewHelper.webView(), bottomDiv, scale);
  EXPECT_FLOAT_EQ(1, scale);
  simulateMultiTargetZoom(webViewHelper.webView(), viewportRect, scale);
  EXPECT_FLOAT_EQ(1, scale);
  webViewHelper.webView()->setPageScaleFactor(
      webViewHelper.webView()->minimumPageScaleFactor());
  simulateMultiTargetZoom(webViewHelper.webView(), topDiv, scale);
  EXPECT_FLOAT_EQ(1, scale);
}

TEST_F(WebFrameTest, DontZoomInOnFocusedInTouchAction) {
  registerMockedHttpURLLoad("textbox_in_touch_action.html");

  int viewportWidth = 600;
  int viewportHeight = 1000;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "textbox_in_touch_action.html");
  webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 4);
  webViewHelper.webView()->enableFakePageScaleAnimationForTesting(true);
  webViewHelper.webView()->page()->settings().setTextAutosizingEnabled(false);
  webViewHelper.webView()->settings()->setAutoZoomFocusedNodeToLegibleScale(
      true);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  float initialScale = webViewHelper.webView()->pageScaleFactor();

  // Focus the first textbox that's in a touch-action: pan-x ancestor, this
  // shouldn't cause an autozoom since pan-x disables pinch-zoom.
  webViewHelper.webView()->advanceFocus(false);
  webViewHelper.webView()->scrollFocusedEditableElementIntoRect(WebRect());
  EXPECT_EQ(
      webViewHelper.webView()->fakePageScaleAnimationPageScaleForTesting(), 0);

  setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(0, 0),
                             initialScale);
  ASSERT_EQ(initialScale, webViewHelper.webView()->pageScaleFactor());

  // Focus the second textbox that's in a touch-action: manipulation ancestor,
  // this should cause an autozoom since it allows pinch-zoom.
  webViewHelper.webView()->advanceFocus(false);
  webViewHelper.webView()->scrollFocusedEditableElementIntoRect(WebRect());
  EXPECT_GT(
      webViewHelper.webView()->fakePageScaleAnimationPageScaleForTesting(),
      initialScale);

  setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(0, 0),
                             initialScale);
  ASSERT_EQ(initialScale, webViewHelper.webView()->pageScaleFactor());

  // Focus the third textbox that has a touch-action: pan-x ancestor, this
  // should cause an autozoom since it's seperated from the node with the
  // touch-action by an overflow:scroll element.
  webViewHelper.webView()->advanceFocus(false);
  webViewHelper.webView()->scrollFocusedEditableElementIntoRect(WebRect());
  EXPECT_GT(
      webViewHelper.webView()->fakePageScaleAnimationPageScaleForTesting(),
      initialScale);
}

TEST_F(WebFrameTest, DivScrollIntoEditableTest) {
  registerMockedHttpURLLoad("get_scale_for_zoom_into_editable_test.html");

  const bool autoZoomToLegibleScale = true;
  int viewportWidth = 450;
  int viewportHeight = 300;
  float leftBoxRatio = 0.3f;
  int caretPadding = 10;
  float minReadableCaretHeight = 16.0f;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL +
                                  "get_scale_for_zoom_into_editable_test.html");
  webViewHelper.webView()->page()->settings().setTextAutosizingEnabled(false);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 4);

  webViewHelper.webView()->enableFakePageScaleAnimationForTesting(true);

  WebRect editBoxWithText(200, 200, 250, 20);
  WebRect editBoxWithNoText(200, 250, 250, 20);

  // Test scrolling the focused node
  // The edit box is shorter and narrower than the viewport when legible.
  webViewHelper.webView()->advanceFocus(false);
  // Set the caret to the end of the input box.
  webViewHelper.webView()
      ->mainFrame()
      ->document()
      .getElementById("EditBoxWithText")
      .to<WebInputElement>()
      .setSelectionRange(1000, 1000);
  setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(0, 0), 1);
  WebRect rect, caret;
  webViewHelper.webView()->selectionBounds(caret, rect);

  // Set the page scale to be smaller than the minimal readable scale.
  float initialScale = minReadableCaretHeight / caret.height * 0.5f;
  setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(0, 0),
                             initialScale);

  float scale;
  IntPoint scroll;
  bool needAnimation;
  webViewHelper.webView()->computeScaleAndScrollForFocusedNode(
      webViewHelper.webView()->focusedElement(), autoZoomToLegibleScale, scale,
      scroll, needAnimation);
  EXPECT_TRUE(needAnimation);
  // The edit box should be left aligned with a margin for possible label.
  int hScroll = editBoxWithText.x - leftBoxRatio * viewportWidth / scale;
  EXPECT_NEAR(hScroll, scroll.x(), 2);
  int vScroll =
      editBoxWithText.y - (viewportHeight / scale - editBoxWithText.height) / 2;
  EXPECT_NEAR(vScroll, scroll.y(), 2);
  EXPECT_NEAR(minReadableCaretHeight / caret.height, scale, 0.1);

  // The edit box is wider than the viewport when legible.
  viewportWidth = 200;
  viewportHeight = 150;
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(0, 0),
                             initialScale);
  webViewHelper.webView()->computeScaleAndScrollForFocusedNode(
      webViewHelper.webView()->focusedElement(), autoZoomToLegibleScale, scale,
      scroll, needAnimation);
  EXPECT_TRUE(needAnimation);
  // The caret should be right aligned since the caret would be offscreen when
  // the edit box is left aligned.
  hScroll = caret.x + caret.width + caretPadding - viewportWidth / scale;
  EXPECT_NEAR(hScroll, scroll.x(), 2);
  EXPECT_NEAR(minReadableCaretHeight / caret.height, scale, 0.1);

  setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(0, 0),
                             initialScale);
  // Move focus to edit box with text.
  webViewHelper.webView()->advanceFocus(false);
  webViewHelper.webView()->computeScaleAndScrollForFocusedNode(
      webViewHelper.webView()->focusedElement(), autoZoomToLegibleScale, scale,
      scroll, needAnimation);
  EXPECT_TRUE(needAnimation);
  // The edit box should be left aligned.
  hScroll = editBoxWithNoText.x;
  EXPECT_NEAR(hScroll, scroll.x(), 2);
  vScroll = editBoxWithNoText.y -
            (viewportHeight / scale - editBoxWithNoText.height) / 2;
  EXPECT_NEAR(vScroll, scroll.y(), 2);
  EXPECT_NEAR(minReadableCaretHeight / caret.height, scale, 0.1);

  // Move focus back to the first edit box.
  webViewHelper.webView()->advanceFocus(true);
  // Zoom out slightly.
  const float withinToleranceScale = scale * 0.9f;
  setScaleAndScrollAndLayout(webViewHelper.webView(), scroll,
                             withinToleranceScale);
  // Move focus back to the second edit box.
  webViewHelper.webView()->advanceFocus(false);
  webViewHelper.webView()->computeScaleAndScrollForFocusedNode(
      webViewHelper.webView()->focusedElement(), autoZoomToLegibleScale, scale,
      scroll, needAnimation);
  // The scale should not be adjusted as the zoomed out scale was sufficiently
  // close to the previously focused scale.
  EXPECT_FALSE(needAnimation);
}

TEST_F(WebFrameTest, DivScrollIntoEditablePreservePageScaleTest) {
  registerMockedHttpURLLoad("get_scale_for_zoom_into_editable_test.html");

  const bool autoZoomToLegibleScale = true;
  const int viewportWidth = 450;
  const int viewportHeight = 300;
  const float minReadableCaretHeight = 16.0f;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL +
                                  "get_scale_for_zoom_into_editable_test.html");
  webViewHelper.webView()->page()->settings().setTextAutosizingEnabled(false);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewHelper.webView()->enableFakePageScaleAnimationForTesting(true);

  const WebRect editBoxWithText(200, 200, 250, 20);

  webViewHelper.webView()->advanceFocus(false);
  // Set the caret to the begining of the input box.
  webViewHelper.webView()
      ->mainFrame()
      ->document()
      .getElementById("EditBoxWithText")
      .to<WebInputElement>()
      .setSelectionRange(0, 0);
  setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(0, 0), 1);
  WebRect rect, caret;
  webViewHelper.webView()->selectionBounds(caret, rect);

  // Set the page scale to be twice as large as the minimal readable scale.
  float newScale = minReadableCaretHeight / caret.height * 2.0;
  setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(0, 0), newScale);

  float scale;
  IntPoint scroll;
  bool needAnimation;
  webViewHelper.webView()->computeScaleAndScrollForFocusedNode(
      webViewHelper.webView()->focusedElement(), autoZoomToLegibleScale, scale,
      scroll, needAnimation);
  EXPECT_TRUE(needAnimation);
  // Edit box and caret should be left alinged
  int hScroll = editBoxWithText.x;
  EXPECT_NEAR(hScroll, scroll.x(), 1);
  int vScroll =
      editBoxWithText.y - (viewportHeight / scale - editBoxWithText.height) / 2;
  EXPECT_NEAR(vScroll, scroll.y(), 1);
  // Page scale have to be unchanged
  EXPECT_EQ(newScale, scale);

  // Set page scale and scroll such that edit box will be under the screen
  newScale = 3.0;
  hScroll = 200;
  setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(hScroll, 0),
                             newScale);
  webViewHelper.webView()->computeScaleAndScrollForFocusedNode(
      webViewHelper.webView()->focusedElement(), autoZoomToLegibleScale, scale,
      scroll, needAnimation);
  EXPECT_TRUE(needAnimation);
  // Horizontal scroll have to be the same
  EXPECT_NEAR(hScroll, scroll.x(), 1);
  vScroll =
      editBoxWithText.y - (viewportHeight / scale - editBoxWithText.height) / 2;
  EXPECT_NEAR(vScroll, scroll.y(), 1);
  // Page scale have to be unchanged
  EXPECT_EQ(newScale, scale);
}

// Tests the scroll into view functionality when
// autoZoomeFocusedNodeToLegibleScale set to false. i.e. The path non-Android
// platforms take.
TEST_F(WebFrameTest, DivScrollIntoEditableTestZoomToLegibleScaleDisabled) {
  registerMockedHttpURLLoad("get_scale_for_zoom_into_editable_test.html");

  const bool autoZoomToLegibleScale = false;
  int viewportWidth = 100;
  int viewportHeight = 100;
  float leftBoxRatio = 0.3f;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL +
                                  "get_scale_for_zoom_into_editable_test.html");
  webViewHelper.webView()->page()->settings().setTextAutosizingEnabled(false);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewHelper.webView()->setDefaultPageScaleLimits(0.25f, 4);

  webViewHelper.webView()->enableFakePageScaleAnimationForTesting(true);

  WebRect editBoxWithText(200, 200, 250, 20);
  WebRect editBoxWithNoText(200, 250, 250, 20);

  // Test scrolling the focused node
  // Since we're zoomed out, the caret is considered too small to be legible and
  // so we'd normally zoom in. Make sure we don't change scale since the
  // auto-zoom setting is off.

  // Focus the second empty textbox.
  webViewHelper.webView()->advanceFocus(false);
  webViewHelper.webView()->advanceFocus(false);

  // Set the page scale to be smaller than the minimal readable scale.
  float initialScale = 0.25f;
  setScaleAndScrollAndLayout(webViewHelper.webView(), WebPoint(0, 0),
                             initialScale);

  float scale;
  IntPoint scroll;
  bool needAnimation;
  webViewHelper.webView()->computeScaleAndScrollForFocusedNode(
      webViewHelper.webView()->focusedElement(), autoZoomToLegibleScale, scale,
      scroll, needAnimation);

  // There should be no change in page scale.
  EXPECT_EQ(initialScale, scale);
  // The edit box should be left aligned with a margin for possible label.
  EXPECT_TRUE(needAnimation);
  int hScroll = editBoxWithNoText.x - leftBoxRatio * viewportWidth / scale;
  EXPECT_NEAR(hScroll, scroll.x(), 2);
  int vScroll = editBoxWithNoText.y -
                (viewportHeight / scale - editBoxWithNoText.height) / 2;
  EXPECT_NEAR(vScroll, scroll.y(), 2);

  setScaleAndScrollAndLayout(webViewHelper.webView(), scroll, scale);

  // Select the first textbox.
  webViewHelper.webView()->advanceFocus(true);
  WebRect rect, caret;
  webViewHelper.webView()->selectionBounds(caret, rect);
  webViewHelper.webView()->computeScaleAndScrollForFocusedNode(
      webViewHelper.webView()->focusedElement(), autoZoomToLegibleScale, scale,
      scroll, needAnimation);

  // There should be no change at all since the textbox is fully visible
  // already.
  EXPECT_EQ(initialScale, scale);
  EXPECT_FALSE(needAnimation);
}

TEST_P(ParameterizedWebFrameTest, CharacterIndexAtPointWithPinchZoom) {
  registerMockedHttpURLLoad("sometext.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "sometext.html");
  webViewHelper.resize(WebSize(640, 480));

  webViewHelper.webView()->setPageScaleFactor(2);
  webViewHelper.webView()->setVisualViewportOffset(WebFloatPoint(50, 60));

  WebRect baseRect;
  WebRect extentRect;

  WebLocalFrame* mainFrame =
      webViewHelper.webView()->mainFrame()->toWebLocalFrame();
  size_t ix = mainFrame->characterIndexForPoint(WebPoint(320, 388));

  EXPECT_EQ(2ul, ix);
}

TEST_P(ParameterizedWebFrameTest, FirstRectForCharacterRangeWithPinchZoom) {
  registerMockedHttpURLLoad("textbox.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "textbox.html", true);
  webViewHelper.resize(WebSize(640, 480));

  WebLocalFrame* mainFrame =
      webViewHelper.webView()->mainFrame()->toWebLocalFrame();
  mainFrame->executeScript(WebScriptSource("selectRange();"));

  WebRect oldRect;
  mainFrame->firstRectForCharacterRange(0, 5, oldRect);

  WebFloatPoint visualOffset(100, 130);
  float scale = 2;
  webViewHelper.webView()->setPageScaleFactor(scale);
  webViewHelper.webView()->setVisualViewportOffset(visualOffset);

  WebRect baseRect;
  WebRect extentRect;

  WebRect rect;
  mainFrame->firstRectForCharacterRange(0, 5, rect);

  EXPECT_EQ((oldRect.x - visualOffset.x) * scale, rect.x);
  EXPECT_EQ((oldRect.y - visualOffset.y) * scale, rect.y);
  EXPECT_EQ(oldRect.width * scale, rect.width);
  EXPECT_EQ(oldRect.height * scale, rect.height);
}
class TestReloadDoesntRedirectWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  WebNavigationPolicy decidePolicyForNavigation(
      const NavigationPolicyInfo& info) override {
    EXPECT_FALSE(info.extraData);
    return WebNavigationPolicyCurrentTab;
  }
};

TEST_P(ParameterizedWebFrameTest, ReloadDoesntSetRedirect) {
  // Test for case in http://crbug.com/73104. Reloading a frame very quickly
  // would sometimes call decidePolicyForNavigation with isRedirect=true
  registerMockedHttpURLLoad("form.html");

  TestReloadDoesntRedirectWebFrameClient webFrameClient;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "form.html", false,
                                  &webFrameClient);

  webViewHelper.webView()->mainFrame()->reload(
      WebFrameLoadType::ReloadBypassingCache);
  // start another reload before request is delivered.
  FrameTestHelpers::reloadFrameIgnoringCache(
      webViewHelper.webView()->mainFrame());
}

class ClearScrollStateOnCommitWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  void didCommitProvisionalLoad(WebLocalFrame* frame,
                                const WebHistoryItem&,
                                WebHistoryCommitType) override {
    frame->view()->resetScrollAndScaleState();
  }
};

TEST_F(WebFrameTest, ReloadWithOverrideURLPreservesState) {
  const std::string firstURL = "200-by-300.html";
  const std::string secondURL = "content-width-1000.html";
  const std::string thirdURL = "very_tall_div.html";
  const float pageScaleFactor = 1.1684f;
  const int pageWidth = 120;
  const int pageHeight = 100;

  registerMockedHttpURLLoad(firstURL);
  registerMockedHttpURLLoad(secondURL);
  registerMockedHttpURLLoad(thirdURL);

  FrameTestHelpers::WebViewHelper webViewHelper;
  ClearScrollStateOnCommitWebFrameClient client;
  webViewHelper.initializeAndLoad(m_baseURL + firstURL, true, &client);
  webViewHelper.resize(WebSize(pageWidth, pageHeight));
  webViewHelper.webView()->mainFrame()->setScrollOffset(
      WebSize(pageWidth / 4, pageHeight / 4));
  webViewHelper.webView()->setPageScaleFactor(pageScaleFactor);

  WebSize previousOffset = webViewHelper.webView()->mainFrame()->scrollOffset();
  float previousScale = webViewHelper.webView()->pageScaleFactor();

  // Reload the page and end up at the same url. State should be propagated.
  webViewHelper.webView()->mainFrame()->reloadWithOverrideURL(
      toKURL(m_baseURL + firstURL), WebFrameLoadType::Reload);
  FrameTestHelpers::pumpPendingRequestsForFrameToLoad(
      webViewHelper.webView()->mainFrame());
  EXPECT_EQ(previousOffset.width,
            webViewHelper.webView()->mainFrame()->scrollOffset().width);
  EXPECT_EQ(previousOffset.height,
            webViewHelper.webView()->mainFrame()->scrollOffset().height);
  EXPECT_EQ(previousScale, webViewHelper.webView()->pageScaleFactor());

  // Reload the page using the cache. State should not be propagated.
  webViewHelper.webView()->mainFrame()->reloadWithOverrideURL(
      toKURL(m_baseURL + secondURL), WebFrameLoadType::Reload);
  FrameTestHelpers::pumpPendingRequestsForFrameToLoad(
      webViewHelper.webView()->mainFrame());
  EXPECT_EQ(0, webViewHelper.webView()->mainFrame()->scrollOffset().width);
  EXPECT_EQ(0, webViewHelper.webView()->mainFrame()->scrollOffset().height);
  EXPECT_EQ(1.0f, webViewHelper.webView()->pageScaleFactor());

  // Reload the page while ignoring the cache. State should not be propagated.
  webViewHelper.webView()->mainFrame()->reloadWithOverrideURL(
      toKURL(m_baseURL + thirdURL), WebFrameLoadType::ReloadBypassingCache);
  FrameTestHelpers::pumpPendingRequestsForFrameToLoad(
      webViewHelper.webView()->mainFrame());
  EXPECT_EQ(0, webViewHelper.webView()->mainFrame()->scrollOffset().width);
  EXPECT_EQ(0, webViewHelper.webView()->mainFrame()->scrollOffset().height);
  EXPECT_EQ(1.0f, webViewHelper.webView()->pageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest, ReloadWhileProvisional) {
  // Test that reloading while the previous load is still pending does not cause
  // the initial request to get lost.
  registerMockedHttpURLLoad("fixed_layout.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize();
  WebURLRequest request;
  request.setURL(toKURL(m_baseURL + "fixed_layout.html"));
  request.setRequestorOrigin(WebSecurityOrigin::createUnique());
  webViewHelper.webView()->mainFrame()->loadRequest(request);
  // start reload before first request is delivered.
  FrameTestHelpers::reloadFrameIgnoringCache(
      webViewHelper.webView()->mainFrame());

  WebDataSource* dataSource =
      webViewHelper.webView()->mainFrame()->dataSource();
  ASSERT_TRUE(dataSource);
  EXPECT_EQ(toKURL(m_baseURL + "fixed_layout.html"),
            KURL(dataSource->request().url()));
}

TEST_P(ParameterizedWebFrameTest, AppendRedirects) {
  const std::string firstURL = "about:blank";
  const std::string secondURL = "http://internal.test";

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(firstURL, true);

  WebDataSource* dataSource =
      webViewHelper.webView()->mainFrame()->dataSource();
  ASSERT_TRUE(dataSource);
  dataSource->appendRedirect(toKURL(secondURL));

  WebVector<WebURL> redirects;
  dataSource->redirectChain(redirects);
  ASSERT_EQ(2U, redirects.size());
  EXPECT_EQ(toKURL(firstURL), KURL(redirects[0]));
  EXPECT_EQ(toKURL(secondURL), KURL(redirects[1]));
}

TEST_P(ParameterizedWebFrameTest, IframeRedirect) {
  registerMockedHttpURLLoad("iframe_redirect.html");
  registerMockedHttpURLLoad("visible_iframe.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "iframe_redirect.html", true);
  // Pump pending requests one more time. The test page loads script that
  // navigates.
  FrameTestHelpers::pumpPendingRequestsForFrameToLoad(
      webViewHelper.webView()->mainFrame());

  WebFrame* iframe = webViewHelper.webView()->findFrameByName(
      WebString::fromUTF8("ifr"), nullptr);
  ASSERT_TRUE(iframe);
  WebDataSource* iframeDataSource = iframe->dataSource();
  ASSERT_TRUE(iframeDataSource);
  WebVector<WebURL> redirects;
  iframeDataSource->redirectChain(redirects);
  ASSERT_EQ(2U, redirects.size());
  EXPECT_EQ(toKURL("about:blank"), KURL(redirects[0]));
  EXPECT_EQ(toKURL("http://internal.test/visible_iframe.html"),
            KURL(redirects[1]));
}

TEST_P(ParameterizedWebFrameTest, ClearFocusedNodeTest) {
  registerMockedHttpURLLoad("iframe_clear_focused_node_test.html");
  registerMockedHttpURLLoad("autofocus_input_field_iframe.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "iframe_clear_focused_node_test.html", true);

  // Clear the focused node.
  webViewHelper.webView()->clearFocusedElement();

  // Now retrieve the FocusedNode and test it should be null.
  EXPECT_EQ(0, webViewHelper.webView()->focusedElement());
}

// Implementation of WebFrameClient that tracks the v8 contexts that are created
// and destroyed for verification.
class ContextLifetimeTestWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  struct Notification {
   public:
    Notification(WebLocalFrame* frame,
                 v8::Local<v8::Context> context,
                 int worldId)
        : frame(frame),
          context(context->GetIsolate(), context),
          worldId(worldId) {}

    ~Notification() { context.Reset(); }

    bool Equals(Notification* other) {
      return other && frame == other->frame && context == other->context &&
             worldId == other->worldId;
    }

    WebLocalFrame* frame;
    v8::Persistent<v8::Context> context;
    int worldId;
  };

  ~ContextLifetimeTestWebFrameClient() override { reset(); }

  void reset() {
    createNotifications.clear();
    releaseNotifications.clear();
  }

  Vector<std::unique_ptr<Notification>> createNotifications;
  Vector<std::unique_ptr<Notification>> releaseNotifications;

 private:
  void didCreateScriptContext(WebLocalFrame* frame,
                              v8::Local<v8::Context> context,
                              int extensionGroup,
                              int worldId) override {
    createNotifications.append(
        wrapUnique(new Notification(frame, context, worldId)));
  }

  void willReleaseScriptContext(WebLocalFrame* frame,
                                v8::Local<v8::Context> context,
                                int worldId) override {
    releaseNotifications.append(
        wrapUnique(new Notification(frame, context, worldId)));
  }
};

TEST_P(ParameterizedWebFrameTest, ContextNotificationsLoadUnload) {
  v8::HandleScope handleScope(v8::Isolate::GetCurrent());

  registerMockedHttpURLLoad("context_notifications_test.html");
  registerMockedHttpURLLoad("context_notifications_test_frame.html");

  // Load a frame with an iframe, make sure we get the right create
  // notifications.
  ContextLifetimeTestWebFrameClient webFrameClient;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "context_notifications_test.html",
                                  true, &webFrameClient);

  WebFrame* mainFrame = webViewHelper.webView()->mainFrame();
  WebFrame* childFrame = mainFrame->firstChild();

  ASSERT_EQ(2u, webFrameClient.createNotifications.size());
  EXPECT_EQ(0u, webFrameClient.releaseNotifications.size());

  auto& firstCreateNotification = webFrameClient.createNotifications[0];
  auto& secondCreateNotification = webFrameClient.createNotifications[1];

  EXPECT_EQ(mainFrame, firstCreateNotification->frame);
  EXPECT_EQ(mainFrame->mainWorldScriptContext(),
            firstCreateNotification->context);
  EXPECT_EQ(0, firstCreateNotification->worldId);

  EXPECT_EQ(childFrame, secondCreateNotification->frame);
  EXPECT_EQ(childFrame->mainWorldScriptContext(),
            secondCreateNotification->context);
  EXPECT_EQ(0, secondCreateNotification->worldId);

  // Close the view. We should get two release notifications that are exactly
  // the same as the create ones, in reverse order.
  webViewHelper.reset();

  ASSERT_EQ(2u, webFrameClient.releaseNotifications.size());
  auto& firstReleaseNotification = webFrameClient.releaseNotifications[0];
  auto& secondReleaseNotification = webFrameClient.releaseNotifications[1];

  ASSERT_TRUE(firstCreateNotification->Equals(secondReleaseNotification.get()));
  ASSERT_TRUE(secondCreateNotification->Equals(firstReleaseNotification.get()));
}

TEST_P(ParameterizedWebFrameTest, ContextNotificationsReload) {
  v8::HandleScope handleScope(v8::Isolate::GetCurrent());

  registerMockedHttpURLLoad("context_notifications_test.html");
  registerMockedHttpURLLoad("context_notifications_test_frame.html");

  ContextLifetimeTestWebFrameClient webFrameClient;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "context_notifications_test.html",
                                  true, &webFrameClient);

  // Refresh, we should get two release notifications and two more create
  // notifications.
  FrameTestHelpers::reloadFrame(webViewHelper.webView()->mainFrame());
  ASSERT_EQ(4u, webFrameClient.createNotifications.size());
  ASSERT_EQ(2u, webFrameClient.releaseNotifications.size());

  // The two release notifications we got should be exactly the same as the
  // first two create notifications.
  for (size_t i = 0; i < webFrameClient.releaseNotifications.size(); ++i) {
    EXPECT_TRUE(webFrameClient.releaseNotifications[i]->Equals(
        webFrameClient
            .createNotifications[webFrameClient.createNotifications.size() - 3 -
                                 i]
            .get()));
  }

  // The last two create notifications should be for the current frames and
  // context.
  WebFrame* mainFrame = webViewHelper.webView()->mainFrame();
  WebFrame* childFrame = mainFrame->firstChild();
  auto& firstRefreshNotification = webFrameClient.createNotifications[2];
  auto& secondRefreshNotification = webFrameClient.createNotifications[3];

  EXPECT_EQ(mainFrame, firstRefreshNotification->frame);
  EXPECT_EQ(mainFrame->mainWorldScriptContext(),
            firstRefreshNotification->context);
  EXPECT_EQ(0, firstRefreshNotification->worldId);

  EXPECT_EQ(childFrame, secondRefreshNotification->frame);
  EXPECT_EQ(childFrame->mainWorldScriptContext(),
            secondRefreshNotification->context);
  EXPECT_EQ(0, secondRefreshNotification->worldId);
}

TEST_P(ParameterizedWebFrameTest, ContextNotificationsIsolatedWorlds) {
  v8::Isolate* isolate = v8::Isolate::GetCurrent();
  v8::HandleScope handleScope(isolate);

  registerMockedHttpURLLoad("context_notifications_test.html");
  registerMockedHttpURLLoad("context_notifications_test_frame.html");

  ContextLifetimeTestWebFrameClient webFrameClient;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "context_notifications_test.html",
                                  true, &webFrameClient);

  // Add an isolated world.
  webFrameClient.reset();

  int isolatedWorldId = 42;
  WebScriptSource scriptSource("hi!");
  int numSources = 1;
  int extensionGroup = 0;
  webViewHelper.webView()->mainFrame()->executeScriptInIsolatedWorld(
      isolatedWorldId, &scriptSource, numSources, extensionGroup);

  // We should now have a new create notification.
  ASSERT_EQ(1u, webFrameClient.createNotifications.size());
  auto& notification = webFrameClient.createNotifications[0];
  ASSERT_EQ(isolatedWorldId, notification->worldId);
  ASSERT_EQ(webViewHelper.webView()->mainFrame(), notification->frame);

  // We don't have an API to enumarate isolated worlds for a frame, but we can
  // at least assert that the context we got is *not* the main world's context.
  ASSERT_NE(webViewHelper.webView()->mainFrame()->mainWorldScriptContext(),
            v8::Local<v8::Context>::New(isolate, notification->context));

  webViewHelper.reset();

  // We should have gotten three release notifications (one for each of the
  // frames, plus one for the isolated context).
  ASSERT_EQ(3u, webFrameClient.releaseNotifications.size());

  // And one of them should be exactly the same as the create notification for
  // the isolated context.
  int matchCount = 0;
  for (size_t i = 0; i < webFrameClient.releaseNotifications.size(); ++i) {
    if (webFrameClient.releaseNotifications[i]->Equals(
            webFrameClient.createNotifications[0].get()))
      ++matchCount;
  }
  EXPECT_EQ(1, matchCount);
}

TEST_P(ParameterizedWebFrameTest, FindInPage) {
  registerMockedHttpURLLoad("find.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "find.html");
  ASSERT_TRUE(webViewHelper.webView()->mainFrameImpl());
  WebLocalFrame* frame = webViewHelper.webView()->mainFrameImpl();
  const int findIdentifier = 12345;
  WebFindOptions options;

  // Find in a <div> element.
  EXPECT_TRUE(
      frame->find(findIdentifier, WebString::fromUTF8("bar1"), options, false));
  frame->stopFinding(WebLocalFrame::StopFindActionKeepSelection);
  WebRange range = frame->selectionRange();
  EXPECT_EQ(5, range.startOffset());
  EXPECT_EQ(9, range.endOffset());
  EXPECT_TRUE(frame->document().focusedElement().isNull());

  // Find in an <input> value.
  EXPECT_TRUE(
      frame->find(findIdentifier, WebString::fromUTF8("bar2"), options, false));
  // Confirm stopFinding(WebLocalFrame::StopFindActionKeepSelection) sets the
  // selection on the found text.
  frame->stopFinding(WebLocalFrame::StopFindActionKeepSelection);
  range = frame->selectionRange();
  ASSERT_FALSE(range.isNull());
  EXPECT_EQ(5, range.startOffset());
  EXPECT_EQ(9, range.endOffset());
  EXPECT_TRUE(frame->document().focusedElement().hasHTMLTagName("input"));

  // Find in a <textarea> content.
  EXPECT_TRUE(
      frame->find(findIdentifier, WebString::fromUTF8("bar3"), options, false));
  // Confirm stopFinding(WebLocalFrame::StopFindActionKeepSelection) sets the
  // selection on the found text.
  frame->stopFinding(WebLocalFrame::StopFindActionKeepSelection);
  range = frame->selectionRange();
  ASSERT_FALSE(range.isNull());
  EXPECT_EQ(5, range.startOffset());
  EXPECT_EQ(9, range.endOffset());
  EXPECT_TRUE(frame->document().focusedElement().hasHTMLTagName("textarea"));

  // Find in a contentEditable element.
  EXPECT_TRUE(
      frame->find(findIdentifier, WebString::fromUTF8("bar4"), options, false));
  // Confirm stopFinding(WebLocalFrame::StopFindActionKeepSelection) sets the
  // selection on the found text.
  frame->stopFinding(WebLocalFrame::StopFindActionKeepSelection);
  range = frame->selectionRange();
  ASSERT_FALSE(range.isNull());
  EXPECT_EQ(0, range.startOffset());
  EXPECT_EQ(4, range.endOffset());
  // "bar4" is surrounded by <span>, but the focusable node should be the parent
  // <div>.
  EXPECT_TRUE(frame->document().focusedElement().hasHTMLTagName("div"));

  // Find in <select> content.
  EXPECT_FALSE(
      frame->find(findIdentifier, WebString::fromUTF8("bar5"), options, false));
  // If there are any matches, stopFinding will set the selection on the found
  // text.  However, we do not expect any matches, so check that the selection
  // is null.
  frame->stopFinding(WebLocalFrame::StopFindActionKeepSelection);
  range = frame->selectionRange();
  ASSERT_TRUE(range.isNull());
}

TEST_P(ParameterizedWebFrameTest, GetContentAsPlainText) {
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad("about:blank", true);
  // We set the size because it impacts line wrapping, which changes the
  // resulting text value.
  webViewHelper.resize(WebSize(640, 480));
  WebFrame* frame = webViewHelper.webView()->mainFrame();

  // Generate a simple test case.
  const char simpleSource[] = "<div>Foo bar</div><div></div>baz";
  KURL testURL = toKURL("about:blank");
  FrameTestHelpers::loadHTMLString(frame, simpleSource, testURL);

  // Make sure it comes out OK.
  const std::string expected("Foo bar\nbaz");
  WebString text = WebFrameContentDumper::dumpWebViewAsText(
      webViewHelper.webView(), std::numeric_limits<size_t>::max());
  EXPECT_EQ(expected, text.utf8());

  // Try reading the same one with clipping of the text.
  const int length = 5;
  text =
      WebFrameContentDumper::dumpWebViewAsText(webViewHelper.webView(), length);
  EXPECT_EQ(expected.substr(0, length), text.utf8());

  // Now do a new test with a subframe.
  const char outerFrameSource[] = "Hello<iframe></iframe> world";
  FrameTestHelpers::loadHTMLString(frame, outerFrameSource, testURL);

  // Load something into the subframe.
  WebFrame* subframe = frame->firstChild();
  ASSERT_TRUE(subframe);
  FrameTestHelpers::loadHTMLString(subframe, "sub<p>text", testURL);

  text = WebFrameContentDumper::dumpWebViewAsText(
      webViewHelper.webView(), std::numeric_limits<size_t>::max());
  EXPECT_EQ("Hello world\n\nsub\ntext", text.utf8());

  // Get the frame text where the subframe separator falls on the boundary of
  // what we'll take. There used to be a crash in this case.
  text = WebFrameContentDumper::dumpWebViewAsText(webViewHelper.webView(), 12);
  EXPECT_EQ("Hello world", text.utf8());
}

TEST_P(ParameterizedWebFrameTest, GetFullHtmlOfPage) {
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad("about:blank", true);
  WebLocalFrame* frame = webViewHelper.webView()->mainFrameImpl();

  // Generate a simple test case.
  const char simpleSource[] = "<p>Hello</p><p>World</p>";
  KURL testURL = toKURL("about:blank");
  FrameTestHelpers::loadHTMLString(frame, simpleSource, testURL);

  WebString text = WebFrameContentDumper::dumpWebViewAsText(
      webViewHelper.webView(), std::numeric_limits<size_t>::max());
  EXPECT_EQ("Hello\n\nWorld", text.utf8());

  const std::string html = WebFrameContentDumper::dumpAsMarkup(frame).utf8();

  // Load again with the output html.
  FrameTestHelpers::loadHTMLString(frame, html, testURL);

  EXPECT_EQ(html, WebFrameContentDumper::dumpAsMarkup(frame).utf8());

  text = WebFrameContentDumper::dumpWebViewAsText(
      webViewHelper.webView(), std::numeric_limits<size_t>::max());
  EXPECT_EQ("Hello\n\nWorld", text.utf8());

  // Test selection check
  EXPECT_FALSE(frame->hasSelection());
  frame->executeCommand(WebString::fromUTF8("SelectAll"));
  EXPECT_TRUE(frame->hasSelection());
  frame->executeCommand(WebString::fromUTF8("Unselect"));
  EXPECT_FALSE(frame->hasSelection());
  WebString selectionHtml = frame->selectionAsMarkup();
  EXPECT_TRUE(selectionHtml.isEmpty());
}

class TestExecuteScriptDuringDidCreateScriptContext
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  void didCreateScriptContext(WebLocalFrame* frame,
                              v8::Local<v8::Context> context,
                              int extensionGroup,
                              int worldId) override {
    frame->executeScript(WebScriptSource("window.history = 'replaced';"));
  }
};

TEST_P(ParameterizedWebFrameTest, ExecuteScriptDuringDidCreateScriptContext) {
  registerMockedHttpURLLoad("hello_world.html");

  TestExecuteScriptDuringDidCreateScriptContext webFrameClient;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "hello_world.html", true,
                                  &webFrameClient);

  FrameTestHelpers::reloadFrame(webViewHelper.webView()->mainFrame());
}

class FindUpdateWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
 public:
  FindUpdateWebFrameClient()
      : m_findResultsAreReady(false), m_count(-1), m_activeIndex(-1) {}

  void reportFindInPageMatchCount(int, int count, bool finalUpdate) override {
    m_count = count;
    if (finalUpdate)
      m_findResultsAreReady = true;
  }

  void reportFindInPageSelection(int,
                                 int activeMatchOrdinal,
                                 const WebRect&) override {
    m_activeIndex = activeMatchOrdinal;
  }

  bool findResultsAreReady() const { return m_findResultsAreReady; }
  int count() const { return m_count; }
  int activeIndex() const { return m_activeIndex; }

 private:
  bool m_findResultsAreReady;
  int m_count;
  int m_activeIndex;
};

TEST_P(ParameterizedWebFrameTest, FindInPageMatchRects) {
  registerMockedHttpURLLoad("find_in_page_frame.html");

  FindUpdateWebFrameClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "find_in_page_frame.html", true,
                                  &client);
  webViewHelper.resize(WebSize(640, 480));
  webViewHelper.webView()->setMaximumLegibleScale(1.f);
  webViewHelper.webView()->updateAllLifecyclePhases();
  runPendingTasks();

  // Note that the 'result 19' in the <select> element is not expected to
  // produce a match. Also, results 00 and 01 are in a different frame that is
  // not included in this test.
  const char kFindString[] = "result";
  const int kFindIdentifier = 12345;
  const int kNumResults = 17;

  WebFindOptions options;
  WebString searchText = WebString::fromUTF8(kFindString);
  WebLocalFrameImpl* mainFrame = webViewHelper.webView()->mainFrameImpl();
  EXPECT_TRUE(mainFrame->find(kFindIdentifier, searchText, options, false));

  mainFrame->ensureTextFinder().resetMatchCount();

  for (WebLocalFrameImpl* frame = mainFrame; frame;
       frame = static_cast<WebLocalFrameImpl*>(frame->traverseNext(false)))
    frame->ensureTextFinder().scopeStringMatches(kFindIdentifier, searchText,
                                                 options, true);

  runPendingTasks();
  EXPECT_TRUE(client.findResultsAreReady());

  WebVector<WebFloatRect> webMatchRects;
  mainFrame->findMatchRects(webMatchRects);
  ASSERT_EQ(static_cast<size_t>(kNumResults), webMatchRects.size());
  int rectsVersion = mainFrame->findMatchMarkersVersion();

  for (int resultIndex = 0; resultIndex < kNumResults; ++resultIndex) {
    FloatRect resultRect = static_cast<FloatRect>(webMatchRects[resultIndex]);

    // Select the match by the center of its rect.
    EXPECT_EQ(mainFrame->selectNearestFindMatch(resultRect.center(), 0),
              resultIndex + 1);

    // Check that the find result ordering matches with our expectations.
    Range* result = mainFrame->textFinder()->activeMatch();
    ASSERT_TRUE(result);
    result->setEnd(result->endContainer(), result->endOffset() + 3);
    EXPECT_EQ(result->text(),
              String::format("%s %02d", kFindString, resultIndex + 2));

    // Verify that the expected match rect also matches the currently active
    // match.  Compare the enclosing rects to prevent precision issues caused by
    // CSS transforms.
    FloatRect activeMatch = mainFrame->activeFindMatchRect();
    EXPECT_EQ(enclosingIntRect(activeMatch), enclosingIntRect(resultRect));

    // The rects version should not have changed.
    EXPECT_EQ(mainFrame->findMatchMarkersVersion(), rectsVersion);
  }

  // Resizing should update the rects version.
  webViewHelper.resize(WebSize(800, 600));
  runPendingTasks();
  EXPECT_TRUE(mainFrame->findMatchMarkersVersion() != rectsVersion);
}

TEST_F(WebFrameTest, FindInPageActiveIndex) {
  registerMockedHttpURLLoad("find_match_count.html");

  FindUpdateWebFrameClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "find_match_count.html", true,
                                  &client);
  webViewHelper.webView()->resize(WebSize(640, 480));
  runPendingTasks();

  const char* kFindString = "a";
  const int kFindIdentifier = 7777;
  const int kActiveIndex = 1;

  WebFindOptions options;
  WebString searchText = WebString::fromUTF8(kFindString);
  WebLocalFrameImpl* mainFrame = webViewHelper.webView()->mainFrameImpl();
  EXPECT_TRUE(mainFrame->find(kFindIdentifier, searchText, options, false));
  mainFrame->ensureTextFinder().resetMatchCount();

  for (WebLocalFrameImpl* frame = mainFrame; frame;
       frame = static_cast<WebLocalFrameImpl*>(frame->traverseNext(false)))
    frame->ensureTextFinder().scopeStringMatches(kFindIdentifier, searchText,
                                                 options, true);

  runPendingTasks();
  EXPECT_TRUE(mainFrame->find(kFindIdentifier, searchText, options, false));
  mainFrame->stopFinding(WebLocalFrame::StopFindActionClearSelection);

  for (WebLocalFrameImpl* frame = mainFrame; frame;
       frame = static_cast<WebLocalFrameImpl*>(frame->traverseNext(false)))
    frame->ensureTextFinder().scopeStringMatches(kFindIdentifier, searchText,
                                                 options, true);

  runPendingTasks();
  EXPECT_TRUE(client.findResultsAreReady());
  EXPECT_EQ(kActiveIndex, client.activeIndex());

  const char* kFindStringNew = "e";
  WebString searchTextNew = WebString::fromUTF8(kFindStringNew);

  EXPECT_TRUE(mainFrame->find(kFindIdentifier, searchTextNew, options, false));
  mainFrame->ensureTextFinder().resetMatchCount();

  for (WebLocalFrameImpl* frame = mainFrame; frame;
       frame = static_cast<WebLocalFrameImpl*>(frame->traverseNext(false)))
    frame->ensureTextFinder().scopeStringMatches(kFindIdentifier, searchTextNew,
                                                 options, true);

  runPendingTasks();
  EXPECT_TRUE(client.findResultsAreReady());
  EXPECT_EQ(kActiveIndex, client.activeIndex());
}

TEST_P(ParameterizedWebFrameTest, FindOnDetachedFrame) {
  registerMockedHttpURLLoad("find_in_page.html");
  registerMockedHttpURLLoad("find_in_page_frame.html");

  FindUpdateWebFrameClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "find_in_page.html", true,
                                  &client);
  webViewHelper.resize(WebSize(640, 480));
  runPendingTasks();

  const char kFindString[] = "result";
  const int kFindIdentifier = 12345;

  WebFindOptions options;
  WebString searchText = WebString::fromUTF8(kFindString);
  WebLocalFrameImpl* mainFrame = webViewHelper.webView()->mainFrameImpl();
  WebLocalFrameImpl* secondFrame =
      toWebLocalFrameImpl(mainFrame->traverseNext(false));

  // Detach the frame before finding.
  removeElementById(mainFrame, "frame");

  EXPECT_TRUE(mainFrame->find(kFindIdentifier, searchText, options, false));
  EXPECT_FALSE(secondFrame->find(kFindIdentifier, searchText, options, false));

  runPendingTasks();
  EXPECT_FALSE(client.findResultsAreReady());

  mainFrame->ensureTextFinder().resetMatchCount();

  for (WebLocalFrameImpl* frame = mainFrame; frame;
       frame = static_cast<WebLocalFrameImpl*>(frame->traverseNext(false)))
    frame->ensureTextFinder().scopeStringMatches(kFindIdentifier, searchText,
                                                 options, true);

  runPendingTasks();
  EXPECT_TRUE(client.findResultsAreReady());
}

TEST_P(ParameterizedWebFrameTest, FindDetachFrameBeforeScopeStrings) {
  registerMockedHttpURLLoad("find_in_page.html");
  registerMockedHttpURLLoad("find_in_page_frame.html");

  FindUpdateWebFrameClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "find_in_page.html", true,
                                  &client);
  webViewHelper.resize(WebSize(640, 480));
  runPendingTasks();

  const char kFindString[] = "result";
  const int kFindIdentifier = 12345;

  WebFindOptions options;
  WebString searchText = WebString::fromUTF8(kFindString);
  WebLocalFrameImpl* mainFrame = webViewHelper.webView()->mainFrameImpl();

  for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
    EXPECT_TRUE(frame->toWebLocalFrame()->find(kFindIdentifier, searchText,
                                               options, false));

  runPendingTasks();
  EXPECT_FALSE(client.findResultsAreReady());

  // Detach the frame between finding and scoping.
  removeElementById(mainFrame, "frame");

  mainFrame->ensureTextFinder().resetMatchCount();

  for (WebLocalFrameImpl* frame = mainFrame; frame;
       frame = static_cast<WebLocalFrameImpl*>(frame->traverseNext(false)))
    frame->ensureTextFinder().scopeStringMatches(kFindIdentifier, searchText,
                                                 options, true);

  runPendingTasks();
  EXPECT_TRUE(client.findResultsAreReady());
}

TEST_P(ParameterizedWebFrameTest, FindDetachFrameWhileScopingStrings) {
  registerMockedHttpURLLoad("find_in_page.html");
  registerMockedHttpURLLoad("find_in_page_frame.html");

  FindUpdateWebFrameClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "find_in_page.html", true,
                                  &client);
  webViewHelper.resize(WebSize(640, 480));
  runPendingTasks();

  const char kFindString[] = "result";
  const int kFindIdentifier = 12345;

  WebFindOptions options;
  WebString searchText = WebString::fromUTF8(kFindString);
  WebLocalFrameImpl* mainFrame = webViewHelper.webView()->mainFrameImpl();

  for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
    EXPECT_TRUE(frame->toWebLocalFrame()->find(kFindIdentifier, searchText,
                                               options, false));

  runPendingTasks();
  EXPECT_FALSE(client.findResultsAreReady());

  mainFrame->ensureTextFinder().resetMatchCount();

  for (WebLocalFrameImpl* frame = mainFrame; frame;
       frame = static_cast<WebLocalFrameImpl*>(frame->traverseNext(false)))
    frame->ensureTextFinder().scopeStringMatches(kFindIdentifier, searchText,
                                                 options, true);

  // The first scopeStringMatches will have reset the state. Detach before it
  // actually scopes.
  removeElementById(mainFrame, "frame");

  runPendingTasks();
  EXPECT_TRUE(client.findResultsAreReady());
}

TEST_P(ParameterizedWebFrameTest, ResetMatchCount) {
  registerMockedHttpURLLoad("find_in_generated_frame.html");

  FindUpdateWebFrameClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "find_in_generated_frame.html",
                                  true, &client);
  webViewHelper.resize(WebSize(640, 480));
  runPendingTasks();

  const char kFindString[] = "result";
  const int kFindIdentifier = 12345;

  WebFindOptions options;
  WebString searchText = WebString::fromUTF8(kFindString);
  WebLocalFrameImpl* mainFrame = webViewHelper.webView()->mainFrameImpl();

  // Check that child frame exists.
  EXPECT_TRUE(!!mainFrame->traverseNext(false));

  for (WebFrame* frame = mainFrame; frame; frame = frame->traverseNext(false))
    EXPECT_FALSE(frame->toWebLocalFrame()->find(kFindIdentifier, searchText,
                                                options, false));

  runPendingTasks();
  EXPECT_FALSE(client.findResultsAreReady());

  mainFrame->ensureTextFinder().resetMatchCount();
}

TEST_P(ParameterizedWebFrameTest, SetTickmarks) {
  registerMockedHttpURLLoad("find.html");

  FindUpdateWebFrameClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "find.html", true, &client);
  webViewHelper.resize(WebSize(640, 480));
  runPendingTasks();

  const char kFindString[] = "foo";
  const int kFindIdentifier = 12345;

  WebFindOptions options;
  WebString searchText = WebString::fromUTF8(kFindString);
  WebLocalFrameImpl* mainFrame = webViewHelper.webView()->mainFrameImpl();
  EXPECT_TRUE(mainFrame->find(kFindIdentifier, searchText, options, false));

  mainFrame->ensureTextFinder().resetMatchCount();
  mainFrame->ensureTextFinder().scopeStringMatches(kFindIdentifier, searchText,
                                                   options, true);

  runPendingTasks();
  EXPECT_TRUE(client.findResultsAreReady());

  // Get the tickmarks for the original find request.
  FrameView* frameView = webViewHelper.webView()->mainFrameImpl()->frameView();
  Scrollbar* scrollbar = frameView->createScrollbar(HorizontalScrollbar);
  Vector<IntRect> originalTickmarks;
  scrollbar->getTickmarks(originalTickmarks);
  EXPECT_EQ(4u, originalTickmarks.size());

  // Override the tickmarks.
  Vector<IntRect> overridingTickmarksExpected;
  overridingTickmarksExpected.append(IntRect(0, 0, 100, 100));
  overridingTickmarksExpected.append(IntRect(0, 20, 100, 100));
  overridingTickmarksExpected.append(IntRect(0, 30, 100, 100));
  mainFrame->setTickmarks(overridingTickmarksExpected);

  // Check the tickmarks are overriden correctly.
  Vector<IntRect> overridingTickmarksActual;
  scrollbar->getTickmarks(overridingTickmarksActual);
  EXPECT_EQ(overridingTickmarksExpected, overridingTickmarksActual);

  // Reset the tickmark behavior.
  Vector<IntRect> resetTickmarks;
  mainFrame->setTickmarks(resetTickmarks);

  // Check that the original tickmarks are returned
  Vector<IntRect> originalTickmarksAfterReset;
  scrollbar->getTickmarks(originalTickmarksAfterReset);
  EXPECT_EQ(originalTickmarks, originalTickmarksAfterReset);
}

TEST_P(ParameterizedWebFrameTest, FindInPageJavaScriptUpdatesDOM) {
  registerMockedHttpURLLoad("find.html");

  FindUpdateWebFrameClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "find.html", true, &client);
  webViewHelper.resize(WebSize(640, 480));
  runPendingTasks();

  WebLocalFrameImpl* frame = webViewHelper.webView()->mainFrameImpl();
  const int findIdentifier = 12345;
  static const char* kFindString = "foo";
  WebString searchText = WebString::fromUTF8(kFindString);
  WebFindOptions options;
  bool activeNow;

  frame->ensureTextFinder().resetMatchCount();
  frame->ensureTextFinder().scopeStringMatches(findIdentifier, searchText,
                                               options, true);
  runPendingTasks();
  EXPECT_TRUE(client.findResultsAreReady());

  // Find in a <div> element.
  options.findNext = true;
  EXPECT_TRUE(
      frame->find(findIdentifier, searchText, options, false, &activeNow));
  EXPECT_TRUE(activeNow);

  // Insert new text, which contains occurence of |searchText|.
  frame->executeScript(WebScriptSource(
      "var newTextNode = document.createTextNode('bar5 foo5');"
      "var textArea = document.getElementsByTagName('textarea')[0];"
      "document.body.insertBefore(newTextNode, textArea);"));

  // Find in a <input> element.
  EXPECT_TRUE(
      frame->find(findIdentifier, searchText, options, false, &activeNow));
  EXPECT_TRUE(activeNow);

  // Find in the inserted text node.
  EXPECT_TRUE(
      frame->find(findIdentifier, searchText, options, false, &activeNow));
  frame->stopFinding(WebLocalFrame::StopFindActionKeepSelection);
  WebRange range = frame->selectionRange();
  EXPECT_EQ(5, range.startOffset());
  EXPECT_EQ(8, range.endOffset());
  EXPECT_TRUE(frame->document().focusedElement().isNull());
  EXPECT_FALSE(activeNow);
}

static WebPoint topLeft(const WebRect& rect) {
  return WebPoint(rect.x, rect.y);
}

static WebPoint bottomRightMinusOne(const WebRect& rect) {
  // FIXME: If we don't subtract 1 from the x- and y-coordinates of the
  // selection bounds, selectRange() will select the *next* element. That's
  // strictly correct, as hit-testing checks the pixel to the lower-right of
  // the input coordinate, but it's a wart on the API.
  return WebPoint(rect.x + rect.width - 1, rect.y + rect.height - 1);
}

static WebRect elementBounds(WebFrame* frame, const WebString& id) {
  return frame->document().getElementById(id).boundsInViewport();
}

static std::string selectionAsString(WebFrame* frame) {
  return frame->toWebLocalFrame()->selectionAsText().utf8();
}

TEST_P(ParameterizedWebFrameTest, SelectRange) {
  WebLocalFrame* frame;
  WebRect startWebRect;
  WebRect endWebRect;

  registerMockedHttpURLLoad("select_range_basic.html");
  registerMockedHttpURLLoad("select_range_scroll.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  initializeTextSelectionWebView(m_baseURL + "select_range_basic.html",
                                 &webViewHelper);
  frame = webViewHelper.webView()->mainFrameImpl();
  EXPECT_EQ("Some test text for testing.", selectionAsString(frame));
  webViewHelper.webView()->selectionBounds(startWebRect, endWebRect);
  frame->executeCommand(WebString::fromUTF8("Unselect"));
  EXPECT_EQ("", selectionAsString(frame));
  frame->selectRange(topLeft(startWebRect), bottomRightMinusOne(endWebRect));
  // On some devices, the above bottomRightMinusOne() causes the ending '.' not
  // selected.
  std::string selectionString = selectionAsString(frame);
  EXPECT_TRUE(selectionString == "Some test text for testing." ||
              selectionString == "Some test text for testing");

  initializeTextSelectionWebView(m_baseURL + "select_range_scroll.html",
                                 &webViewHelper);
  frame = webViewHelper.webView()->mainFrameImpl();
  EXPECT_EQ("Some offscreen test text for testing.", selectionAsString(frame));
  webViewHelper.webView()->selectionBounds(startWebRect, endWebRect);
  frame->executeCommand(WebString::fromUTF8("Unselect"));
  EXPECT_EQ("", selectionAsString(frame));
  frame->selectRange(topLeft(startWebRect), bottomRightMinusOne(endWebRect));
  // On some devices, the above bottomRightMinusOne() causes the ending '.' not
  // selected.
  selectionString = selectionAsString(frame);
  EXPECT_TRUE(selectionString == "Some offscreen test text for testing." ||
              selectionString == "Some offscreen test text for testing");
}

TEST_P(ParameterizedWebFrameTest, SelectRangeInIframe) {
  WebFrame* frame;
  WebRect startWebRect;
  WebRect endWebRect;

  registerMockedHttpURLLoad("select_range_iframe.html");
  registerMockedHttpURLLoad("select_range_basic.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  initializeTextSelectionWebView(m_baseURL + "select_range_iframe.html",
                                 &webViewHelper);
  frame = webViewHelper.webView()->mainFrame();
  WebLocalFrame* subframe = frame->firstChild()->toWebLocalFrame();
  EXPECT_EQ("Some test text for testing.", selectionAsString(subframe));
  webViewHelper.webView()->selectionBounds(startWebRect, endWebRect);
  subframe->executeCommand(WebString::fromUTF8("Unselect"));
  EXPECT_EQ("", selectionAsString(subframe));
  subframe->selectRange(topLeft(startWebRect), bottomRightMinusOne(endWebRect));
  // On some devices, the above bottomRightMinusOne() causes the ending '.' not
  // selected.
  std::string selectionString = selectionAsString(subframe);
  EXPECT_TRUE(selectionString == "Some test text for testing." ||
              selectionString == "Some test text for testing");
}

TEST_P(ParameterizedWebFrameTest, SelectRangeDivContentEditable) {
  WebLocalFrame* frame;
  WebRect startWebRect;
  WebRect endWebRect;

  registerMockedHttpURLLoad("select_range_div_editable.html");

  // Select the middle of an editable element, then try to extend the selection
  // to the top of the document.  The selection range should be clipped to the
  // bounds of the editable element.
  FrameTestHelpers::WebViewHelper webViewHelper;
  initializeTextSelectionWebView(m_baseURL + "select_range_div_editable.html",
                                 &webViewHelper);
  frame = webViewHelper.webView()->mainFrameImpl();
  EXPECT_EQ("This text is initially selected.", selectionAsString(frame));
  webViewHelper.webView()->selectionBounds(startWebRect, endWebRect);

  frame->selectRange(bottomRightMinusOne(endWebRect), WebPoint(0, 0));
  EXPECT_EQ("16-char header. This text is initially selected.",
            selectionAsString(frame));

  // As above, but extending the selection to the bottom of the document.
  initializeTextSelectionWebView(m_baseURL + "select_range_div_editable.html",
                                 &webViewHelper);
  frame = webViewHelper.webView()->mainFrameImpl();

  webViewHelper.webView()->selectionBounds(startWebRect, endWebRect);
  frame->selectRange(topLeft(startWebRect), bottomRightMinusOne(endWebRect));
  EXPECT_EQ("This text is initially selected.", selectionAsString(frame));
  webViewHelper.webView()->selectionBounds(startWebRect, endWebRect);

  webViewHelper.webView()->selectionBounds(startWebRect, endWebRect);
  frame->selectRange(topLeft(startWebRect), WebPoint(640, 480));
  EXPECT_EQ("This text is initially selected. 16-char footer.",
            selectionAsString(frame));
}

// positionForPoint returns the wrong values for contenteditable spans. See
// http://crbug.com/238334.
TEST_P(ParameterizedWebFrameTest, DISABLED_SelectRangeSpanContentEditable) {
  WebLocalFrame* frame;
  WebRect startWebRect;
  WebRect endWebRect;

  registerMockedHttpURLLoad("select_range_span_editable.html");

  // Select the middle of an editable element, then try to extend the selection
  // to the top of the document.
  // The selection range should be clipped to the bounds of the editable
  // element.
  FrameTestHelpers::WebViewHelper webViewHelper;
  initializeTextSelectionWebView(m_baseURL + "select_range_span_editable.html",
                                 &webViewHelper);
  frame = webViewHelper.webView()->mainFrameImpl();
  EXPECT_EQ("This text is initially selected.", selectionAsString(frame));
  webViewHelper.webView()->selectionBounds(startWebRect, endWebRect);

  frame->selectRange(bottomRightMinusOne(endWebRect), WebPoint(0, 0));
  EXPECT_EQ("16-char header. This text is initially selected.",
            selectionAsString(frame));

  // As above, but extending the selection to the bottom of the document.
  initializeTextSelectionWebView(m_baseURL + "select_range_span_editable.html",
                                 &webViewHelper);
  frame = webViewHelper.webView()->mainFrameImpl();

  webViewHelper.webView()->selectionBounds(startWebRect, endWebRect);
  frame->selectRange(topLeft(startWebRect), bottomRightMinusOne(endWebRect));
  EXPECT_EQ("This text is initially selected.", selectionAsString(frame));
  webViewHelper.webView()->selectionBounds(startWebRect, endWebRect);

  EXPECT_EQ("This text is initially selected.", selectionAsString(frame));
  webViewHelper.webView()->selectionBounds(startWebRect, endWebRect);
  frame->selectRange(topLeft(startWebRect), WebPoint(640, 480));
  EXPECT_EQ("This text is initially selected. 16-char footer.",
            selectionAsString(frame));
}

TEST_P(ParameterizedWebFrameTest, SelectRangeCanMoveSelectionStart) {
  registerMockedHttpURLLoad("text_selection.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  initializeTextSelectionWebView(m_baseURL + "text_selection.html",
                                 &webViewHelper);
  WebLocalFrame* frame = webViewHelper.webView()->mainFrameImpl();

  // Select second span. We can move the start to include the first span.
  frame->executeScript(WebScriptSource("selectElement('header_2');"));
  EXPECT_EQ("Header 2.", selectionAsString(frame));
  frame->selectRange(bottomRightMinusOne(elementBounds(frame, "header_2")),
                     topLeft(elementBounds(frame, "header_1")));
  EXPECT_EQ("Header 1. Header 2.", selectionAsString(frame));

  // We can move the start and end together.
  frame->executeScript(WebScriptSource("selectElement('header_1');"));
  EXPECT_EQ("Header 1.", selectionAsString(frame));
  frame->selectRange(bottomRightMinusOne(elementBounds(frame, "header_1")),
                     bottomRightMinusOne(elementBounds(frame, "header_1")));
  EXPECT_EQ("", selectionAsString(frame));
  // Selection is a caret, not empty.
  EXPECT_FALSE(frame->selectionRange().isNull());

  // We can move the start across the end.
  frame->executeScript(WebScriptSource("selectElement('header_1');"));
  EXPECT_EQ("Header 1.", selectionAsString(frame));
  frame->selectRange(bottomRightMinusOne(elementBounds(frame, "header_1")),
                     bottomRightMinusOne(elementBounds(frame, "header_2")));
  EXPECT_EQ(" Header 2.", selectionAsString(frame));

  // Can't extend the selection part-way into an editable element.
  frame->executeScript(WebScriptSource("selectElement('footer_2');"));
  EXPECT_EQ("Footer 2.", selectionAsString(frame));
  frame->selectRange(bottomRightMinusOne(elementBounds(frame, "footer_2")),
                     topLeft(elementBounds(frame, "editable_2")));
  EXPECT_EQ(" [ Footer 1. Footer 2.", selectionAsString(frame));

  // Can extend the selection completely across editable elements.
  frame->executeScript(WebScriptSource("selectElement('footer_2');"));
  EXPECT_EQ("Footer 2.", selectionAsString(frame));
  frame->selectRange(bottomRightMinusOne(elementBounds(frame, "footer_2")),
                     topLeft(elementBounds(frame, "header_2")));
  EXPECT_EQ("Header 2. ] [ Editable 1. Editable 2. ] [ Footer 1. Footer 2.",
            selectionAsString(frame));

  // If the selection is editable text, we can't extend it into non-editable
  // text.
  frame->executeScript(WebScriptSource("selectElement('editable_2');"));
  EXPECT_EQ("Editable 2.", selectionAsString(frame));
  frame->selectRange(bottomRightMinusOne(elementBounds(frame, "editable_2")),
                     topLeft(elementBounds(frame, "header_2")));
  // positionForPoint returns the wrong values for contenteditable spans. See
  // http://crbug.com/238334.
  // EXPECT_EQ("[ Editable 1. Editable 2.", selectionAsString(frame));
}

TEST_P(ParameterizedWebFrameTest, SelectRangeCanMoveSelectionEnd) {
  registerMockedHttpURLLoad("text_selection.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  initializeTextSelectionWebView(m_baseURL + "text_selection.html",
                                 &webViewHelper);
  WebLocalFrame* frame = webViewHelper.webView()->mainFrameImpl();

  // Select first span. We can move the end to include the second span.
  frame->executeScript(WebScriptSource("selectElement('header_1');"));
  EXPECT_EQ("Header 1.", selectionAsString(frame));
  frame->selectRange(topLeft(elementBounds(frame, "header_1")),
                     bottomRightMinusOne(elementBounds(frame, "header_2")));
  EXPECT_EQ("Header 1. Header 2.", selectionAsString(frame));

  // We can move the start and end together.
  frame->executeScript(WebScriptSource("selectElement('header_2');"));
  EXPECT_EQ("Header 2.", selectionAsString(frame));
  frame->selectRange(topLeft(elementBounds(frame, "header_2")),
                     topLeft(elementBounds(frame, "header_2")));
  EXPECT_EQ("", selectionAsString(frame));
  // Selection is a caret, not empty.
  EXPECT_FALSE(frame->selectionRange().isNull());

  // We can move the end across the start.
  frame->executeScript(WebScriptSource("selectElement('header_2');"));
  EXPECT_EQ("Header 2.", selectionAsString(frame));
  frame->selectRange(topLeft(elementBounds(frame, "header_2")),
                     topLeft(elementBounds(frame, "header_1")));
  EXPECT_EQ("Header 1. ", selectionAsString(frame));

  // Can't extend the selection part-way into an editable element.
  frame->executeScript(WebScriptSource("selectElement('header_1');"));
  EXPECT_EQ("Header 1.", selectionAsString(frame));
  frame->selectRange(topLeft(elementBounds(frame, "header_1")),
                     bottomRightMinusOne(elementBounds(frame, "editable_1")));
  EXPECT_EQ("Header 1. Header 2. ] ", selectionAsString(frame));

  // Can extend the selection completely across editable elements.
  frame->executeScript(WebScriptSource("selectElement('header_1');"));
  EXPECT_EQ("Header 1.", selectionAsString(frame));
  frame->selectRange(topLeft(elementBounds(frame, "header_1")),
                     bottomRightMinusOne(elementBounds(frame, "footer_1")));
  EXPECT_EQ("Header 1. Header 2. ] [ Editable 1. Editable 2. ] [ Footer 1.",
            selectionAsString(frame));

  // If the selection is editable text, we can't extend it into non-editable
  // text.
  frame->executeScript(WebScriptSource("selectElement('editable_1');"));
  EXPECT_EQ("Editable 1.", selectionAsString(frame));
  frame->selectRange(topLeft(elementBounds(frame, "editable_1")),
                     bottomRightMinusOne(elementBounds(frame, "footer_1")));
  // positionForPoint returns the wrong values for contenteditable spans. See
  // http://crbug.com/238334.
  // EXPECT_EQ("Editable 1. Editable 2. ]", selectionAsString(frame));
}

TEST_P(ParameterizedWebFrameTest, MoveRangeSelectionExtent) {
  WebLocalFrameImpl* frame;
  WebRect startWebRect;
  WebRect endWebRect;

  registerMockedHttpURLLoad("move_range_selection_extent.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  initializeTextSelectionWebView(m_baseURL + "move_range_selection_extent.html",
                                 &webViewHelper);
  frame = webViewHelper.webView()->mainFrameImpl();
  EXPECT_EQ("This text is initially selected.", selectionAsString(frame));
  webViewHelper.webView()->selectionBounds(startWebRect, endWebRect);

  frame->moveRangeSelectionExtent(WebPoint(640, 480));
  EXPECT_EQ("This text is initially selected. 16-char footer.",
            selectionAsString(frame));

  frame->moveRangeSelectionExtent(WebPoint(0, 0));
  EXPECT_EQ("16-char header. ", selectionAsString(frame));

  // Reset with swapped base and extent.
  frame->selectRange(topLeft(endWebRect), bottomRightMinusOne(startWebRect));
  EXPECT_EQ("This text is initially selected.", selectionAsString(frame));

  frame->moveRangeSelectionExtent(WebPoint(640, 480));
  EXPECT_EQ(" 16-char footer.", selectionAsString(frame));

  frame->moveRangeSelectionExtent(WebPoint(0, 0));
  EXPECT_EQ("16-char header. This text is initially selected.",
            selectionAsString(frame));

  frame->executeCommand(WebString::fromUTF8("Unselect"));
  EXPECT_EQ("", selectionAsString(frame));
}

TEST_P(ParameterizedWebFrameTest, MoveRangeSelectionExtentCannotCollapse) {
  WebLocalFrameImpl* frame;
  WebRect startWebRect;
  WebRect endWebRect;

  registerMockedHttpURLLoad("move_range_selection_extent.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  initializeTextSelectionWebView(m_baseURL + "move_range_selection_extent.html",
                                 &webViewHelper);
  frame = webViewHelper.webView()->mainFrameImpl();
  EXPECT_EQ("This text is initially selected.", selectionAsString(frame));
  webViewHelper.webView()->selectionBounds(startWebRect, endWebRect);

  frame->moveRangeSelectionExtent(bottomRightMinusOne(startWebRect));
  EXPECT_EQ("This text is initially selected.", selectionAsString(frame));

  // Reset with swapped base and extent.
  frame->selectRange(topLeft(endWebRect), bottomRightMinusOne(startWebRect));
  EXPECT_EQ("This text is initially selected.", selectionAsString(frame));

  frame->moveRangeSelectionExtent(bottomRightMinusOne(endWebRect));
  EXPECT_EQ("This text is initially selected.", selectionAsString(frame));
}

TEST_P(ParameterizedWebFrameTest, MoveRangeSelectionExtentScollsInputField) {
  WebLocalFrameImpl* frame;
  WebRect startWebRect;
  WebRect endWebRect;

  registerMockedHttpURLLoad("move_range_selection_extent_input_field.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  initializeTextSelectionWebView(
      m_baseURL + "move_range_selection_extent_input_field.html",
      &webViewHelper);
  frame = webViewHelper.webView()->mainFrameImpl();
  EXPECT_EQ("Length", selectionAsString(frame));
  webViewHelper.webView()->selectionBounds(startWebRect, endWebRect);

  EXPECT_EQ(0, frame->frame()->selection().rootEditableElement()->scrollLeft());
  frame->moveRangeSelectionExtent(WebPoint(endWebRect.x + 500, endWebRect.y));
  EXPECT_GE(frame->frame()->selection().rootEditableElement()->scrollLeft(), 1);
  EXPECT_EQ("Lengthy text goes here.", selectionAsString(frame));
}

static int computeOffset(LayoutObject* layoutObject, int x, int y) {
  return createVisiblePosition(
             layoutObject->positionForPoint(LayoutPoint(x, y)))
      .deepEquivalent()
      .computeOffsetInContainerNode();
}

// positionForPoint returns the wrong values for contenteditable spans. See
// http://crbug.com/238334.
TEST_P(ParameterizedWebFrameTest, DISABLED_PositionForPointTest) {
  registerMockedHttpURLLoad("select_range_span_editable.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  initializeTextSelectionWebView(m_baseURL + "select_range_span_editable.html",
                                 &webViewHelper);
  WebLocalFrameImpl* mainFrame = webViewHelper.webView()->mainFrameImpl();
  LayoutObject* layoutObject =
      mainFrame->frame()->selection().rootEditableElement()->layoutObject();
  EXPECT_EQ(0, computeOffset(layoutObject, -1, -1));
  EXPECT_EQ(64, computeOffset(layoutObject, 1000, 1000));

  registerMockedHttpURLLoad("select_range_div_editable.html");
  initializeTextSelectionWebView(m_baseURL + "select_range_div_editable.html",
                                 &webViewHelper);
  mainFrame = webViewHelper.webView()->mainFrameImpl();
  layoutObject =
      mainFrame->frame()->selection().rootEditableElement()->layoutObject();
  EXPECT_EQ(0, computeOffset(layoutObject, -1, -1));
  EXPECT_EQ(64, computeOffset(layoutObject, 1000, 1000));
}

#if !OS(MACOSX) && !OS(LINUX)
TEST_P(ParameterizedWebFrameTest,
       SelectRangeStaysHorizontallyAlignedWhenMoved) {
  registerMockedHttpURLLoad("move_caret.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  initializeTextSelectionWebView(m_baseURL + "move_caret.html", &webViewHelper);
  WebLocalFrameImpl* frame = webViewHelper.webView()->mainFrameImpl();

  WebRect initialStartRect;
  WebRect initialEndRect;
  WebRect startRect;
  WebRect endRect;

  frame->executeScript(WebScriptSource("selectRange();"));
  webViewHelper.webView()->selectionBounds(initialStartRect, initialEndRect);
  WebPoint movedStart(topLeft(initialStartRect));

  movedStart.y += 40;
  frame->selectRange(movedStart, bottomRightMinusOne(initialEndRect));
  webViewHelper.webView()->selectionBounds(startRect, endRect);
  EXPECT_EQ(startRect, initialStartRect);
  EXPECT_EQ(endRect, initialEndRect);

  movedStart.y -= 80;
  frame->selectRange(movedStart, bottomRightMinusOne(initialEndRect));
  webViewHelper.webView()->selectionBounds(startRect, endRect);
  EXPECT_EQ(startRect, initialStartRect);
  EXPECT_EQ(endRect, initialEndRect);

  WebPoint movedEnd(bottomRightMinusOne(initialEndRect));

  movedEnd.y += 40;
  frame->selectRange(topLeft(initialStartRect), movedEnd);
  webViewHelper.webView()->selectionBounds(startRect, endRect);
  EXPECT_EQ(startRect, initialStartRect);
  EXPECT_EQ(endRect, initialEndRect);

  movedEnd.y -= 80;
  frame->selectRange(topLeft(initialStartRect), movedEnd);
  webViewHelper.webView()->selectionBounds(startRect, endRect);
  EXPECT_EQ(startRect, initialStartRect);
  EXPECT_EQ(endRect, initialEndRect);
}

TEST_P(ParameterizedWebFrameTest, MoveCaretStaysHorizontallyAlignedWhenMoved) {
  WebLocalFrameImpl* frame;
  registerMockedHttpURLLoad("move_caret.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  initializeTextSelectionWebView(m_baseURL + "move_caret.html", &webViewHelper);
  frame = (WebLocalFrameImpl*)webViewHelper.webView()->mainFrame();

  WebRect initialStartRect;
  WebRect initialEndRect;
  WebRect startRect;
  WebRect endRect;

  frame->executeScript(WebScriptSource("selectCaret();"));
  webViewHelper.webView()->selectionBounds(initialStartRect, initialEndRect);
  WebPoint moveTo(topLeft(initialStartRect));

  moveTo.y += 40;
  frame->moveCaretSelection(moveTo);
  webViewHelper.webView()->selectionBounds(startRect, endRect);
  EXPECT_EQ(startRect, initialStartRect);
  EXPECT_EQ(endRect, initialEndRect);

  moveTo.y -= 80;
  frame->moveCaretSelection(moveTo);
  webViewHelper.webView()->selectionBounds(startRect, endRect);
  EXPECT_EQ(startRect, initialStartRect);
  EXPECT_EQ(endRect, initialEndRect);
}
#endif

class CompositedSelectionBoundsTestLayerTreeView : public WebLayerTreeView {
 public:
  CompositedSelectionBoundsTestLayerTreeView() : m_selectionCleared(false) {}
  ~CompositedSelectionBoundsTestLayerTreeView() override {}

  void registerSelection(const WebSelection& selection) override {
    m_selection = wrapUnique(new WebSelection(selection));
  }

  void clearSelection() override {
    m_selectionCleared = true;
    m_selection.reset();
  }

  bool getAndResetSelectionCleared() {
    bool selectionCleared = m_selectionCleared;
    m_selectionCleared = false;
    return selectionCleared;
  }

  const WebSelection* selection() const { return m_selection.get(); }
  const WebSelectionBound* start() const {
    return m_selection ? &m_selection->start() : nullptr;
  }
  const WebSelectionBound* end() const {
    return m_selection ? &m_selection->end() : nullptr;
  }

 private:
  bool m_selectionCleared;
  std::unique_ptr<WebSelection> m_selection;
};

class CompositedSelectionBoundsTestWebViewClient
    : public FrameTestHelpers::TestWebViewClient {
 public:
  ~CompositedSelectionBoundsTestWebViewClient() override {}
  WebLayerTreeView* layerTreeView() override { return &m_testLayerTreeView; }

  CompositedSelectionBoundsTestLayerTreeView& selectionLayerTreeView() {
    return m_testLayerTreeView;
  }

 private:
  CompositedSelectionBoundsTestLayerTreeView m_testLayerTreeView;
};

class CompositedSelectionBoundsTest : public WebFrameTest {
 protected:
  CompositedSelectionBoundsTest()
      : m_fakeSelectionLayerTreeView(
            m_fakeSelectionWebViewClient.selectionLayerTreeView()) {
    RuntimeEnabledFeatures::setCompositedSelectionUpdateEnabled(true);
    registerMockedHttpURLLoad("Ahem.ttf");

    m_webViewHelper.initialize(true, nullptr, &m_fakeSelectionWebViewClient,
                               nullptr);
    m_webViewHelper.webView()->settings()->setDefaultFontSize(12);
    m_webViewHelper.webView()->setDefaultPageScaleLimits(1, 1);
    m_webViewHelper.resize(WebSize(640, 480));
  }

  void runTest(const char* testFile) {
    registerMockedHttpURLLoad(testFile);
    m_webViewHelper.webView()->setFocus(true);
    FrameTestHelpers::loadFrame(m_webViewHelper.webView()->mainFrame(),
                                m_baseURL + testFile);
    m_webViewHelper.webView()->updateAllLifecyclePhases();

    const WebSelection* selection = m_fakeSelectionLayerTreeView.selection();
    const WebSelectionBound* selectStart = m_fakeSelectionLayerTreeView.start();
    const WebSelectionBound* selectEnd = m_fakeSelectionLayerTreeView.end();

    v8::HandleScope handleScope(v8::Isolate::GetCurrent());
    v8::Local<v8::Value> result =
        m_webViewHelper.webView()->mainFrameImpl()->executeScriptAndReturnValue(
            WebScriptSource("expectedResult"));
    if (result.IsEmpty() || (*result)->IsUndefined()) {
      EXPECT_FALSE(selection);
      EXPECT_FALSE(selectStart);
      EXPECT_FALSE(selectEnd);
      return;
    }

    ASSERT_TRUE(selection);
    ASSERT_TRUE(selectStart);
    ASSERT_TRUE(selectEnd);

    EXPECT_FALSE(selection->isNone());

    ASSERT_TRUE((*result)->IsArray());
    v8::Array& expectedResult = *v8::Array::Cast(*result);
    ASSERT_GE(expectedResult.Length(), 10u);

    blink::Node* layerOwnerNodeForStart = V8Node::toImplWithTypeCheck(
        v8::Isolate::GetCurrent(), expectedResult.Get(0));
    ASSERT_TRUE(layerOwnerNodeForStart);
    EXPECT_EQ(layerOwnerNodeForStart->layoutObject()
                  ->enclosingLayer()
                  ->enclosingLayerForPaintInvalidation()
                  ->graphicsLayerBacking()
                  ->platformLayer()
                  ->id(),
              selectStart->layerId);
    v8::Local<v8::Context> context =
        v8::Isolate::GetCurrent()->GetCurrentContext();
    EXPECT_EQ(expectedResult.Get(context, 1)
                  .ToLocalChecked()
                  .As<v8::Int32>()
                  ->Value(),
              selectStart->edgeTopInLayer.x);
    EXPECT_EQ(expectedResult.Get(context, 2)
                  .ToLocalChecked()
                  .As<v8::Int32>()
                  ->Value(),
              selectStart->edgeTopInLayer.y);
    EXPECT_EQ(expectedResult.Get(context, 3)
                  .ToLocalChecked()
                  .As<v8::Int32>()
                  ->Value(),
              selectStart->edgeBottomInLayer.x);

    blink::Node* layerOwnerNodeForEnd = V8Node::toImplWithTypeCheck(
        v8::Isolate::GetCurrent(),
        expectedResult.Get(context, 5).ToLocalChecked());

    ASSERT_TRUE(layerOwnerNodeForEnd);
    EXPECT_EQ(layerOwnerNodeForEnd->layoutObject()
                  ->enclosingLayer()
                  ->enclosingLayerForPaintInvalidation()
                  ->graphicsLayerBacking()
                  ->platformLayer()
                  ->id(),
              selectEnd->layerId);
    EXPECT_EQ(expectedResult.Get(context, 6)
                  .ToLocalChecked()
                  .As<v8::Int32>()
                  ->Value(),
              selectEnd->edgeTopInLayer.x);
    EXPECT_EQ(expectedResult.Get(context, 7)
                  .ToLocalChecked()
                  .As<v8::Int32>()
                  ->Value(),
              selectEnd->edgeTopInLayer.y);
    EXPECT_EQ(expectedResult.Get(context, 8)
                  .ToLocalChecked()
                  .As<v8::Int32>()
                  ->Value(),
              selectEnd->edgeBottomInLayer.x);

    // Platform differences can introduce small stylistic deviations in
    // y-axis positioning, the details of which aren't relevant to
    // selection behavior. However, such deviations from the expected value
    // should be consistent for the corresponding y coordinates.
    int yBottomEpsilon = 0;
    if (expectedResult.Length() == 13)
      yBottomEpsilon = expectedResult.Get(context, 12)
                           .ToLocalChecked()
                           .As<v8::Int32>()
                           ->Value();
    int yBottomDeviation = expectedResult.Get(context, 4)
                               .ToLocalChecked()
                               .As<v8::Int32>()
                               ->Value() -
                           selectStart->edgeBottomInLayer.y;
    EXPECT_GE(yBottomEpsilon, std::abs(yBottomDeviation));
    EXPECT_EQ(yBottomDeviation, expectedResult.Get(context, 9)
                                        .ToLocalChecked()
                                        .As<v8::Int32>()
                                        ->Value() -
                                    selectEnd->edgeBottomInLayer.y);

    if (expectedResult.Length() >= 12) {
      EXPECT_EQ(expectedResult.Get(context, 10)
                    .ToLocalChecked()
                    .As<v8::Boolean>()
                    ->Value(),
                m_fakeSelectionLayerTreeView.selection()->isEditable());
      EXPECT_EQ(
          expectedResult.Get(context, 11)
              .ToLocalChecked()
              .As<v8::Boolean>()
              ->Value(),
          m_fakeSelectionLayerTreeView.selection()->isEmptyTextFormControl());
    }
  }

  void runTestWithMultipleFiles(const char* testFile, ...) {
    va_list auxFiles;
    va_start(auxFiles, testFile);
    while (const char* auxFile = va_arg(auxFiles, const char*))
      registerMockedHttpURLLoad(auxFile);
    va_end(auxFiles);

    runTest(testFile);
  }

  CompositedSelectionBoundsTestWebViewClient m_fakeSelectionWebViewClient;
  CompositedSelectionBoundsTestLayerTreeView& m_fakeSelectionLayerTreeView;
  FrameTestHelpers::WebViewHelper m_webViewHelper;
};

TEST_F(CompositedSelectionBoundsTest, None) {
  runTest("composited_selection_bounds_none.html");
}
TEST_F(CompositedSelectionBoundsTest, NoneReadonlyCaret) {
  runTest("composited_selection_bounds_none_readonly_caret.html");
}
TEST_F(CompositedSelectionBoundsTest, Basic) {
  runTest("composited_selection_bounds_basic.html");
}
TEST_F(CompositedSelectionBoundsTest, Transformed) {
  runTest("composited_selection_bounds_transformed.html");
}
TEST_F(CompositedSelectionBoundsTest, VerticalRightToLeft) {
  runTest("composited_selection_bounds_vertical_rl.html");
}
TEST_F(CompositedSelectionBoundsTest, VerticalLeftToRight) {
  runTest("composited_selection_bounds_vertical_lr.html");
}
TEST_F(CompositedSelectionBoundsTest, SplitLayer) {
  runTest("composited_selection_bounds_split_layer.html");
}
TEST_F(CompositedSelectionBoundsTest, EmptyLayer) {
  runTest("composited_selection_bounds_empty_layer.html");
}
TEST_F(CompositedSelectionBoundsTest, Iframe) {
  runTestWithMultipleFiles("composited_selection_bounds_iframe.html",
                           "composited_selection_bounds_basic.html", nullptr);
}
TEST_F(CompositedSelectionBoundsTest, DetachedFrame) {
  runTest("composited_selection_bounds_detached_frame.html");
}
TEST_F(CompositedSelectionBoundsTest, Editable) {
  runTest("composited_selection_bounds_editable.html");
}
TEST_F(CompositedSelectionBoundsTest, EditableDiv) {
  runTest("composited_selection_bounds_editable_div.html");
}
TEST_F(CompositedSelectionBoundsTest, EmptyEditableInput) {
  runTest("composited_selection_bounds_empty_editable_input.html");
}
TEST_F(CompositedSelectionBoundsTest, EmptyEditableArea) {
  runTest("composited_selection_bounds_empty_editable_area.html");
}

// Fails on Mac ASan 64 bot. https://crbug.com/588769.
#if OS(MACOSX) && defined(ADDRESS_SANITIZER)
TEST_P(ParameterizedWebFrameTest, DISABLED_CompositedSelectionBoundsCleared)
#else
TEST_P(ParameterizedWebFrameTest, CompositedSelectionBoundsCleared)
#endif
{
  RuntimeEnabledFeatures::setCompositedSelectionUpdateEnabled(true);

  registerMockedHttpURLLoad("select_range_basic.html");
  registerMockedHttpURLLoad("select_range_scroll.html");

  int viewWidth = 500;
  int viewHeight = 500;

  CompositedSelectionBoundsTestWebViewClient fakeSelectionWebViewClient;
  CompositedSelectionBoundsTestLayerTreeView& fakeSelectionLayerTreeView =
      fakeSelectionWebViewClient.selectionLayerTreeView();

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, nullptr, &fakeSelectionWebViewClient, nullptr);
  webViewHelper.webView()->settings()->setDefaultFontSize(12);
  webViewHelper.webView()->setDefaultPageScaleLimits(1, 1);
  webViewHelper.resize(WebSize(viewWidth, viewHeight));
  webViewHelper.webView()->setFocus(true);
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "select_range_basic.html");

  // The frame starts with no selection.
  WebLocalFrame* frame = webViewHelper.webView()->mainFrameImpl();
  ASSERT_TRUE(frame->hasSelection());
  EXPECT_TRUE(fakeSelectionLayerTreeView.getAndResetSelectionCleared());

  // The selection cleared notification should be triggered upon layout.
  frame->executeCommand(WebString::fromUTF8("Unselect"));
  ASSERT_FALSE(frame->hasSelection());
  EXPECT_FALSE(fakeSelectionLayerTreeView.getAndResetSelectionCleared());
  webViewHelper.webView()->updateAllLifecyclePhases();
  EXPECT_TRUE(fakeSelectionLayerTreeView.getAndResetSelectionCleared());

  frame->executeCommand(WebString::fromUTF8("SelectAll"));
  webViewHelper.webView()->updateAllLifecyclePhases();
  ASSERT_TRUE(frame->hasSelection());
  EXPECT_FALSE(fakeSelectionLayerTreeView.getAndResetSelectionCleared());

  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "select_range_scroll.html");
  ASSERT_TRUE(frame->hasSelection());
  EXPECT_FALSE(fakeSelectionLayerTreeView.getAndResetSelectionCleared());

  // Transitions between non-empty selections should not trigger a clearing.
  WebRect startWebRect;
  WebRect endWebRect;
  webViewHelper.webView()->selectionBounds(startWebRect, endWebRect);
  WebPoint movedEnd(bottomRightMinusOne(endWebRect));
  endWebRect.x -= 20;
  frame->selectRange(topLeft(startWebRect), movedEnd);
  webViewHelper.webView()->updateAllLifecyclePhases();
  ASSERT_TRUE(frame->hasSelection());
  EXPECT_FALSE(fakeSelectionLayerTreeView.getAndResetSelectionCleared());

  frame = webViewHelper.webView()->mainFrameImpl();
  frame->executeCommand(WebString::fromUTF8("Unselect"));
  webViewHelper.webView()->updateAllLifecyclePhases();
  ASSERT_FALSE(frame->hasSelection());
  EXPECT_TRUE(fakeSelectionLayerTreeView.getAndResetSelectionCleared());
}

class DisambiguationPopupTestWebViewClient
    : public FrameTestHelpers::TestWebViewClient {
 public:
  bool didTapMultipleTargets(const WebSize&,
                             const WebRect&,
                             const WebVector<WebRect>& targetRects) override {
    EXPECT_GE(targetRects.size(), 2u);
    m_triggered = true;
    return true;
  }

  bool triggered() const { return m_triggered; }
  void resetTriggered() { m_triggered = false; }
  bool m_triggered;
};

static WebGestureEvent fatTap(int x, int y) {
  WebGestureEvent event;
  event.type = WebInputEvent::GestureTap;
  event.sourceDevice = WebGestureDeviceTouchscreen;
  event.x = x;
  event.y = y;
  event.data.tap.width = 50;
  event.data.tap.height = 50;
  return event;
}

TEST_P(ParameterizedWebFrameTest, DisambiguationPopup) {
  const std::string htmlFile = "disambiguation_popup.html";
  registerMockedHttpURLLoad(htmlFile);

  DisambiguationPopupTestWebViewClient client;

  // Make sure we initialize to minimum scale, even if the window size
  // only becomes available after the load begins.
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, 0, &client);
  webViewHelper.resize(WebSize(1000, 1000));

  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(fatTap(0, 0));
  EXPECT_FALSE(client.triggered());

  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(fatTap(200, 115));
  EXPECT_FALSE(client.triggered());

  for (int i = 0; i <= 46; i++) {
    client.resetTriggered();
    webViewHelper.webView()->handleInputEvent(fatTap(120, 230 + i * 5));

    int j = i % 10;
    if (j >= 7 && j <= 9)
      EXPECT_TRUE(client.triggered());
    else
      EXPECT_FALSE(client.triggered());
  }

  for (int i = 0; i <= 46; i++) {
    client.resetTriggered();
    webViewHelper.webView()->handleInputEvent(fatTap(10 + i * 5, 590));

    int j = i % 10;
    if (j >= 7 && j <= 9)
      EXPECT_TRUE(client.triggered());
    else
      EXPECT_FALSE(client.triggered());
  }

  // The same taps shouldn't trigger didTapMultipleTargets() after disabling the
  // notification for multi-target-tap.
  webViewHelper.webView()->settings()->setMultiTargetTapNotificationEnabled(
      false);

  for (int i = 0; i <= 46; i++) {
    client.resetTriggered();
    webViewHelper.webView()->handleInputEvent(fatTap(10 + i * 5, 590));
    EXPECT_FALSE(client.triggered());
  }
}

TEST_P(ParameterizedWebFrameTest, DisambiguationPopupNoContainer) {
  registerMockedHttpURLLoad("disambiguation_popup_no_container.html");

  DisambiguationPopupTestWebViewClient client;

  // Make sure we initialize to minimum scale, even if the window size
  // only becomes available after the load begins.
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "disambiguation_popup_no_container.html", true, 0, &client);
  webViewHelper.resize(WebSize(1000, 1000));

  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(fatTap(50, 50));
  EXPECT_FALSE(client.triggered());
}

TEST_P(ParameterizedWebFrameTest, DisambiguationPopupMobileSite) {
  const std::string htmlFile = "disambiguation_popup_mobile_site.html";
  registerMockedHttpURLLoad(htmlFile);

  DisambiguationPopupTestWebViewClient client;

  // Make sure we initialize to minimum scale, even if the window size
  // only becomes available after the load begins.
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, nullptr, &client,
                                  nullptr, enableViewportSettings);
  webViewHelper.resize(WebSize(1000, 1000));

  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(fatTap(0, 0));
  EXPECT_FALSE(client.triggered());

  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(fatTap(200, 115));
  EXPECT_FALSE(client.triggered());

  for (int i = 0; i <= 46; i++) {
    client.resetTriggered();
    webViewHelper.webView()->handleInputEvent(fatTap(120, 230 + i * 5));
    EXPECT_FALSE(client.triggered());
  }

  for (int i = 0; i <= 46; i++) {
    client.resetTriggered();
    webViewHelper.webView()->handleInputEvent(fatTap(10 + i * 5, 590));
    EXPECT_FALSE(client.triggered());
  }
}

TEST_P(ParameterizedWebFrameTest, DisambiguationPopupViewportSite) {
  const std::string htmlFile = "disambiguation_popup_viewport_site.html";
  registerMockedHttpURLLoad(htmlFile);

  DisambiguationPopupTestWebViewClient client;

  // Make sure we initialize to minimum scale, even if the window size
  // only becomes available after the load begins.
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, nullptr, &client,
                                  nullptr, enableViewportSettings);
  webViewHelper.resize(WebSize(1000, 1000));

  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(fatTap(0, 0));
  EXPECT_FALSE(client.triggered());

  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(fatTap(200, 115));
  EXPECT_FALSE(client.triggered());

  for (int i = 0; i <= 46; i++) {
    client.resetTriggered();
    webViewHelper.webView()->handleInputEvent(fatTap(120, 230 + i * 5));
    EXPECT_FALSE(client.triggered());
  }

  for (int i = 0; i <= 46; i++) {
    client.resetTriggered();
    webViewHelper.webView()->handleInputEvent(fatTap(10 + i * 5, 590));
    EXPECT_FALSE(client.triggered());
  }
}

TEST_F(WebFrameTest, DisambiguationPopupVisualViewport) {
  const std::string htmlFile = "disambiguation_popup_200_by_800.html";
  registerMockedHttpURLLoad(htmlFile);

  DisambiguationPopupTestWebViewClient client;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, nullptr, &client,
                                  nullptr, configureAndroid);

  WebViewImpl* webViewImpl = webViewHelper.webView();
  ASSERT_TRUE(webViewImpl);
  LocalFrame* frame = webViewImpl->mainFrameImpl()->frame();
  ASSERT_TRUE(frame);

  webViewHelper.resize(WebSize(100, 200));

  // Scroll main frame to the bottom of the document
  webViewImpl->mainFrame()->setScrollOffset(WebSize(0, 400));
  EXPECT_SIZE_EQ(ScrollOffset(0, 400), frame->view()->scrollOffset());

  webViewImpl->setPageScaleFactor(2.0);

  // Scroll visual viewport to the top of the main frame.
  VisualViewport& visualViewport = frame->page()->frameHost().visualViewport();
  visualViewport.setLocation(FloatPoint(0, 0));
  EXPECT_SIZE_EQ(ScrollOffset(0, 0), visualViewport.scrollOffset());

  // Tap at the top: there is nothing there.
  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(fatTap(10, 60));
  EXPECT_FALSE(client.triggered());

  // Scroll visual viewport to the bottom of the main frame.
  visualViewport.setLocation(FloatPoint(0, 200));
  EXPECT_SIZE_EQ(ScrollOffset(0, 200), visualViewport.scrollOffset());

  // Now the tap with the same coordinates should hit two elements.
  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(fatTap(10, 60));
  EXPECT_TRUE(client.triggered());

  // The same tap shouldn't trigger didTapMultipleTargets() after disabling the
  // notification for multi-target-tap.
  webViewHelper.webView()->settings()->setMultiTargetTapNotificationEnabled(
      false);
  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(fatTap(10, 60));
  EXPECT_FALSE(client.triggered());
}

TEST_P(ParameterizedWebFrameTest, DisambiguationPopupBlacklist) {
  const unsigned viewportWidth = 500;
  const unsigned viewportHeight = 1000;
  const unsigned divHeight = 100;
  const std::string htmlFile = "disambiguation_popup_blacklist.html";
  registerMockedHttpURLLoad(htmlFile);

  DisambiguationPopupTestWebViewClient client;

  // Make sure we initialize to minimum scale, even if the window size
  // only becomes available after the load begins.
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + htmlFile, true, 0, &client);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));

  // Click somewhere where the popup shouldn't appear.
  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(fatTap(viewportWidth / 2, 0));
  EXPECT_FALSE(client.triggered());

  // Click directly in between two container divs with click handlers, with
  // children that don't handle clicks.
  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(
      fatTap(viewportWidth / 2, divHeight));
  EXPECT_TRUE(client.triggered());

  // The third div container should be blacklisted if you click on the link it
  // contains.
  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(
      fatTap(viewportWidth / 2, divHeight * 3.25));
  EXPECT_FALSE(client.triggered());
}

TEST_P(ParameterizedWebFrameTest, DisambiguationPopupPageScale) {
  registerMockedHttpURLLoad("disambiguation_popup_page_scale.html");

  DisambiguationPopupTestWebViewClient client;

  // Make sure we initialize to minimum scale, even if the window size
  // only becomes available after the load begins.
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "disambiguation_popup_page_scale.html", true, 0, &client);
  webViewHelper.resize(WebSize(1000, 1000));

  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(fatTap(80, 80));
  EXPECT_TRUE(client.triggered());

  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(fatTap(230, 190));
  EXPECT_TRUE(client.triggered());

  webViewHelper.webView()->setPageScaleFactor(3.0f);
  webViewHelper.webView()->updateAllLifecyclePhases();

  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(fatTap(240, 240));
  EXPECT_TRUE(client.triggered());

  client.resetTriggered();
  webViewHelper.webView()->handleInputEvent(fatTap(690, 570));
  EXPECT_FALSE(client.triggered());
}

class TestSubstituteDataWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  TestSubstituteDataWebFrameClient() : m_commitCalled(false) {}

  virtual void didFailProvisionalLoad(WebLocalFrame* frame,
                                      const WebURLError& error,
                                      WebHistoryCommitType) {
    frame->loadHTMLString("This should appear",
                          toKURL("data:text/html,chromewebdata"),
                          error.unreachableURL, true);
  }

  virtual void didCommitProvisionalLoad(WebLocalFrame* frame,
                                        const WebHistoryItem&,
                                        WebHistoryCommitType) {
    if (frame->dataSource()->response().url() !=
        WebURL(URLTestHelpers::toKURL("about:blank")))
      m_commitCalled = true;
  }

  bool commitCalled() const { return m_commitCalled; }

 private:
  bool m_commitCalled;
};

TEST_P(ParameterizedWebFrameTest, ReplaceNavigationAfterHistoryNavigation) {
  TestSubstituteDataWebFrameClient webFrameClient;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad("about:blank", true, &webFrameClient);
  WebFrame* frame = webViewHelper.webView()->mainFrame();

  // Load a url as a history navigation that will return an error.
  // TestSubstituteDataWebFrameClient will start a SubstituteData load in
  // response to the load failure, which should get fully committed.  Due to
  // https://bugs.webkit.org/show_bug.cgi?id=91685,
  // FrameLoader::didReceiveData() wasn't getting called in this case, which
  // resulted in the SubstituteData document not getting displayed.
  WebURLError error;
  error.reason = 1337;
  error.domain = "WebFrameTest";
  std::string errorURL = "http://0.0.0.0";
  WebURLResponse response;
  response.setURL(URLTestHelpers::toKURL(errorURL));
  response.setMIMEType("text/html");
  response.setHTTPStatusCode(500);
  WebHistoryItem errorHistoryItem;
  errorHistoryItem.initialize();
  errorHistoryItem.setURLString(
      WebString::fromUTF8(errorURL.c_str(), errorURL.length()));
  Platform::current()->getURLLoaderMockFactory()->registerErrorURL(
      URLTestHelpers::toKURL(errorURL), response, error);
  FrameTestHelpers::loadHistoryItem(frame, errorHistoryItem,
                                    WebHistoryDifferentDocumentLoad,
                                    WebCachePolicy::UseProtocolCachePolicy);
  WebString text = WebFrameContentDumper::dumpWebViewAsText(
      webViewHelper.webView(), std::numeric_limits<size_t>::max());
  EXPECT_EQ("This should appear", text.utf8());
  EXPECT_TRUE(webFrameClient.commitCalled());
}

class TestWillInsertBodyWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  TestWillInsertBodyWebFrameClient() : m_numBodies(0), m_didLoad(false) {}

  void didCommitProvisionalLoad(WebLocalFrame*,
                                const WebHistoryItem&,
                                WebHistoryCommitType) override {
    m_numBodies = 0;
    m_didLoad = true;
  }

  void didCreateDocumentElement(WebLocalFrame*) override {
    EXPECT_EQ(0, m_numBodies);
  }

  void willInsertBody(WebLocalFrame*) override { m_numBodies++; }

  int m_numBodies;
  bool m_didLoad;
};

TEST_P(ParameterizedWebFrameTest, HTMLDocument) {
  registerMockedHttpURLLoad("clipped-body.html");

  TestWillInsertBodyWebFrameClient webFrameClient;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "clipped-body.html", false,
                                  &webFrameClient);

  EXPECT_TRUE(webFrameClient.m_didLoad);
  EXPECT_EQ(1, webFrameClient.m_numBodies);
}

TEST_P(ParameterizedWebFrameTest, EmptyDocument) {
  registerMockedHttpURLLoad("frameserializer/svg/green_rectangle.svg");

  TestWillInsertBodyWebFrameClient webFrameClient;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(false, &webFrameClient);

  EXPECT_FALSE(webFrameClient.m_didLoad);
  // The empty document that a new frame starts with triggers this.
  EXPECT_EQ(1, webFrameClient.m_numBodies);
}

TEST_P(ParameterizedWebFrameTest,
       MoveCaretSelectionTowardsWindowPointWithNoSelection) {
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad("about:blank", true);
  WebFrame* frame = webViewHelper.webView()->mainFrame();

  // This test passes if this doesn't crash.
  frame->toWebLocalFrame()->moveCaretSelection(WebPoint(0, 0));
}

class SpellCheckClient : public WebSpellCheckClient {
 public:
  explicit SpellCheckClient(uint32_t hash = 0)
      : m_numberOfTimesChecked(0), m_hash(hash) {}
  virtual ~SpellCheckClient() {}
  void requestCheckingOfText(const WebString&,
                             const WebVector<uint32_t>&,
                             const WebVector<unsigned>&,
                             WebTextCheckingCompletion* completion) override {
    ++m_numberOfTimesChecked;
    Vector<WebTextCheckingResult> results;
    const int misspellingStartOffset = 1;
    const int misspellingLength = 8;
    results.append(WebTextCheckingResult(
        WebTextDecorationTypeSpelling, misspellingStartOffset,
        misspellingLength, WebString(), m_hash));
    completion->didFinishCheckingText(results);
  }
  int numberOfTimesChecked() const { return m_numberOfTimesChecked; }

 private:
  int m_numberOfTimesChecked;
  uint32_t m_hash;
};

TEST_P(ParameterizedWebFrameTest, ReplaceMisspelledRange) {
  registerMockedHttpURLLoad("spell.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "spell.html");
  SpellCheckClient spellcheck;
  webViewHelper.webView()->setSpellCheckClient(&spellcheck);

  WebLocalFrameImpl* frame = webViewHelper.webView()->mainFrameImpl();
  Document* document = frame->frame()->document();
  Element* element = document->getElementById("data");

  webViewHelper.webView()->settings()->setEditingBehavior(
      WebSettings::EditingBehaviorWin);

  element->focus();
  NonThrowableExceptionState exceptionState;
  document->execCommand("InsertText", false, "_wellcome_.", exceptionState);
  EXPECT_FALSE(exceptionState.hadException());

  const int allTextBeginOffset = 0;
  const int allTextLength = 11;
  frame->selectRange(WebRange(allTextBeginOffset, allTextLength));
  EphemeralRange selectionRange =
      frame->frame()->selection().selection().toNormalizedEphemeralRange();

  EXPECT_EQ(1, spellcheck.numberOfTimesChecked());
  EXPECT_EQ(1U, document->markers()
                    .markersInRange(selectionRange, DocumentMarker::Spelling)
                    .size());

  frame->replaceMisspelledRange("welcome");
  EXPECT_EQ("_welcome_.",
            WebFrameContentDumper::dumpWebViewAsText(
                webViewHelper.webView(), std::numeric_limits<size_t>::max())
                .utf8());
}

TEST_P(ParameterizedWebFrameTest, RemoveSpellingMarkers) {
  registerMockedHttpURLLoad("spell.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "spell.html");
  SpellCheckClient spellcheck;
  webViewHelper.webView()->setSpellCheckClient(&spellcheck);

  WebLocalFrameImpl* frame = webViewHelper.webView()->mainFrameImpl();
  Document* document = frame->frame()->document();
  Element* element = document->getElementById("data");

  webViewHelper.webView()->settings()->setEditingBehavior(
      WebSettings::EditingBehaviorWin);

  element->focus();
  NonThrowableExceptionState exceptionState;
  document->execCommand("InsertText", false, "_wellcome_.", exceptionState);
  EXPECT_FALSE(exceptionState.hadException());

  frame->removeSpellingMarkers();

  const int allTextBeginOffset = 0;
  const int allTextLength = 11;
  frame->selectRange(WebRange(allTextBeginOffset, allTextLength));
  EphemeralRange selectionRange =
      frame->frame()->selection().selection().toNormalizedEphemeralRange();

  EXPECT_EQ(0U, document->markers()
                    .markersInRange(selectionRange, DocumentMarker::Spelling)
                    .size());
}

TEST_P(ParameterizedWebFrameTest, RemoveSpellingMarkersUnderWords) {
  registerMockedHttpURLLoad("spell.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "spell.html");
  SpellCheckClient spellcheck;
  webViewHelper.webView()->setSpellCheckClient(&spellcheck);

  LocalFrame* frame = webViewHelper.webView()->mainFrameImpl()->frame();
  Document* document = frame->document();
  Element* element = document->getElementById("data");

  webViewHelper.webView()->settings()->setEditingBehavior(
      WebSettings::EditingBehaviorWin);

  element->focus();
  NonThrowableExceptionState exceptionState;
  document->execCommand("InsertText", false, " wellcome ", exceptionState);
  EXPECT_FALSE(exceptionState.hadException());

  WebVector<uint32_t> documentMarkers1;
  webViewHelper.webView()->spellingMarkers(&documentMarkers1);
  EXPECT_EQ(1U, documentMarkers1.size());

  Vector<String> words;
  words.append("wellcome");
  frame->removeSpellingMarkersUnderWords(words);

  WebVector<uint32_t> documentMarkers2;
  webViewHelper.webView()->spellingMarkers(&documentMarkers2);
  EXPECT_EQ(0U, documentMarkers2.size());
}

TEST_P(ParameterizedWebFrameTest, MarkerHashIdentifiers) {
  registerMockedHttpURLLoad("spell.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "spell.html");

  static const uint32_t kHash = 42;
  SpellCheckClient spellcheck(kHash);
  webViewHelper.webView()->setSpellCheckClient(&spellcheck);

  WebLocalFrameImpl* frame = webViewHelper.webView()->mainFrameImpl();
  Document* document = frame->frame()->document();
  Element* element = document->getElementById("data");

  webViewHelper.webView()->settings()->setEditingBehavior(
      WebSettings::EditingBehaviorWin);

  element->focus();
  NonThrowableExceptionState exceptionState;
  document->execCommand("InsertText", false, "wellcome.", exceptionState);
  EXPECT_FALSE(exceptionState.hadException());

  WebVector<uint32_t> documentMarkers;
  webViewHelper.webView()->spellingMarkers(&documentMarkers);
  EXPECT_EQ(1U, documentMarkers.size());
  EXPECT_EQ(kHash, documentMarkers[0]);
}

class StubbornSpellCheckClient : public WebSpellCheckClient {
 public:
  StubbornSpellCheckClient() : m_completion(0) {}
  virtual ~StubbornSpellCheckClient() {}

  virtual void requestCheckingOfText(
      const WebString&,
      const WebVector<uint32_t>&,
      const WebVector<unsigned>&,
      WebTextCheckingCompletion* completion) override {
    m_completion = completion;
  }

  void cancelAllPendingRequests() override {
    if (!m_completion)
      return;
    m_completion->didCancelCheckingText();
    m_completion = nullptr;
  }

  void kickNoResults() { kick(-1, -1, WebTextDecorationTypeSpelling); }

  void kick() { kick(1, 8, WebTextDecorationTypeSpelling); }

  void kickGrammar() { kick(1, 8, WebTextDecorationTypeGrammar); }

  void kickInvisibleSpellcheck() {
    kick(1, 8, WebTextDecorationTypeInvisibleSpellcheck);
  }

 private:
  void kick(int misspellingStartOffset,
            int misspellingLength,
            WebTextDecorationType type) {
    if (!m_completion)
      return;
    Vector<WebTextCheckingResult> results;
    if (misspellingStartOffset >= 0 && misspellingLength > 0)
      results.append(WebTextCheckingResult(type, misspellingStartOffset,
                                           misspellingLength));
    m_completion->didFinishCheckingText(results);
    m_completion = 0;
  }

  WebTextCheckingCompletion* m_completion;
};

TEST_P(ParameterizedWebFrameTest, SlowSpellcheckMarkerPosition) {
  registerMockedHttpURLLoad("spell.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "spell.html");

  StubbornSpellCheckClient spellcheck;
  webViewHelper.webView()->setSpellCheckClient(&spellcheck);

  WebLocalFrameImpl* frame = webViewHelper.webView()->mainFrameImpl();
  Document* document = frame->frame()->document();
  Element* element = document->getElementById("data");

  webViewHelper.webView()->settings()->setEditingBehavior(
      WebSettings::EditingBehaviorWin);

  element->focus();
  NonThrowableExceptionState exceptionState;
  document->execCommand("InsertText", false, "wellcome ", exceptionState);
  EXPECT_FALSE(exceptionState.hadException());
  document->execCommand("InsertText", false, "he", exceptionState);
  EXPECT_FALSE(exceptionState.hadException());

  spellcheck.kick();

  WebVector<uint32_t> documentMarkers;
  webViewHelper.webView()->spellingMarkers(&documentMarkers);
  EXPECT_EQ(0U, documentMarkers.size());
}

// This test verifies that cancelling spelling request does not cause a
// write-after-free when there's no spellcheck client set.
TEST_P(ParameterizedWebFrameTest, CancelSpellingRequestCrash) {
  registerMockedHttpURLLoad("spell.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "spell.html");
  webViewHelper.webView()->setSpellCheckClient(0);

  WebLocalFrameImpl* frame = webViewHelper.webView()->mainFrameImpl();
  Document* document = frame->frame()->document();
  Element* element = document->getElementById("data");

  webViewHelper.webView()->settings()->setEditingBehavior(
      WebSettings::EditingBehaviorWin);

  element->focus();
  frame->frame()->editor().replaceSelectionWithText("A", false, false);
  frame->frame()->spellChecker().cancelCheck();
}

TEST_P(ParameterizedWebFrameTest, SpellcheckResultErasesMarkers) {
  registerMockedHttpURLLoad("spell.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "spell.html");

  StubbornSpellCheckClient spellcheck;
  webViewHelper.webView()->setSpellCheckClient(&spellcheck);

  WebLocalFrameImpl* frame = webViewHelper.webView()->mainFrameImpl();
  Document* document = frame->frame()->document();
  Element* element = document->getElementById("data");

  webViewHelper.webView()->settings()->setEditingBehavior(
      WebSettings::EditingBehaviorWin);

  element->focus();
  NonThrowableExceptionState exceptionState;
  document->execCommand("InsertText", false, "welcome ", exceptionState);

  document->updateStyleAndLayout();

  EXPECT_FALSE(exceptionState.hadException());
  auto range = EphemeralRange::rangeOfContents(*element);
  document->markers().addMarker(range.startPosition(), range.endPosition(),
                                DocumentMarker::Spelling);
  document->markers().addMarker(range.startPosition(), range.endPosition(),
                                DocumentMarker::Grammar);
  document->markers().addMarker(range.startPosition(), range.endPosition(),
                                DocumentMarker::InvisibleSpellcheck);
  EXPECT_EQ(3U, document->markers().markers().size());

  spellcheck.kickNoResults();
  EXPECT_EQ(0U, document->markers().markers().size());
}

TEST_P(ParameterizedWebFrameTest, SpellcheckResultsSavedInDocument) {
  registerMockedHttpURLLoad("spell.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "spell.html");

  StubbornSpellCheckClient spellcheck;
  webViewHelper.webView()->setSpellCheckClient(&spellcheck);

  WebLocalFrameImpl* frame = webViewHelper.webView()->mainFrameImpl();
  Document* document = frame->frame()->document();
  Element* element = document->getElementById("data");

  webViewHelper.webView()->settings()->setEditingBehavior(
      WebSettings::EditingBehaviorWin);

  element->focus();
  NonThrowableExceptionState exceptionState;
  document->execCommand("InsertText", false, "wellcome ", exceptionState);
  EXPECT_FALSE(exceptionState.hadException());

  spellcheck.kick();
  ASSERT_EQ(1U, document->markers().markers().size());
  ASSERT_NE(static_cast<DocumentMarker*>(0), document->markers().markers()[0]);
  EXPECT_EQ(DocumentMarker::Spelling, document->markers().markers()[0]->type());

  document->execCommand("InsertText", false, "wellcome ", exceptionState);
  EXPECT_FALSE(exceptionState.hadException());

  spellcheck.kickGrammar();
  ASSERT_EQ(1U, document->markers().markers().size());
  ASSERT_NE(static_cast<DocumentMarker*>(0), document->markers().markers()[0]);
  EXPECT_EQ(DocumentMarker::Grammar, document->markers().markers()[0]->type());

  document->execCommand("InsertText", false, "wellcome ", exceptionState);
  EXPECT_FALSE(exceptionState.hadException());

  spellcheck.kickInvisibleSpellcheck();
  ASSERT_EQ(1U, document->markers().markers().size());
  ASSERT_NE(static_cast<DocumentMarker*>(0), document->markers().markers()[0]);
  EXPECT_EQ(DocumentMarker::InvisibleSpellcheck,
            document->markers().markers()[0]->type());
}

class TestAccessInitialDocumentWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  TestAccessInitialDocumentWebFrameClient()
      : m_didAccessInitialDocument(false) {}

  virtual void didAccessInitialDocument() { m_didAccessInitialDocument = true; }

  bool m_didAccessInitialDocument;
};

TEST_P(ParameterizedWebFrameTest, DidAccessInitialDocumentBody) {
  // FIXME: Why is this local webViewClient needed instead of the default
  // WebViewHelper one? With out it there's some mysterious crash in the
  // WebViewHelper destructor.
  FrameTestHelpers::TestWebViewClient webViewClient;
  TestAccessInitialDocumentWebFrameClient webFrameClient;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, &webFrameClient, &webViewClient);
  runPendingTasks();
  EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);

  // Create another window that will try to access it.
  FrameTestHelpers::WebViewHelper newWebViewHelper;
  WebView* newView = newWebViewHelper.initializeWithOpener(
      webViewHelper.webView()->mainFrame(), true);
  runPendingTasks();
  EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);

  // Access the initial document by modifying the body.
  newView->mainFrame()->executeScript(
      WebScriptSource("window.opener.document.body.innerHTML += 'Modified';"));
  runPendingTasks();
  EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);

  // Access the initial document again, to ensure we don't notify twice.
  newView->mainFrame()->executeScript(
      WebScriptSource("window.opener.document.body.innerHTML += 'Modified';"));
  runPendingTasks();
  EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);
}

TEST_P(ParameterizedWebFrameTest, DidAccessInitialDocumentNavigator) {
  // FIXME: Why is this local webViewClient needed instead of the default
  // WebViewHelper one? With out it there's some mysterious crash in the
  // WebViewHelper destructor.
  FrameTestHelpers::TestWebViewClient webViewClient;
  TestAccessInitialDocumentWebFrameClient webFrameClient;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, &webFrameClient, &webViewClient);
  runPendingTasks();
  EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);

  // Create another window that will try to access it.
  FrameTestHelpers::WebViewHelper newWebViewHelper;
  WebView* newView = newWebViewHelper.initializeWithOpener(
      webViewHelper.webView()->mainFrame(), true);
  runPendingTasks();
  EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);

  // Access the initial document to get to the navigator object.
  newView->mainFrame()->executeScript(
      WebScriptSource("console.log(window.opener.navigator);"));
  runPendingTasks();
  EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);
}

TEST_P(ParameterizedWebFrameTest, DidAccessInitialDocumentViaJavascriptUrl) {
  TestAccessInitialDocumentWebFrameClient webFrameClient;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, &webFrameClient);
  runPendingTasks();
  EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);

  // Access the initial document from a javascript: URL.
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              "javascript:document.body.appendChild(document."
                              "createTextNode('Modified'))");
  EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);
}

// Fails on the WebKit XP (deps) bot. http://crbug.com/312192
#if OS(WIN)
TEST_P(ParameterizedWebFrameTest,
       DISABLED_DidAccessInitialDocumentBodyBeforeModalDialog)
#else
TEST_P(ParameterizedWebFrameTest, DidAccessInitialDocumentBodyBeforeModalDialog)
#endif
{
  // FIXME: Why is this local webViewClient needed instead of the default
  // WebViewHelper one? With out it there's some mysterious crash in the
  // WebViewHelper destructor.
  FrameTestHelpers::TestWebViewClient webViewClient;
  TestAccessInitialDocumentWebFrameClient webFrameClient;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, &webFrameClient, &webViewClient);
  runPendingTasks();
  EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);

  // Create another window that will try to access it.
  FrameTestHelpers::WebViewHelper newWebViewHelper;
  WebView* newView = newWebViewHelper.initializeWithOpener(
      webViewHelper.webView()->mainFrame(), true);
  runPendingTasks();
  EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);

  // Access the initial document by modifying the body.
  newView->mainFrame()->executeScript(
      WebScriptSource("window.opener.document.body.innerHTML += 'Modified';"));
  EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);

  // Run a modal dialog, which used to run a nested message loop and require
  // a special case for notifying about the access.
  newView->mainFrame()->executeScript(
      WebScriptSource("window.opener.confirm('Modal');"));
  EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);

  // Ensure that we don't notify again later.
  runPendingTasks();
  EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);
}

// Fails on the WebKit XP (deps) bot. http://crbug.com/312192
#if OS(WIN)
TEST_P(ParameterizedWebFrameTest,
       DISABLED_DidWriteToInitialDocumentBeforeModalDialog)
#else
TEST_P(ParameterizedWebFrameTest, DidWriteToInitialDocumentBeforeModalDialog)
#endif
{
  // FIXME: Why is this local webViewClient needed instead of the default
  // WebViewHelper one? With out it there's some mysterious crash in the
  // WebViewHelper destructor.
  FrameTestHelpers::TestWebViewClient webViewClient;
  TestAccessInitialDocumentWebFrameClient webFrameClient;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, &webFrameClient, &webViewClient);
  runPendingTasks();
  EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);

  // Create another window that will try to access it.
  FrameTestHelpers::WebViewHelper newWebViewHelper;
  WebView* newView = newWebViewHelper.initializeWithOpener(
      webViewHelper.webView()->mainFrame(), true);
  runPendingTasks();
  EXPECT_FALSE(webFrameClient.m_didAccessInitialDocument);

  // Access the initial document with document.write, which moves us past the
  // initial empty document state of the state machine.
  newView->mainFrame()->executeScript(
      WebScriptSource("window.opener.document.write('Modified'); "
                      "window.opener.document.close();"));
  EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);

  // Run a modal dialog, which used to run a nested message loop and require
  // a special case for notifying about the access.
  newView->mainFrame()->executeScript(
      WebScriptSource("window.opener.confirm('Modal');"));
  EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);

  // Ensure that we don't notify again later.
  runPendingTasks();
  EXPECT_TRUE(webFrameClient.m_didAccessInitialDocument);
}

class TestScrolledFrameClient : public FrameTestHelpers::TestWebFrameClient {
 public:
  TestScrolledFrameClient() { reset(); }
  void reset() { m_didScrollFrame = false; }
  bool wasFrameScrolled() const { return m_didScrollFrame; }

  // WebFrameClient:
  void didChangeScrollOffset(WebLocalFrame* frame) override {
    if (frame->parent())
      return;
    EXPECT_FALSE(m_didScrollFrame);
    FrameView* view = toWebLocalFrameImpl(frame)->frameView();
    // FrameView can be scrolled in FrameView::setFixedVisibleContentRect which
    // is called from LocalFrame::createView (before the frame is associated
    // with the the view).
    if (view)
      m_didScrollFrame = true;
  }

 private:
  bool m_didScrollFrame;
};

TEST_F(WebFrameTest, CompositorScrollIsUserScrollLongPage) {
  registerMockedHttpURLLoad("long_scroll.html");
  TestScrolledFrameClient client;

  // Make sure we initialize to minimum scale, even if the window size
  // only becomes available after the load begins.
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "long_scroll.html", true,
                                  &client);
  webViewHelper.resize(WebSize(1000, 1000));

  WebLocalFrameImpl* frameImpl = webViewHelper.webView()->mainFrameImpl();
  DocumentLoader::InitialScrollState& initialScrollState =
      frameImpl->frame()->loader().documentLoader()->initialScrollState();
  GraphicsLayer* frameViewLayer = frameImpl->frameView()->layerForScrolling();

  EXPECT_FALSE(client.wasFrameScrolled());
  EXPECT_FALSE(initialScrollState.wasScrolledByUser);

  // Do a compositor scroll, verify that this is counted as a user scroll.
  frameViewLayer->platformLayer()->setScrollPositionDouble(
      WebDoublePoint(0, 1));
  frameViewLayer->didScroll();
  webViewHelper.webView()->applyViewportDeltas(WebFloatSize(), WebFloatSize(),
                                               WebFloatSize(), 1.7f, 0);
  EXPECT_TRUE(client.wasFrameScrolled());
  EXPECT_TRUE(initialScrollState.wasScrolledByUser);

  client.reset();
  initialScrollState.wasScrolledByUser = false;

  // The page scale 1.0f and scroll.
  frameViewLayer->platformLayer()->setScrollPositionDouble(
      WebDoublePoint(0, 2));
  frameViewLayer->didScroll();
  webViewHelper.webView()->applyViewportDeltas(WebFloatSize(), WebFloatSize(),
                                               WebFloatSize(), 1.0f, 0);
  EXPECT_TRUE(client.wasFrameScrolled());
  EXPECT_TRUE(initialScrollState.wasScrolledByUser);
  client.reset();
  initialScrollState.wasScrolledByUser = false;

  // No scroll event if there is no scroll delta.
  frameViewLayer->didScroll();
  webViewHelper.webView()->applyViewportDeltas(WebFloatSize(), WebFloatSize(),
                                               WebFloatSize(), 1.0f, 0);
  EXPECT_FALSE(client.wasFrameScrolled());
  EXPECT_FALSE(initialScrollState.wasScrolledByUser);
  client.reset();

  // Non zero page scale and scroll.
  frameViewLayer->platformLayer()->setScrollPositionDouble(
      WebDoublePoint(9, 15));
  frameViewLayer->didScroll();
  webViewHelper.webView()->applyViewportDeltas(WebFloatSize(), WebFloatSize(),
                                               WebFloatSize(), 0.6f, 0);
  EXPECT_TRUE(client.wasFrameScrolled());
  EXPECT_TRUE(initialScrollState.wasScrolledByUser);
  client.reset();
  initialScrollState.wasScrolledByUser = false;

  // Programmatic scroll.
  frameImpl->executeScript(WebScriptSource("window.scrollTo(0, 20);"));
  EXPECT_TRUE(client.wasFrameScrolled());
  EXPECT_FALSE(initialScrollState.wasScrolledByUser);
  client.reset();

  // Programmatic scroll to same offset. No scroll event should be generated.
  frameImpl->executeScript(WebScriptSource("window.scrollTo(0, 20);"));
  EXPECT_FALSE(client.wasFrameScrolled());
  EXPECT_FALSE(initialScrollState.wasScrolledByUser);
  client.reset();
}

TEST_P(ParameterizedWebFrameTest, FirstPartyForCookiesForRedirect) {
  String filePath = testing::blinkRootDir();
  filePath.append("/Source/web/tests/data/first_party.html");

  WebURL testURL(toKURL("http://internal.test/first_party_redirect.html"));
  char redirect[] = "http://internal.test/first_party.html";
  WebURL redirectURL(toKURL(redirect));
  WebURLResponse redirectResponse;
  redirectResponse.setMIMEType("text/html");
  redirectResponse.setHTTPStatusCode(302);
  redirectResponse.setHTTPHeaderField("Location", redirect);
  Platform::current()->getURLLoaderMockFactory()->registerURL(
      testURL, redirectResponse, filePath);

  WebURLResponse finalResponse;
  finalResponse.setMIMEType("text/html");
  Platform::current()->getURLLoaderMockFactory()->registerURL(
      redirectURL, finalResponse, filePath);

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "first_party_redirect.html",
                                  true);
  EXPECT_TRUE(
      webViewHelper.webView()->mainFrame()->document().firstPartyForCookies() ==
      redirectURL);
}

class TestNavigationPolicyWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  void didNavigateWithinPage(WebLocalFrame*,
                             const WebHistoryItem&,
                             WebHistoryCommitType,
                             bool) override {
    EXPECT_TRUE(false);
  }
};

TEST_P(ParameterizedWebFrameTest, SimulateFragmentAnchorMiddleClick) {
  registerMockedHttpURLLoad("fragment_middle_click.html");
  TestNavigationPolicyWebFrameClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "fragment_middle_click.html",
                                  true, &client);

  Document* document =
      toLocalFrame(webViewHelper.webView()->page()->mainFrame())->document();
  KURL destination = document->url();
  destination.setFragmentIdentifier("test");

  Event* event = MouseEvent::create(
      EventTypeNames::click, false, false, document->domWindow(), 0, 0, 0, 0, 0,
      0, 0, PlatformEvent::NoModifiers, 1, 0, nullptr, 0,
      PlatformMouseEvent::RealOrIndistinguishable, String(), nullptr);
  FrameLoadRequest frameRequest(document, ResourceRequest(destination));
  frameRequest.setTriggeringEvent(event);
  toLocalFrame(webViewHelper.webView()->page()->mainFrame())
      ->loader()
      .load(frameRequest);
}

class TestNewWindowWebViewClient : public FrameTestHelpers::TestWebViewClient {
 public:
  virtual WebView* createView(WebLocalFrame*,
                              const WebURLRequest&,
                              const WebWindowFeatures&,
                              const WebString&,
                              WebNavigationPolicy,
                              bool) override {
    EXPECT_TRUE(false);
    return 0;
  }
};

class TestNewWindowWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  TestNewWindowWebFrameClient() : m_decidePolicyCallCount(0) {}

  WebNavigationPolicy decidePolicyForNavigation(
      const NavigationPolicyInfo& info) override {
    m_decidePolicyCallCount++;
    return info.defaultPolicy;
  }

  int decidePolicyCallCount() const { return m_decidePolicyCallCount; }

 private:
  int m_decidePolicyCallCount;
};

TEST_P(ParameterizedWebFrameTest, ModifiedClickNewWindow) {
  registerMockedHttpURLLoad("ctrl_click.html");
  registerMockedHttpURLLoad("hello_world.html");
  TestNewWindowWebViewClient webViewClient;
  TestNewWindowWebFrameClient webFrameClient;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "ctrl_click.html", true,
                                  &webFrameClient, &webViewClient);

  Document* document =
      toLocalFrame(webViewHelper.webView()->page()->mainFrame())->document();
  KURL destination = toKURL(m_baseURL + "hello_world.html");

  // ctrl+click event
  Event* event = MouseEvent::create(
      EventTypeNames::click, false, false, document->domWindow(), 0, 0, 0, 0, 0,
      0, 0, PlatformEvent::CtrlKey, 0, 0, nullptr, 0,
      PlatformMouseEvent::RealOrIndistinguishable, String(), nullptr);
  FrameLoadRequest frameRequest(document, ResourceRequest(destination));
  frameRequest.setTriggeringEvent(event);
  UserGestureIndicator gesture(UserGestureToken::create());
  toLocalFrame(webViewHelper.webView()->page()->mainFrame())
      ->loader()
      .load(frameRequest);
  FrameTestHelpers::pumpPendingRequestsForFrameToLoad(
      webViewHelper.webView()->mainFrame());

  // decidePolicyForNavigation should be called both for the original request
  // and the ctrl+click.
  EXPECT_EQ(2, webFrameClient.decidePolicyCallCount());
}

TEST_P(ParameterizedWebFrameTest, BackToReload) {
  registerMockedHttpURLLoad("fragment_middle_click.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "fragment_middle_click.html",
                                  true);
  WebFrame* frame = webViewHelper.webView()->mainFrame();
  const FrameLoader& mainFrameLoader =
      webViewHelper.webView()->mainFrameImpl()->frame()->loader();
  Persistent<HistoryItem> firstItem = mainFrameLoader.currentItem();
  EXPECT_TRUE(firstItem);

  registerMockedHttpURLLoad("white-1x1.png");
  FrameTestHelpers::loadFrame(frame, m_baseURL + "white-1x1.png");
  EXPECT_NE(firstItem.get(), mainFrameLoader.currentItem());

  FrameTestHelpers::loadHistoryItem(frame, WebHistoryItem(firstItem.get()),
                                    WebHistoryDifferentDocumentLoad,
                                    WebCachePolicy::UseProtocolCachePolicy);
  EXPECT_EQ(firstItem.get(), mainFrameLoader.currentItem());

  FrameTestHelpers::reloadFrame(frame);
  EXPECT_EQ(WebCachePolicy::ValidatingCacheData,
            frame->dataSource()->request().getCachePolicy());
}

TEST_P(ParameterizedWebFrameTest, BackDuringChildFrameReload) {
  registerMockedHttpURLLoad("page_with_blank_iframe.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "page_with_blank_iframe.html",
                                  true);
  WebLocalFrame* mainFrame = webViewHelper.webView()->mainFrameImpl();
  const FrameLoader& mainFrameLoader =
      webViewHelper.webView()->mainFrameImpl()->frame()->loader();
  WebFrame* childFrame = mainFrame->firstChild();
  ASSERT_TRUE(childFrame);

  // Start a history navigation, then have a different frame commit a
  // navigation.  In this case, reload an about:blank frame, which will commit
  // synchronously.  After the history navigation completes, both the
  // appropriate document url and the current history item should reflect the
  // history navigation.
  registerMockedHttpURLLoad("white-1x1.png");
  WebHistoryItem item;
  item.initialize();
  WebURL historyURL(toKURL(m_baseURL + "white-1x1.png"));
  item.setURLString(historyURL.string());
  WebURLRequest request = mainFrame->requestFromHistoryItem(
      item, WebCachePolicy::UseProtocolCachePolicy);
  mainFrame->load(request, WebFrameLoadType::BackForward, item);

  FrameTestHelpers::reloadFrame(childFrame);
  EXPECT_EQ(item.urlString(), mainFrame->document().url().string());
  EXPECT_EQ(item.urlString(),
            WebString(mainFrameLoader.currentItem()->urlString()));
}

TEST_P(ParameterizedWebFrameTest, ReloadPost) {
  registerMockedHttpURLLoad("reload_post.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "reload_post.html", true);
  WebFrame* frame = webViewHelper.webView()->mainFrame();

  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              "javascript:document.forms[0].submit()");
  // Pump requests one more time after the javascript URL has executed to
  // trigger the actual POST load request.
  FrameTestHelpers::pumpPendingRequestsForFrameToLoad(
      webViewHelper.webView()->mainFrame());
  EXPECT_EQ(WebString::fromUTF8("POST"),
            frame->dataSource()->request().httpMethod());

  FrameTestHelpers::reloadFrame(frame);
  EXPECT_EQ(WebCachePolicy::ValidatingCacheData,
            frame->dataSource()->request().getCachePolicy());
  EXPECT_EQ(WebNavigationTypeFormResubmitted,
            frame->dataSource()->navigationType());
}

TEST_P(ParameterizedWebFrameTest, LoadHistoryItemReload) {
  registerMockedHttpURLLoad("fragment_middle_click.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "fragment_middle_click.html",
                                  true);
  WebFrame* frame = webViewHelper.webView()->mainFrame();
  const FrameLoader& mainFrameLoader =
      webViewHelper.webView()->mainFrameImpl()->frame()->loader();
  Persistent<HistoryItem> firstItem = mainFrameLoader.currentItem();
  EXPECT_TRUE(firstItem);

  registerMockedHttpURLLoad("white-1x1.png");
  FrameTestHelpers::loadFrame(frame, m_baseURL + "white-1x1.png");
  EXPECT_NE(firstItem.get(), mainFrameLoader.currentItem());

  // Cache policy overrides should take.
  FrameTestHelpers::loadHistoryItem(frame, WebHistoryItem(firstItem),
                                    WebHistoryDifferentDocumentLoad,
                                    WebCachePolicy::ValidatingCacheData);
  EXPECT_EQ(firstItem.get(), mainFrameLoader.currentItem());
  EXPECT_EQ(WebCachePolicy::ValidatingCacheData,
            frame->dataSource()->request().getCachePolicy());
}

class TestCachePolicyWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  explicit TestCachePolicyWebFrameClient(
      TestCachePolicyWebFrameClient* parentClient)
      : m_parentClient(parentClient),
        m_policy(WebCachePolicy::UseProtocolCachePolicy),
        m_childClient(0),
        m_willSendRequestCallCount(0),
        m_childFrameCreationCount(0) {}

  void setChildWebFrameClient(TestCachePolicyWebFrameClient* client) {
    m_childClient = client;
  }
  WebCachePolicy getCachePolicy() const { return m_policy; }
  int willSendRequestCallCount() const { return m_willSendRequestCallCount; }
  int childFrameCreationCount() const { return m_childFrameCreationCount; }

  virtual WebLocalFrame* createChildFrame(
      WebLocalFrame* parent,
      WebTreeScopeType scope,
      const WebString&,
      const WebString&,
      WebSandboxFlags,
      const WebFrameOwnerProperties& frameOwnerProperties) {
    DCHECK(m_childClient);
    m_childFrameCreationCount++;
    WebLocalFrame* frame = WebLocalFrame::create(scope, m_childClient);
    parent->appendChild(frame);
    return frame;
  }

  virtual void didStartLoading(bool toDifferentDocument) {
    if (m_parentClient) {
      m_parentClient->didStartLoading(toDifferentDocument);
      return;
    }
    TestWebFrameClient::didStartLoading(toDifferentDocument);
  }

  virtual void didStopLoading() {
    if (m_parentClient) {
      m_parentClient->didStopLoading();
      return;
    }
    TestWebFrameClient::didStopLoading();
  }

  void willSendRequest(WebLocalFrame*, WebURLRequest& request) override {
    m_policy = request.getCachePolicy();
    m_willSendRequestCallCount++;
  }

 private:
  TestCachePolicyWebFrameClient* m_parentClient;

  WebCachePolicy m_policy;
  TestCachePolicyWebFrameClient* m_childClient;
  int m_willSendRequestCallCount;
  int m_childFrameCreationCount;
};

TEST_P(ParameterizedWebFrameTest, ReloadIframe) {
  registerMockedHttpURLLoad("iframe_reload.html");
  registerMockedHttpURLLoad("visible_iframe.html");
  TestCachePolicyWebFrameClient mainClient(0);
  TestCachePolicyWebFrameClient childClient(&mainClient);
  mainClient.setChildWebFrameClient(&childClient);

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "iframe_reload.html", true,
                                  &mainClient);

  WebLocalFrameImpl* mainFrame = webViewHelper.webView()->mainFrameImpl();
  WebLocalFrameImpl* childFrame = toWebLocalFrameImpl(mainFrame->firstChild());
  ASSERT_EQ(childFrame->client(), &childClient);
  EXPECT_EQ(mainClient.childFrameCreationCount(), 1);
  EXPECT_EQ(childClient.willSendRequestCallCount(), 1);
  EXPECT_EQ(childClient.getCachePolicy(),
            WebCachePolicy::UseProtocolCachePolicy);

  FrameTestHelpers::reloadFrame(mainFrame);

  // A new WebFrame should have been created, but the child WebFrameClient
  // should be reused.
  ASSERT_NE(childFrame, toWebLocalFrameImpl(mainFrame->firstChild()));
  ASSERT_EQ(toWebLocalFrameImpl(mainFrame->firstChild())->client(),
            &childClient);

  EXPECT_EQ(mainClient.childFrameCreationCount(), 2);
  EXPECT_EQ(childClient.willSendRequestCallCount(), 2);
  EXPECT_EQ(childClient.getCachePolicy(), WebCachePolicy::ValidatingCacheData);
}

class TestSameDocumentWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  TestSameDocumentWebFrameClient()
      : m_frameLoadTypeReloadMainResourceSeen(false) {}

  virtual void willSendRequest(WebLocalFrame* frame, WebURLRequest&) {
    if (toWebLocalFrameImpl(frame)->frame()->loader().loadType() ==
        FrameLoadTypeReloadMainResource)
      m_frameLoadTypeReloadMainResourceSeen = true;
  }

  bool frameLoadTypeReloadMainResourceSeen() const {
    return m_frameLoadTypeReloadMainResourceSeen;
  }

 private:
  bool m_frameLoadTypeReloadMainResourceSeen;
};

TEST_P(ParameterizedWebFrameTest, NavigateToSame) {
  registerMockedHttpURLLoad("navigate_to_same.html");
  TestSameDocumentWebFrameClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "navigate_to_same.html", true,
                                  &client);
  EXPECT_FALSE(client.frameLoadTypeReloadMainResourceSeen());

  FrameLoadRequest frameRequest(
      0,
      ResourceRequest(toLocalFrame(webViewHelper.webView()->page()->mainFrame())
                          ->document()
                          ->url()));
  toLocalFrame(webViewHelper.webView()->page()->mainFrame())
      ->loader()
      .load(frameRequest);
  FrameTestHelpers::pumpPendingRequestsForFrameToLoad(
      webViewHelper.webView()->mainFrame());

  EXPECT_TRUE(client.frameLoadTypeReloadMainResourceSeen());
}

class TestSameDocumentWithImageWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  TestSameDocumentWithImageWebFrameClient() : m_numOfImageRequests(0) {}

  virtual void willSendRequest(WebLocalFrame*, WebURLRequest& request) {
    if (request.getRequestContext() == WebURLRequest::RequestContextImage) {
      m_numOfImageRequests++;
      EXPECT_EQ(WebCachePolicy::UseProtocolCachePolicy,
                request.getCachePolicy());
    }
  }

  int numOfImageRequests() const { return m_numOfImageRequests; }

 private:
  int m_numOfImageRequests;
};

TEST_P(ParameterizedWebFrameTest,
       NavigateToSameNoConditionalRequestForSubresource) {
  registerMockedHttpURLLoad("foo_with_image.html");
  registerMockedHttpURLLoad("white-1x1.png");
  TestSameDocumentWithImageWebFrameClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "foo_with_image.html", true,
                                  &client, nullptr, nullptr,
                                  &configureLoadsImagesAutomatically);

  WebCache::clear();
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "foo_with_image.html");

  // 2 images are requested, and each triggers 2 willSendRequest() calls,
  // once for preloading and once for the real request.
  EXPECT_EQ(client.numOfImageRequests(), 4);
}

TEST_P(ParameterizedWebFrameTest, WebNodeImageContents) {
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad("about:blank", true);
  WebFrame* frame = webViewHelper.webView()->mainFrame();

  static const char bluePNG[] =
      "<img "
      "src=\"data:image/"
      "png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+"
      "9AAAAGElEQVQYV2NkYPj/n4EIwDiqEF8oUT94AFIQE/cCn90IAAAAAElFTkSuQmCC\">";

  // Load up the image and test that we can extract the contents.
  KURL testURL = toKURL("about:blank");
  FrameTestHelpers::loadHTMLString(frame, bluePNG, testURL);

  WebNode node = frame->document().body().firstChild();
  EXPECT_TRUE(node.isElementNode());
  WebElement element = node.to<WebElement>();
  WebImage image = element.imageContents();
  ASSERT_FALSE(image.isNull());
  EXPECT_EQ(image.size().width, 10);
  EXPECT_EQ(image.size().height, 10);
  // FIXME: The rest of this test is disabled since the ImageDecodeCache state
  // may be inconsistent when this test runs, crbug.com/266088
  // SkBitmap bitmap = image.getSkBitmap();
  // SkAutoLockPixels locker(bitmap);
  // EXPECT_EQ(bitmap.getColor(0, 0), SK_ColorBLUE);
}

class TestStartStopCallbackWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  TestStartStopCallbackWebFrameClient()
      : m_startLoadingCount(0),
        m_stopLoadingCount(0),
        m_differentDocumentStartCount(0) {}

  void didStartLoading(bool toDifferentDocument) override {
    TestWebFrameClient::didStartLoading(toDifferentDocument);
    m_startLoadingCount++;
    if (toDifferentDocument)
      m_differentDocumentStartCount++;
  }

  void didStopLoading() override {
    TestWebFrameClient::didStopLoading();
    m_stopLoadingCount++;
  }

  int startLoadingCount() const { return m_startLoadingCount; }
  int stopLoadingCount() const { return m_stopLoadingCount; }
  int differentDocumentStartCount() const {
    return m_differentDocumentStartCount;
  }

 private:
  int m_startLoadingCount;
  int m_stopLoadingCount;
  int m_differentDocumentStartCount;
};

TEST_P(ParameterizedWebFrameTest, PushStateStartsAndStops) {
  registerMockedHttpURLLoad("push_state.html");
  TestStartStopCallbackWebFrameClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "push_state.html", true, &client);

  EXPECT_EQ(client.startLoadingCount(), 2);
  EXPECT_EQ(client.stopLoadingCount(), 2);
  EXPECT_EQ(client.differentDocumentStartCount(), 1);
}

class TestDidNavigateCommitTypeWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  TestDidNavigateCommitTypeWebFrameClient()
      : m_lastCommitType(WebHistoryInertCommit) {}

  void didNavigateWithinPage(WebLocalFrame*,
                             const WebHistoryItem&,
                             WebHistoryCommitType type,
                             bool) override {
    m_lastCommitType = type;
  }

  WebHistoryCommitType lastCommitType() const { return m_lastCommitType; }

 private:
  WebHistoryCommitType m_lastCommitType;
};

TEST_P(ParameterizedWebFrameTest, SameDocumentHistoryNavigationCommitType) {
  registerMockedHttpURLLoad("push_state.html");
  TestDidNavigateCommitTypeWebFrameClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(
      m_baseURL + "push_state.html", true, &client);
  Persistent<HistoryItem> item =
      toLocalFrame(webViewImpl->page()->mainFrame())->loader().currentItem();
  runPendingTasks();

  toLocalFrame(webViewImpl->page()->mainFrame())
      ->loader()
      .load(
          FrameLoadRequest(
              nullptr, FrameLoader::resourceRequestFromHistoryItem(
                           item.get(), WebCachePolicy::UseProtocolCachePolicy)),
          FrameLoadTypeBackForward, item.get(), HistorySameDocumentLoad);
  EXPECT_EQ(WebBackForwardCommit, client.lastCommitType());
}

class TestHistoryWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
 public:
  TestHistoryWebFrameClient() {
    m_replacesCurrentHistoryItem = false;
    m_frame = nullptr;
  }

  void didStartProvisionalLoad(WebLocalFrame* frame, double) {
    WebDataSource* ds = frame->provisionalDataSource();
    m_replacesCurrentHistoryItem = ds->replacesCurrentHistoryItem();
    m_frame = frame;
  }

  bool replacesCurrentHistoryItem() { return m_replacesCurrentHistoryItem; }
  WebFrame* frame() { return m_frame; }

 private:
  bool m_replacesCurrentHistoryItem;
  WebFrame* m_frame;
};

// Tests that the first navigation in an initially blank subframe will result in
// a history entry being replaced and not a new one being added.
TEST_P(ParameterizedWebFrameTest, FirstBlankSubframeNavigation) {
  registerMockedHttpURLLoad("history.html");
  registerMockedHttpURLLoad("find.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  TestHistoryWebFrameClient client;
  webViewHelper.initializeAndLoad("about:blank", true, &client);

  WebFrame* frame = webViewHelper.webView()->mainFrame();

  frame->executeScript(WebScriptSource(WebString::fromUTF8(
      "document.body.appendChild(document.createElement('iframe'))")));

  WebFrame* iframe = frame->firstChild();
  ASSERT_EQ(&client, toWebLocalFrameImpl(iframe)->client());
  EXPECT_EQ(iframe, client.frame());

  std::string url1 = m_baseURL + "history.html";
  FrameTestHelpers::loadFrame(iframe, url1);
  EXPECT_EQ(iframe, client.frame());
  EXPECT_EQ(url1, iframe->document().url().string().utf8());
  EXPECT_TRUE(client.replacesCurrentHistoryItem());

  std::string url2 = m_baseURL + "find.html";
  FrameTestHelpers::loadFrame(iframe, url2);
  EXPECT_EQ(iframe, client.frame());
  EXPECT_EQ(url2, iframe->document().url().string().utf8());
  EXPECT_FALSE(client.replacesCurrentHistoryItem());
}

// Tests that a navigation in a frame with a non-blank initial URL will create
// a new history item, unlike the case above.
TEST_P(ParameterizedWebFrameTest, FirstNonBlankSubframeNavigation) {
  registerMockedHttpURLLoad("history.html");
  registerMockedHttpURLLoad("find.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  TestHistoryWebFrameClient client;
  webViewHelper.initializeAndLoad("about:blank", true, &client);

  WebFrame* frame = webViewHelper.webView()->mainFrame();

  std::string url1 = m_baseURL + "history.html";
  FrameTestHelpers::loadFrame(
      frame,
      "javascript:var f = document.createElement('iframe'); "
      "f.src = '" +
          url1 +
          "';"
          "document.body.appendChild(f)");

  WebFrame* iframe = frame->firstChild();
  EXPECT_EQ(iframe, client.frame());
  EXPECT_EQ(url1, iframe->document().url().string().utf8());

  std::string url2 = m_baseURL + "find.html";
  FrameTestHelpers::loadFrame(iframe, url2);
  EXPECT_EQ(iframe, client.frame());
  EXPECT_EQ(url2, iframe->document().url().string().utf8());
  EXPECT_FALSE(client.replacesCurrentHistoryItem());
}

// Test verifies that layout will change a layer's scrollable attibutes
TEST_F(WebFrameTest, overflowHiddenRewrite) {
  registerMockedHttpURLLoad("non-scrollable.html");
  std::unique_ptr<FakeCompositingWebViewClient> fakeCompositingWebViewClient =
      wrapUnique(new FakeCompositingWebViewClient());
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize(true, nullptr, fakeCompositingWebViewClient.get(),
                           nullptr, &configureCompositingWebView);

  webViewHelper.resize(WebSize(100, 100));
  FrameTestHelpers::loadFrame(webViewHelper.webView()->mainFrame(),
                              m_baseURL + "non-scrollable.html");

  PaintLayerCompositor* compositor = webViewHelper.webView()->compositor();
  ASSERT_TRUE(compositor->scrollLayer());

  // Verify that the WebLayer is not scrollable initially.
  GraphicsLayer* scrollLayer = compositor->scrollLayer();
  WebLayer* webScrollLayer = scrollLayer->platformLayer();
  ASSERT_FALSE(webScrollLayer->userScrollableHorizontal());
  ASSERT_FALSE(webScrollLayer->userScrollableVertical());

  // Call javascript to make the layer scrollable, and verify it.
  WebLocalFrameImpl* frame =
      (WebLocalFrameImpl*)webViewHelper.webView()->mainFrame();
  frame->executeScript(WebScriptSource("allowScroll();"));
  webViewHelper.webView()->updateAllLifecyclePhases();
  ASSERT_TRUE(webScrollLayer->userScrollableHorizontal());
  ASSERT_TRUE(webScrollLayer->userScrollableVertical());
}

// Test that currentHistoryItem reflects the current page, not the provisional
// load.
TEST_P(ParameterizedWebFrameTest, CurrentHistoryItem) {
  registerMockedHttpURLLoad("fixed_layout.html");
  std::string url = m_baseURL + "fixed_layout.html";

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initialize();
  WebFrame* frame = webViewHelper.webView()->mainFrame();
  const FrameLoader& mainFrameLoader =
      webViewHelper.webView()->mainFrameImpl()->frame()->loader();
  WebURLRequest request;
  request.setURL(toKURL(url));
  request.setRequestorOrigin(WebSecurityOrigin::createUnique());
  frame->loadRequest(request);

  // Before commit, there is no history item.
  EXPECT_FALSE(mainFrameLoader.currentItem());

  FrameTestHelpers::pumpPendingRequestsForFrameToLoad(frame);

  // After commit, there is.
  HistoryItem* item = mainFrameLoader.currentItem();
  ASSERT_TRUE(item);
  EXPECT_EQ(WTF::String(url.data()), item->urlString());
}

class FailCreateChildFrame : public FrameTestHelpers::TestWebFrameClient {
 public:
  FailCreateChildFrame() : m_callCount(0) {}

  WebLocalFrame* createChildFrame(
      WebLocalFrame* parent,
      WebTreeScopeType scope,
      const WebString& frameName,
      const WebString& frameUniqueName,
      WebSandboxFlags sandboxFlags,
      const WebFrameOwnerProperties& frameOwnerProperties) override {
    ++m_callCount;
    return nullptr;
  }

  int callCount() const { return m_callCount; }

 private:
  int m_callCount;
};

// Test that we don't crash if WebFrameClient::createChildFrame() fails.
TEST_P(ParameterizedWebFrameTest, CreateChildFrameFailure) {
  registerMockedHttpURLLoad("create_child_frame_fail.html");
  FailCreateChildFrame client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "create_child_frame_fail.html",
                                  true, &client);

  EXPECT_EQ(1, client.callCount());
}

TEST_P(ParameterizedWebFrameTest, fixedPositionInFixedViewport) {
  registerMockedHttpURLLoad("fixed-position-in-fixed-viewport.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "fixed-position-in-fixed-viewport.html", true, nullptr,
      nullptr, nullptr, enableViewportSettings);

  WebViewImpl* webView = webViewHelper.webView();
  webViewHelper.resize(WebSize(100, 100));

  Document* document = webView->mainFrameImpl()->frame()->document();
  Element* bottomFixed = document->getElementById("bottom-fixed");
  Element* topBottomFixed = document->getElementById("top-bottom-fixed");
  Element* rightFixed = document->getElementById("right-fixed");
  Element* leftRightFixed = document->getElementById("left-right-fixed");

  // The layout viewport will hit the min-scale limit of 0.25, so it'll be
  // 400x800.
  webViewHelper.resize(WebSize(100, 200));
  EXPECT_EQ(800, bottomFixed->offsetTop() + bottomFixed->offsetHeight());
  EXPECT_EQ(800, topBottomFixed->offsetHeight());

  // Now the layout viewport hits the content width limit of 500px so it'll be
  // 500x500.
  webViewHelper.resize(WebSize(200, 200));
  EXPECT_EQ(500, rightFixed->offsetLeft() + rightFixed->offsetWidth());
  EXPECT_EQ(500, leftRightFixed->offsetWidth());
}

TEST_P(ParameterizedWebFrameTest, FrameViewMoveWithSetFrameRect) {
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad("about:blank");
  webViewHelper.resize(WebSize(200, 200));
  webViewHelper.webView()->updateAllLifecyclePhases();

  FrameView* frameView = webViewHelper.webView()->mainFrameImpl()->frameView();
  EXPECT_RECT_EQ(IntRect(0, 0, 200, 200), frameView->frameRect());
  frameView->setFrameRect(IntRect(100, 100, 200, 200));
  EXPECT_RECT_EQ(IntRect(100, 100, 200, 200), frameView->frameRect());
}

TEST_F(WebFrameTest, FrameViewScrollAccountsForTopControls) {
  FakeCompositingWebViewClient client;
  registerMockedHttpURLLoad("long_scroll.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "long_scroll.html", true, nullptr,
                                  &client, nullptr, configureAndroid);

  WebViewImpl* webView = webViewHelper.webView();
  FrameView* frameView = webViewHelper.webView()->mainFrameImpl()->frameView();

  float topControlsHeight = 40;
  webView->resizeWithTopControls(WebSize(100, 100), topControlsHeight, false);
  webView->setPageScaleFactor(2.0f);
  webView->updateAllLifecyclePhases();

  webView->mainFrame()->setScrollOffset(WebSize(0, 2000));
  EXPECT_SIZE_EQ(ScrollOffset(0, 1900), frameView->scrollOffset());

  // Simulate the top controls showing by 20px, thus shrinking the viewport
  // and allowing it to scroll an additional 20px.
  webView->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(),
                               1.0f, 20.0f / topControlsHeight);
  EXPECT_SIZE_EQ(ScrollOffset(0, 1920), frameView->maximumScrollOffset());

  // Show more, make sure the scroll actually gets clamped.
  webView->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(),
                               1.0f, 20.0f / topControlsHeight);
  webView->mainFrame()->setScrollOffset(WebSize(0, 2000));
  EXPECT_SIZE_EQ(ScrollOffset(0, 1940), frameView->scrollOffset());

  // Hide until there's 10px showing.
  webView->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(),
                               1.0f, -30.0f / topControlsHeight);
  EXPECT_SIZE_EQ(ScrollOffset(0, 1910), frameView->maximumScrollOffset());

  // Simulate a LayoutPart::resize. The frame is resized to accomodate
  // the top controls and Blink's view of the top controls matches that of
  // the CC
  webView->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(),
                               1.0f, 30.0f / topControlsHeight);
  webView->resizeWithTopControls(WebSize(100, 60), 40.0f, true);
  webView->updateAllLifecyclePhases();
  EXPECT_SIZE_EQ(ScrollOffset(0, 1940), frameView->maximumScrollOffset());

  // Now simulate hiding.
  webView->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(),
                               1.0f, -10.0f / topControlsHeight);
  EXPECT_SIZE_EQ(ScrollOffset(0, 1930), frameView->maximumScrollOffset());

  // Reset to original state: 100px widget height, top controls fully hidden.
  webView->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(),
                               1.0f, -30.0f / topControlsHeight);
  webView->resizeWithTopControls(WebSize(100, 100), topControlsHeight, false);
  webView->updateAllLifecyclePhases();
  EXPECT_SIZE_EQ(ScrollOffset(0, 1900), frameView->maximumScrollOffset());

  // Show the top controls by just 1px, since we're zoomed in to 2X, that
  // should allow an extra 0.5px of scrolling in the visual viewport. Make
  // sure we're not losing any pixels when applying the adjustment on the
  // main frame.
  webView->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(),
                               1.0f, 1.0f / topControlsHeight);
  EXPECT_SIZE_EQ(ScrollOffset(0, 1901), frameView->maximumScrollOffset());

  webView->applyViewportDeltas(WebFloatSize(), WebFloatSize(), WebFloatSize(),
                               1.0f, 2.0f / topControlsHeight);
  EXPECT_SIZE_EQ(ScrollOffset(0, 1903), frameView->maximumScrollOffset());
}

TEST_F(WebFrameTest, MaximumScrollPositionCanBeNegative) {
  registerMockedHttpURLLoad("rtl-overview-mode.html");

  FixedLayoutTestWebViewClient client;
  client.m_screenInfo.deviceScaleFactor = 1;
  int viewportWidth = 640;
  int viewportHeight = 480;

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "rtl-overview-mode.html", true,
                                  nullptr, &client, nullptr,
                                  enableViewportSettings);
  webViewHelper.webView()->setInitialPageScaleOverride(-1);
  webViewHelper.webView()->settings()->setWideViewportQuirkEnabled(true);
  webViewHelper.webView()->settings()->setLoadWithOverviewMode(true);
  webViewHelper.webView()->settings()->setUseWideViewport(true);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewHelper.webView()->updateAllLifecyclePhases();

  FrameView* frameView = webViewHelper.webView()->mainFrameImpl()->frameView();
  EXPECT_LT(frameView->maximumScrollOffset().width(), 0);
}

TEST_P(ParameterizedWebFrameTest, FullscreenLayerSize) {
  FakeCompositingWebViewClient client;
  registerMockedHttpURLLoad("fullscreen_div.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  int viewportWidth = 640;
  int viewportHeight = 480;
  client.m_screenInfo.rect.width = viewportWidth;
  client.m_screenInfo.rect.height = viewportHeight;
  WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(
      m_baseURL + "fullscreen_div.html", true, nullptr, &client, nullptr,
      configureAndroid);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewImpl->updateAllLifecyclePhases();

  Document* document = webViewImpl->mainFrameImpl()->frame()->document();
  UserGestureIndicator gesture(UserGestureToken::create());
  Element* divFullscreen = document->getElementById("div1");
  Fullscreen::requestFullscreen(*divFullscreen, Fullscreen::PrefixedRequest);
  webViewImpl->didEnterFullscreen();
  webViewImpl->updateAllLifecyclePhases();
  EXPECT_EQ(Fullscreen::currentFullScreenElementFrom(*document), divFullscreen);

  // Verify that the element is sized to the viewport.
  LayoutFullScreen* fullscreenLayoutObject =
      Fullscreen::from(*document).fullScreenLayoutObject();
  EXPECT_EQ(viewportWidth, fullscreenLayoutObject->logicalWidth().toInt());
  EXPECT_EQ(viewportHeight, fullscreenLayoutObject->logicalHeight().toInt());

  // Verify it's updated after a device rotation.
  client.m_screenInfo.rect.width = viewportHeight;
  client.m_screenInfo.rect.height = viewportWidth;
  webViewHelper.resize(WebSize(viewportHeight, viewportWidth));
  webViewImpl->updateAllLifecyclePhases();
  EXPECT_EQ(viewportHeight, fullscreenLayoutObject->logicalWidth().toInt());
  EXPECT_EQ(viewportWidth, fullscreenLayoutObject->logicalHeight().toInt());
}

TEST_F(WebFrameTest, FullscreenLayerNonScrollable) {
  FakeCompositingWebViewClient client;
  registerMockedHttpURLLoad("fullscreen_div.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  int viewportWidth = 640;
  int viewportHeight = 480;
  WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(
      m_baseURL + "fullscreen_div.html", true, nullptr, &client, nullptr,
      configureAndroid);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewImpl->updateAllLifecyclePhases();

  Document* document = webViewImpl->mainFrameImpl()->frame()->document();
  UserGestureIndicator gesture(UserGestureToken::create());
  Element* divFullscreen = document->getElementById("div1");
  Fullscreen::requestFullscreen(*divFullscreen, Fullscreen::PrefixedRequest);
  webViewImpl->didEnterFullscreen();
  webViewImpl->updateAllLifecyclePhases();

  // Verify that the viewports are nonscrollable.
  EXPECT_EQ(Fullscreen::currentFullScreenElementFrom(*document), divFullscreen);
  FrameView* frameView = webViewHelper.webView()->mainFrameImpl()->frameView();
  WebLayer* layoutViewportScrollLayer =
      webViewImpl->compositor()->scrollLayer()->platformLayer();
  WebLayer* visualViewportScrollLayer = frameView->page()
                                            ->frameHost()
                                            .visualViewport()
                                            .scrollLayer()
                                            ->platformLayer();
  ASSERT_FALSE(layoutViewportScrollLayer->userScrollableHorizontal());
  ASSERT_FALSE(layoutViewportScrollLayer->userScrollableVertical());
  ASSERT_FALSE(visualViewportScrollLayer->userScrollableHorizontal());
  ASSERT_FALSE(visualViewportScrollLayer->userScrollableVertical());

  // Verify that the viewports are scrollable upon exiting fullscreen.
  webViewImpl->didExitFullscreen();
  webViewImpl->updateAllLifecyclePhases();
  EXPECT_EQ(Fullscreen::currentFullScreenElementFrom(*document), nullptr);
  ASSERT_TRUE(layoutViewportScrollLayer->userScrollableHorizontal());
  ASSERT_TRUE(layoutViewportScrollLayer->userScrollableVertical());
  ASSERT_TRUE(visualViewportScrollLayer->userScrollableHorizontal());
  ASSERT_TRUE(visualViewportScrollLayer->userScrollableVertical());
}

TEST_P(ParameterizedWebFrameTest, FullscreenMainFrame) {
  FakeCompositingWebViewClient client;
  registerMockedHttpURLLoad("fullscreen_div.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  int viewportWidth = 640;
  int viewportHeight = 480;
  WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(
      m_baseURL + "fullscreen_div.html", true, nullptr, &client, nullptr,
      configureAndroid);
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewImpl->updateAllLifecyclePhases();

  Document* document = webViewImpl->mainFrameImpl()->frame()->document();
  UserGestureIndicator gesture(UserGestureToken::create());
  Fullscreen::requestFullscreen(*document->documentElement(),
                                Fullscreen::PrefixedRequest);
  webViewImpl->didEnterFullscreen();
  webViewImpl->updateAllLifecyclePhases();

  // Verify that the main frame is still scrollable.
  EXPECT_EQ(Fullscreen::currentFullScreenElementFrom(*document),
            document->documentElement());
  WebLayer* webScrollLayer =
      webViewImpl->compositor()->scrollLayer()->platformLayer();
  ASSERT_TRUE(webScrollLayer->scrollable());
  ASSERT_TRUE(webScrollLayer->userScrollableHorizontal());
  ASSERT_TRUE(webScrollLayer->userScrollableVertical());

  // Verify the main frame still behaves correctly after a resize.
  webViewHelper.resize(WebSize(viewportHeight, viewportWidth));
  ASSERT_TRUE(webScrollLayer->scrollable());
  ASSERT_TRUE(webScrollLayer->userScrollableHorizontal());
  ASSERT_TRUE(webScrollLayer->userScrollableVertical());
}

TEST_P(ParameterizedWebFrameTest, FullscreenSubframe) {
  FakeCompositingWebViewClient client;
  registerMockedHttpURLLoad("fullscreen_iframe.html");
  registerMockedHttpURLLoad("fullscreen_div.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(
      m_baseURL + "fullscreen_iframe.html", true, nullptr, &client, nullptr,
      configureAndroid);
  int viewportWidth = 640;
  int viewportHeight = 480;
  client.m_screenInfo.rect.width = viewportWidth;
  client.m_screenInfo.rect.height = viewportHeight;
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewImpl->updateAllLifecyclePhases();

  Document* document =
      toWebLocalFrameImpl(webViewHelper.webView()->mainFrame()->firstChild())
          ->frame()
          ->document();
  UserGestureIndicator gesture(UserGestureToken::create());
  Element* divFullscreen = document->getElementById("div1");
  Fullscreen::requestFullscreen(*divFullscreen, Fullscreen::PrefixedRequest);
  webViewImpl->didEnterFullscreen();
  webViewImpl->updateAllLifecyclePhases();

  // Verify that the element is sized to the viewport.
  LayoutFullScreen* fullscreenLayoutObject =
      Fullscreen::from(*document).fullScreenLayoutObject();
  EXPECT_EQ(viewportWidth, fullscreenLayoutObject->logicalWidth().toInt());
  EXPECT_EQ(viewportHeight, fullscreenLayoutObject->logicalHeight().toInt());

  // Verify it's updated after a device rotation.
  client.m_screenInfo.rect.width = viewportHeight;
  client.m_screenInfo.rect.height = viewportWidth;
  webViewHelper.resize(WebSize(viewportHeight, viewportWidth));
  webViewImpl->updateAllLifecyclePhases();
  EXPECT_EQ(viewportHeight, fullscreenLayoutObject->logicalWidth().toInt());
  EXPECT_EQ(viewportWidth, fullscreenLayoutObject->logicalHeight().toInt());
}

TEST_P(ParameterizedWebFrameTest, FullscreenWithTinyViewport) {
  FakeCompositingWebViewClient client;
  registerMockedHttpURLLoad("viewport-tiny.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(
      m_baseURL + "viewport-tiny.html", true, nullptr, &client, nullptr,
      configureAndroid);
  int viewportWidth = 384;
  int viewportHeight = 640;
  client.m_screenInfo.rect.width = viewportWidth;
  client.m_screenInfo.rect.height = viewportHeight;
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewImpl->updateAllLifecyclePhases();

  LayoutViewItem layoutViewItem =
      webViewHelper.webView()->mainFrameImpl()->frameView()->layoutViewItem();
  EXPECT_EQ(320, layoutViewItem.logicalWidth().floor());
  EXPECT_EQ(533, layoutViewItem.logicalHeight().floor());
  EXPECT_FLOAT_EQ(1.2, webViewImpl->pageScaleFactor());
  EXPECT_FLOAT_EQ(1.2, webViewImpl->minimumPageScaleFactor());
  EXPECT_FLOAT_EQ(5.0, webViewImpl->maximumPageScaleFactor());

  Document* document = webViewImpl->mainFrameImpl()->frame()->document();
  UserGestureIndicator gesture(UserGestureToken::create());
  Fullscreen::requestFullscreen(*document->documentElement(),
                                Fullscreen::PrefixedRequest);
  webViewImpl->didEnterFullscreen();
  webViewImpl->updateAllLifecyclePhases();
  EXPECT_EQ(384, layoutViewItem.logicalWidth().floor());
  EXPECT_EQ(640, layoutViewItem.logicalHeight().floor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->pageScaleFactor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->minimumPageScaleFactor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->maximumPageScaleFactor());

  webViewImpl->didExitFullscreen();
  webViewImpl->updateAllLifecyclePhases();
  EXPECT_EQ(320, layoutViewItem.logicalWidth().floor());
  EXPECT_EQ(533, layoutViewItem.logicalHeight().floor());
  EXPECT_FLOAT_EQ(1.2, webViewImpl->pageScaleFactor());
  EXPECT_FLOAT_EQ(1.2, webViewImpl->minimumPageScaleFactor());
  EXPECT_FLOAT_EQ(5.0, webViewImpl->maximumPageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest, FullscreenResizeWithTinyViewport) {
  FakeCompositingWebViewClient client;
  registerMockedHttpURLLoad("viewport-tiny.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(
      m_baseURL + "viewport-tiny.html", true, nullptr, &client, nullptr,
      configureAndroid);
  int viewportWidth = 384;
  int viewportHeight = 640;
  client.m_screenInfo.rect.width = viewportWidth;
  client.m_screenInfo.rect.height = viewportHeight;
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewImpl->updateAllLifecyclePhases();

  LayoutViewItem layoutViewItem =
      webViewHelper.webView()->mainFrameImpl()->frameView()->layoutViewItem();
  Document* document = webViewImpl->mainFrameImpl()->frame()->document();
  UserGestureIndicator gesture(UserGestureToken::create());
  Fullscreen::requestFullscreen(*document->documentElement(),
                                Fullscreen::PrefixedRequest);
  webViewImpl->didEnterFullscreen();
  webViewImpl->updateAllLifecyclePhases();
  EXPECT_EQ(384, layoutViewItem.logicalWidth().floor());
  EXPECT_EQ(640, layoutViewItem.logicalHeight().floor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->pageScaleFactor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->minimumPageScaleFactor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->maximumPageScaleFactor());

  viewportWidth = 640;
  viewportHeight = 384;
  client.m_screenInfo.rect.width = viewportWidth;
  client.m_screenInfo.rect.height = viewportHeight;
  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewImpl->updateAllLifecyclePhases();
  EXPECT_EQ(640, layoutViewItem.logicalWidth().floor());
  EXPECT_EQ(384, layoutViewItem.logicalHeight().floor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->pageScaleFactor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->minimumPageScaleFactor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->maximumPageScaleFactor());

  webViewImpl->didExitFullscreen();
  webViewImpl->updateAllLifecyclePhases();
  EXPECT_EQ(320, layoutViewItem.logicalWidth().floor());
  EXPECT_EQ(192, layoutViewItem.logicalHeight().floor());
  EXPECT_FLOAT_EQ(2, webViewImpl->pageScaleFactor());
  EXPECT_FLOAT_EQ(2, webViewImpl->minimumPageScaleFactor());
  EXPECT_FLOAT_EQ(5.0, webViewImpl->maximumPageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest, FullscreenRestoreScaleFactorUponExiting) {
  // The purpose of this test is to more precisely simulate the sequence of
  // resize and switching fullscreen state operations on WebView, with the
  // interference from Android status bars like a real device does.
  // This verifies we handle the transition and restore states correctly.
  WebSize screenSizeMinusStatusBarsMinusUrlBar(598, 303);
  WebSize screenSizeMinusStatusBars(598, 359);
  WebSize screenSize(640, 384);

  FakeCompositingWebViewClient client;
  registerMockedHttpURLLoad("fullscreen_restore_scale_factor.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(
      m_baseURL + "fullscreen_restore_scale_factor.html", true, nullptr,
      &client, nullptr, &configureAndroid);
  client.m_screenInfo.rect.width = screenSizeMinusStatusBarsMinusUrlBar.width;
  client.m_screenInfo.rect.height = screenSizeMinusStatusBarsMinusUrlBar.height;
  webViewHelper.resize(screenSizeMinusStatusBarsMinusUrlBar);
  LayoutViewItem layoutViewItem =
      webViewHelper.webView()->mainFrameImpl()->frameView()->layoutViewItem();
  EXPECT_EQ(screenSizeMinusStatusBarsMinusUrlBar.width,
            layoutViewItem.logicalWidth().floor());
  EXPECT_EQ(screenSizeMinusStatusBarsMinusUrlBar.height,
            layoutViewItem.logicalHeight().floor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->pageScaleFactor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->minimumPageScaleFactor());
  EXPECT_FLOAT_EQ(5.0, webViewImpl->maximumPageScaleFactor());

  {
    Document* document = webViewImpl->mainFrameImpl()->frame()->document();
    UserGestureIndicator gesture(UserGestureToken::create());
    Fullscreen::requestFullscreen(*document->body(),
                                  Fullscreen::PrefixedRequest);
  }

  webViewImpl->didEnterFullscreen();
  webViewImpl->updateAllLifecyclePhases();
  client.m_screenInfo.rect.width = screenSizeMinusStatusBars.width;
  client.m_screenInfo.rect.height = screenSizeMinusStatusBars.height;
  webViewHelper.resize(screenSizeMinusStatusBars);
  client.m_screenInfo.rect.width = screenSize.width;
  client.m_screenInfo.rect.height = screenSize.height;
  webViewHelper.resize(screenSize);
  EXPECT_EQ(screenSize.width, layoutViewItem.logicalWidth().floor());
  EXPECT_EQ(screenSize.height, layoutViewItem.logicalHeight().floor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->pageScaleFactor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->minimumPageScaleFactor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->maximumPageScaleFactor());

  webViewImpl->didExitFullscreen();
  webViewImpl->updateAllLifecyclePhases();
  client.m_screenInfo.rect.width = screenSizeMinusStatusBars.width;
  client.m_screenInfo.rect.height = screenSizeMinusStatusBars.height;
  webViewHelper.resize(screenSizeMinusStatusBars);
  client.m_screenInfo.rect.width = screenSizeMinusStatusBarsMinusUrlBar.width;
  client.m_screenInfo.rect.height = screenSizeMinusStatusBarsMinusUrlBar.height;
  webViewHelper.resize(screenSizeMinusStatusBarsMinusUrlBar);
  EXPECT_EQ(screenSizeMinusStatusBarsMinusUrlBar.width,
            layoutViewItem.logicalWidth().floor());
  EXPECT_EQ(screenSizeMinusStatusBarsMinusUrlBar.height,
            layoutViewItem.logicalHeight().floor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->pageScaleFactor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->minimumPageScaleFactor());
  EXPECT_FLOAT_EQ(5.0, webViewImpl->maximumPageScaleFactor());
}

// Tests that leaving fullscreen by navigating to a new page resets the
// fullscreen page scale constraints.
TEST_P(ParameterizedWebFrameTest, ClearFullscreenConstraintsOnNavigation) {
  registerMockedHttpURLLoad("viewport-tiny.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  int viewportWidth = 100;
  int viewportHeight = 200;

  WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(
      m_baseURL + "viewport-tiny.html", true, nullptr, nullptr, nullptr,
      configureAndroid);

  webViewHelper.resize(WebSize(viewportWidth, viewportHeight));
  webViewImpl->updateAllLifecyclePhases();

  // viewport-tiny.html specifies a 320px layout width.
  LayoutViewItem layoutViewItem =
      webViewImpl->mainFrameImpl()->frameView()->layoutViewItem();
  EXPECT_EQ(320, layoutViewItem.logicalWidth().floor());
  EXPECT_EQ(640, layoutViewItem.logicalHeight().floor());
  EXPECT_FLOAT_EQ(0.3125, webViewImpl->pageScaleFactor());
  EXPECT_FLOAT_EQ(0.3125, webViewImpl->minimumPageScaleFactor());
  EXPECT_FLOAT_EQ(5.0, webViewImpl->maximumPageScaleFactor());

  Document* document = webViewImpl->mainFrameImpl()->frame()->document();
  UserGestureIndicator gesture(
      UserGestureToken::create(UserGestureToken::NewGesture));
  Fullscreen::requestFullscreen(*document->documentElement(),
                                Fullscreen::PrefixedRequest);
  webViewImpl->didEnterFullscreen();
  webViewImpl->updateAllLifecyclePhases();

  // Entering fullscreen causes layout size and page scale limits to be
  // overridden.
  EXPECT_EQ(100, layoutViewItem.logicalWidth().floor());
  EXPECT_EQ(200, layoutViewItem.logicalHeight().floor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->pageScaleFactor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->minimumPageScaleFactor());
  EXPECT_FLOAT_EQ(1.0, webViewImpl->maximumPageScaleFactor());

  const char source[] = "<meta name=\"viewport\" content=\"width=200\">";

  // Load a new page before exiting fullscreen.
  KURL testURL = toKURL("about:blank");
  WebFrame* frame = webViewHelper.webView()->mainFrame();
  FrameTestHelpers::loadHTMLString(frame, source, testURL);
  webViewImpl->didExitFullscreen();
  webViewImpl->updateAllLifecyclePhases();

  // Make sure the new page's layout size and scale factor limits aren't
  // overridden.
  layoutViewItem = webViewImpl->mainFrameImpl()->frameView()->layoutViewItem();
  EXPECT_EQ(200, layoutViewItem.logicalWidth().floor());
  EXPECT_EQ(400, layoutViewItem.logicalHeight().floor());
  EXPECT_FLOAT_EQ(0.5, webViewImpl->minimumPageScaleFactor());
  EXPECT_FLOAT_EQ(5.0, webViewImpl->maximumPageScaleFactor());
}

TEST_P(ParameterizedWebFrameTest, LayoutBlockPercentHeightDescendants) {
  registerMockedHttpURLLoad("percent-height-descendants.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL +
                                  "percent-height-descendants.html");

  WebViewImpl* webView = webViewHelper.webView();
  webViewHelper.resize(WebSize(800, 800));
  webView->updateAllLifecyclePhases();

  Document* document = webView->mainFrameImpl()->frame()->document();
  LayoutBlock* container =
      toLayoutBlock(document->getElementById("container")->layoutObject());
  LayoutBox* percentHeightInAnonymous = toLayoutBox(
      document->getElementById("percent-height-in-anonymous")->layoutObject());
  LayoutBox* percentHeightDirectChild = toLayoutBox(
      document->getElementById("percent-height-direct-child")->layoutObject());

  EXPECT_TRUE(container->hasPercentHeightDescendant(percentHeightInAnonymous));
  EXPECT_TRUE(container->hasPercentHeightDescendant(percentHeightDirectChild));

  ASSERT_TRUE(container->percentHeightDescendants());
  ASSERT_TRUE(container->hasPercentHeightDescendants());
  EXPECT_EQ(2U, container->percentHeightDescendants()->size());
  EXPECT_TRUE(container->percentHeightDescendants()->contains(
      percentHeightInAnonymous));
  EXPECT_TRUE(container->percentHeightDescendants()->contains(
      percentHeightDirectChild));

  LayoutBlock* anonymousBlock = percentHeightInAnonymous->containingBlock();
  EXPECT_TRUE(anonymousBlock->isAnonymous());
  EXPECT_FALSE(anonymousBlock->hasPercentHeightDescendants());
}

TEST_P(ParameterizedWebFrameTest, HasVisibleContentOnVisibleFrames) {
  registerMockedHttpURLLoad("visible_frames.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  WebViewImpl* webViewImpl =
      webViewHelper.initializeAndLoad(m_baseURL + "visible_frames.html");
  for (WebFrame* frame = webViewImpl->mainFrameImpl()->traverseNext(false);
       frame; frame = frame->traverseNext(false)) {
    EXPECT_TRUE(frame->hasVisibleContent());
  }
}

TEST_P(ParameterizedWebFrameTest, HasVisibleContentOnHiddenFrames) {
  registerMockedHttpURLLoad("hidden_frames.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  WebViewImpl* webViewImpl =
      webViewHelper.initializeAndLoad(m_baseURL + "hidden_frames.html");
  for (WebFrame* frame = webViewImpl->mainFrameImpl()->traverseNext(false);
       frame; frame = frame->traverseNext(false)) {
    EXPECT_FALSE(frame->hasVisibleContent());
  }
}

class ManifestChangeWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  ManifestChangeWebFrameClient() : m_manifestChangeCount(0) {}
  void didChangeManifest() override { ++m_manifestChangeCount; }

  int manifestChangeCount() { return m_manifestChangeCount; }

 private:
  int m_manifestChangeCount;
};

TEST_P(ParameterizedWebFrameTest, NotifyManifestChange) {
  registerMockedHttpURLLoad("link-manifest-change.html");

  ManifestChangeWebFrameClient webFrameClient;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "link-manifest-change.html", true,
                                  &webFrameClient);

  EXPECT_EQ(14, webFrameClient.manifestChangeCount());
}

static Resource* fetchManifest(Document* document, const KURL& url) {
  FetchRequest fetchRequest =
      FetchRequest(ResourceRequest(url), FetchInitiatorInfo());
  fetchRequest.mutableResourceRequest().setRequestContext(
      WebURLRequest::RequestContextManifest);

  return RawResource::fetchSynchronously(fetchRequest, document->fetcher());
}

TEST_P(ParameterizedWebFrameTest, ManifestFetch) {
  registerMockedHttpURLLoad("foo.html");
  registerMockedHttpURLLoad("link-manifest-fetch.json");

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "foo.html");
  Document* document =
      webViewHelper.webView()->mainFrameImpl()->frame()->document();

  Resource* resource =
      fetchManifest(document, toKURL(m_baseURL + "link-manifest-fetch.json"));

  EXPECT_TRUE(resource->isLoaded());
}

TEST_P(ParameterizedWebFrameTest, ManifestCSPFetchAllow) {
  URLTestHelpers::registerMockedURLLoad(
      toKURL(m_notBaseURL + "link-manifest-fetch.json"),
      "link-manifest-fetch.json");
  registerMockedHttpURLLoadWithCSP("foo.html", "manifest-src *");

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "foo.html");
  Document* document =
      webViewHelper.webView()->mainFrameImpl()->frame()->document();

  Resource* resource = fetchManifest(
      document, toKURL(m_notBaseURL + "link-manifest-fetch.json"));

  EXPECT_TRUE(resource->isLoaded());
}

TEST_P(ParameterizedWebFrameTest, ManifestCSPFetchSelf) {
  URLTestHelpers::registerMockedURLLoad(
      toKURL(m_notBaseURL + "link-manifest-fetch.json"),
      "link-manifest-fetch.json");
  registerMockedHttpURLLoadWithCSP("foo.html", "manifest-src 'self'");

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "foo.html");
  Document* document =
      webViewHelper.webView()->mainFrameImpl()->frame()->document();

  Resource* resource = fetchManifest(
      document, toKURL(m_notBaseURL + "link-manifest-fetch.json"));

  // Fetching resource wasn't allowed.
  ASSERT_TRUE(resource);
  EXPECT_TRUE(resource->errorOccurred());
  EXPECT_TRUE(resource->resourceError().isAccessCheck());
}

TEST_P(ParameterizedWebFrameTest, ManifestCSPFetchSelfReportOnly) {
  URLTestHelpers::registerMockedURLLoad(
      toKURL(m_notBaseURL + "link-manifest-fetch.json"),
      "link-manifest-fetch.json");
  registerMockedHttpURLLoadWithCSP("foo.html", "manifest-src 'self'",
                                   /* report only */ true);

  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "foo.html");
  Document* document =
      webViewHelper.webView()->mainFrameImpl()->frame()->document();

  Resource* resource = fetchManifest(
      document, toKURL(m_notBaseURL + "link-manifest-fetch.json"));

  EXPECT_TRUE(resource->isLoaded());
}

TEST_P(ParameterizedWebFrameTest, ReloadBypassingCache) {
  // Check that a reload ignoring cache on a frame will result in the cache
  // policy of the request being set to ReloadBypassingCache.
  registerMockedHttpURLLoad("foo.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "foo.html", true);
  WebFrame* frame = webViewHelper.webView()->mainFrame();
  FrameTestHelpers::reloadFrameIgnoringCache(frame);
  EXPECT_EQ(WebCachePolicy::BypassingCache,
            frame->dataSource()->request().getCachePolicy());
}

static void nodeImageTestValidation(const IntSize& referenceBitmapSize,
                                    DragImage* dragImage) {
  // Prepare the reference bitmap.
  SkBitmap bitmap;
  bitmap.allocN32Pixels(referenceBitmapSize.width(),
                        referenceBitmapSize.height());
  SkCanvas canvas(bitmap);
  canvas.drawColor(SK_ColorGREEN);

  EXPECT_EQ(referenceBitmapSize.width(), dragImage->size().width());
  EXPECT_EQ(referenceBitmapSize.height(), dragImage->size().height());
  const SkBitmap& dragBitmap = dragImage->bitmap();
  SkAutoLockPixels lockPixel(dragBitmap);
  EXPECT_EQ(
      0, memcmp(bitmap.getPixels(), dragBitmap.getPixels(), bitmap.getSize()));
}

TEST_P(ParameterizedWebFrameTest, NodeImageTestCSSTransformDescendant) {
  FrameTestHelpers::WebViewHelper webViewHelper;
  std::unique_ptr<DragImage> dragImage = nodeImageTestSetup(
      &webViewHelper, std::string("case-css-3dtransform-descendant"));
  EXPECT_TRUE(dragImage);

  nodeImageTestValidation(IntSize(40, 40), dragImage.get());
}

TEST_P(ParameterizedWebFrameTest, NodeImageTestCSSTransform) {
  FrameTestHelpers::WebViewHelper webViewHelper;
  std::unique_ptr<DragImage> dragImage =
      nodeImageTestSetup(&webViewHelper, std::string("case-css-transform"));
  EXPECT_TRUE(dragImage);

  nodeImageTestValidation(IntSize(40, 40), dragImage.get());
}

TEST_P(ParameterizedWebFrameTest, NodeImageTestCSS3DTransform) {
  FrameTestHelpers::WebViewHelper webViewHelper;
  std::unique_ptr<DragImage> dragImage =
      nodeImageTestSetup(&webViewHelper, std::string("case-css-3dtransform"));
  EXPECT_TRUE(dragImage);

  nodeImageTestValidation(IntSize(40, 40), dragImage.get());
}

TEST_P(ParameterizedWebFrameTest, NodeImageTestInlineBlock) {
  FrameTestHelpers::WebViewHelper webViewHelper;
  std::unique_ptr<DragImage> dragImage =
      nodeImageTestSetup(&webViewHelper, std::string("case-inlineblock"));
  EXPECT_TRUE(dragImage);

  nodeImageTestValidation(IntSize(40, 40), dragImage.get());
}

TEST_P(ParameterizedWebFrameTest, NodeImageTestFloatLeft) {
  FrameTestHelpers::WebViewHelper webViewHelper;
  std::unique_ptr<DragImage> dragImage = nodeImageTestSetup(
      &webViewHelper, std::string("case-float-left-overflow-hidden"));
  EXPECT_TRUE(dragImage);

  nodeImageTestValidation(IntSize(40, 40), dragImage.get());
}

// Crashes on Android: http://crbug.com/403804
#if OS(ANDROID)
TEST_P(ParameterizedWebFrameTest, DISABLED_PrintingBasic)
#else
TEST_P(ParameterizedWebFrameTest, PrintingBasic)
#endif
{
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad("data:text/html,Hello, world.");

  WebFrame* frame = webViewHelper.webView()->mainFrame();

  WebPrintParams printParams;
  printParams.printContentArea.width = 500;
  printParams.printContentArea.height = 500;

  int pageCount = frame->printBegin(printParams);
  EXPECT_EQ(1, pageCount);
  frame->printEnd();
}

class ThemeColorTestWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  ThemeColorTestWebFrameClient() : m_didNotify(false) {}

  void reset() { m_didNotify = false; }

  bool didNotify() const { return m_didNotify; }

 private:
  virtual void didChangeThemeColor() { m_didNotify = true; }

  bool m_didNotify;
};

TEST_P(ParameterizedWebFrameTest, ThemeColor) {
  registerMockedHttpURLLoad("theme_color_test.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  ThemeColorTestWebFrameClient client;
  webViewHelper.initializeAndLoad(m_baseURL + "theme_color_test.html", true,
                                  &client);
  EXPECT_TRUE(client.didNotify());
  WebLocalFrameImpl* frame = webViewHelper.webView()->mainFrameImpl();
  EXPECT_EQ(0xff0000ff, frame->document().themeColor());
  // Change color by rgb.
  client.reset();
  frame->executeScript(
      WebScriptSource("document.getElementById('tc1').setAttribute('content', "
                      "'rgb(0, 0, 0)');"));
  EXPECT_TRUE(client.didNotify());
  EXPECT_EQ(0xff000000, frame->document().themeColor());
  // Change color by hsl.
  client.reset();
  frame->executeScript(
      WebScriptSource("document.getElementById('tc1').setAttribute('content', "
                      "'hsl(240,100%, 50%)');"));
  EXPECT_TRUE(client.didNotify());
  EXPECT_EQ(0xff0000ff, frame->document().themeColor());
  // Change of second theme-color meta tag will not change frame's theme
  // color.
  client.reset();
  frame->executeScript(WebScriptSource(
      "document.getElementById('tc2').setAttribute('content', '#00FF00');"));
  EXPECT_TRUE(client.didNotify());
  EXPECT_EQ(0xff0000ff, frame->document().themeColor());
}

// Make sure that an embedder-triggered detach with a remote frame parent
// doesn't leave behind dangling pointers.
TEST_P(ParameterizedWebFrameTest, EmbedderTriggeredDetachWithRemoteMainFrame) {
  // FIXME: Refactor some of this logic into WebViewHelper to make it easier to
  // write tests with a top-level remote frame.
  FrameTestHelpers::TestWebViewClient viewClient;
  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebView* view = WebView::create(&viewClient, WebPageVisibilityStateVisible);
  view->setMainFrame(remoteClient.frame());
  WebLocalFrame* childFrame =
      FrameTestHelpers::createLocalChild(view->mainFrame()->toWebRemoteFrame());

  // Purposely keep the LocalFrame alive so it's the last thing to be destroyed.
  Persistent<Frame> childCoreFrame = childFrame->toImplBase()->frame();
  view->close();
  childCoreFrame.clear();
}

class WebFrameSwapTest : public WebFrameTest {
 protected:
  WebFrameSwapTest() {
    registerMockedHttpURLLoad("frame-a-b-c.html");
    registerMockedHttpURLLoad("subframe-a.html");
    registerMockedHttpURLLoad("subframe-b.html");
    registerMockedHttpURLLoad("subframe-c.html");
    registerMockedHttpURLLoad("subframe-hello.html");

    m_webViewHelper.initializeAndLoad(m_baseURL + "frame-a-b-c.html", true);
  }

  void reset() { m_webViewHelper.reset(); }
  WebFrame* mainFrame() const { return m_webViewHelper.webView()->mainFrame(); }
  WebView* webView() const { return m_webViewHelper.webView(); }

 private:
  FrameTestHelpers::WebViewHelper m_webViewHelper;
};

TEST_F(WebFrameSwapTest, SwapMainFrame) {
  WebRemoteFrame* remoteFrame =
      WebRemoteFrame::create(WebTreeScopeType::Document, nullptr);
  mainFrame()->swap(remoteFrame);

  FrameTestHelpers::TestWebFrameClient client;
  WebLocalFrame* localFrame = WebLocalFrame::createProvisional(
      &client, remoteFrame, WebSandboxFlags::None);
  FrameTestHelpers::TestWebWidgetClient webWidgetClient;
  WebFrameWidget::create(&webWidgetClient, localFrame);
  remoteFrame->swap(localFrame);

  // Finally, make sure an embedder triggered load in the local frame swapped
  // back in works.
  FrameTestHelpers::loadFrame(localFrame, m_baseURL + "subframe-hello.html");

  std::string content =
      WebFrameContentDumper::dumpWebViewAsText(webView(), 1024).utf8();
  EXPECT_EQ("hello", content);

  // Manually reset to break WebViewHelper's dependency on the stack allocated
  // TestWebFrameClient.
  reset();
  remoteFrame->close();
}

TEST_F(WebFrameSwapTest, ValidateSizeOnRemoteToLocalMainFrameSwap) {
  WebSize size(111, 222);

  WebRemoteFrame* remoteFrame =
      WebRemoteFrame::create(WebTreeScopeType::Document, nullptr);
  mainFrame()->swap(remoteFrame);

  remoteFrame->view()->resize(size);

  FrameTestHelpers::TestWebFrameClient client;
  WebLocalFrame* localFrame = WebLocalFrame::createProvisional(
      &client, remoteFrame, WebSandboxFlags::None);
  remoteFrame->swap(localFrame);

  // Verify that the size that was set with a remote main frame is correct
  // after swapping to a local frame.
  FrameHost* host =
      toWebViewImpl(localFrame->view())->page()->mainFrame()->host();
  EXPECT_EQ(size.width, host->visualViewport().size().width());
  EXPECT_EQ(size.height, host->visualViewport().size().height());

  // Manually reset to break WebViewHelper's dependency on the stack allocated
  // TestWebFrameClient.
  reset();
  remoteFrame->close();
}

namespace {

class SwapMainFrameWhenTitleChangesWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  SwapMainFrameWhenTitleChangesWebFrameClient() : m_remoteFrame(nullptr) {}

  ~SwapMainFrameWhenTitleChangesWebFrameClient() override {
    if (m_remoteFrame)
      m_remoteFrame->close();
  }

  void didReceiveTitle(WebLocalFrame* frame,
                       const WebString&,
                       WebTextDirection) override {
    if (!frame->parent()) {
      m_remoteFrame =
          WebRemoteFrame::create(WebTreeScopeType::Document, nullptr);
      frame->swap(m_remoteFrame);
    }
  }

 private:
  WebRemoteFrame* m_remoteFrame;
};

}  // anonymous namespace

TEST_F(WebFrameTest, SwapMainFrameWhileLoading) {
  SwapMainFrameWhenTitleChangesWebFrameClient frameClient;

  FrameTestHelpers::WebViewHelper webViewHelper;
  registerMockedHttpURLLoad("frame-a-b-c.html");
  registerMockedHttpURLLoad("subframe-a.html");
  registerMockedHttpURLLoad("subframe-b.html");
  registerMockedHttpURLLoad("subframe-c.html");
  registerMockedHttpURLLoad("subframe-hello.html");

  webViewHelper.initializeAndLoad(m_baseURL + "frame-a-b-c.html", true,
                                  &frameClient);
}

void swapAndVerifyFirstChildConsistency(const char* const message,
                                        WebFrame* parent,
                                        WebFrame* newChild) {
  SCOPED_TRACE(message);
  parent->firstChild()->swap(newChild);

  EXPECT_EQ(newChild, parent->firstChild());
  EXPECT_EQ(newChild->parent(), parent);
  EXPECT_EQ(newChild,
            parent->lastChild()->previousSibling()->previousSibling());
  EXPECT_EQ(newChild->nextSibling(), parent->lastChild()->previousSibling());
}

TEST_F(WebFrameSwapTest, SwapFirstChild) {
  FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient;
  WebRemoteFrame* remoteFrame =
      WebRemoteFrame::create(WebTreeScopeType::Document, &remoteFrameClient);
  swapAndVerifyFirstChildConsistency("local->remote", mainFrame(), remoteFrame);

  FrameTestHelpers::TestWebFrameClient client;
  WebLocalFrame* localFrame = WebLocalFrame::createProvisional(
      &client, remoteFrame, WebSandboxFlags::None);
  swapAndVerifyFirstChildConsistency("remote->local", mainFrame(), localFrame);

  // FIXME: This almost certainly fires more load events on the iframe element
  // than it should.
  // Finally, make sure an embedder triggered load in the local frame swapped
  // back in works.
  FrameTestHelpers::loadFrame(localFrame, m_baseURL + "subframe-hello.html");
  std::string content =
      WebFrameContentDumper::dumpWebViewAsText(webView(), 1024).utf8();
  EXPECT_EQ("  \n\nhello\n\nb \n\na\n\nc", content);

  // Manually reset to break WebViewHelper's dependency on the stack allocated
  // TestWebFrameClient.
  reset();
  remoteFrame->close();
}

void swapAndVerifyMiddleChildConsistency(const char* const message,
                                         WebFrame* parent,
                                         WebFrame* newChild) {
  SCOPED_TRACE(message);
  parent->firstChild()->nextSibling()->swap(newChild);

  EXPECT_EQ(newChild, parent->firstChild()->nextSibling());
  EXPECT_EQ(newChild, parent->lastChild()->previousSibling());
  EXPECT_EQ(newChild->parent(), parent);
  EXPECT_EQ(newChild, parent->firstChild()->nextSibling());
  EXPECT_EQ(newChild->previousSibling(), parent->firstChild());
  EXPECT_EQ(newChild, parent->lastChild()->previousSibling());
  EXPECT_EQ(newChild->nextSibling(), parent->lastChild());
}

TEST_F(WebFrameSwapTest, SwapMiddleChild) {
  FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient;
  WebRemoteFrame* remoteFrame =
      WebRemoteFrame::create(WebTreeScopeType::Document, &remoteFrameClient);
  swapAndVerifyMiddleChildConsistency("local->remote", mainFrame(),
                                      remoteFrame);

  FrameTestHelpers::TestWebFrameClient client;
  WebLocalFrame* localFrame = WebLocalFrame::createProvisional(
      &client, remoteFrame, WebSandboxFlags::None);
  swapAndVerifyMiddleChildConsistency("remote->local", mainFrame(), localFrame);

  // FIXME: This almost certainly fires more load events on the iframe element
  // than it should.
  // Finally, make sure an embedder triggered load in the local frame swapped
  // back in works.
  FrameTestHelpers::loadFrame(localFrame, m_baseURL + "subframe-hello.html");
  std::string content =
      WebFrameContentDumper::dumpWebViewAsText(webView(), 1024).utf8();
  EXPECT_EQ("  \n\na\n\nhello\n\nc", content);

  // Manually reset to break WebViewHelper's dependency on the stack allocated
  // TestWebFrameClient.
  reset();
  remoteFrame->close();
}

void swapAndVerifyLastChildConsistency(const char* const message,
                                       WebFrame* parent,
                                       WebFrame* newChild) {
  SCOPED_TRACE(message);
  parent->lastChild()->swap(newChild);

  EXPECT_EQ(newChild, parent->lastChild());
  EXPECT_EQ(newChild->parent(), parent);
  EXPECT_EQ(newChild, parent->firstChild()->nextSibling()->nextSibling());
  EXPECT_EQ(newChild->previousSibling(), parent->firstChild()->nextSibling());
}

TEST_F(WebFrameSwapTest, SwapLastChild) {
  FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient;
  WebRemoteFrame* remoteFrame =
      WebRemoteFrame::create(WebTreeScopeType::Document, &remoteFrameClient);
  swapAndVerifyLastChildConsistency("local->remote", mainFrame(), remoteFrame);

  FrameTestHelpers::TestWebFrameClient client;
  WebLocalFrame* localFrame = WebLocalFrame::createProvisional(
      &client, remoteFrame, WebSandboxFlags::None);
  swapAndVerifyLastChildConsistency("remote->local", mainFrame(), localFrame);

  // FIXME: This almost certainly fires more load events on the iframe element
  // than it should.
  // Finally, make sure an embedder triggered load in the local frame swapped
  // back in works.
  FrameTestHelpers::loadFrame(localFrame, m_baseURL + "subframe-hello.html");
  std::string content =
      WebFrameContentDumper::dumpWebViewAsText(webView(), 1024).utf8();
  EXPECT_EQ("  \n\na\n\nb \n\na\n\nhello", content);

  // Manually reset to break WebViewHelper's dependency on the stack allocated
  // TestWebFrameClient.
  reset();
  remoteFrame->close();
}

void swapAndVerifySubframeConsistency(const char* const message,
                                      WebFrame* oldFrame,
                                      WebFrame* newFrame) {
  SCOPED_TRACE(message);

  EXPECT_TRUE(oldFrame->firstChild());
  oldFrame->swap(newFrame);

  EXPECT_FALSE(newFrame->firstChild());
  EXPECT_FALSE(newFrame->lastChild());
}

TEST_F(WebFrameSwapTest, SwapParentShouldDetachChildren) {
  FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient1;
  WebRemoteFrame* remoteFrame =
      WebRemoteFrame::create(WebTreeScopeType::Document, &remoteFrameClient1);
  WebFrame* targetFrame = mainFrame()->firstChild()->nextSibling();
  EXPECT_TRUE(targetFrame);
  swapAndVerifySubframeConsistency("local->remote", targetFrame, remoteFrame);

  targetFrame = mainFrame()->firstChild()->nextSibling();
  EXPECT_TRUE(targetFrame);

  // Create child frames in the target frame before testing the swap.
  FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient2;
  WebRemoteFrame* childRemoteFrame =
      FrameTestHelpers::createRemoteChild(remoteFrame, &remoteFrameClient2);

  FrameTestHelpers::TestWebFrameClient client;
  WebLocalFrame* localFrame = WebLocalFrame::createProvisional(
      &client, remoteFrame, WebSandboxFlags::None);
  swapAndVerifySubframeConsistency("remote->local", targetFrame, localFrame);

  // FIXME: This almost certainly fires more load events on the iframe element
  // than it should.
  // Finally, make sure an embedder triggered load in the local frame swapped
  // back in works.
  FrameTestHelpers::loadFrame(localFrame, m_baseURL + "subframe-hello.html");
  std::string content =
      WebFrameContentDumper::dumpWebViewAsText(webView(), 1024).utf8();
  EXPECT_EQ("  \n\na\n\nhello\n\nc", content);

  // Manually reset to break WebViewHelper's dependency on the stack allocated
  // TestWebFrameClient.
  reset();
  remoteFrame->close();
  childRemoteFrame->close();
}

TEST_F(WebFrameSwapTest, SwapPreservesGlobalContext) {
  v8::HandleScope scope(v8::Isolate::GetCurrent());
  v8::Local<v8::Value> windowTop =
      mainFrame()->executeScriptAndReturnValue(WebScriptSource("window"));
  ASSERT_TRUE(windowTop->IsObject());
  v8::Local<v8::Value> originalWindow =
      mainFrame()->executeScriptAndReturnValue(
          WebScriptSource("document.querySelector('#frame2').contentWindow;"));
  ASSERT_TRUE(originalWindow->IsObject());

  // Make sure window reference stays the same when swapping to a remote frame.
  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebRemoteFrame* remoteFrame = remoteClient.frame();
  WebFrame* targetFrame = mainFrame()->firstChild()->nextSibling();
  targetFrame->swap(remoteFrame);
  remoteFrame->setReplicatedOrigin(SecurityOrigin::createUnique());
  v8::Local<v8::Value> remoteWindow = mainFrame()->executeScriptAndReturnValue(
      WebScriptSource("document.querySelector('#frame2').contentWindow;"));
  EXPECT_TRUE(originalWindow->StrictEquals(remoteWindow));
  // Check that its view is consistent with the world.
  v8::Local<v8::Value> remoteWindowTop =
      mainFrame()->executeScriptAndReturnValue(WebScriptSource(
          "document.querySelector('#frame2').contentWindow.top;"));
  EXPECT_TRUE(windowTop->StrictEquals(remoteWindowTop));

  // Now check that remote -> local works too, since it goes through a different
  // code path.
  FrameTestHelpers::TestWebFrameClient client;
  WebLocalFrame* localFrame = WebLocalFrame::createProvisional(
      &client, remoteFrame, WebSandboxFlags::None);
  remoteFrame->swap(localFrame);
  v8::Local<v8::Value> localWindow = mainFrame()->executeScriptAndReturnValue(
      WebScriptSource("document.querySelector('#frame2').contentWindow;"));
  EXPECT_TRUE(originalWindow->StrictEquals(localWindow));
  v8::Local<v8::Value> localWindowTop =
      mainFrame()->executeScriptAndReturnValue(WebScriptSource(
          "document.querySelector('#frame2').contentWindow.top;"));
  EXPECT_TRUE(windowTop->StrictEquals(localWindowTop));

  // Manually reset to break WebViewHelper's dependency on the stack allocated
  // TestWebFrameClient.
  reset();
}

TEST_F(WebFrameSwapTest, SwapInitializesGlobal) {
  v8::HandleScope scope(v8::Isolate::GetCurrent());

  v8::Local<v8::Value> windowTop =
      mainFrame()->executeScriptAndReturnValue(WebScriptSource("window"));
  ASSERT_TRUE(windowTop->IsObject());

  v8::Local<v8::Value> lastChild = mainFrame()->executeScriptAndReturnValue(
      WebScriptSource("saved = window[2]"));
  ASSERT_TRUE(lastChild->IsObject());

  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebRemoteFrame* remoteFrame = remoteClient.frame();
  mainFrame()->lastChild()->swap(remoteFrame);
  remoteFrame->setReplicatedOrigin(SecurityOrigin::createUnique());
  v8::Local<v8::Value> remoteWindowTop =
      mainFrame()->executeScriptAndReturnValue(WebScriptSource("saved.top"));
  EXPECT_TRUE(remoteWindowTop->IsObject());
  EXPECT_TRUE(windowTop->StrictEquals(remoteWindowTop));

  FrameTestHelpers::TestWebFrameClient client;
  WebLocalFrame* localFrame = WebLocalFrame::createProvisional(
      &client, remoteFrame, WebSandboxFlags::None);
  remoteFrame->swap(localFrame);
  v8::Local<v8::Value> localWindowTop =
      mainFrame()->executeScriptAndReturnValue(WebScriptSource("saved.top"));
  EXPECT_TRUE(localWindowTop->IsObject());
  EXPECT_TRUE(windowTop->StrictEquals(localWindowTop));

  reset();
}

TEST_F(WebFrameSwapTest, RemoteFramesAreIndexable) {
  v8::HandleScope scope(v8::Isolate::GetCurrent());

  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebRemoteFrame* remoteFrame = remoteClient.frame();
  mainFrame()->lastChild()->swap(remoteFrame);
  remoteFrame->setReplicatedOrigin(SecurityOrigin::createUnique());
  v8::Local<v8::Value> remoteWindow =
      mainFrame()->executeScriptAndReturnValue(WebScriptSource("window[2]"));
  EXPECT_TRUE(remoteWindow->IsObject());
  v8::Local<v8::Value> windowLength = mainFrame()->executeScriptAndReturnValue(
      WebScriptSource("window.length"));
  ASSERT_TRUE(windowLength->IsInt32());
  EXPECT_EQ(3, windowLength.As<v8::Int32>()->Value());

  reset();
}

TEST_F(WebFrameSwapTest, RemoteFrameLengthAccess) {
  v8::HandleScope scope(v8::Isolate::GetCurrent());

  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebRemoteFrame* remoteFrame = remoteClient.frame();
  mainFrame()->lastChild()->swap(remoteFrame);
  remoteFrame->setReplicatedOrigin(SecurityOrigin::createUnique());
  v8::Local<v8::Value> remoteWindowLength =
      mainFrame()->executeScriptAndReturnValue(
          WebScriptSource("window[2].length"));
  ASSERT_TRUE(remoteWindowLength->IsInt32());
  EXPECT_EQ(0, remoteWindowLength.As<v8::Int32>()->Value());

  reset();
}

TEST_F(WebFrameSwapTest, RemoteWindowNamedAccess) {
  v8::HandleScope scope(v8::Isolate::GetCurrent());

  // FIXME: Once OOPIF unit test infrastructure is in place, test that named
  // window access on a remote window works. For now, just test that accessing
  // a named property doesn't crash.
  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebRemoteFrame* remoteFrame = remoteClient.frame();
  mainFrame()->lastChild()->swap(remoteFrame);
  remoteFrame->setReplicatedOrigin(SecurityOrigin::createUnique());
  v8::Local<v8::Value> remoteWindowProperty =
      mainFrame()->executeScriptAndReturnValue(
          WebScriptSource("window[2].foo"));
  EXPECT_TRUE(remoteWindowProperty.IsEmpty());

  reset();
}

// TODO(alexmos, dcheng): This test and some other OOPIF tests use
// very little of the test fixture support in WebFrameSwapTest.  We should
// clean these tests up.
TEST_F(WebFrameSwapTest, FramesOfRemoteParentAreIndexable) {
  v8::HandleScope scope(v8::Isolate::GetCurrent());

  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebRemoteFrame* remoteParentFrame = remoteClient.frame();
  mainFrame()->swap(remoteParentFrame);
  remoteParentFrame->setReplicatedOrigin(SecurityOrigin::createUnique());

  WebLocalFrame* childFrame =
      FrameTestHelpers::createLocalChild(remoteParentFrame);
  FrameTestHelpers::loadFrame(childFrame, m_baseURL + "subframe-hello.html");

  v8::Local<v8::Value> window =
      childFrame->executeScriptAndReturnValue(WebScriptSource("window"));
  v8::Local<v8::Value> childOfRemoteParent =
      childFrame->executeScriptAndReturnValue(
          WebScriptSource("parent.frames[0]"));
  EXPECT_TRUE(childOfRemoteParent->IsObject());
  EXPECT_TRUE(window->StrictEquals(childOfRemoteParent));

  v8::Local<v8::Value> windowLength = childFrame->executeScriptAndReturnValue(
      WebScriptSource("parent.frames.length"));
  ASSERT_TRUE(windowLength->IsInt32());
  EXPECT_EQ(1, windowLength.As<v8::Int32>()->Value());

  // Manually reset to break WebViewHelper's dependency on the stack allocated
  // clients.
  reset();
}

// Check that frames with a remote parent don't crash while accessing
// window.frameElement.
TEST_F(WebFrameSwapTest, FrameElementInFramesWithRemoteParent) {
  v8::HandleScope scope(v8::Isolate::GetCurrent());

  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebRemoteFrame* remoteParentFrame = remoteClient.frame();
  mainFrame()->swap(remoteParentFrame);
  remoteParentFrame->setReplicatedOrigin(SecurityOrigin::createUnique());

  WebLocalFrame* childFrame =
      FrameTestHelpers::createLocalChild(remoteParentFrame);
  FrameTestHelpers::loadFrame(childFrame, m_baseURL + "subframe-hello.html");

  v8::Local<v8::Value> frameElement = childFrame->executeScriptAndReturnValue(
      WebScriptSource("window.frameElement"));
  // frameElement should be null if cross-origin.
  ASSERT_FALSE(frameElement.IsEmpty());
  EXPECT_TRUE(frameElement->IsNull());

  // Manually reset to break WebViewHelper's dependency on the stack allocated
  // clients.
  reset();
}

class RemoteToLocalSwapWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  explicit RemoteToLocalSwapWebFrameClient(WebRemoteFrame* remoteFrame)
      : m_historyCommitType(WebHistoryInertCommit),
        m_remoteFrame(remoteFrame) {}

  void didCommitProvisionalLoad(
      WebLocalFrame* frame,
      const WebHistoryItem&,
      WebHistoryCommitType historyCommitType) override {
    m_historyCommitType = historyCommitType;
    m_remoteFrame->swap(frame);
  }

  WebHistoryCommitType historyCommitType() const { return m_historyCommitType; }

  WebHistoryCommitType m_historyCommitType;
  WebRemoteFrame* m_remoteFrame;
};

// The commit type should be Initial if we are swapping a RemoteFrame to a
// LocalFrame as it is first being created.  This happens when another frame
// exists in the same process, such that we create the RemoteFrame before the
// first navigation occurs.
TEST_F(WebFrameSwapTest, HistoryCommitTypeAfterNewRemoteToLocalSwap) {
  FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient;
  WebRemoteFrame* remoteFrame =
      WebRemoteFrame::create(WebTreeScopeType::Document, &remoteFrameClient);
  WebFrame* targetFrame = mainFrame()->firstChild();
  ASSERT_TRUE(targetFrame);
  targetFrame->swap(remoteFrame);
  ASSERT_TRUE(mainFrame()->firstChild());
  ASSERT_EQ(mainFrame()->firstChild(), remoteFrame);

  RemoteToLocalSwapWebFrameClient client(remoteFrame);
  WebLocalFrame* localFrame = WebLocalFrame::createProvisional(
      &client, remoteFrame, WebSandboxFlags::None);
  FrameTestHelpers::loadFrame(localFrame, m_baseURL + "subframe-hello.html");
  EXPECT_EQ(WebInitialCommitInChildFrame, client.historyCommitType());

  // Manually reset to break WebViewHelper's dependency on the stack allocated
  // TestWebFrameClient.
  reset();
  remoteFrame->close();
}

// The commit type should be Standard if we are swapping a RemoteFrame to a
// LocalFrame after commits have already happened in the frame.  The browser
// process will inform us via setCommittedFirstRealLoad.
TEST_F(WebFrameSwapTest, HistoryCommitTypeAfterExistingRemoteToLocalSwap) {
  FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient;
  WebRemoteFrame* remoteFrame =
      WebRemoteFrame::create(WebTreeScopeType::Document, &remoteFrameClient);
  WebFrame* targetFrame = mainFrame()->firstChild();
  ASSERT_TRUE(targetFrame);
  targetFrame->swap(remoteFrame);
  ASSERT_TRUE(mainFrame()->firstChild());
  ASSERT_EQ(mainFrame()->firstChild(), remoteFrame);

  RemoteToLocalSwapWebFrameClient client(remoteFrame);
  WebLocalFrame* localFrame = WebLocalFrame::createProvisional(
      &client, remoteFrame, WebSandboxFlags::None);
  localFrame->setCommittedFirstRealLoad();
  FrameTestHelpers::loadFrame(localFrame, m_baseURL + "subframe-hello.html");
  EXPECT_EQ(WebStandardCommit, client.historyCommitType());

  // Manually reset to break WebViewHelper's dependency on the stack allocated
  // TestWebFrameClient.
  reset();
  remoteFrame->close();
}

// The uniqueName should be preserved when swapping to a RemoteFrame and back,
// whether the frame has a name or not.
TEST_F(WebFrameSwapTest, UniqueNameAfterRemoteToLocalSwap) {
  // Start with a named frame.
  WebFrame* targetFrame = mainFrame()->firstChild();
  ASSERT_TRUE(targetFrame);
  WebString uniqueName = targetFrame->uniqueName();
  EXPECT_EQ("frame1", uniqueName.utf8());

  // Swap to a RemoteFrame.
  FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient;
  WebRemoteFrameImpl* remoteFrame = WebRemoteFrameImpl::create(
      WebTreeScopeType::Document, &remoteFrameClient);
  targetFrame->swap(remoteFrame);
  ASSERT_TRUE(mainFrame()->firstChild());
  ASSERT_EQ(mainFrame()->firstChild(), remoteFrame);
  EXPECT_EQ(uniqueName.utf8(),
            WebString(remoteFrame->frame()->tree().uniqueName()).utf8());

  // Swap back to a LocalFrame.
  RemoteToLocalSwapWebFrameClient client(remoteFrame);
  WebLocalFrame* localFrame = WebLocalFrame::createProvisional(
      &client, remoteFrame, WebSandboxFlags::None);
  FrameTestHelpers::loadFrame(localFrame, m_baseURL + "subframe-hello.html");
  EXPECT_EQ(uniqueName.utf8(), localFrame->uniqueName().utf8());
  EXPECT_EQ(uniqueName.utf8(), WebString(toWebLocalFrameImpl(localFrame)
                                             ->frame()
                                             ->loader()
                                             .currentItem()
                                             ->target())
                                   .utf8());

  // Repeat with no name on the frame.
  // (note that uniqueName is immutable after first real commit).
  localFrame->setName("");
  WebString uniqueName2 = localFrame->uniqueName();
  EXPECT_EQ("frame1", uniqueName2.utf8());

  FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient2;
  WebRemoteFrameImpl* remoteFrame2 = WebRemoteFrameImpl::create(
      WebTreeScopeType::Document, &remoteFrameClient2);
  localFrame->swap(remoteFrame2);
  ASSERT_TRUE(mainFrame()->firstChild());
  ASSERT_EQ(mainFrame()->firstChild(), remoteFrame2);
  EXPECT_EQ(uniqueName2.utf8(),
            WebString(remoteFrame2->frame()->tree().uniqueName()).utf8());

  RemoteToLocalSwapWebFrameClient client2(remoteFrame2);
  WebLocalFrame* localFrame2 = WebLocalFrame::createProvisional(
      &client2, remoteFrame2, WebSandboxFlags::None);
  FrameTestHelpers::loadFrame(localFrame2, m_baseURL + "subframe-hello.html");
  EXPECT_EQ(uniqueName2.utf8(), localFrame2->uniqueName().utf8());
  EXPECT_EQ(uniqueName2.utf8(), WebString(toWebLocalFrameImpl(localFrame2)
                                              ->frame()
                                              ->loader()
                                              .currentItem()
                                              ->target())
                                    .utf8());

  // Manually reset to break WebViewHelper's dependency on the stack allocated
  // TestWebFrameClient.
  reset();
  remoteFrame->close();
  remoteFrame2->close();
}

class RemoteNavigationClient
    : public FrameTestHelpers::TestWebRemoteFrameClient {
 public:
  void navigate(const WebURLRequest& request,
                bool shouldReplaceCurrentEntry) override {
    m_lastRequest = request;
  }

  const WebURLRequest& lastRequest() const { return m_lastRequest; }

 private:
  WebURLRequest m_lastRequest;
};

TEST_F(WebFrameSwapTest, NavigateRemoteFrameViaLocation) {
  RemoteNavigationClient client;
  WebRemoteFrame* remoteFrame = client.frame();
  WebFrame* targetFrame = mainFrame()->firstChild();
  ASSERT_TRUE(targetFrame);
  targetFrame->swap(remoteFrame);
  ASSERT_TRUE(mainFrame()->firstChild());
  ASSERT_EQ(mainFrame()->firstChild(), remoteFrame);

  remoteFrame->setReplicatedOrigin(
      WebSecurityOrigin::createFromString("http://127.0.0.1"));
  mainFrame()->executeScript(
      WebScriptSource("document.getElementsByTagName('iframe')[0]."
                      "contentWindow.location = 'data:text/html,hi'"));
  ASSERT_FALSE(client.lastRequest().isNull());
  EXPECT_EQ(WebURL(toKURL("data:text/html,hi")), client.lastRequest().url());

  // Manually reset to break WebViewHelper's dependency on the stack allocated
  // TestWebFrameClient.
  reset();
}

TEST_F(WebFrameSwapTest, WindowOpenOnRemoteFrame) {
  RemoteNavigationClient remoteClient;
  WebRemoteFrame* remoteFrame = remoteClient.frame();
  mainFrame()->firstChild()->swap(remoteFrame);
  remoteFrame->setReplicatedOrigin(
      WebSecurityOrigin::createFromString("http://127.0.0.1"));

  ASSERT_TRUE(mainFrame()->isWebLocalFrame());
  ASSERT_TRUE(mainFrame()->firstChild()->isWebRemoteFrame());
  LocalDOMWindow* mainWindow =
      toWebLocalFrameImpl(mainFrame())->frame()->localDOMWindow();

  KURL destination = toKURL("data:text/html:destination");
  mainWindow->open(destination.getString(), "frame1", "", mainWindow,
                   mainWindow);
  ASSERT_FALSE(remoteClient.lastRequest().isNull());
  EXPECT_EQ(remoteClient.lastRequest().url(), WebURL(destination));

  // Pointing a named frame to an empty URL should just return a reference to
  // the frame's window without navigating it.
  DOMWindow* result =
      mainWindow->open("", "frame1", "", mainWindow, mainWindow);
  EXPECT_EQ(remoteClient.lastRequest().url(), WebURL(destination));
  EXPECT_EQ(result, remoteFrame->toImplBase()->frame()->domWindow());

  reset();
}

class RemoteWindowCloseClient : public FrameTestHelpers::TestWebViewClient {
 public:
  RemoteWindowCloseClient() : m_closed(false) {}

  void closeWidgetSoon() override { m_closed = true; }

  bool closed() const { return m_closed; }

 private:
  bool m_closed;
};

TEST_F(WebFrameTest, WindowOpenRemoteClose) {
  FrameTestHelpers::WebViewHelper mainWebView;
  mainWebView.initialize(true);

  // Create a remote window that will be closed later in the test.
  RemoteWindowCloseClient viewClient;
  FrameTestHelpers::TestWebRemoteFrameClient frameClient;
  WebRemoteFrameImpl* webRemoteFrame = frameClient.frame();

  WebView* view = WebView::create(&viewClient, WebPageVisibilityStateVisible);
  view->setMainFrame(webRemoteFrame);
  view->mainFrame()->setOpener(mainWebView.webView()->mainFrame());
  webRemoteFrame->setReplicatedOrigin(
      WebSecurityOrigin::createFromString("http://127.0.0.1"));

  LocalFrame* localFrame =
      toLocalFrame(mainWebView.webView()->mainFrame()->toImplBase()->frame());
  RemoteFrame* remoteFrame = webRemoteFrame->frame();

  // Attempt to close the window, which should fail as it isn't opened
  // by a script.
  remoteFrame->domWindow()->close(localFrame->document());
  EXPECT_FALSE(viewClient.closed());

  // Marking it as opened by a script should now allow it to be closed.
  remoteFrame->page()->setOpenedByDOM();
  remoteFrame->domWindow()->close(localFrame->document());
  EXPECT_TRUE(viewClient.closed());

  view->close();
}

TEST_F(WebFrameTest, NavigateRemoteToLocalWithOpener) {
  FrameTestHelpers::WebViewHelper mainWebView;
  mainWebView.initialize(true);
  WebFrame* mainFrame = mainWebView.webView()->mainFrame();

  // Create a popup with a remote frame and set its opener to the main frame.
  FrameTestHelpers::TestWebViewClient popupViewClient;
  WebView* popupView =
      WebView::create(&popupViewClient, WebPageVisibilityStateVisible);
  FrameTestHelpers::TestWebRemoteFrameClient popupRemoteClient;
  WebRemoteFrame* popupRemoteFrame = popupRemoteClient.frame();
  popupView->setMainFrame(popupRemoteFrame);
  popupRemoteFrame->setOpener(mainFrame);
  popupRemoteFrame->setReplicatedOrigin(
      WebSecurityOrigin::createFromString("http://foo.com"));
  EXPECT_FALSE(mainFrame->getSecurityOrigin().canAccess(
      popupView->mainFrame()->getSecurityOrigin()));

  // Do a remote-to-local swap in the popup.
  FrameTestHelpers::TestWebFrameClient popupLocalClient;
  WebLocalFrame* popupLocalFrame = WebLocalFrame::createProvisional(
      &popupLocalClient, popupRemoteFrame, WebSandboxFlags::None);
  popupRemoteFrame->swap(popupLocalFrame);

  // The initial document created during the remote-to-local swap should have
  // inherited its opener's SecurityOrigin.
  EXPECT_TRUE(mainFrame->getSecurityOrigin().canAccess(
      popupView->mainFrame()->getSecurityOrigin()));

  popupView->close();
}

TEST_F(WebFrameTest, SwapWithOpenerCycle) {
  // First, create a remote main frame with itself as the opener.
  FrameTestHelpers::TestWebViewClient viewClient;
  WebView* view = WebView::create(&viewClient, WebPageVisibilityStateVisible);
  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebRemoteFrame* remoteFrame = remoteClient.frame();
  view->setMainFrame(remoteFrame);
  remoteFrame->setOpener(remoteFrame);

  // Now swap in a local frame. It shouldn't crash.
  FrameTestHelpers::TestWebFrameClient localClient;
  WebLocalFrame* localFrame = WebLocalFrame::createProvisional(
      &localClient, remoteFrame, WebSandboxFlags::None);
  remoteFrame->swap(localFrame);

  // And the opener cycle should still be preserved.
  EXPECT_EQ(localFrame, localFrame->opener());

  view->close();
}

class CommitTypeWebFrameClient : public FrameTestHelpers::TestWebFrameClient {
 public:
  explicit CommitTypeWebFrameClient()
      : m_historyCommitType(WebHistoryInertCommit) {}

  void didCommitProvisionalLoad(
      WebLocalFrame*,
      const WebHistoryItem&,
      WebHistoryCommitType historyCommitType) override {
    m_historyCommitType = historyCommitType;
  }

  WebHistoryCommitType historyCommitType() const { return m_historyCommitType; }

 private:
  WebHistoryCommitType m_historyCommitType;
};

TEST_P(ParameterizedWebFrameTest, RemoteFrameInitialCommitType) {
  FrameTestHelpers::TestWebViewClient viewClient;
  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebView* view = WebView::create(&viewClient, WebPageVisibilityStateVisible);
  view->setMainFrame(remoteClient.frame());
  remoteClient.frame()->setReplicatedOrigin(
      WebSecurityOrigin::createFromString(WebString::fromUTF8(m_baseURL)));

  // If an iframe has a remote main frame, ensure the inital commit is correctly
  // identified as WebInitialCommitInChildFrame.
  CommitTypeWebFrameClient childFrameClient;
  WebLocalFrame* childFrame = FrameTestHelpers::createLocalChild(
      view->mainFrame()->toWebRemoteFrame(), "frameName", &childFrameClient);
  registerMockedHttpURLLoad("foo.html");
  FrameTestHelpers::loadFrame(childFrame, m_baseURL + "foo.html");
  EXPECT_EQ(WebInitialCommitInChildFrame, childFrameClient.historyCommitType());
  view->close();
}

class GestureEventTestWebWidgetClient
    : public FrameTestHelpers::TestWebWidgetClient {
 public:
  GestureEventTestWebWidgetClient() : m_didHandleGestureEvent(false) {}
  void didHandleGestureEvent(const WebGestureEvent& event,
                             bool eventCancelled) override {
    m_didHandleGestureEvent = true;
  }
  bool didHandleGestureEvent() const { return m_didHandleGestureEvent; }

 private:
  bool m_didHandleGestureEvent;
};

TEST_P(ParameterizedWebFrameTest, FrameWidgetTest) {
  FrameTestHelpers::TestWebViewClient viewClient;
  WebView* view = WebView::create(&viewClient, WebPageVisibilityStateVisible);

  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  view->setMainFrame(remoteClient.frame());

  GestureEventTestWebWidgetClient childWidgetClient;
  WebLocalFrame* childFrame = FrameTestHelpers::createLocalChild(
      view->mainFrame()->toWebRemoteFrame(), WebString(), nullptr,
      &childWidgetClient);

  view->resize(WebSize(1000, 1000));

  childFrame->frameWidget()->handleInputEvent(fatTap(20, 20));
  EXPECT_TRUE(childWidgetClient.didHandleGestureEvent());

  view->close();
}

class MockDocumentThreadableLoaderClient
    : public DocumentThreadableLoaderClient {
 public:
  MockDocumentThreadableLoaderClient() : m_failed(false) {}
  void didFail(const ResourceError&) override { m_failed = true; }

  void reset() { m_failed = false; }
  bool failed() { return m_failed; }

  bool m_failed;
};

// FIXME: This would be better as a unittest on DocumentThreadableLoader but it
// requires spin-up of a frame. It may be possible to remove that requirement
// and convert it to a unittest.
TEST_P(ParameterizedWebFrameTest, LoaderOriginAccess) {
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad("about:blank");

  SchemeRegistry::registerURLSchemeAsDisplayIsolated("chrome");

  // Cross-origin request.
  KURL resourceUrl(ParsedURLString, "chrome://test.pdf");
  ResourceRequest request(resourceUrl);
  request.setRequestContext(WebURLRequest::RequestContextObject);
  registerMockedChromeURLLoad("test.pdf");

  LocalFrame* frame(toLocalFrame(webViewHelper.webView()->page()->mainFrame()));

  MockDocumentThreadableLoaderClient client;
  ThreadableLoaderOptions options;

  // First try to load the request with regular access. Should fail.
  options.crossOriginRequestPolicy = UseAccessControl;
  ResourceLoaderOptions resourceLoaderOptions;
  DocumentThreadableLoader::loadResourceSynchronously(
      *frame->document(), request, client, options, resourceLoaderOptions);
  EXPECT_TRUE(client.failed());

  client.reset();
  // Try to load the request with cross origin access. Should succeed.
  options.crossOriginRequestPolicy = AllowCrossOriginRequests;
  DocumentThreadableLoader::loadResourceSynchronously(
      *frame->document(), request, client, options, resourceLoaderOptions);
  EXPECT_FALSE(client.failed());
}

TEST_P(ParameterizedWebFrameTest, DetachRemoteFrame) {
  FrameTestHelpers::TestWebViewClient viewClient;
  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebView* view = WebView::create(&viewClient, WebPageVisibilityStateVisible);
  view->setMainFrame(remoteClient.frame());
  FrameTestHelpers::TestWebRemoteFrameClient childFrameClient;
  WebRemoteFrame* childFrame = FrameTestHelpers::createRemoteChild(
      view->mainFrame()->toWebRemoteFrame(), &childFrameClient);
  childFrame->detach();
  view->close();
  childFrame->close();
}

class TestConsoleMessageWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  virtual void didAddMessageToConsole(const WebConsoleMessage& message,
                                      const WebString& sourceName,
                                      unsigned sourceLine,
                                      const WebString& stackTrace) {
    messages.append(message);
  }

  Vector<WebConsoleMessage> messages;
};

TEST_P(ParameterizedWebFrameTest, CrossDomainAccessErrorsUseCallingWindow) {
  registerMockedHttpURLLoad("hidden_frames.html");
  registerMockedChromeURLLoad("hello_world.html");

  FrameTestHelpers::WebViewHelper webViewHelper;
  TestConsoleMessageWebFrameClient webFrameClient;
  FrameTestHelpers::TestWebViewClient webViewClient;
  webViewHelper.initializeAndLoad(m_baseURL + "hidden_frames.html", true,
                                  &webFrameClient, &webViewClient);

  // Create another window with a cross-origin page, and point its opener to
  // first window.
  FrameTestHelpers::WebViewHelper popupWebViewHelper;
  TestConsoleMessageWebFrameClient popupWebFrameClient;
  WebView* popupView = popupWebViewHelper.initializeAndLoad(
      m_chromeURL + "hello_world.html", true, &popupWebFrameClient);
  popupView->mainFrame()->setOpener(webViewHelper.webView()->mainFrame());

  // Attempt a blocked navigation of an opener's subframe, and ensure that
  // the error shows up on the popup (calling) window's console, rather than
  // the target window.
  popupView->mainFrame()->executeScript(WebScriptSource(
      "try { opener.frames[1].location.href='data:text/html,foo'; } catch (e) "
      "{}"));
  EXPECT_TRUE(webFrameClient.messages.isEmpty());
  ASSERT_EQ(1u, popupWebFrameClient.messages.size());
  EXPECT_TRUE(std::string::npos !=
              popupWebFrameClient.messages[0].text.utf8().find(
                  "Unsafe JavaScript attempt to initiate navigation"));

  // Try setting a cross-origin iframe element's source to a javascript: URL,
  // and check that this error is also printed on the calling window.
  popupView->mainFrame()->executeScript(
      WebScriptSource("opener.document.querySelectorAll('iframe')[1].src='"
                      "javascript:alert()'"));
  EXPECT_TRUE(webFrameClient.messages.isEmpty());
  ASSERT_EQ(2u, popupWebFrameClient.messages.size());
  EXPECT_TRUE(
      std::string::npos !=
      popupWebFrameClient.messages[1].text.utf8().find("Blocked a frame"));

  // Manually reset to break WebViewHelpers' dependencies on the stack
  // allocated WebFrameClients.
  webViewHelper.reset();
  popupWebViewHelper.reset();
}

TEST_P(ParameterizedWebFrameTest, ResizeInvalidatesDeviceMediaQueries) {
  registerMockedHttpURLLoad("device_media_queries.html");
  FixedLayoutTestWebViewClient client;
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "device_media_queries.html", true,
                                  nullptr, &client, nullptr, configureAndroid);
  LocalFrame* frame =
      toLocalFrame(webViewHelper.webView()->page()->mainFrame());
  Element* element = frame->document()->getElementById("test");
  ASSERT_TRUE(element);

  client.m_screenInfo.rect = WebRect(0, 0, 700, 500);
  client.m_screenInfo.availableRect = client.m_screenInfo.rect;
  webViewHelper.resize(WebSize(700, 500));
  EXPECT_EQ(300, element->offsetWidth());
  EXPECT_EQ(300, element->offsetHeight());

  client.m_screenInfo.rect = WebRect(0, 0, 710, 500);
  client.m_screenInfo.availableRect = client.m_screenInfo.rect;
  webViewHelper.resize(WebSize(710, 500));
  EXPECT_EQ(400, element->offsetWidth());
  EXPECT_EQ(300, element->offsetHeight());

  client.m_screenInfo.rect = WebRect(0, 0, 690, 500);
  client.m_screenInfo.availableRect = client.m_screenInfo.rect;
  webViewHelper.resize(WebSize(690, 500));
  EXPECT_EQ(200, element->offsetWidth());
  EXPECT_EQ(300, element->offsetHeight());

  client.m_screenInfo.rect = WebRect(0, 0, 700, 510);
  client.m_screenInfo.availableRect = client.m_screenInfo.rect;
  webViewHelper.resize(WebSize(700, 510));
  EXPECT_EQ(300, element->offsetWidth());
  EXPECT_EQ(400, element->offsetHeight());

  client.m_screenInfo.rect = WebRect(0, 0, 700, 490);
  client.m_screenInfo.availableRect = client.m_screenInfo.rect;
  webViewHelper.resize(WebSize(700, 490));
  EXPECT_EQ(300, element->offsetWidth());
  EXPECT_EQ(200, element->offsetHeight());

  client.m_screenInfo.rect = WebRect(0, 0, 690, 510);
  client.m_screenInfo.availableRect = client.m_screenInfo.rect;
  webViewHelper.resize(WebSize(690, 510));
  EXPECT_EQ(200, element->offsetWidth());
  EXPECT_EQ(400, element->offsetHeight());
}

class DeviceEmulationTest : public ParameterizedWebFrameTest {
 protected:
  DeviceEmulationTest() {
    registerMockedHttpURLLoad("device_emulation.html");
    m_client.m_screenInfo.deviceScaleFactor = 1;
    m_webViewHelper.initializeAndLoad(m_baseURL + "device_emulation.html", true,
                                      0, &m_client);
  }

  void testResize(const WebSize size, const String& expectedSize) {
    m_client.m_screenInfo.rect = WebRect(0, 0, size.width, size.height);
    m_client.m_screenInfo.availableRect = m_client.m_screenInfo.rect;
    m_webViewHelper.resize(size);
    EXPECT_EQ(expectedSize, dumpSize("test"));
  }

  String dumpSize(const String& id) {
    String code = "dumpSize('" + id + "')";
    v8::HandleScope scope(v8::Isolate::GetCurrent());
    ScriptExecutionCallbackHelper callbackHelper(
        m_webViewHelper.webView()->mainFrame()->mainWorldScriptContext());
    m_webViewHelper.webView()
        ->mainFrameImpl()
        ->requestExecuteScriptAndReturnValue(WebScriptSource(WebString(code)),
                                             false, &callbackHelper);
    runPendingTasks();
    EXPECT_TRUE(callbackHelper.didComplete());
    return callbackHelper.stringValue();
  }

  FixedLayoutTestWebViewClient m_client;
  FrameTestHelpers::WebViewHelper m_webViewHelper;
};

INSTANTIATE_TEST_CASE_P(All, DeviceEmulationTest, ::testing::Bool());

TEST_P(DeviceEmulationTest, DeviceSizeInvalidatedOnResize) {
  WebDeviceEmulationParams params;
  params.screenPosition = WebDeviceEmulationParams::Mobile;
  m_webViewHelper.webView()->enableDeviceEmulation(params);

  testResize(WebSize(700, 500), "300x300");
  testResize(WebSize(710, 500), "400x300");
  testResize(WebSize(690, 500), "200x300");
  testResize(WebSize(700, 510), "300x400");
  testResize(WebSize(700, 490), "300x200");
  testResize(WebSize(710, 510), "400x400");
  testResize(WebSize(690, 490), "200x200");
  testResize(WebSize(800, 600), "400x400");

  m_webViewHelper.webView()->disableDeviceEmulation();
}

TEST_P(DeviceEmulationTest, PointerAndHoverTypes) {
  WebDeviceEmulationParams params;
  params.screenPosition = WebDeviceEmulationParams::Mobile;
  m_webViewHelper.webView()->enableDeviceEmulation(params);
  EXPECT_EQ("20x20", dumpSize("pointer"));
  m_webViewHelper.webView()->disableDeviceEmulation();
}

TEST_P(ParameterizedWebFrameTest, CreateLocalChildWithPreviousSibling) {
  FrameTestHelpers::TestWebViewClient viewClient;
  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebView* view = WebView::create(&viewClient, WebPageVisibilityStateVisible);
  view->setMainFrame(remoteClient.frame());
  WebRemoteFrame* parent = view->mainFrame()->toWebRemoteFrame();

  WebLocalFrame* secondFrame(
      FrameTestHelpers::createLocalChild(parent, "name2"));
  WebLocalFrame* fourthFrame(FrameTestHelpers::createLocalChild(
      parent, "name4", nullptr, nullptr, secondFrame));
  WebLocalFrame* thirdFrame(FrameTestHelpers::createLocalChild(
      parent, "name3", nullptr, nullptr, secondFrame));
  WebLocalFrame* firstFrame(
      FrameTestHelpers::createLocalChild(parent, "name1"));

  EXPECT_EQ(firstFrame, parent->firstChild());
  EXPECT_EQ(nullptr, firstFrame->previousSibling());
  EXPECT_EQ(secondFrame, firstFrame->nextSibling());

  EXPECT_EQ(firstFrame, secondFrame->previousSibling());
  EXPECT_EQ(thirdFrame, secondFrame->nextSibling());

  EXPECT_EQ(secondFrame, thirdFrame->previousSibling());
  EXPECT_EQ(fourthFrame, thirdFrame->nextSibling());

  EXPECT_EQ(thirdFrame, fourthFrame->previousSibling());
  EXPECT_EQ(nullptr, fourthFrame->nextSibling());
  EXPECT_EQ(fourthFrame, parent->lastChild());

  EXPECT_EQ(parent, firstFrame->parent());
  EXPECT_EQ(parent, secondFrame->parent());
  EXPECT_EQ(parent, thirdFrame->parent());
  EXPECT_EQ(parent, fourthFrame->parent());

  view->close();
}

TEST_P(ParameterizedWebFrameTest, SendBeaconFromChildWithRemoteMainFrame) {
  FrameTestHelpers::TestWebViewClient viewClient;
  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebView* view = WebView::create(&viewClient, WebPageVisibilityStateVisible);
  view->settings()->setJavaScriptEnabled(true);
  view->setMainFrame(remoteClient.frame());
  WebRemoteFrame* root = view->mainFrame()->toWebRemoteFrame();
  root->setReplicatedOrigin(SecurityOrigin::createUnique());

  WebLocalFrame* localFrame = FrameTestHelpers::createLocalChild(root);

  // Finally, make sure an embedder triggered load in the local frame swapped
  // back in works.
  registerMockedHttpURLLoad("send_beacon.html");
  registerMockedHttpURLLoad("reload_post.html");  // url param to sendBeacon()
  FrameTestHelpers::loadFrame(localFrame, m_baseURL + "send_beacon.html");

  view->close();
}

TEST_P(ParameterizedWebFrameTest,
       FirstPartyForCookiesFromChildWithRemoteMainFrame) {
  FrameTestHelpers::TestWebViewClient viewClient;
  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebView* view = WebView::create(&viewClient, WebPageVisibilityStateVisible);
  view->setMainFrame(remoteClient.frame());
  WebRemoteFrame* root = view->mainFrame()->toWebRemoteFrame();
  root->setReplicatedOrigin(SecurityOrigin::create(toKURL(m_notBaseURL)));

  WebLocalFrame* localFrame = FrameTestHelpers::createLocalChild(root);

  registerMockedHttpURLLoad("foo.html");
  FrameTestHelpers::loadFrame(localFrame, m_baseURL + "foo.html");
  EXPECT_EQ(WebURL(SecurityOrigin::urlWithUniqueSecurityOrigin()),
            localFrame->document().firstPartyForCookies());

  SchemeRegistry::registerURLSchemeAsFirstPartyWhenTopLevel("http");
  EXPECT_EQ(WebURL(toKURL(m_notBaseURL)),
            localFrame->document().firstPartyForCookies());
  SchemeRegistry::removeURLSchemeAsFirstPartyWhenTopLevel("http");

  view->close();
}

// See https://crbug.com/525285.
TEST_P(ParameterizedWebFrameTest,
       RemoteToLocalSwapOnMainFrameInitializesCoreFrame) {
  FrameTestHelpers::TestWebViewClient viewClient;
  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebView* view = WebView::create(&viewClient, WebPageVisibilityStateVisible);
  view->setMainFrame(remoteClient.frame());
  WebRemoteFrame* remoteRoot = view->mainFrame()->toWebRemoteFrame();
  remoteRoot->setReplicatedOrigin(SecurityOrigin::createUnique());

  FrameTestHelpers::createLocalChild(remoteRoot);

  // Do a remote-to-local swap of the top frame.
  FrameTestHelpers::TestWebFrameClient localClient;
  WebLocalFrame* localRoot = WebLocalFrame::createProvisional(
      &localClient, remoteRoot, WebSandboxFlags::None);
  FrameTestHelpers::TestWebWidgetClient webWidgetClient;
  WebFrameWidget::create(&webWidgetClient, localRoot);
  remoteRoot->swap(localRoot);

  // Load a page with a child frame in the new root to make sure this doesn't
  // crash when the child frame invokes setCoreFrame.
  registerMockedHttpURLLoad("single_iframe.html");
  registerMockedHttpURLLoad("visible_iframe.html");
  FrameTestHelpers::loadFrame(localRoot, m_baseURL + "single_iframe.html");

  view->close();
}

// See https://crbug.com/628942.
TEST_P(ParameterizedWebFrameTest, DeferredPageLoadWithRemoteMainFrame) {
  // Prepare a page with a remote main frame.
  FrameTestHelpers::TestWebViewClient viewClient;
  FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
  WebView* view = WebView::create(&viewClient, WebPageVisibilityStateVisible);
  view->setMainFrame(remoteClient.frame());
  WebRemoteFrame* remoteRoot = view->mainFrame()->toWebRemoteFrame();
  remoteRoot->setReplicatedOrigin(SecurityOrigin::createUnique());

  // Check that ScopedPageLoadDeferrer properly triggers deferred loading for
  // the current Page.
  Page* page = remoteRoot->toImplBase()->frame()->page();
  EXPECT_FALSE(page->defersLoading());
  {
    ScopedPageLoadDeferrer deferrer;
    EXPECT_TRUE(page->defersLoading());
  }
  EXPECT_FALSE(page->defersLoading());

  // Repeat this for a page with a local child frame, and ensure that the
  // child frame's loads are also deferred.
  WebLocalFrame* webLocalChild = FrameTestHelpers::createLocalChild(remoteRoot);
  registerMockedHttpURLLoad("foo.html");
  FrameTestHelpers::loadFrame(webLocalChild, m_baseURL + "foo.html");
  LocalFrame* localChild = toWebLocalFrameImpl(webLocalChild)->frame();
  EXPECT_FALSE(page->defersLoading());
  EXPECT_FALSE(localChild->document()->fetcher()->defersLoading());
  {
    ScopedPageLoadDeferrer deferrer;
    EXPECT_TRUE(page->defersLoading());
    EXPECT_TRUE(localChild->document()->fetcher()->defersLoading());
  }
  EXPECT_FALSE(page->defersLoading());
  EXPECT_FALSE(localChild->document()->fetcher()->defersLoading());

  view->close();
}

class OverscrollWebViewClient : public FrameTestHelpers::TestWebViewClient {
 public:
  MOCK_METHOD4(didOverscroll,
               void(const WebFloatSize&,
                    const WebFloatSize&,
                    const WebFloatPoint&,
                    const WebFloatSize&));
};

class WebFrameOverscrollTest
    : public WebFrameTest,
      public ::testing::WithParamInterface<blink::WebGestureDevice> {
 protected:
  WebGestureEvent generateEvent(WebInputEvent::Type type,
                                float deltaX = 0.0,
                                float deltaY = 0.0) {
    WebGestureEvent event;
    event.type = type;
    // TODO(wjmaclean): Make sure that touchpad device is only ever used for
    // gesture scrolling event types.
    event.sourceDevice = GetParam();
    event.x = 100;
    event.y = 100;
    if (type == WebInputEvent::GestureScrollUpdate) {
      event.data.scrollUpdate.deltaX = deltaX;
      event.data.scrollUpdate.deltaY = deltaY;
    }
    return event;
  }

  void ScrollBegin(FrameTestHelpers::WebViewHelper* webViewHelper) {
    webViewHelper->webView()->handleInputEvent(
        generateEvent(WebInputEvent::GestureScrollBegin));
  }

  void ScrollUpdate(FrameTestHelpers::WebViewHelper* webViewHelper,
                    float deltaX,
                    float deltaY) {
    webViewHelper->webView()->handleInputEvent(
        generateEvent(WebInputEvent::GestureScrollUpdate, deltaX, deltaY));
  }

  void ScrollEnd(FrameTestHelpers::WebViewHelper* webViewHelper) {
    webViewHelper->webView()->handleInputEvent(
        generateEvent(WebInputEvent::GestureScrollEnd));
  }
};

INSTANTIATE_TEST_CASE_P(All,
                        WebFrameOverscrollTest,
                        ::testing::Values(WebGestureDeviceTouchpad,
                                          WebGestureDeviceTouchscreen));

TEST_P(WebFrameOverscrollTest,
       AccumulatedRootOverscrollAndUnsedDeltaValuesOnOverscroll) {
  OverscrollWebViewClient client;
  registerMockedHttpURLLoad("overscroll/overscroll.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "overscroll/overscroll.html",
                                  true, nullptr, &client, nullptr,
                                  configureAndroid);
  webViewHelper.resize(WebSize(200, 200));

  // Calculation of accumulatedRootOverscroll and unusedDelta on multiple
  // scrollUpdate.
  ScrollBegin(&webViewHelper);
  EXPECT_CALL(client, didOverscroll(WebFloatSize(8, 16), WebFloatSize(8, 16),
                                    WebFloatPoint(100, 100), WebFloatSize()));
  ScrollUpdate(&webViewHelper, -308, -316);
  Mock::VerifyAndClearExpectations(&client);

  EXPECT_CALL(client, didOverscroll(WebFloatSize(0, 13), WebFloatSize(8, 29),
                                    WebFloatPoint(100, 100), WebFloatSize()));
  ScrollUpdate(&webViewHelper, 0, -13);
  Mock::VerifyAndClearExpectations(&client);

  EXPECT_CALL(client, didOverscroll(WebFloatSize(20, 13), WebFloatSize(28, 42),
                                    WebFloatPoint(100, 100), WebFloatSize()));
  ScrollUpdate(&webViewHelper, -20, -13);
  Mock::VerifyAndClearExpectations(&client);

  // Overscroll is not reported.
  EXPECT_CALL(client, didOverscroll(_, _, _, _)).Times(0);
  ScrollUpdate(&webViewHelper, 0, 1);
  Mock::VerifyAndClearExpectations(&client);

  EXPECT_CALL(client, didOverscroll(_, _, _, _)).Times(0);
  ScrollUpdate(&webViewHelper, 1, 0);
  Mock::VerifyAndClearExpectations(&client);

  // Overscroll is reported.
  EXPECT_CALL(client,
              didOverscroll(WebFloatSize(0, -701), WebFloatSize(0, -701),
                            WebFloatPoint(100, 100), WebFloatSize()));
  ScrollUpdate(&webViewHelper, 0, 1000);
  Mock::VerifyAndClearExpectations(&client);

  // Overscroll is not reported.
  EXPECT_CALL(client, didOverscroll(_, _, _, _)).Times(0);
  ScrollEnd(&webViewHelper);
  Mock::VerifyAndClearExpectations(&client);
}

TEST_P(WebFrameOverscrollTest,
       AccumulatedOverscrollAndUnusedDeltaValuesOnDifferentAxesOverscroll) {
  OverscrollWebViewClient client;
  registerMockedHttpURLLoad("overscroll/div-overscroll.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "overscroll/div-overscroll.html",
                                  true, nullptr, &client, nullptr,
                                  configureAndroid);
  webViewHelper.resize(WebSize(200, 200));

  ScrollBegin(&webViewHelper);

  // Scroll the Div to the end.
  EXPECT_CALL(client, didOverscroll(_, _, _, _)).Times(0);
  ScrollUpdate(&webViewHelper, 0, -316);
  Mock::VerifyAndClearExpectations(&client);

  ScrollEnd(&webViewHelper);
  ScrollBegin(&webViewHelper);

  // Now On Scrolling DIV, scroll is bubbled and root layer is over-scrolled.
  EXPECT_CALL(client, didOverscroll(WebFloatSize(0, 100), WebFloatSize(0, 100),
                                    WebFloatPoint(100, 100), WebFloatSize()));
  ScrollUpdate(&webViewHelper, 0, -100);
  ScrollUpdate(&webViewHelper, 0, -100);
  Mock::VerifyAndClearExpectations(&client);

  // TODO(bokan): This has never worked but by the accident that this test was
  // being run in a WebView without a size. This test should be fixed along with
  // the bug, crbug.com/589320.
  // Page scrolls vertically, but over-scrolls horizontally.
  // EXPECT_CALL(client, didOverscroll(WebFloatSize(-100, 0), WebFloatSize(-100,
  // 0), WebFloatPoint(100, 100), WebFloatSize()));
  // ScrollUpdate(&webViewHelper, 100, 50);
  // Mock::VerifyAndClearExpectations(&client);

  // Scrolling up, Overscroll is not reported.
  // EXPECT_CALL(client, didOverscroll(_, _, _, _)).Times(0);
  // ScrollUpdate(&webViewHelper, 0, -50);
  // Mock::VerifyAndClearExpectations(&client);

  // Page scrolls horizontally, but over-scrolls vertically.
  // EXPECT_CALL(client, didOverscroll(WebFloatSize(0, 100), WebFloatSize(0,
  // 100), WebFloatPoint(100, 100), WebFloatSize()));
  // ScrollUpdate(&webViewHelper, -100, -100);
  // Mock::VerifyAndClearExpectations(&client);
}

TEST_P(WebFrameOverscrollTest, RootLayerOverscrolledOnInnerDivOverScroll) {
  OverscrollWebViewClient client;
  registerMockedHttpURLLoad("overscroll/div-overscroll.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "overscroll/div-overscroll.html",
                                  true, nullptr, &client, nullptr,
                                  configureAndroid);
  webViewHelper.resize(WebSize(200, 200));

  ScrollBegin(&webViewHelper);

  // Scroll the Div to the end.
  EXPECT_CALL(client, didOverscroll(_, _, _, _)).Times(0);
  ScrollUpdate(&webViewHelper, 0, -316);
  Mock::VerifyAndClearExpectations(&client);

  ScrollEnd(&webViewHelper);
  ScrollBegin(&webViewHelper);

  // Now On Scrolling DIV, scroll is bubbled and root layer is over-scrolled.
  EXPECT_CALL(client, didOverscroll(WebFloatSize(0, 50), WebFloatSize(0, 50),
                                    WebFloatPoint(100, 100), WebFloatSize()));
  ScrollUpdate(&webViewHelper, 0, -150);
  Mock::VerifyAndClearExpectations(&client);
}

TEST_P(WebFrameOverscrollTest, RootLayerOverscrolledOnInnerIFrameOverScroll) {
  OverscrollWebViewClient client;
  registerMockedHttpURLLoad("overscroll/iframe-overscroll.html");
  registerMockedHttpURLLoad("overscroll/scrollable-iframe.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(
      m_baseURL + "overscroll/iframe-overscroll.html", true, nullptr, &client,
      nullptr, configureAndroid);
  webViewHelper.resize(WebSize(200, 200));

  ScrollBegin(&webViewHelper);
  // Scroll the IFrame to the end.
  EXPECT_CALL(client, didOverscroll(_, _, _, _)).Times(0);

  // This scroll will fully scroll the iframe but will be consumed before being
  // counted as overscroll.
  ScrollUpdate(&webViewHelper, 0, -320);

  // This scroll will again target the iframe but wont bubble further up. Make
  // sure that the unused scroll isn't handled as overscroll.
  ScrollUpdate(&webViewHelper, 0, -50);
  Mock::VerifyAndClearExpectations(&client);

  ScrollEnd(&webViewHelper);
  ScrollBegin(&webViewHelper);

  // Now On Scrolling IFrame, scroll is bubbled and root layer is over-scrolled.
  EXPECT_CALL(client, didOverscroll(WebFloatSize(0, 50), WebFloatSize(0, 50),
                                    WebFloatPoint(100, 100), WebFloatSize()));
  ScrollUpdate(&webViewHelper, 0, -150);
  Mock::VerifyAndClearExpectations(&client);

  ScrollEnd(&webViewHelper);
}

TEST_P(WebFrameOverscrollTest, ScaledPageRootLayerOverscrolled) {
  OverscrollWebViewClient client;
  registerMockedHttpURLLoad("overscroll/overscroll.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(
      m_baseURL + "overscroll/overscroll.html", true, nullptr, &client, nullptr,
      configureAndroid);
  webViewHelper.resize(WebSize(200, 200));
  webViewImpl->setPageScaleFactor(3.0);

  // Calculation of accumulatedRootOverscroll and unusedDelta on scaled page.
  // The point is (99, 99) because we clamp in the division by 3 to 33 so when
  // we go back to viewport coordinates it becomes (99, 99).
  ScrollBegin(&webViewHelper);
  EXPECT_CALL(client, didOverscroll(WebFloatSize(0, -30), WebFloatSize(0, -30),
                                    WebFloatPoint(99, 99), WebFloatSize()));
  ScrollUpdate(&webViewHelper, 0, 30);
  Mock::VerifyAndClearExpectations(&client);

  EXPECT_CALL(client, didOverscroll(WebFloatSize(0, -30), WebFloatSize(0, -60),
                                    WebFloatPoint(99, 99), WebFloatSize()));
  ScrollUpdate(&webViewHelper, 0, 30);
  Mock::VerifyAndClearExpectations(&client);

  EXPECT_CALL(client,
              didOverscroll(WebFloatSize(-30, -30), WebFloatSize(-30, -90),
                            WebFloatPoint(99, 99), WebFloatSize()));
  ScrollUpdate(&webViewHelper, 30, 30);
  Mock::VerifyAndClearExpectations(&client);

  EXPECT_CALL(client,
              didOverscroll(WebFloatSize(-30, 0), WebFloatSize(-60, -90),
                            WebFloatPoint(99, 99), WebFloatSize()));
  ScrollUpdate(&webViewHelper, 30, 0);
  Mock::VerifyAndClearExpectations(&client);

  // Overscroll is not reported.
  EXPECT_CALL(client, didOverscroll(_, _, _, _)).Times(0);
  ScrollEnd(&webViewHelper);
  Mock::VerifyAndClearExpectations(&client);
}

TEST_P(WebFrameOverscrollTest, NoOverscrollForSmallvalues) {
  OverscrollWebViewClient client;
  registerMockedHttpURLLoad("overscroll/overscroll.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "overscroll/overscroll.html",
                                  true, nullptr, &client, nullptr,
                                  configureAndroid);
  webViewHelper.resize(WebSize(200, 200));

  ScrollBegin(&webViewHelper);
  EXPECT_CALL(client,
              didOverscroll(WebFloatSize(-10, -10), WebFloatSize(-10, -10),
                            WebFloatPoint(100, 100), WebFloatSize()));
  ScrollUpdate(&webViewHelper, 10, 10);
  Mock::VerifyAndClearExpectations(&client);

  EXPECT_CALL(client,
              didOverscroll(WebFloatSize(0, -0.10), WebFloatSize(-10, -10.10),
                            WebFloatPoint(100, 100), WebFloatSize()));
  ScrollUpdate(&webViewHelper, 0, 0.10);
  Mock::VerifyAndClearExpectations(&client);

  EXPECT_CALL(client, didOverscroll(WebFloatSize(-0.10, 0),
                                    WebFloatSize(-10.10, -10.10),
                                    WebFloatPoint(100, 100), WebFloatSize()));
  ScrollUpdate(&webViewHelper, 0.10, 0);
  Mock::VerifyAndClearExpectations(&client);

  // For residual values overscrollDelta should be reset and didOverscroll
  // shouldn't be called.
  EXPECT_CALL(client, didOverscroll(_, _, _, _)).Times(0);
  ScrollUpdate(&webViewHelper, 0, 0.09);
  Mock::VerifyAndClearExpectations(&client);

  EXPECT_CALL(client, didOverscroll(_, _, _, _)).Times(0);
  ScrollUpdate(&webViewHelper, 0.09, 0.09);
  Mock::VerifyAndClearExpectations(&client);

  EXPECT_CALL(client, didOverscroll(_, _, _, _)).Times(0);
  ScrollUpdate(&webViewHelper, 0.09, 0);
  Mock::VerifyAndClearExpectations(&client);

  EXPECT_CALL(client, didOverscroll(_, _, _, _)).Times(0);
  ScrollUpdate(&webViewHelper, 0, -0.09);
  Mock::VerifyAndClearExpectations(&client);

  EXPECT_CALL(client, didOverscroll(_, _, _, _)).Times(0);
  ScrollUpdate(&webViewHelper, -0.09, -0.09);
  Mock::VerifyAndClearExpectations(&client);

  EXPECT_CALL(client, didOverscroll(_, _, _, _)).Times(0);
  ScrollUpdate(&webViewHelper, -0.09, 0);
  Mock::VerifyAndClearExpectations(&client);

  EXPECT_CALL(client, didOverscroll(_, _, _, _)).Times(0);
  ScrollEnd(&webViewHelper);
  Mock::VerifyAndClearExpectations(&client);
}

TEST_F(WebFrameTest, OrientationFrameDetach) {
  RuntimeEnabledFeatures::setOrientationEventEnabled(true);
  registerMockedHttpURLLoad("orientation-frame-detach.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(
      m_baseURL + "orientation-frame-detach.html", true);
  webViewImpl->mainFrameImpl()->sendOrientationChangeEvent();
}

TEST_F(WebFrameTest, MaxFramesDetach) {
  registerMockedHttpURLLoad("max-frames-detach.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(
      m_baseURL + "max-frames-detach.html", true);
  webViewImpl->mainFrameImpl()->collectGarbage();
}

TEST_F(WebFrameTest, ImageDocumentLoadFinishTime) {
  // Loading an image resource directly generates an ImageDocument with
  // the document loader feeding image data into the resource of a generated
  // img tag. We expect the load finish time to be the same for the document
  // and the image resource.

  registerMockedHttpURLLoadWithMimeType("white-1x1.png", "image/png");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "white-1x1.png");
  WebViewImpl* webView = webViewHelper.webView();
  Document* document = webView->mainFrameImpl()->frame()->document();

  EXPECT_TRUE(document);
  EXPECT_TRUE(document->isImageDocument());

  ImageDocument* imgDocument = toImageDocument(document);
  ImageResource* resource = imgDocument->cachedImage();

  EXPECT_TRUE(resource);
  EXPECT_NE(0, resource->loadFinishTime());

  DocumentLoader* loader = document->loader();

  EXPECT_TRUE(loader);
  EXPECT_EQ(loader->timing().responseEnd(), resource->loadFinishTime());
}

class CallbackOrderingWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  CallbackOrderingWebFrameClient() : m_callbackCount(0) {}

  void didStartLoading(bool toDifferentDocument) override {
    EXPECT_EQ(0, m_callbackCount++);
    FrameTestHelpers::TestWebFrameClient::didStartLoading(toDifferentDocument);
  }
  void didStartProvisionalLoad(WebLocalFrame*, double) override {
    EXPECT_EQ(1, m_callbackCount++);
  }
  void didCommitProvisionalLoad(WebLocalFrame*,
                                const WebHistoryItem&,
                                WebHistoryCommitType) override {
    EXPECT_EQ(2, m_callbackCount++);
  }
  void didFinishDocumentLoad(WebLocalFrame*) override {
    EXPECT_EQ(3, m_callbackCount++);
  }
  void didHandleOnloadEvents(WebLocalFrame*) override {
    EXPECT_EQ(4, m_callbackCount++);
  }
  void didFinishLoad(WebLocalFrame*) override {
    EXPECT_EQ(5, m_callbackCount++);
  }
  void didStopLoading() override {
    EXPECT_EQ(6, m_callbackCount++);
    FrameTestHelpers::TestWebFrameClient::didStopLoading();
  }

 private:
  int m_callbackCount;
};

TEST_F(WebFrameTest, CallbackOrdering) {
  registerMockedHttpURLLoad("foo.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  CallbackOrderingWebFrameClient client;
  webViewHelper.initializeAndLoad(m_baseURL + "foo.html", true, &client);
}

class TestWebRemoteFrameClientForVisibility
    : public FrameTestHelpers::TestWebRemoteFrameClient {
 public:
  TestWebRemoteFrameClientForVisibility() : m_visible(true) {}
  void visibilityChanged(bool visible) override { m_visible = visible; }

  bool isVisible() const { return m_visible; }

 private:
  bool m_visible;
};

class WebFrameVisibilityChangeTest : public WebFrameTest {
 public:
  WebFrameVisibilityChangeTest() {
    registerMockedHttpURLLoad("visible_iframe.html");
    registerMockedHttpURLLoad("single_iframe.html");
    m_frame = m_webViewHelper
                  .initializeAndLoad(m_baseURL + "single_iframe.html", true)
                  ->mainFrame();
    m_webRemoteFrame = remoteFrameClient()->frame();
  }

  ~WebFrameVisibilityChangeTest() {}

  void executeScriptOnMainFrame(const WebScriptSource& script) {
    mainFrame()->executeScript(script);
    mainFrame()->view()->updateAllLifecyclePhases();
    runPendingTasks();
  }

  void swapLocalFrameToRemoteFrame() {
    mainFrame()->lastChild()->swap(remoteFrame());
    remoteFrame()->setReplicatedOrigin(SecurityOrigin::createUnique());
  }

  WebFrame* mainFrame() { return m_frame; }
  WebRemoteFrameImpl* remoteFrame() { return m_webRemoteFrame; }
  TestWebRemoteFrameClientForVisibility* remoteFrameClient() {
    return &m_remoteFrameClient;
  }

 private:
  TestWebRemoteFrameClientForVisibility m_remoteFrameClient;
  FrameTestHelpers::WebViewHelper m_webViewHelper;
  WebFrame* m_frame;
  Persistent<WebRemoteFrameImpl> m_webRemoteFrame;
};

TEST_F(WebFrameVisibilityChangeTest, RemoteFrameVisibilityChange) {
  swapLocalFrameToRemoteFrame();
  executeScriptOnMainFrame(WebScriptSource(
      "document.querySelector('iframe').style.display = 'none';"));
  EXPECT_FALSE(remoteFrameClient()->isVisible());

  executeScriptOnMainFrame(WebScriptSource(
      "document.querySelector('iframe').style.display = 'block';"));
  EXPECT_TRUE(remoteFrameClient()->isVisible());
}

TEST_F(WebFrameVisibilityChangeTest, RemoteFrameParentVisibilityChange) {
  swapLocalFrameToRemoteFrame();
  executeScriptOnMainFrame(
      WebScriptSource("document.querySelector('iframe').parentElement.style."
                      "display = 'none';"));
  EXPECT_FALSE(remoteFrameClient()->isVisible());
}

static void enableGlobalReuseForUnownedMainFrames(WebSettings* settings) {
  settings->setShouldReuseGlobalForUnownedMainFrame(true);
}

// A main frame with no opener should have a unique security origin. Thus, the
// global should never be reused on the initial navigation.
TEST(WebFrameGlobalReuseTest, MainFrameWithNoOpener) {
  FrameTestHelpers::WebViewHelper helper;
  helper.initialize(true);

  WebLocalFrame* mainFrame = helper.webView()->mainFrameImpl();
  v8::HandleScope scope(v8::Isolate::GetCurrent());
  mainFrame->executeScript(WebScriptSource("hello = 'world';"));
  FrameTestHelpers::loadFrame(mainFrame, "data:text/html,new page");
  v8::Local<v8::Value> result =
      mainFrame->executeScriptAndReturnValue(WebScriptSource("hello"));
  EXPECT_TRUE(result.IsEmpty());
}

// Child frames should never reuse the global on a cross-origin navigation, even
// if the setting is enabled. It's not safe to since the parent could have
// injected script before the initial navigation.
TEST(WebFrameGlobalReuseTest, ChildFrame) {
  FrameTestHelpers::WebViewHelper helper;
  helper.initialize(true, nullptr, nullptr, nullptr,
                    enableGlobalReuseForUnownedMainFrames);

  WebLocalFrame* mainFrame = helper.webView()->mainFrameImpl();
  FrameTestHelpers::loadFrame(mainFrame, "data:text/html,<iframe></iframe>");

  WebLocalFrame* childFrame = mainFrame->firstChild()->toWebLocalFrame();
  v8::HandleScope scope(v8::Isolate::GetCurrent());
  childFrame->executeScript(WebScriptSource("hello = 'world';"));
  FrameTestHelpers::loadFrame(childFrame, "data:text/html,new page");
  v8::Local<v8::Value> result =
      childFrame->executeScriptAndReturnValue(WebScriptSource("hello"));
  EXPECT_TRUE(result.IsEmpty());
}

// A main frame with an opener should never reuse the global on a cross-origin
// navigation, even if the setting is enabled. It's not safe to since the opener
// could have injected script.
TEST(WebFrameGlobalReuseTest, MainFrameWithOpener) {
  FrameTestHelpers::TestWebViewClient openerWebViewClient;
  FrameTestHelpers::WebViewHelper openerHelper;
  openerHelper.initialize(false, nullptr, &openerWebViewClient, nullptr);
  FrameTestHelpers::WebViewHelper helper;
  helper.initializeWithOpener(openerHelper.webView()->mainFrame(), true,
                              nullptr, nullptr, nullptr,
                              enableGlobalReuseForUnownedMainFrames);

  WebLocalFrame* mainFrame = helper.webView()->mainFrameImpl();
  v8::HandleScope scope(v8::Isolate::GetCurrent());
  mainFrame->executeScript(WebScriptSource("hello = 'world';"));
  FrameTestHelpers::loadFrame(mainFrame, "data:text/html,new page");
  v8::Local<v8::Value> result =
      mainFrame->executeScriptAndReturnValue(WebScriptSource("hello"));
  EXPECT_TRUE(result.IsEmpty());
}

// A main frame that is unrelated to any other frame /can/ reuse the global if
// the setting is enabled. In this case, it's impossible for any other frames to
// have touched the global. Only the embedder could have injected script, and
// the embedder enabling this setting is a signal that the injected script needs
// to persist on the first navigation away from the initial empty document.
TEST(WebFrameGlobalReuseTest, ReuseForMainFrameIfEnabled) {
  FrameTestHelpers::WebViewHelper helper;
  helper.initialize(true, nullptr, nullptr, nullptr,
                    enableGlobalReuseForUnownedMainFrames);

  WebLocalFrame* mainFrame = helper.webView()->mainFrameImpl();
  v8::HandleScope scope(v8::Isolate::GetCurrent());
  mainFrame->executeScript(WebScriptSource("hello = 'world';"));
  FrameTestHelpers::loadFrame(mainFrame, "data:text/html,new page");
  v8::Local<v8::Value> result =
      mainFrame->executeScriptAndReturnValue(WebScriptSource("hello"));
  ASSERT_TRUE(result->IsString());
  EXPECT_EQ("world",
            toCoreString(result->ToString(mainFrame->mainWorldScriptContext())
                             .ToLocalChecked()));
}

class SaveImageFromDataURLWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  // WebFrameClient methods
  void saveImageFromDataURL(const WebString& dataURL) override {
    m_dataURL = dataURL;
  }

  // Local methods
  const WebString& result() const { return m_dataURL; }
  void reset() { m_dataURL = WebString(); }

 private:
  WebString m_dataURL;
};

TEST_F(WebFrameTest, SaveImageAt) {
  std::string url = m_baseURL + "image-with-data-url.html";
  URLTestHelpers::registerMockedURLLoad(toKURL(url),
                                        "image-with-data-url.html");
  URLTestHelpers::registerMockedURLLoad(toKURL("http://test"), "white-1x1.png");

  FrameTestHelpers::WebViewHelper helper;
  SaveImageFromDataURLWebFrameClient client;
  WebViewImpl* webView = helper.initializeAndLoad(url, true, &client);
  webView->resize(WebSize(400, 400));
  webView->updateAllLifecyclePhases();

  WebLocalFrame* localFrame = webView->mainFrameImpl();

  client.reset();
  localFrame->saveImageAt(WebPoint(1, 1));
  EXPECT_EQ(
      WebString::fromUTF8("data:image/gif;base64"
                          ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
      client.result());

  client.reset();
  localFrame->saveImageAt(WebPoint(1, 2));
  EXPECT_EQ(WebString(), client.result());

  webView->setPageScaleFactor(4);
  webView->setVisualViewportOffset(WebFloatPoint(1, 1));

  client.reset();
  localFrame->saveImageAt(WebPoint(3, 3));
  EXPECT_EQ(
      WebString::fromUTF8("data:image/gif;base64"
                          ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
      client.result());

  // Explicitly reset to break dependency on locally scoped client.
  helper.reset();
}

TEST_F(WebFrameTest, SaveImageWithImageMap) {
  std::string url = m_baseURL + "image-map.html";
  URLTestHelpers::registerMockedURLLoad(toKURL(url), "image-map.html");

  FrameTestHelpers::WebViewHelper helper;
  SaveImageFromDataURLWebFrameClient client;
  WebViewImpl* webView = helper.initializeAndLoad(url, true, &client);
  webView->resize(WebSize(400, 400));

  WebLocalFrame* localFrame = webView->mainFrameImpl();

  client.reset();
  localFrame->saveImageAt(WebPoint(25, 25));
  EXPECT_EQ(
      WebString::fromUTF8("data:image/gif;base64"
                          ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
      client.result());

  client.reset();
  localFrame->saveImageAt(WebPoint(75, 25));
  EXPECT_EQ(
      WebString::fromUTF8("data:image/gif;base64"
                          ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
      client.result());

  client.reset();
  localFrame->saveImageAt(WebPoint(125, 25));
  EXPECT_EQ(WebString(), client.result());

  // Explicitly reset to break dependency on locally scoped client.
  helper.reset();
}

TEST_F(WebFrameTest, CopyImageAt) {
  std::string url = m_baseURL + "canvas-copy-image.html";
  URLTestHelpers::registerMockedURLLoad(toKURL(url), "canvas-copy-image.html");

  FrameTestHelpers::WebViewHelper helper;
  WebViewImpl* webView = helper.initializeAndLoad(url, true, 0);
  webView->resize(WebSize(400, 400));

  uint64_t sequence = Platform::current()->clipboard()->sequenceNumber(
      WebClipboard::BufferStandard);

  WebLocalFrame* localFrame = webView->mainFrameImpl();
  localFrame->copyImageAt(WebPoint(50, 50));

  EXPECT_NE(sequence, Platform::current()->clipboard()->sequenceNumber(
                          WebClipboard::BufferStandard));

  WebImage image =
      static_cast<WebMockClipboard*>(Platform::current()->clipboard())
          ->readRawImage(WebClipboard::Buffer());

  SkAutoLockPixels autoLock(image.getSkBitmap());
  EXPECT_EQ(SkColorSetARGB(255, 255, 0, 0), image.getSkBitmap().getColor(0, 0));
};

TEST_F(WebFrameTest, CopyImageAtWithPinchZoom) {
  std::string url = m_baseURL + "canvas-copy-image.html";
  URLTestHelpers::registerMockedURLLoad(toKURL(url), "canvas-copy-image.html");

  FrameTestHelpers::WebViewHelper helper;
  WebViewImpl* webView = helper.initializeAndLoad(url, true, 0);
  webView->resize(WebSize(400, 400));
  webView->updateAllLifecyclePhases();
  webView->setPageScaleFactor(2);
  webView->setVisualViewportOffset(WebFloatPoint(200, 200));

  uint64_t sequence = Platform::current()->clipboard()->sequenceNumber(
      WebClipboard::BufferStandard);

  WebLocalFrame* localFrame = webView->mainFrameImpl();
  localFrame->copyImageAt(WebPoint(0, 0));

  EXPECT_NE(sequence, Platform::current()->clipboard()->sequenceNumber(
                          WebClipboard::BufferStandard));

  WebImage image =
      static_cast<WebMockClipboard*>(Platform::current()->clipboard())
          ->readRawImage(WebClipboard::Buffer());

  SkAutoLockPixels autoLock(image.getSkBitmap());
  EXPECT_EQ(SkColorSetARGB(255, 255, 0, 0), image.getSkBitmap().getColor(0, 0));
};

TEST_F(WebFrameTest, CopyImageWithImageMap) {
  SaveImageFromDataURLWebFrameClient client;

  std::string url = m_baseURL + "image-map.html";
  URLTestHelpers::registerMockedURLLoad(toKURL(url), "image-map.html");

  FrameTestHelpers::WebViewHelper helper;
  WebViewImpl* webView = helper.initializeAndLoad(url, true, &client);
  webView->resize(WebSize(400, 400));

  client.reset();
  WebLocalFrame* localFrame = webView->mainFrameImpl();
  localFrame->saveImageAt(WebPoint(25, 25));
  EXPECT_EQ(
      WebString::fromUTF8("data:image/gif;base64"
                          ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
      client.result());

  client.reset();
  localFrame->saveImageAt(WebPoint(75, 25));
  EXPECT_EQ(
      WebString::fromUTF8("data:image/gif;base64"
                          ",R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs="),
      client.result());

  client.reset();
  localFrame->saveImageAt(WebPoint(125, 25));
  EXPECT_EQ(WebString(), client.result());
  // Explicitly reset to break dependency on locally scoped client.
  helper.reset();
}

TEST_F(WebFrameTest, LoadJavascriptURLInNewFrame) {
  FrameTestHelpers::WebViewHelper helper;
  helper.initialize(true);

  WebURLRequest request;
  std::string redirectURL = m_baseURL + "foo.html";
  URLTestHelpers::registerMockedURLLoad(toKURL(redirectURL), "foo.html");
  request.setURL(toKURL("javascript:location='" + redirectURL + "'"));
  request.setRequestorOrigin(WebSecurityOrigin::createUnique());
  helper.webView()->mainFrameImpl()->loadRequest(request);

  // Normally, the result of the JS url replaces the existing contents on the
  // Document. However, if the JS triggers a navigation, the contents should
  // not be replaced.
  EXPECT_EQ("", toLocalFrame(helper.webView()->page()->mainFrame())
                    ->document()
                    ->documentElement()
                    ->innerText());
}

class TestResourcePriorityWebFrameClient
    : public FrameTestHelpers::TestWebFrameClient {
 public:
  class ExpectedRequest {
   public:
    ExpectedRequest(const KURL& url, WebURLRequest::Priority priority)
        : url(url), priority(priority), seen(false) {}

    KURL url;
    WebURLRequest::Priority priority;
    bool seen;
  };

  TestResourcePriorityWebFrameClient() {}

  void willSendRequest(WebLocalFrame*, WebURLRequest& request) override {
    ExpectedRequest* expectedRequest = m_expectedRequests.get(request.url());
    DCHECK(expectedRequest);
    EXPECT_EQ(expectedRequest->priority, request.getPriority());
    expectedRequest->seen = true;
  }

  void addExpectedRequest(const KURL& url, WebURLRequest::Priority priority) {
    m_expectedRequests.add(url, wrapUnique(new ExpectedRequest(url, priority)));
  }

  void verifyAllRequests() {
    for (const auto& request : m_expectedRequests)
      EXPECT_TRUE(request.value->seen);
  }

 private:
  HashMap<KURL, std::unique_ptr<ExpectedRequest>> m_expectedRequests;
};

TEST_F(WebFrameTest, ChangeResourcePriority) {
  TestResourcePriorityWebFrameClient client;
  registerMockedHttpURLLoad("promote_img_in_viewport_priority.html");
  registerMockedHttpURLLoad("image_slow.pl");
  registerMockedHttpURLLoad("image_slow_out_of_viewport.pl");
  client.addExpectedRequest(
      toKURL("http://internal.test/promote_img_in_viewport_priority.html"),
      WebURLRequest::PriorityVeryHigh);
  client.addExpectedRequest(toKURL("http://internal.test/image_slow.pl"),
                            WebURLRequest::PriorityLow);
  client.addExpectedRequest(
      toKURL("http://internal.test/image_slow_out_of_viewport.pl"),
      WebURLRequest::PriorityLow);

  FrameTestHelpers::WebViewHelper helper;
  helper.initialize(true, &client);
  helper.resize(WebSize(640, 480));
  FrameTestHelpers::loadFrame(
      helper.webView()->mainFrame(),
      m_baseURL + "promote_img_in_viewport_priority.html");

  // Ensure the image in the viewport got promoted after the request was sent.
  Resource* image = toWebLocalFrameImpl(helper.webView()->mainFrame())
                        ->frame()
                        ->document()
                        ->fetcher()
                        ->allResources()
                        .get(toKURL("http://internal.test/image_slow.pl"));
  DCHECK(image);
  EXPECT_EQ(ResourceLoadPriorityHigh, image->resourceRequest().priority());

  client.verifyAllRequests();
}

TEST_F(WebFrameTest, ScriptPriority) {
  TestResourcePriorityWebFrameClient client;
  registerMockedHttpURLLoad("script_priority.html");
  registerMockedHttpURLLoad("priorities/defer.js");
  registerMockedHttpURLLoad("priorities/async.js");
  registerMockedHttpURLLoad("priorities/head.js");
  registerMockedHttpURLLoad("priorities/document-write.js");
  registerMockedHttpURLLoad("priorities/injected.js");
  registerMockedHttpURLLoad("priorities/injected-async.js");
  registerMockedHttpURLLoad("priorities/body.js");
  client.addExpectedRequest(toKURL("http://internal.test/script_priority.html"),
                            WebURLRequest::PriorityVeryHigh);
  client.addExpectedRequest(toKURL("http://internal.test/priorities/defer.js"),
                            WebURLRequest::PriorityLow);
  client.addExpectedRequest(toKURL("http://internal.test/priorities/async.js"),
                            WebURLRequest::PriorityLow);
  client.addExpectedRequest(toKURL("http://internal.test/priorities/head.js"),
                            WebURLRequest::PriorityHigh);
  client.addExpectedRequest(
      toKURL("http://internal.test/priorities/document-write.js"),
      WebURLRequest::PriorityHigh);
  client.addExpectedRequest(
      toKURL("http://internal.test/priorities/injected.js"),
      WebURLRequest::PriorityLow);
  client.addExpectedRequest(
      toKURL("http://internal.test/priorities/injected-async.js"),
      WebURLRequest::PriorityLow);
  client.addExpectedRequest(toKURL("http://internal.test/priorities/body.js"),
                            WebURLRequest::PriorityHigh);

  FrameTestHelpers::WebViewHelper helper;
  helper.initializeAndLoad(m_baseURL + "script_priority.html", true, &client);
  client.verifyAllRequests();
}

class MultipleDataChunkDelegate : public WebURLLoaderTestDelegate {
 public:
  void didReceiveData(WebURLLoaderClient* originalClient,
                      WebURLLoader* loader,
                      const char* data,
                      int dataLength,
                      int encodedDataLength) override {
    EXPECT_GT(dataLength, 16);
    originalClient->didReceiveData(loader, data, 16, 16, 16);
    // This didReceiveData call shouldn't crash due to a failed assertion.
    originalClient->didReceiveData(loader, data + 16, dataLength - 16,
                                   encodedDataLength - 16, dataLength - 16);
  }
};

TEST_F(WebFrameTest, ImageDocumentDecodeError) {
  std::string url = m_baseURL + "not_an_image.ico";
  URLTestHelpers::registerMockedURLLoad(toKURL(url), "not_an_image.ico",
                                        "image/x-icon");
  MultipleDataChunkDelegate delegate;
  Platform::current()->getURLLoaderMockFactory()->setLoaderDelegate(&delegate);
  FrameTestHelpers::WebViewHelper helper;
  helper.initializeAndLoad(url, true);
  Platform::current()->getURLLoaderMockFactory()->setLoaderDelegate(nullptr);

  Document* document =
      toLocalFrame(helper.webView()->page()->mainFrame())->document();
  EXPECT_TRUE(document->isImageDocument());
  EXPECT_EQ(Resource::DecodeError,
            toImageDocument(document)->cachedImage()->getStatus());
}

// Load a page with display:none set and try to scroll it. It shouldn't crash
// due to lack of layoutObject. crbug.com/653327.
TEST_F(WebFrameTest, ScrollBeforeLayoutDoesntCrash) {
  registerMockedHttpURLLoad("display-none.html");
  FrameTestHelpers::WebViewHelper webViewHelper;
  webViewHelper.initializeAndLoad(m_baseURL + "display-none.html");
  WebViewImpl* webView = webViewHelper.webView();
  webViewHelper.resize(WebSize(640, 480));

  Document* document = webView->mainFrameImpl()->frame()->document();
  document->documentElement()->setLayoutObject(nullptr);

  WebGestureEvent beginEvent;
  beginEvent.type = WebInputEvent::GestureScrollEnd;
  beginEvent.sourceDevice = WebGestureDeviceTouchpad;
  WebGestureEvent updateEvent;
  updateEvent.type = WebInputEvent::GestureScrollEnd;
  updateEvent.sourceDevice = WebGestureDeviceTouchpad;
  WebGestureEvent endEvent;
  endEvent.type = WebInputEvent::GestureScrollEnd;
  endEvent.sourceDevice = WebGestureDeviceTouchpad;

  // Try GestureScrollEnd and GestureScrollUpdate first to make sure that not
  // seeing a Begin first doesn't break anything. (This currently happens).
  webViewHelper.webView()->handleInputEvent(endEvent);
  webViewHelper.webView()->handleInputEvent(updateEvent);

  // Try a full Begin/Update/End cycle.
  webViewHelper.webView()->handleInputEvent(beginEvent);
  webViewHelper.webView()->handleInputEvent(updateEvent);
  webViewHelper.webView()->handleInputEvent(endEvent);
}

}  // namespace blink
